View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.plsql.symboltable;
5   
6   import java.util.logging.Logger;
7   
8   import net.sourceforge.pmd.lang.ast.Node;
9   import net.sourceforge.pmd.lang.plsql.ast.ASTFormalParameter;
10  import net.sourceforge.pmd.lang.plsql.ast.ASTFormalParameters;
11  import net.sourceforge.pmd.lang.plsql.ast.ASTMethodDeclarator;
12  import net.sourceforge.pmd.lang.plsql.ast.ASTTriggerTimingPointSection;
13  import net.sourceforge.pmd.lang.plsql.ast.AbstractPLSQLNode;
14  import net.sourceforge.pmd.lang.symboltable.AbstractNameDeclaration;
15  
16  public class MethodNameDeclaration extends AbstractNameDeclaration {
17     private final static Logger LOGGER = Logger.getLogger(MethodNameDeclaration.class.getName()); 
18  
19      public MethodNameDeclaration(ASTMethodDeclarator node) {
20          super(node);
21      }
22  
23      /** Treat a TimingPointSection within a Compound Trigger like a 
24       *  packaged FUNCTION or PROCEDURE.
25       *  SRT 
26       * 
27       * @param node 
28       */
29      public MethodNameDeclaration(ASTTriggerTimingPointSection node) {
30          super(node);
31      }
32  
33      public int getParameterCount() {
34          return ((ASTMethodDeclarator) node).getParameterCount();
35      }
36  
37      /**
38       * PL/SQL does not currently allow varargs outside the STANDARD package.
39       * @return false 
40       */
41      public boolean isVarargs() {
42          ASTFormalParameters params = (ASTFormalParameters) node.jjtGetChild(0);
43          for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
44              ASTFormalParameter p = (ASTFormalParameter) params.jjtGetChild(i);
45              //if (p.isVarargs()) {
46              //	return true;
47              //}
48          }
49          return false;
50      }
51  
52      public ASTMethodDeclarator getMethodNameDeclaratorNode() {
53          return (ASTMethodDeclarator) node;
54      }
55  
56      public String getParameterDisplaySignature() {
57      	StringBuilder sb = new StringBuilder("(");
58          ASTFormalParameters params = (ASTFormalParameters) node.jjtGetChild(0);
59          // TODO - this can be optimized - add [0] then ,[n] in a loop.
60          //        no need to trim at the end
61          for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
62              ASTFormalParameter p = (ASTFormalParameter) params.jjtGetChild(i);
63              sb.append(p.getTypeNode().getTypeImage());
64              //if (p.isVarargs()) {
65              //	sb.append("...");
66              //}
67              sb.append(',');
68          }
69          if (sb.charAt(sb.length() - 1) == ',') {
70              sb.deleteCharAt(sb.length() - 1);
71          }
72          sb.append(')');
73          return sb.toString();
74      }
75  
76      @Override
77      public boolean equals(Object o) {
78          if (!(o instanceof MethodNameDeclaration)) {
79              return false;
80          }
81  
82          MethodNameDeclaration other = (MethodNameDeclaration) o;
83  
84          // compare name
85          if (!other.node.getImage().equals(node.getImage())) {
86              return false;
87          }
88  
89          // compare parameter count - this catches the case where there are no params, too
90          if (((ASTMethodDeclarator) other.node).getParameterCount() != ((ASTMethodDeclarator) node).getParameterCount()) {
91              return false;
92          }
93  
94          // compare parameter types
95          //SRT ASTFormalParameters myParams = (ASTFormalParameters) node.jjtGetChild(0);
96          //SRT ASTFormalParameters otherParams = (ASTFormalParameters) other.node.jjtGetChild(0);
97          ASTFormalParameters myParams = node.getFirstDescendantOfType(ASTFormalParameters.class) ;
98          ASTFormalParameters otherParams = other.node.getFirstDescendantOfType(ASTFormalParameters.class) ;
99          for (int i = 0; i < ((ASTMethodDeclarator) node).getParameterCount(); i++) {
100             ASTFormalParameter myParam = (ASTFormalParameter) myParams.jjtGetChild(i);
101             ASTFormalParameter otherParam = (ASTFormalParameter) otherParams.jjtGetChild(i);
102 
103             // Compare vararg
104             //if (myParam.isVarargs() != otherParam.isVarargs()) {
105             //	return false;
106             //}
107 
108             Node myTypeNode = myParam.getTypeNode().jjtGetChild(0);
109             Node otherTypeNode = otherParam.getTypeNode().jjtGetChild(0);
110 
111             // compare primitive vs reference type
112             if (myTypeNode.getClass() != otherTypeNode.getClass()) {
113                 return false;
114             }
115 
116             // simple comparison of type images
117             // this can be fooled by one method using "String"
118             // and the other method using "java.lang.String"
119             // once we get real types in here that should get fixed
120             String myTypeImg;
121             String otherTypeImg;
122             //if (myTypeNode instanceof ASTPrimitiveType) {
123             //    myTypeImg = myTypeNode.getImage();
124             //    otherTypeImg = otherTypeNode.getImage();
125             //} else {
126                 myTypeImg = ( (AbstractPLSQLNode) myTypeNode .jjtGetChild(0) ) .getImage();
127                 otherTypeImg = ( (AbstractPLSQLNode) otherTypeNode.jjtGetChild(0) ).getImage();
128             //}
129 
130             if (!myTypeImg.equals(otherTypeImg)) {
131                 return false;
132             }
133 
134             // if type is ASTPrimitiveType and is an array, make sure the other one is also
135         }
136         return true;
137     }
138 
139     @Override
140     public int hashCode() {
141 	try 
142 	{
143         return node.hashCode(); //SRT node.getImage().hashCode() + ((ASTMethodDeclarator) node).getParameterCount();
144 	}
145 	catch (Exception e)
146 	{
147 	  LOGGER.finest("MethodNameDeclaration problem for " + node
148 			 +" of class " + node.getClass().getCanonicalName()
149 		         +" => "+ node.getBeginLine()+"/"+node.getBeginColumn()
150 			);	
151 	  //@TODO SRT restore the thrown exception - throw e;
152 	  return 0; 
153 	}
154     }
155 
156     @Override
157     public String toString() {
158         //SRT return "Method " + node.getImage() + ", line " + node.getBeginLine() + ", params = " + ((ASTMethodDeclarator) node).getParameterCount();
159         return node.toString();
160     }
161 }