/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.plsql.symboltable;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.plsql.ast.ASTFormalParameter;
import net.sourceforge.pmd.lang.plsql.ast.ASTFormalParameters;
import net.sourceforge.pmd.lang.plsql.ast.ASTMethodDeclarator;
import net.sourceforge.pmd.lang.plsql.ast.ASTTriggerTimingPointSection;
import net.sourceforge.pmd.lang.plsql.ast.AbstractPLSQLNode;
import net.sourceforge.pmd.lang.symboltable.AbstractNameDeclaration;
public class MethodNameDeclaration extends AbstractNameDeclaration {
private static final Logger LOGGER = Logger.getLogger(MethodNameDeclaration.class.getName());
public MethodNameDeclaration(ASTMethodDeclarator node) {
super(node);
}
/**
* Treat a TimingPointSection within a Compound Trigger like a packaged
* FUNCTION or PROCEDURE. SRT
*
* @param node
*/
public MethodNameDeclaration(ASTTriggerTimingPointSection node) {
super(node);
}
public int getParameterCount() {
return ((ASTMethodDeclarator) node).getParameterCount();
}
/**
* PL/SQL does not currently allow varargs outside the STANDARD package.
*
* @return false
*/
public boolean isVarargs() {
return false;
}
public ASTMethodDeclarator getMethodNameDeclaratorNode() {
return (ASTMethodDeclarator) node;
}
public String getParameterDisplaySignature() {
StringBuilder sb = new StringBuilder("(");
ASTFormalParameters params = (ASTFormalParameters) node.jjtGetChild(0);
// TODO - this can be optimized - add [0] then ,[n] in a loop.
// no need to trim at the end
for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
ASTFormalParameter p = (ASTFormalParameter) params.jjtGetChild(i);
sb.append(p.getTypeNode().getTypeImage());
// if (p.isVarargs()) {
// sb.append("...");
// }
sb.append(',');
}
if (sb.charAt(sb.length() - 1) == ',') {
sb.deleteCharAt(sb.length() - 1);
}
sb.append(')');
return sb.toString();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof MethodNameDeclaration)) {
return false;
}
MethodNameDeclaration other = (MethodNameDeclaration) o;
// compare name
if (!other.node.getImage().equals(node.getImage())) {
return false;
}
// compare parameter count - this catches the case where there are no
// params, too
if (((ASTMethodDeclarator) other.node).getParameterCount() != ((ASTMethodDeclarator) node)
.getParameterCount()) {
return false;
}
// compare parameter types
// SRT ASTFormalParameters myParams = (ASTFormalParameters)
// node.jjtGetChild(0);
// SRT ASTFormalParameters otherParams = (ASTFormalParameters)
// other.node.jjtGetChild(0);
ASTFormalParameters myParams = node.getFirstDescendantOfType(ASTFormalParameters.class);
ASTFormalParameters otherParams = other.node.getFirstDescendantOfType(ASTFormalParameters.class);
for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
ASTFormalParameter myParam = (ASTFormalParameter) myParams.jjtGetChild(i);
ASTFormalParameter otherParam = (ASTFormalParameter) otherParams.jjtGetChild(i);
// Compare vararg
// if (myParam.isVarargs() != otherParam.isVarargs()) {
// return false;
// }
Node myTypeNode = myParam.getTypeNode().jjtGetChild(0);
Node otherTypeNode = otherParam.getTypeNode().jjtGetChild(0);
// compare primitive vs reference type
if (myTypeNode.getClass() != otherTypeNode.getClass()) {
return false;
}
// simple comparison of type images
// this can be fooled by one method using "String"
// and the other method using "java.lang.String"
// once we get real types in here that should get fixed
String myTypeImg;
String otherTypeImg;
// if (myTypeNode instanceof ASTPrimitiveType) {
// myTypeImg = myTypeNode.getImage();
// otherTypeImg = otherTypeNode.getImage();
// } else {
myTypeImg = ((AbstractPLSQLNode) myTypeNode.jjtGetChild(0)).getImage();
otherTypeImg = ((AbstractPLSQLNode) otherTypeNode.jjtGetChild(0)).getImage();
// }
if (!myTypeImg.equals(otherTypeImg)) {
return false;
}
// if type is ASTPrimitiveType and is an array, make sure the other
// one is also
}
return true;
}
@Override
public int hashCode() {
try {
// SRT node.getImage().hashCode() + ((ASTMethodDeclarator)node).getParameterCount();
return node.hashCode();
} catch (Exception e) {
if (LOGGER.isLoggable(Level.FINEST)) {
LOGGER.finest(
"MethodNameDeclaration problem for " + node + " of class " + node.getClass().getCanonicalName()
+ " => " + node.getBeginLine() + "/" + node.getBeginColumn());
}
// @TODO SRT restore the thrown exception - throw e;
return 0;
}
}
@Override
public String toString() {
// SRT return "Method " + node.getImage() + ", line " +
// node.getBeginLine() + ", params = " + ((ASTMethodDeclarator)
// node).getParameterCount();
return node.toString();
}
}