001: package javaparser;
002:
003: import snow.utils.StringUtils;
004: import snow.utils.ArrayUtils;
005: import javaparser.javacc_gen.JavaParserConstants;
006: import javaparser.javacc_gen.Token;
007: import java.util.*;
008:
009: /** Some utils.
010: */
011: public final class CCTreeUtils {
012: private CCTreeUtils() {
013: }
014:
015: /** Depth first. used
016: */
017: static void collectChilds(RAWParserTreeNode tn, List<Token> tokens) {
018: if (tn.t != null) {
019: tokens.add(tn.t);
020: return; // a token is terminal
021: }
022:
023: for (RAWParserTreeNode ci : tn.childs) {
024: collectChilds(ci, tokens);
025: }
026: }
027:
028: /** used for extends, implements, ...
029: */
030: public static List<String> collectIdentifiers(
031: RAWParserTreeNode node, String name) {
032: List<String> ids = new ArrayList<String>();
033: for (RAWParserTreeNode ci : node.childs) {
034: if (ci.toString().equals(name)) {
035: ids.add(getImageOfAllSubElements(ci));
036: }
037: }
038: return ids;
039: }
040:
041: /** Depth first.
042: */
043: public static Token getFirstSubchild(RAWParserTreeNode tn) {
044: if (tn.t != null) // first at first level = first
045: {
046: return tn.t;
047: }
048:
049: for (RAWParserTreeNode ci : tn.childs) {
050: Token t = getFirstSubchild(ci);
051: if (t != null)
052: return t;
053: }
054: // none found
055: return null;
056: }
057:
058: /** depth first. used
059: */
060: @tide.annotations.Recurse
061: public static Token getLastSubchild(RAWParserTreeNode tn) {
062: if (tn.t != null) // last at first level = last
063: {
064: return tn.t;
065: }
066:
067: for (int i = tn.childs.size() - 1; i >= 0; i--) // reverse search
068: {
069: RAWParserTreeNode ci = tn.childs.get(i);
070: Token t = getLastSubchild(ci);
071: if (t != null)
072: return t;
073: }
074: // none found
075: return null;
076: }
077:
078: /** if any mod found, a space after is present
079: Annotations are ignored
080: */
081: public static String getModifiers(RAWParserTreeNode mods) {
082: if (mods == null)
083: return "<ERR: no modifiers>"; // ERROR
084: if (mods.getChildCount() == 0)
085: return "";
086: StringBuilder mod = new StringBuilder();
087: for (RAWParserTreeNode ci : mods.childs) {
088: if (!ci.toString().equals("Annotation")) {
089: mod.append(ci);
090: mod.append(" ");
091: }
092: }
093: return mod.toString();
094: }
095:
096: public static boolean methodOverrides(RAWParserTreeNode mods) {
097: if (mods == null)
098: return false; //error
099: for (RAWParserTreeNode ci : mods.childs) {
100: String st = getImageOfAllSubElements(ci);
101: //System.out.println("Method mod: "+ci);
102: // avoid collisions with OverrideMustInvoke
103: if (st.endsWith("@Override"))
104: return true;
105: if (st.endsWith(".Override"))
106: return true; // @java.lang.Override
107: }
108: return false;
109: }
110:
111: /** Hint: if present (true), use methodImplementsAnnParam to fetch the optional value...
112: */
113: public static boolean methodImplementsAnn(RAWParserTreeNode mods) {
114: if (mods == null)
115: return false; //error
116: for (RAWParserTreeNode ci : mods.childs) {
117: String st = getImageOfAllSubElements(ci);
118: //System.out.println("Method mod: "+ci);
119: if (st.contains("@Implements"))
120: return true;
121: if (st.contains(".Implements"))
122: return true;
123: }
124: return false;
125: }
126:
127: /** null if not found.
128: * Lazy method, just looking for any annotation with the simple name "Implements"
129: */
130: public static String methodImplementsAnnParam(RAWParserTreeNode mods) {
131: if (mods == null)
132: return null; //error
133: for (RAWParserTreeNode ci : mods.childs) {
134: String st = getImageOfAllSubElements(ci);
135: //System.out.println("Method mod: "+ci);
136: int pos = st.indexOf("@Implements(");
137: if (pos < 0)
138: pos = st.indexOf(".Implements("); // same length 12
139: if (pos > 0) {
140: return StringUtils.extractFromFirstToNext_Excluded(st
141: .substring(pos + 10), "(", ")");
142: }
143: }
144: return null;
145: }
146:
147: /** Lazy method, just looking for any annotation with the simple name "OverrideMustInvoke"
148: */
149: public static boolean hasOverrideMustInvokeAnnotation(
150: RAWParserTreeNode mods) {
151: if (mods == null)
152: return false; //error
153: for (RAWParserTreeNode ci : mods.childs) {
154: String st = getImageOfAllSubElements(ci);
155: //System.out.println("Method mod: "+ci);
156: if (st.contains("@OverrideMustInvoke"))
157: return true;
158: if (st.contains(".OverrideMustInvoke"))
159: return true;
160: }
161: return false;
162: }
163:
164: /** Lazy method, just looking for any annotation with the simple name "Recurse"
165: */
166: public static boolean hasRecurseAnnotation(RAWParserTreeNode mods) {
167: if (mods == null)
168: return false; //error
169: for (RAWParserTreeNode ci : mods.childs) {
170: String st = getImageOfAllSubElements(ci);
171: //System.out.println("Method mod: "+ci);
172: if (st.contains("@Recurse"))
173: return true;
174: if (st.contains(".Recurse"))
175: return true;
176: }
177: return false;
178: }
179:
180: /** @return a list of all modifiers according to the JavaParserConstants.
181: -1 for unknown !
182: use ArrayUtils.contains()
183: */
184: public static int[] getAllModifiers(final RAWParserTreeNode mods) {
185: if (mods == null)
186: return null; //error
187: List<Integer> modsv = new ArrayList<Integer>();
188: for (RAWParserTreeNode ci : mods.childs) {
189: switch (ci.getTokenKind()) {
190: case -1:
191: break;
192: case JavaParserConstants.PUBLIC:
193: modsv.add(ci.getTokenKind());
194: break;
195: case JavaParserConstants.PRIVATE:
196: modsv.add(ci.getTokenKind());
197: break;
198: case JavaParserConstants.PROTECTED:
199: modsv.add(ci.getTokenKind());
200: break;
201: case JavaParserConstants.FINAL:
202: modsv.add(ci.getTokenKind());
203: break;
204: case JavaParserConstants.STATIC:
205: modsv.add(ci.getTokenKind());
206: break;
207: case JavaParserConstants.ABSTRACT:
208: modsv.add(ci.getTokenKind());
209: break;
210: case JavaParserConstants.STRICTFP:
211: modsv.add(ci.getTokenKind());
212: break;
213: case JavaParserConstants.SYNCHRONIZED:
214: modsv.add(ci.getTokenKind());
215: break;
216: case JavaParserConstants.NATIVE:
217: modsv.add(ci.getTokenKind());
218: break;
219: case JavaParserConstants.TRANSIENT:
220: modsv.add(ci.getTokenKind());
221: break;
222: case JavaParserConstants.VOLATILE:
223: modsv.add(ci.getTokenKind());
224: break;
225: default:
226: modsv.add(-1);
227: break;
228: }
229: }
230: return ArrayUtils.toIntArray(modsv);
231: }
232:
233: /** Recurse in all subtrees.
234: */
235: public static void getAllChildsNamed(RAWParserTreeNode node,
236: String name, List<RAWParserTreeNode> found) {
237: for (RAWParserTreeNode ci : node.childs) {
238: if (ci.toString().equals(name)) {
239: found.add(ci);
240: }
241:
242: // recurse
243: getAllChildsNamed(ci, name, found);
244: }
245: }
246:
247: /** null if none
248: */
249: @edu.umd.cs.findbugs.annotations.CheckForNull
250: public static RAWParserTreeNode getFirstSubchildNamed_ONLYInDirectChilds(
251: RAWParserTreeNode tn, String name) {
252: for (RAWParserTreeNode ci : tn.childs) {
253: if (ci.toString().equals(name))
254: return ci;
255: }
256: // none found
257: return null;
258: }
259:
260: /** null if none, null if tn is null
261: */
262: @edu.umd.cs.findbugs.annotations.CheckForNull
263: public static Token getFirstToken_ONLYInDirectChilds(
264: RAWParserTreeNode tn, int kind) {
265: if (tn == null)
266: return null;
267: for (RAWParserTreeNode ci : tn.childs) {
268: if (ci.t != null && ci.t.kind == kind)
269: return ci.t;
270: }
271: // none found
272: return null;
273: }
274:
275: /** Collects the paramters.
276: */
277: public static List<Parameter> getParameters(
278: RAWParserTreeNode formalParametersNode) {
279: List<Parameter> params = new ArrayList<Parameter>();
280: for (RAWParserTreeNode ci : formalParametersNode.childs) {
281: if (ci.toString().equals("FormalParameter")) {
282: params.add(Parameter.parseFromFormalParamNode(ci));
283: }
284: }
285: return params;
286: }
287:
288: public static String getImageOfAllSubElements(RAWParserTreeNode tn) {
289: ArrayList<Token> tokens = new ArrayList<Token>();
290: collectChilds(tn, tokens);
291: StringBuilder sb = new StringBuilder();
292: for (int i = 0; i < tokens.size(); i++) {
293: //if(i>0) sb.append(" ");
294: sb.append(tokens.get(i).image);
295:
296: }
297: return sb.toString();
298: }
299:
300: }
|