View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.symboltable;
5   
6   import net.sourceforge.pmd.lang.ast.Node;
7   import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
8   import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
9   import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclarator;
10  import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
11  import net.sourceforge.pmd.lang.symboltable.AbstractNameDeclaration;
12  
13  public class MethodNameDeclaration extends AbstractNameDeclaration {
14  
15      public MethodNameDeclaration(ASTMethodDeclarator node) {
16          super(node);
17      }
18  
19      public int getParameterCount() {
20          return ((ASTMethodDeclarator) node).getParameterCount();
21      }
22  
23      public boolean isVarargs() {
24          ASTFormalParameters params = (ASTFormalParameters) node.jjtGetChild(0);
25          for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
26              ASTFormalParameter p = (ASTFormalParameter) params.jjtGetChild(i);
27              if (p.isVarargs()) {
28              	return true;
29              }
30          }
31          return false;
32      }
33  
34      public ASTMethodDeclarator getMethodNameDeclaratorNode() {
35          return (ASTMethodDeclarator) node;
36      }
37  
38      public String getParameterDisplaySignature() {
39      	StringBuilder sb = new StringBuilder("(");
40          ASTFormalParameters params = (ASTFormalParameters) node.jjtGetChild(0);
41          // TODO - this can be optimized - add [0] then ,[n] in a loop.
42          //        no need to trim at the end
43          for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
44              ASTFormalParameter p = (ASTFormalParameter) params.jjtGetChild(i);
45              sb.append(p.getTypeNode().getTypeImage());
46              if (p.isVarargs()) {
47              	sb.append("...");
48              }
49              sb.append(',');
50          }
51          if (sb.charAt(sb.length() - 1) == ',') {
52              sb.deleteCharAt(sb.length() - 1);
53          }
54          sb.append(')');
55          return sb.toString();
56      }
57  
58      @Override
59      public boolean equals(Object o) {
60          if (!(o instanceof MethodNameDeclaration)) {
61              return false;
62          }
63  
64          MethodNameDeclaration other = (MethodNameDeclaration) o;
65  
66          // compare name
67          if (!other.node.getImage().equals(node.getImage())) {
68              return false;
69          }
70  
71          // compare parameter count - this catches the case where there are no params, too
72          if (((ASTMethodDeclarator) other.node).getParameterCount() != ((ASTMethodDeclarator) node).getParameterCount()) {
73              return false;
74          }
75  
76          // compare parameter types
77          ASTFormalParameters myParams = (ASTFormalParameters) node.jjtGetChild(0);
78          ASTFormalParameters otherParams = (ASTFormalParameters) other.node.jjtGetChild(0);
79          for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
80              ASTFormalParameter myParam = (ASTFormalParameter) myParams.jjtGetChild(i);
81              ASTFormalParameter otherParam = (ASTFormalParameter) otherParams.jjtGetChild(i);
82  
83              // Compare vararg
84              if (myParam.isVarargs() != otherParam.isVarargs()) {
85              	return false;
86              }
87  
88              Node myTypeNode = myParam.getTypeNode().jjtGetChild(0);
89              Node otherTypeNode = otherParam.getTypeNode().jjtGetChild(0);
90  
91              // compare primitive vs reference type
92              if (myTypeNode.getClass() != otherTypeNode.getClass()) {
93                  return false;
94              }
95  
96              // simple comparison of type images
97              // this can be fooled by one method using "String"
98              // and the other method using "java.lang.String"
99              // once we get real types in here that should get fixed
100             String myTypeImg;
101             String otherTypeImg;
102             if (myTypeNode instanceof ASTPrimitiveType) {
103                 myTypeImg = myTypeNode.getImage();
104                 otherTypeImg = otherTypeNode.getImage();
105             } else {
106                 myTypeImg = myTypeNode.jjtGetChild(0).getImage();
107                 otherTypeImg = otherTypeNode.jjtGetChild(0).getImage();
108             }
109 
110             if (!myTypeImg.equals(otherTypeImg)) {
111                 return false;
112             }
113 
114             // if type is ASTPrimitiveType and is an array, make sure the other one is also
115         }
116         return true;
117     }
118 
119     @Override
120     public int hashCode() {
121         return node.getImage().hashCode() + ((ASTMethodDeclarator) node).getParameterCount();
122     }
123 
124     @Override
125     public String toString() {
126         return "Method " + node.getImage() + ", line " + node.getBeginLine() + ", params = " + ((ASTMethodDeclarator) node).getParameterCount();
127     }
128 }