001: package javaparser;
002:
003: import tide.utils.SyntaxUtils;
004: import java.util.*;
005: import javaparser.javacc_gen.*;
006:
007: public class MethodNode extends ParserTreeNode implements NodeWithMod {
008: // true if the Override annotation is present.
009: // makes sense to record because retention is source => no more present in the class
010: // so our internal analysis must use the javaCC parsed Override info.
011: public boolean override_ = false;
012: public boolean implements _ = false;
013:
014: // true if present @edu.umd.cs.findbugs.annotations.OverrideMustInvoke or any same name annot.
015: public boolean overrideMustInvoke = false;
016: public boolean hasRecurseAnnotation = false;
017:
018: public int[] modifiers;
019: public String resultType = "";
020: public String name = "";
021: String paramsS = "";
022: public String modifiersShort = "";
023: String typeParameters = null;
024: // (int a, double b)
025: public final List<Parameter> params;
026:
027: // abstract methods may have null block !
028: public Token blokStart, blokEnd;
029:
030: public MethodNode(RAWParserTreeNode methodDeclarationNode,
031: RAWParserTreeNode modNode) {
032: super ("method");
033:
034: this .sortPriority = 1;
035:
036: this .modifiers = CCTreeUtils.getAllModifiers(modNode);
037: this .override_ = CCTreeUtils.methodOverrides(modNode);
038: this .implements _ = CCTreeUtils.methodImplementsAnn(modNode);
039:
040: if (this .implements _) {
041: String arg = CCTreeUtils.methodImplementsAnnParam(modNode);
042: System.out.println("@Impl ARG=" + arg);
043: }
044:
045: this .overrideMustInvoke = CCTreeUtils
046: .hasOverrideMustInvokeAnnotation(modNode);
047: this .hasRecurseAnnotation = CCTreeUtils
048: .hasRecurseAnnotation(modNode);
049:
050: modifiersShort = Utils.getModifiersShortString(this .modifiers);
051:
052: if (modNode.getChildCount() > 0) {
053: this .setStartPosFrom(CCTreeUtils.getFirstSubchild(modNode));
054: } else {
055: this .setStartPosFrom(CCTreeUtils
056: .getFirstSubchild(methodDeclarationNode));
057: }
058: this .setEndPosFrom(CCTreeUtils
059: .getLastSubchild(methodDeclarationNode));
060:
061: //TODO: typeParameters
062: RAWParserTreeNode tp = CCTreeUtils
063: .getFirstSubchildNamed_ONLYInDirectChilds(
064: methodDeclarationNode, "TypeParameters");
065: if (tp != null) {
066: typeParameters = CCTreeUtils.getImageOfAllSubElements(tp);
067: }
068:
069: // childs: {ResultType, VariableDeclarator}
070: RAWParserTreeNode tn = CCTreeUtils
071: .getFirstSubchildNamed_ONLYInDirectChilds(
072: methodDeclarationNode, "ResultType");
073: //methodDeclarationNode.getChildNodeAt(0); //no, sometime ParameterTypes
074: //ParserTreeNode vdn = fieldDeclarationNode.getChildNodeAt(1); // a=1
075: //ParserTreeNode vdidn = vdn.getChildNodeAt(0); // VariableDeclaratorId
076: this .resultType = CCTreeUtils.getImageOfAllSubElements(tn);
077:
078: RAWParserTreeNode md = CCTreeUtils
079: .getFirstSubchildNamed_ONLYInDirectChilds(
080: methodDeclarationNode, "MethodDeclarator");
081: this .name = md.getChildNodeAt(0).toString();
082:
083: RAWParserTreeNode block = CCTreeUtils
084: .getFirstSubchildNamed_ONLYInDirectChilds(
085: methodDeclarationNode, "Block");
086: if (block != null && block.getChildCount() > 1) {
087: for (int i = 0; i < block.getChildCount(); i++) {
088: RAWParserTreeNode ci = block.getChildNodeAt(i);
089: if (ci.getTokenKind() == JavaParserConstants.LBRACE) {
090: blokStart = ci.t;
091: } else if (ci.getTokenKind() == JavaParserConstants.RBRACE) {
092: blokEnd = ci.t;
093: }
094: }
095: }
096:
097: RAWParserTreeNode fp = CCTreeUtils
098: .getFirstSubchildNamed_ONLYInDirectChilds(md,
099: "FormalParameters");
100: this .params = CCTreeUtils.getParameters(fp);
101: this .paramsS = Utils.toStringWithoutBraces(this .params);
102:
103: } // Constructor
104:
105: public final int[] getModifiers() {
106: return modifiers;
107: }
108:
109: public final boolean isStatic() {
110: return Utils.isStatic(modifiers);
111: }
112:
113: public final boolean isPublic() {
114: return Utils.isPublic(modifiers);
115: }
116:
117: public final boolean isPrivate() {
118: return Utils.isPrivate(modifiers);
119: }
120:
121: public final boolean isProtected() {
122: return Utils.isProtected(modifiers);
123: }
124:
125: public boolean isPublicStaticMainMethod() {
126: if (!isPublic())
127: return false;
128: if (!isStatic())
129: return false;
130:
131: if (!"main".equals(name))
132: return false;
133: if (!"void".equals(resultType))
134: return false;
135:
136: // ensure one single param: a string !
137: if (paramsS.contains(","))
138: return false;
139: if (!paramsS.contains("String[] "))
140: return false;
141:
142: return true;
143: }
144:
145: /** Call this to help GC !
146: */
147: @Override
148: public void terminate() {
149: super .terminate();
150:
151: if (params != null)
152: params.clear();
153: blokStart = null;
154: blokEnd = null;
155: modifiers = null;
156: modifiersShort = null;
157: name = null;
158: resultType = null;
159: paramsS = null;
160: }
161:
162: /** [Dec2007]: removed "returns", just appending the return type.
163: */
164: @Override
165: public String toString() {
166: if (name == null)
167: return "######";
168: if ("void".equals(resultType))
169: return name
170: + "("
171: + paramsS
172: + ")"
173: + (typeParameters != null ? " " + typeParameters
174: : "");
175: return name + "(" + paramsS + ")"
176: + (typeParameters != null ? " " + typeParameters : "")
177: + " " + resultType;
178: }
179:
180: /** name + % + nargs. */
181: public String getSignatureSimplified1() {
182: return name + "%" + params.size();
183: }
184:
185: /** Name and simple arg names (without generics). */
186: public String getSignatureSimplified2() {
187: if (params.isEmpty())
188: return name + "()";
189:
190: StringBuilder sb = new StringBuilder(30);
191: sb.append(name);
192: sb.append("(");
193: for (Parameter pi : params) {
194: sb.append(SyntaxUtils.removeSingleTypeParameters(pi.type)); // Vector<String> => Vector
195: sb.append(",");
196: }
197: sb.setLength(sb.length() - 1); // remove last ","
198: sb.append(")");
199:
200: return sb.toString();
201: }
202:
203: }
|