001: package javaparser;
002:
003: import java.awt.Color;
004: import tide.editor.MainEditorFrame;
005: import javaparser.javacc_gen.*;
006: import java.util.*;
007: import tide.editor.UIConstants;
008: import tide.syntaxtree.*;
009:
010: /** class or interface.
011: */
012: public class ClassNode extends TypeNode {
013: public String classOrInterface, name, fullName;
014: final public boolean isInterface;
015: public int[] modifiersInt;
016: public String modifiers = ""; // without main mod "public private, .."
017: public String typeparameters = "";
018: public List<String> implements List = new ArrayList<String>();
019: public List<String> extendsList = new ArrayList<String>();
020: private String extendsImplementsText = "";
021: // used in ID chain
022: public String extendsText = null;
023:
024: /*
025: // methods, fields, class, ...
026: public ParserTreeNode publicChilds = new MainModifierNode("public", UIConstants.blue);
027: public ParserTreeNode packageScopeChilds = new MainModifierNode("package scope", UIConstants.brown);
028: public ParserTreeNode protectedChilds = new MainModifierNode("protected", UIConstants.brown);
029: public ParserTreeNode privateChilds = new MainModifierNode("private", UIConstants.brown);
030: */
031: /** The main category of modifier.
032: */
033: enum MainModifier {
034: Public, Private, Protected, PackageScope
035: }
036:
037: public ClassNode(SimplifiedSyntaxTree2 sst,
038: RAWParserTreeNode classOrInterfaceDeclarationNode,
039: RAWParserTreeNode modNode, ParserTreeNode destination,
040: TypeNode parentType) {
041: super ("class or interface", sst, parentType,
042: classOrInterfaceDeclarationNode);
043:
044: this .sortPriority = 4;
045: this .expandInView = true;
046:
047: RAWParserTreeNode classOrInterfaceN = classOrInterfaceDeclarationNode
048: .getChildNodeAt(0);
049: RAWParserTreeNode nameN = classOrInterfaceDeclarationNode
050: .getChildNodeAt(1);
051:
052: if (modNode.getChildCount() > 0) {
053: this .modifiersInt = CCTreeUtils.getAllModifiers(modNode);
054: this .modifiers = Utils
055: .getModifiersWithoutAccessModifiersFullString(modifiersInt);
056: // OLD CCTreeUtils.getNonAccessModifiers(modNode);
057: this .setStartPosFrom(CCTreeUtils.getFirstSubchild(modNode));
058: } else {
059: this .setStartPosFrom(CCTreeUtils
060: .getFirstSubchild(classOrInterfaceN));
061: modifiersInt = new int[0];
062: }
063:
064: this .classOrInterface = classOrInterfaceN.toString();
065: isInterface = this .classOrInterface
066: .equalsIgnoreCase("interface");
067: this .name = nameN.toString();
068:
069: StringBuilder fn = new StringBuilder();
070: if (parentType != null) {
071: fn.append(parentType.getJavaFullName());
072: fn.append("$"); // inner classes
073: } else {
074: fn.append(sst.packageNode.toString());
075: if (fn.length() > 0)
076: fn.append("."); // may be the root package (no name)
077: }
078:
079: fn.append(name);
080:
081: fullName = fn.toString();
082: /*
083: add(publicChilds);
084: //if( !classOrInterface.equals("interface") ) // interface have only public attributes
085: add(packageScopeChilds);
086: add(protectedChilds);
087: add(privateChilds);
088: */
089:
090: if (parentType == null) {
091: destination.add(this ); // [Jan2007]: was only unsorted
092: } else {
093: Utils.sortedInsert(this , destination); // try... ??? not always fine...
094: }
095:
096: RAWParserTreeNode tpNode = CCTreeUtils
097: .getFirstSubchildNamed_ONLYInDirectChilds(
098: classOrInterfaceDeclarationNode,
099: "TypeParameters");
100: if (tpNode != null) {
101: this .typeparameters = CCTreeUtils
102: .getImageOfAllSubElements(tpNode);
103: }
104:
105: RAWParserTreeNode ciNode = CCTreeUtils
106: .getFirstSubchildNamed_ONLYInDirectChilds(
107: classOrInterfaceDeclarationNode,
108: "ClassOrInterfaceBody");
109: if (ciNode != null) {
110: //System.out.println("has ClassOrInterfaceBody");
111: this .parseClassOrInterfaceBody(ciNode);
112: }
113:
114: RAWParserTreeNode impNode = CCTreeUtils
115: .getFirstSubchildNamed_ONLYInDirectChilds(
116: classOrInterfaceDeclarationNode,
117: "ImplementsList");
118: if (impNode != null) {
119: this .implements List = CCTreeUtils.collectIdentifiers(
120: impNode, "ClassOrInterfaceType");
121: extendsImplementsText += " impl "
122: + Utils.toStringWithoutBraces(implements List);
123:
124: /*ParserTreeNode n = new MainNode(extendsImplementsText, "implements", Color.darkGray, true);
125: n.setStartPosFrom( CCTreeUtils.getFirstSubchild(impNode) );
126: n.setEndPosFrom( CCTreeUtils.getLastSubchild(impNode) );
127: this.insert(n, 0);*/
128: }
129:
130: RAWParserTreeNode extNode = CCTreeUtils
131: .getFirstSubchildNamed_ONLYInDirectChilds(
132: classOrInterfaceDeclarationNode, "ExtendsList");
133: if (extNode != null) {
134:
135: this .extendsList = CCTreeUtils.collectIdentifiers(extNode,
136: "ClassOrInterfaceType");
137: extendsText = Utils.toStringWithoutBraces(extendsList);
138: extendsImplementsText += " ext " + extendsText;
139:
140: /*
141: ParserTreeNode n = new MainNode(extendsText, "extends", Color.darkGray, true);
142: n.setStartPosFrom( CCTreeUtils.getFirstSubchild(extNode) );
143: n.setEndPosFrom( CCTreeUtils.getLastSubchild(extNode) );
144: this.insert(n, 0);*/
145: }
146: } // Constructor
147:
148: /** Call this to help GC !
149: */
150: @Override
151: public void terminate() {
152: super .terminate();
153:
154: implements List.clear();
155: extendsList.clear();
156:
157: extendsImplementsText = null;
158: extendsText = null;
159: modifiers = null;
160: modifiersInt = null;
161: /*
162: packageScopeChilds = null;
163: privateChilds = null;
164: protectedChilds = null;
165: publicChilds = null;
166: */
167: typeparameters = null;
168:
169: classOrInterface = null;
170: name = null;
171: fullName = null;
172:
173: }
174:
175: @Override
176: public String toString() {
177: return modifiers + " " + name + typeparameters
178: + extendsImplementsText;
179: }
180:
181: /** the simple name... without the parent, even for inner classes.
182: */
183: @Override
184: public String getTypeSimpleName() {
185: return name;
186: }
187:
188: /** With the package name.
189: */
190: @Override
191: public String getJavaFullName() {
192: return fullName;
193: }
194:
195: @Override
196: public int[] getModifiers() {
197: return this .modifiersInt;
198: }
199:
200: @Override
201: public boolean isPublic() {
202: return Utils.isPublic(modifiersInt);
203: }
204:
205: public boolean isPrivate() {
206: return Utils.isPrivate(modifiersInt);
207: }
208:
209: public boolean isProtected() {
210: return Utils.isProtected(modifiersInt);
211: }
212:
213: public boolean isStatic() {
214: return Utils.isStatic(modifiersInt);
215: }
216:
217: /** parse the fields, enums, methods, constructors and add them to this class,
218: removing original nodes
219: */
220: private void parseClassOrInterfaceBody(
221: RAWParserTreeNode classOrInterfaceBodyNode) {
222:
223: this .setEndPosFrom(CCTreeUtils
224: .getLastSubchild(classOrInterfaceBodyNode)); // normally "}"
225:
226: for (int i = 0; i < classOrInterfaceBodyNode.getChildCount(); i++) {
227: RAWParserTreeNode ni = classOrInterfaceBodyNode
228: .getChildNodeAt(i);
229: if (ni.getTokenKind() == JavaParserConstants.LBRACE) // {
230: {
231: blokStart = ni.t;
232: } else if (ni.getTokenKind() == JavaParserConstants.RBRACE) {
233: blokEnd = ni.t;
234: } else if (ni.toString().equals(
235: "ClassOrInterfaceBodyDeclaration")) {
236: if (ni.getChildCount() == 1) {
237: // special cases
238: RAWParserTreeNode ci = ni.getChildNodeAt(0);
239: if (ci.toString().equals(";")) {
240: if (MainEditorFrame.instance.enableParserWarnings
241: .isSelected()) {
242: WarningNode warn = new WarningNode(
243: "unuseful semicolon", 2);
244: warn.setStartPosFrom(CCTreeUtils
245: .getFirstSubchild(ni
246: .getChildNodeAt(0)));
247: warn.setEndPosFrom(CCTreeUtils
248: .getFirstSubchild(ni
249: .getChildNodeAt(0)));
250: super .simplifiedSyntaxTree2
251: .addWarning(warn);
252: }
253: continue;
254: } else if (ci.toString().equals("Initializer")) {
255: addClassOrInterfaceBodyDeclaration(
256: simplifiedSyntaxTree2, ni,
257: this /*privateChilds*/, this );
258: continue;
259: }
260: }
261:
262: RAWParserTreeNode modNode = CCTreeUtils
263: .getFirstSubchildNamed_ONLYInDirectChilds(ni,
264: "Modifiers");
265: if (modNode == null) {
266: System.out.println("No modifier node found ! "
267: + this .toString());
268: addClassOrInterfaceBodyDeclaration(
269: this .simplifiedSyntaxTree2, ni,
270: this /*protectedChilds*/, this );
271: } else {
272: switch (getModifier(modNode)) {
273: // [March2008]: direct add to this instead of the modifier !
274: case Public:
275: addClassOrInterfaceBodyDeclaration(
276: this .simplifiedSyntaxTree2, ni,
277: this /*publicChilds*/, this );
278: break;
279: case Private:
280: addClassOrInterfaceBodyDeclaration(
281: this .simplifiedSyntaxTree2, ni,
282: this /*privateChilds*/, this );
283: break;
284: case Protected:
285: addClassOrInterfaceBodyDeclaration(
286: this .simplifiedSyntaxTree2, ni,
287: this /*protectedChilds*/, this );
288: break;
289: case PackageScope:
290: addClassOrInterfaceBodyDeclaration(
291: this .simplifiedSyntaxTree2, ni,
292: this /*packageScopeChilds*/, this );
293: break;
294: }
295: }
296:
297: // analyse field, method, constructor, ...
298: }
299: }
300:
301: /*
302: // terminated
303: if(publicChilds.getChildCount()==0) publicChilds.removeFromParent();
304: if(privateChilds.getChildCount()==0) privateChilds.removeFromParent();
305: if(protectedChilds.getChildCount()==0) protectedChilds.removeFromParent();
306: if(packageScopeChilds.getChildCount()==0) packageScopeChilds.removeFromParent();
307: */
308: }
309:
310: public MainModifier getModifier(ParserTreeNode modifNode) {
311: if (classOrInterface.equals("interface")) {
312: // interface have only public attributes
313: return MainModifier.Public;
314: }
315: if (Utils.getFirstToken_ONLYInDirectChilds(modifNode,
316: JavaParserConstants.PUBLIC) != null)
317: return MainModifier.Public;
318: if (Utils.getFirstToken_ONLYInDirectChilds(modifNode,
319: JavaParserConstants.PRIVATE) != null)
320: return MainModifier.Private;
321: if (Utils.getFirstToken_ONLYInDirectChilds(modifNode,
322: JavaParserConstants.PROTECTED) != null)
323: return MainModifier.Protected;
324: return MainModifier.PackageScope;
325: }
326:
327: public MainModifier getModifier(RAWParserTreeNode modifNode) {
328: if (classOrInterface.equals("interface")) {
329: // interface have only public attributes
330: return MainModifier.Public;
331: }
332: if (CCTreeUtils.getFirstToken_ONLYInDirectChilds(modifNode,
333: JavaParserConstants.PUBLIC) != null)
334: return MainModifier.Public;
335: if (CCTreeUtils.getFirstToken_ONLYInDirectChilds(modifNode,
336: JavaParserConstants.PRIVATE) != null)
337: return MainModifier.Private;
338: if (CCTreeUtils.getFirstToken_ONLYInDirectChilds(modifNode,
339: JavaParserConstants.PROTECTED) != null)
340: return MainModifier.Protected;
341: return MainModifier.PackageScope;
342: }
343:
344: /** add all methods, constructors, fields of the body
345: * @param cibd ClassOrInterfaceBodyDeclaration node
346: child0 is modifiers
347: child1 is one of { EnumDeclaration, ConstructorDeclaration,
348: MethodDeclaration, FieldDeclaration,
349: ClassOrInterfaceDeclaration }
350:
351: special case: static initializer have no modifier node.
352: also used in the enum
353: */
354: public static void addClassOrInterfaceBodyDeclaration(
355: SimplifiedSyntaxTree2 sst, RAWParserTreeNode cibd,
356: ParserTreeNode destination, TypeNode parentType) {
357: RAWParserTreeNode mod = cibd.childs.get(0);
358: RAWParserTreeNode decl = null;
359: if (mod.toString().equals("Initializer")) {
360: // special case: static initializer have no modifier node.
361: decl = mod;
362: mod = null;
363: } else {
364: if (cibd.getChildCount() == 1) {
365: System.out.println("Only one child: " + mod.toString()
366: + " in " + cibd.toString() + " parent type = "
367: + parentType.toString());
368: decl = mod;
369: mod = null;
370: } else {
371: decl = cibd.childs.get(1);
372: if (decl.toString().equals("TypeParameter")) // [Oct2007]
373: {
374: decl = cibd.childs.get(2);
375: }
376: }
377: }
378:
379: if (decl.toString().equals("EnumDeclaration")) {
380: EnumNode en = new EnumNode(sst, decl, mod, parentType);
381: sst.getAllTypes().add(en);
382: Utils.sortedInsert(en, destination);
383: } else if (decl.toString().equals("ConstructorDeclaration")) {
384: ConstructorNode cn = new ConstructorNode(decl, mod);
385: Utils.sortedInsert(cn, destination);
386: } else if (decl.toString().equals("MethodDeclaration")) {
387: MethodNode mn = new MethodNode(decl, mod);
388: Utils.sortedInsert(mn, destination);
389: } else if (decl.toString().equals("FieldDeclaration")) {
390: // childs: {Type, VariableDeclarator}
391: FieldNode fn = new FieldNode(decl, mod, destination);
392: } else if (decl.toString()
393: .equals("ClassOrInterfaceDeclaration")) {
394: // recurse !
395: ClassNode cn = new ClassNode(sst, decl, mod, destination,
396: parentType); // add itself
397: sst.getAllTypes().add(cn);
398: } else if (decl.toString().equals("Initializer")) {
399: //System.out.println("initializer node found");
400: StaticInitializerNode sin = new StaticInitializerNode(decl);
401: destination.insert(sin, 0);
402: } else {
403: System.out.println("Unknown node found: " + decl.toString()
404: + " in " + parentType.toString());
405: }
406: }
407:
408: }
|