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