0001: package tide.syntaxtree;
0002:
0003: import snow.utils.StringUtils;
0004: import tide.sources.*;
0005: import tide.editor.*; // copied from DumpVisitor
0006: import java.util.*;
0007: import java.io.*;
0008: import japa.parser.*;
0009: import japa.parser.ast.visitor.*;
0010: import japa.parser.ast.CompilationUnit;
0011: import japa.parser.ast.ImportDeclaration;
0012: import japa.parser.ast.Node;
0013: import japa.parser.ast.PackageDeclaration;
0014: import japa.parser.ast.TypeParameter;
0015: import japa.parser.ast.body.AnnotationDeclaration;
0016: import japa.parser.ast.body.AnnotationMemberDeclaration;
0017: import japa.parser.ast.body.BodyDeclaration;
0018: import japa.parser.ast.body.ClassOrInterfaceDeclaration;
0019: import japa.parser.ast.body.ConstructorDeclaration;
0020: import japa.parser.ast.body.EmptyMemberDeclaration;
0021: import japa.parser.ast.body.EmptyTypeDeclaration;
0022: import japa.parser.ast.body.EnumConstantDeclaration;
0023: import japa.parser.ast.body.EnumDeclaration;
0024: import japa.parser.ast.body.FieldDeclaration;
0025: import japa.parser.ast.body.InitializerDeclaration;
0026: import japa.parser.ast.body.MethodDeclaration;
0027: import japa.parser.ast.body.ModifierSet;
0028: import japa.parser.ast.body.Parameter;
0029: import japa.parser.ast.body.TypeDeclaration;
0030: import japa.parser.ast.body.VariableDeclarator;
0031: import japa.parser.ast.body.VariableDeclaratorId;
0032: import japa.parser.ast.expr.AnnotationExpr;
0033: import japa.parser.ast.expr.ArrayAccessExpr;
0034: import japa.parser.ast.expr.ArrayCreationExpr;
0035: import japa.parser.ast.expr.ArrayInitializerExpr;
0036: import japa.parser.ast.expr.AssignExpr;
0037: import japa.parser.ast.expr.BinaryExpr;
0038: import japa.parser.ast.expr.BooleanLiteralExpr;
0039: import japa.parser.ast.expr.CastExpr;
0040: import japa.parser.ast.expr.CharLiteralExpr;
0041: import japa.parser.ast.expr.ClassExpr;
0042: import japa.parser.ast.expr.ConditionalExpr;
0043: import japa.parser.ast.expr.DoubleLiteralExpr;
0044: import japa.parser.ast.expr.EnclosedExpr;
0045: import japa.parser.ast.expr.Expression;
0046: import japa.parser.ast.expr.FieldAccessExpr;
0047: import japa.parser.ast.expr.InstanceOfExpr;
0048: import japa.parser.ast.expr.IntegerLiteralExpr;
0049: import japa.parser.ast.expr.IntegerLiteralMinValueExpr;
0050: import japa.parser.ast.expr.LongLiteralExpr;
0051: import japa.parser.ast.expr.LongLiteralMinValueExpr;
0052: import japa.parser.ast.expr.MarkerAnnotationExpr;
0053: import japa.parser.ast.expr.MemberValuePair;
0054: import japa.parser.ast.expr.MethodCallExpr;
0055: import japa.parser.ast.expr.NameExpr;
0056: import japa.parser.ast.expr.NormalAnnotationExpr;
0057: import japa.parser.ast.expr.NullLiteralExpr;
0058: import japa.parser.ast.expr.ObjectCreationExpr;
0059: import japa.parser.ast.expr.QualifiedNameExpr;
0060: import japa.parser.ast.expr.SingleMemberAnnotationExpr;
0061: import japa.parser.ast.expr.StringLiteralExpr;
0062: import japa.parser.ast.expr.SuperExpr;
0063: import japa.parser.ast.expr.SuperMemberAccessExpr;
0064: import japa.parser.ast.expr.ThisExpr;
0065: import japa.parser.ast.expr.UnaryExpr;
0066: import japa.parser.ast.expr.VariableDeclarationExpr;
0067: import japa.parser.ast.stmt.AssertStmt;
0068: import japa.parser.ast.stmt.BlockStmt;
0069: import japa.parser.ast.stmt.BreakStmt;
0070: import japa.parser.ast.stmt.CatchClause;
0071: import japa.parser.ast.stmt.ContinueStmt;
0072: import japa.parser.ast.stmt.DoStmt;
0073: import japa.parser.ast.stmt.EmptyStmt;
0074: import japa.parser.ast.stmt.ExplicitConstructorInvocationStmt;
0075: import japa.parser.ast.stmt.ExpressionStmt;
0076: import japa.parser.ast.stmt.ForStmt;
0077: import japa.parser.ast.stmt.ForeachStmt;
0078: import japa.parser.ast.stmt.IfStmt;
0079: import japa.parser.ast.stmt.LabeledStmt;
0080: import japa.parser.ast.stmt.ReturnStmt;
0081: import japa.parser.ast.stmt.Statement;
0082: import japa.parser.ast.stmt.SwitchEntryStmt;
0083: import japa.parser.ast.stmt.SwitchStmt;
0084: import japa.parser.ast.stmt.SynchronizedStmt;
0085: import japa.parser.ast.stmt.ThrowStmt;
0086: import japa.parser.ast.stmt.TryStmt;
0087: import japa.parser.ast.stmt.TypeDeclarationStmt;
0088: import japa.parser.ast.stmt.WhileStmt;
0089: import japa.parser.ast.type.ClassOrInterfaceType;
0090: import japa.parser.ast.type.PrimitiveType;
0091: import japa.parser.ast.type.ReferenceType;
0092: import japa.parser.ast.type.Type;
0093: import japa.parser.ast.type.VoidType;
0094: import japa.parser.ast.type.WildcardType;
0095:
0096: import java.util.Iterator;
0097: import java.util.List;
0098:
0099: /**
0100: * To discover structure. A copy of DumpVisitor with print statements uncommented.
0101: */
0102: public final class JapaDependenciesDetector implements
0103: VoidVisitor<Object> {
0104:
0105: public final Set<String> typeNamesUsed = new HashSet<String>();
0106: public final Set<String> expressionsToResolve = new HashSet<String>();
0107:
0108: public void reset() {
0109: typeNamesUsed.clear();
0110: expressionsToResolve.clear();
0111: }
0112:
0113: private void scanModifiers(int modifiers) {
0114: if (ModifierSet.isPrivate(modifiers)) {
0115: //printer.print("private ");
0116: }
0117: if (ModifierSet.isProtected(modifiers)) {
0118: //printer.print("protected ");
0119: }
0120: if (ModifierSet.isPublic(modifiers)) {
0121: //printer.print("public ");
0122: }
0123: if (ModifierSet.isAbstract(modifiers)) {
0124: //printer.print("abstract ");
0125: }
0126: if (ModifierSet.isFinal(modifiers)) {
0127: //printer.print("final ");
0128: }
0129: if (ModifierSet.isNative(modifiers)) {
0130: //printer.print("native ");
0131: }
0132: if (ModifierSet.isStatic(modifiers)) {
0133: //printer.print("static ");
0134: }
0135: if (ModifierSet.isStrictfp(modifiers)) {
0136: //printer.print("strictfp ");
0137: }
0138: if (ModifierSet.isSynchronized(modifiers)) {
0139: //printer.print("synchronized ");
0140: }
0141: if (ModifierSet.isTransient(modifiers)) {
0142: //printer.print("transient ");
0143: }
0144: if (ModifierSet.isVolatile(modifiers)) {
0145: //printer.print("volatile ");
0146: }
0147: }
0148:
0149: private void printMembers(List<BodyDeclaration> members, Object arg) {
0150: for (final BodyDeclaration member : members) {
0151: //printer.printLn();
0152: member.accept(this , arg);
0153: //printer.printLn();
0154: }
0155: }
0156:
0157: private void scanMemberAnnotations(
0158: List<AnnotationExpr> annotations, Object arg) {
0159: if (annotations != null) {
0160: for (AnnotationExpr a : annotations) {
0161: a.accept(this , arg);
0162: //printer.printLn();
0163: }
0164: }
0165: }
0166:
0167: private void printAnnotations(List<AnnotationExpr> annotations,
0168: Object arg) {
0169: if (annotations != null) {
0170: for (AnnotationExpr a : annotations) {
0171: a.accept(this , arg);
0172: //printer.print(" ");
0173: }
0174: }
0175: }
0176:
0177: private void printTypeArgs(List<Type> args, Object arg) {
0178: if (args != null) {
0179: //printer.print("<");
0180: for (Iterator<Type> i = args.iterator(); i.hasNext();) {
0181: Type t = i.next();
0182: t.accept(this , arg);
0183: if (i.hasNext()) {
0184: //printer.print(", ");
0185: }
0186: }
0187: //printer.print(">");
0188: }
0189: }
0190:
0191: // ok
0192: private void printTypeParameters(List<TypeParameter> args,
0193: Object arg) {
0194: if (args != null) {
0195: //printer.print("<");
0196: for (Iterator<TypeParameter> i = args.iterator(); i
0197: .hasNext();) {
0198: TypeParameter t = i.next();
0199: t.accept(this , arg);
0200: if (i.hasNext()) {
0201: //printer.print(", ");
0202: }
0203: }
0204: //printer.print(">");
0205: }
0206: }
0207:
0208: // ok
0209: public void visit(Node n, Object arg) {
0210: throw new IllegalStateException(n.getClass().getName());
0211: }
0212:
0213: // ok, import doesn't mean use ! (could be used to detect unused imports)
0214: public void visit(CompilationUnit n, Object arg) {
0215: if (n.pakage != null) {
0216: n.pakage.accept(this , arg);
0217: }
0218: if (n.imports != null) {
0219: for (ImportDeclaration i : n.imports) {
0220: i.accept(this , arg);
0221: }
0222: //printer.printLn();
0223: }
0224: if (n.types != null) {
0225: for (TypeDeclaration i : n.types) {
0226: i.accept(this , arg);
0227: //printer.printLn();
0228: }
0229: }
0230: }
0231:
0232: // ok in the annotations
0233: public void visit(PackageDeclaration n, Object arg) {
0234: printAnnotations(n.annotations, arg);
0235: //printer.print("package ");
0236: n.name.accept(this , arg);
0237: //printer.printLn(";");
0238: //printer.printLn();
0239: }
0240:
0241: // here comes the throws...
0242: // too much !!
0243: public void visit(NameExpr n, Object arg) {
0244: //printer.print(n.name);
0245: //System.out.println("NameExpr "+n.name);
0246: }
0247:
0248: public void visit(QualifiedNameExpr n, Object arg) {
0249: n.qualifier.accept(this , arg);
0250: //printer.print(".");
0251: //printer.print(n.name);
0252: }
0253:
0254: public void visit(ImportDeclaration n, Object arg) {
0255: //printer.print("import ");
0256: if (n.isStatic) {
0257: //printer.print("static ");
0258: }
0259: n.name.accept(this , arg);
0260: if (n.isAsterisk) {
0261: //printer.print(".*");
0262: }
0263: //printer.printLn(";");
0264: }
0265:
0266: // ok in extends, implements
0267: public void visit(ClassOrInterfaceDeclaration n, Object arg) // comes all, with simple name
0268: {
0269: scanMemberAnnotations(n.annotations, arg);
0270: scanModifiers(n.modifiers);
0271:
0272: if (n.isInterface) {
0273: //printer.print("interface ");
0274: } else {
0275: //printer.print("class ");
0276: }
0277:
0278: //printer.print(n.name);
0279:
0280: //System.out.println("========== ClassOrInterfaceDeclaration "+n.name+" =========="); // simple name.
0281:
0282: printTypeParameters(n.typeParameters, arg);
0283:
0284: if (n.extendsList != null) {
0285: //printer.print(" extends ");
0286: for (Iterator<ClassOrInterfaceType> i = n.extendsList
0287: .iterator(); i.hasNext();) {
0288: ClassOrInterfaceType c = i.next();
0289: this .typeNamesUsed.add("" + c.name);
0290: c.accept(this , arg);
0291: if (i.hasNext()) {
0292: //printer.print(", ");
0293: }
0294: }
0295: }
0296:
0297: if (n.implements List != null) {
0298: //printer.print(" implements ");
0299: for (Iterator<ClassOrInterfaceType> i = n.implements List
0300: .iterator(); i.hasNext();) {
0301: ClassOrInterfaceType c = i.next();
0302: this .typeNamesUsed.add("" + c.name);
0303: c.accept(this , arg);
0304: if (i.hasNext()) {
0305: //printer.print(", ");
0306: }
0307: }
0308: }
0309:
0310: //printer.printLn(" {");
0311: //printer.indent();
0312: if (n.members != null) {
0313: printMembers(n.members, arg);
0314: }
0315: //printer.unindent();
0316: //printer.print("}");
0317: }
0318:
0319: public void visit(EmptyTypeDeclaration n, Object arg) {
0320: //printer.print(";");
0321: }
0322:
0323: @tide.annotations.Recurse
0324: public static void createTypeNameResolveScope(StringBuilder sb,
0325: ClassOrInterfaceType n) {
0326: if (n.scope != null) {
0327: createTypeNameResolveScope(sb, n.scope);
0328: sb.append(".");
0329: }
0330: sb.append("" + n.name);
0331: }
0332:
0333: public void visit(ClassOrInterfaceType n, Object arg) {
0334: /* removed
0335: if (n.scope != null) {
0336: n.scope.accept(this, arg); // ClassOrInterfaceType
0337: //printer.print(".");
0338: }*/
0339:
0340: StringBuilder sb = new StringBuilder();
0341: createTypeNameResolveScope(sb, n);
0342: //System.out.println("ClassOrInterfaceType "+sb);
0343: this .typeNamesUsed.add(sb.toString());
0344: /*if (n.scope != null) {
0345: System.out.println(" scope="+n.scope.name);
0346: }*/
0347: //printer.print(n.name);
0348: printTypeArgs(n.typeArgs, arg);
0349: }
0350:
0351: public void visit(TypeParameter n, Object arg) {
0352: //printer.print(n.name);
0353: if (n.typeBound != null) {
0354: //printer.print(" extends ");
0355: for (Iterator<ClassOrInterfaceType> i = n.typeBound
0356: .iterator(); i.hasNext();) {
0357: ClassOrInterfaceType c = i.next();
0358: c.accept(this , arg);
0359: if (i.hasNext()) {
0360: //printer.print(" & ");
0361: }
0362: }
0363: }
0364: }
0365:
0366: public void visit(PrimitiveType n, Object arg) {
0367: switch (n.type) {
0368: case Boolean:
0369: //printer.print("boolean");
0370: break;
0371: case Byte:
0372: //printer.print("byte");
0373: break;
0374: case Char:
0375: //printer.print("char");
0376: break;
0377: case Double:
0378: //printer.print("double");
0379: break;
0380: case Float:
0381: //printer.print("float");
0382: break;
0383: case Int:
0384: //printer.print("int");
0385: break;
0386: case Long:
0387: //printer.print("long");
0388: break;
0389: case Short:
0390: //printer.print("short");
0391: break;
0392: }
0393: }
0394:
0395: public void visit(ReferenceType n, Object arg) {
0396: n.type.accept(this , arg);
0397: for (int i = 0; i < n.arrayCount; i++) {
0398: //printer.print("[]");
0399: }
0400: }
0401:
0402: public void visit(WildcardType n, Object arg) {
0403: //printer.print("?");
0404: if (n.ext != null) {
0405: //printer.print(" extends ");
0406: n.ext.accept(this , arg);
0407: }
0408: if (n.sup != null) {
0409: //printer.print(" super ");
0410: n.sup.accept(this , arg);
0411: }
0412: }
0413:
0414: public void visit(FieldDeclaration n, Object arg) {
0415: scanMemberAnnotations(n.annotations, arg);
0416: scanModifiers(n.modifiers);
0417: n.type.accept(this , arg);
0418:
0419: //printer.print(" ");
0420: for (Iterator<VariableDeclarator> i = n.variables.iterator(); i
0421: .hasNext();) {
0422: VariableDeclarator var = i.next();
0423: var.accept(this , arg);
0424: if (i.hasNext()) {
0425: //printer.print(", ");
0426: }
0427: }
0428:
0429: //printer.print(";");
0430: }
0431:
0432: // ok
0433: public void visit(VariableDeclarator n, Object arg) {
0434: n.id.accept(this , arg);
0435: if (n.init != null) {
0436: //printer.print(" = ");
0437: n.init.accept(this , arg);
0438: }
0439: }
0440:
0441: // ok
0442: public void visit(VariableDeclaratorId n, Object arg) {
0443: //printer.print(n.name);
0444: for (int i = 0; i < n.arrayCount; i++) {
0445: //printer.print("[]"); // Warning: bad style: misplaced
0446: }
0447: }
0448:
0449: // ok, in expr
0450: public void visit(ArrayInitializerExpr n, Object arg) {
0451: //printer.print("{");
0452: if (n.values != null) {
0453: //printer.print(" ");
0454: for (Iterator<Expression> i = n.values.iterator(); i
0455: .hasNext();) {
0456: Expression expr = i.next();
0457: expr.accept(this , arg);
0458: if (i.hasNext()) {
0459: //printer.print(", ");
0460: }
0461: }
0462: //printer.print(" ");
0463: }
0464: //printer.print("}");
0465: }
0466:
0467: public void visit(VoidType n, Object arg) {
0468: //printer.print("void");
0469: }
0470:
0471: // OK
0472: public void visit(ArrayAccessExpr n, Object arg) {
0473: n.name.accept(this , arg);
0474:
0475: //System.out.println("ArrayAccessExpr "+n.name);
0476:
0477: //printer.print("[");
0478: n.index.accept(this , arg);
0479: //printer.print("]");
0480: }
0481:
0482: // ok, in dim, as new int[ Constants.size ]
0483: public void visit(ArrayCreationExpr n, Object arg) {
0484: //printer.print("new ");
0485:
0486: //System.out.println("new type "+n.type); // int, ArrayList, ... (no generics here, compiler not allowing)
0487: //this.typeNamesUsed.add(""+n.type);
0488:
0489: n.type.accept(this , arg);
0490: printTypeArgs(n.typeArgs, arg);
0491:
0492: if (n.dimensions != null) {
0493: for (Expression dim : n.dimensions) {
0494: //printer.print("[");
0495: dim.accept(this , arg);
0496: //printer.print("]");
0497: }
0498: for (int i = 0; i < n.arrayCount; i++) {
0499: //printer.print("[]");
0500: }
0501: } else {
0502: for (int i = 0; i < n.arrayCount; i++) {
0503: //printer.print("[]");
0504: }
0505: //printer.print(" ");
0506: n.initializer.accept(this , arg);
0507: }
0508: }
0509:
0510: // ok
0511: public void visit(AssignExpr n, Object arg) {
0512: n.target.accept(this , arg);
0513: //printer.print(" ");
0514: switch (n.op) {
0515: case assign:
0516: //printer.print("=");
0517: break;
0518: case and:
0519: //printer.print("&=");
0520: break;
0521: case or:
0522: //printer.print("|=");
0523: break;
0524: case xor:
0525: //printer.print("^=");
0526: break;
0527: case plus:
0528: //printer.print("+=");
0529: break;
0530: case minus:
0531: //printer.print("-=");
0532: break;
0533: case rem:
0534: //printer.print("%=");
0535: break;
0536: case slash:
0537: //printer.print("/=");
0538: break;
0539: case star:
0540: //printer.print("*=");
0541: break;
0542: case lShift:
0543: //printer.print("<<=");
0544: break;
0545: case rSignedShift:
0546: //printer.print(">>=");
0547: break;
0548: case rUnsignedShift:
0549: //printer.print(">>>=");
0550: break;
0551: }
0552: //printer.print(" ");
0553: n.value.accept(this , arg);
0554: }
0555:
0556: // ok
0557: public void visit(BinaryExpr n, Object arg) {
0558: n.left.accept(this , arg);
0559: //printer.print(" ");
0560: switch (n.op) {
0561: case or:
0562: //printer.print("||");
0563: break;
0564: case and:
0565: //printer.print("&&");
0566: break;
0567: case binOr:
0568: //printer.print("|");
0569: break;
0570: case binAnd:
0571: //printer.print("&");
0572: break;
0573: case xor:
0574: //printer.print("^");
0575: break;
0576: case equals:
0577: //printer.print("==");
0578: break;
0579: case notEquals:
0580: //printer.print("!=");
0581: break;
0582: case less:
0583: //printer.print("<");
0584: break;
0585: case greater:
0586: //printer.print(">");
0587: break;
0588: case lessEquals:
0589: //printer.print("<=");
0590: break;
0591: case greaterEquals:
0592: //printer.print(">=");
0593: break;
0594: case lShift:
0595: //printer.print("<<");
0596: break;
0597: case rSignedShift:
0598: //printer.print(">>");
0599: break;
0600: case rUnsignedShift:
0601: //printer.print(">>>");
0602: break;
0603: case plus:
0604: //printer.print("+");
0605: break;
0606: case minus:
0607: //printer.print("-");
0608: break;
0609: case times:
0610: //printer.print("*");
0611: break;
0612: case divide:
0613: //printer.print("/");
0614: break;
0615: case remainder:
0616: //printer.print("%");
0617: break;
0618: }
0619: //printer.print(" ");
0620: n.right.accept(this , arg);
0621: }
0622:
0623: // ok
0624: public void visit(CastExpr n, Object arg) {
0625: //printer.print("(");
0626: n.type.accept(this , arg);
0627: //printer.print(") ");
0628: n.expr.accept(this , arg);
0629: }
0630:
0631: // ok
0632: public void visit(ClassExpr n, Object arg) {
0633: n.type.accept(this , arg);
0634: //printer.print(".class");
0635: }
0636:
0637: public void visit(ConditionalExpr n, Object arg) {
0638: n.condition.accept(this , arg);
0639: //printer.print(" ? ");
0640: n.thenExpr.accept(this , arg);
0641: //printer.print(" : ");
0642: n.elseExpr.accept(this , arg);
0643: }
0644:
0645: public void visit(EnclosedExpr n, Object arg) {
0646: //printer.print("(");
0647: n.inner.accept(this , arg);
0648: //printer.print(")");
0649: }
0650:
0651: public void visit(FieldAccessExpr n, Object arg) {
0652: n.scope.accept(this , arg); // expression
0653: //printer.print(".");
0654: //printer.print(n.field);
0655:
0656: //System.out.println(""+n.scope); // Math , java.lang, java.lang.Math (without .PI)
0657: // todo: only add the full, not the intermetiates...
0658: String fn = "" + n.scope + "." + n.field; // not necessary ? maybe yes ! maybe assigned to another type as in A aa = B.C.D; with D impl A
0659: //System.out.println(""+fn);
0660: this .expressionsToResolve.add(fn);
0661: }
0662:
0663: public void visit(InstanceOfExpr n, Object arg) {
0664: n.expr.accept(this , arg);
0665: //printer.print(" instanceof ");
0666: n.type.accept(this , arg);
0667: }
0668:
0669: // ok
0670: public void visit(CharLiteralExpr n, Object arg) {
0671: //printer.print("'");
0672: //printer.print(n.value);
0673: //printer.print("'");
0674: }
0675:
0676: public void visit(DoubleLiteralExpr n, Object arg) {
0677: //printer.print(n.value);
0678: }
0679:
0680: public void visit(IntegerLiteralExpr n, Object arg) {
0681: //printer.print(n.value);
0682: }
0683:
0684: public void visit(LongLiteralExpr n, Object arg) {
0685: //printer.print(n.value);
0686: }
0687:
0688: public void visit(IntegerLiteralMinValueExpr n, Object arg) {
0689: //printer.print(n.value);
0690: }
0691:
0692: public void visit(LongLiteralMinValueExpr n, Object arg) {
0693: //printer.print(n.value);
0694: }
0695:
0696: public void visit(StringLiteralExpr n, Object arg) {
0697: //printer.print("\"");
0698: //printer.print(n.value);
0699: //printer.print("\"");
0700: }
0701:
0702: // ok
0703: public void visit(BooleanLiteralExpr n, Object arg) {
0704: //printer.print(n.value.toString());
0705: }
0706:
0707: public void visit(NullLiteralExpr n, Object arg) {
0708: //printer.print("null");
0709: }
0710:
0711: public void visit(ThisExpr n, Object arg) {
0712: if (n.classExpr != null) {
0713: n.classExpr.accept(this , arg);
0714: //printer.print(".");
0715: }
0716: //printer.print("this");
0717: }
0718:
0719: public void visit(SuperExpr n, Object arg) {
0720: if (n.classExpr != null) {
0721: n.classExpr.accept(this , arg);
0722: //printer.print(".");
0723: }
0724: //printer.print("super");
0725: }
0726:
0727: // ~OK subtle, chains as A.B().D.C appears here, the analysed class IS dependent of the return value
0728: // of B and also D
0729: //
0730: public void visit(MethodCallExpr n, Object arg) {
0731:
0732: //System.out.println(""+n);
0733:
0734: if (n.scope != null) {
0735: String sc = "" + n.scope; // Runtime.getRuntime() or appendModShort(new StringBuilder("A"), ade.modifiers)
0736: // or MainEditorFrame.instance.outputPanels.getExecutionOutputDoc()
0737:
0738: if (sc.indexOf('.') > 0) {
0739: // again MethodCallExpr or FieldAccessExpr
0740: expressionsToResolve.add(sc);
0741:
0742: //System.out.println("MethodCallExpr Scope "+sc+" "+n.scope.getClass());
0743:
0744: // todo: look for types in the return values of called methods !
0745: // "resolve" the chain !!
0746:
0747: } else {
0748: // for example "GUIUtils.display(xxx)";
0749: this .typeNamesUsed.add(sc);
0750: }
0751:
0752: n.scope.accept(this , arg); // recuse Expression
0753:
0754: //printer.print(".");
0755: }
0756: printTypeArgs(n.typeArgs, arg);
0757: //printer.print(n.name);
0758:
0759: //System.out.println("MethodCallExprNAME "+n.name); // currentTimeMillis, println, getRuntime, append
0760:
0761: //printer.print("(");
0762: if (n.args != null) {
0763: for (Iterator<Expression> i = n.args.iterator(); i
0764: .hasNext();) {
0765: Expression e = i.next();
0766: e.accept(this , arg);
0767: if (i.hasNext()) {
0768: //printer.print(", ");
0769: }
0770: }
0771: }
0772: //printer.print(")");
0773: }
0774:
0775: public void visit(ObjectCreationExpr n, Object arg) {
0776: if (n.scope != null) {
0777: n.scope.accept(this , arg);
0778: //printer.print(".");
0779: }
0780:
0781: //printer.print("new ");
0782:
0783: printTypeArgs(n.typeArgs, arg);
0784: n.type.accept(this , arg);
0785:
0786: //printer.print("(");
0787: if (n.args != null) {
0788: for (Iterator<Expression> i = n.args.iterator(); i
0789: .hasNext();) {
0790: Expression e = i.next();
0791: e.accept(this , arg);
0792: if (i.hasNext()) {
0793: //printer.print(", ");
0794: }
0795: }
0796: }
0797: //printer.print(")");
0798:
0799: if (n.anonymousClassBody != null) {
0800: //printer.printLn(" {");
0801: //printer.indent();
0802: printMembers(n.anonymousClassBody, arg);
0803: //printer.unindent();
0804: //printer.print("}");
0805: }
0806: }
0807:
0808: public void visit(SuperMemberAccessExpr n, Object arg) {
0809: //printer.print("super.");
0810: //printer.print(n.name);
0811: }
0812:
0813: public void visit(UnaryExpr n, Object arg) {
0814: switch (n.op) {
0815: case positive:
0816: //printer.print("+");
0817: break;
0818: case negative:
0819: //printer.print("-");
0820: break;
0821: case inverse:
0822: //printer.print("~");
0823: break;
0824: case not:
0825: //printer.print("!");
0826: break;
0827: case preIncrement:
0828: //printer.print("++");
0829: break;
0830: case preDecrement:
0831: //printer.print("--");
0832: break;
0833: }
0834:
0835: n.expr.accept(this , arg);
0836:
0837: switch (n.op) {
0838: case posIncrement:
0839: //printer.print("++");
0840: break;
0841: case posDecrement:
0842: //printer.print("--");
0843: break;
0844: }
0845: }
0846:
0847: public void visit(ConstructorDeclaration n, Object arg) {
0848: scanMemberAnnotations(n.annotations, arg);
0849: scanModifiers(n.modifiers);
0850:
0851: printTypeParameters(n.typeParameters, arg);
0852: if (n.typeParameters != null) {
0853: //printer.print(" ");
0854: }
0855: //printer.print(n.name);
0856:
0857: //printer.print("(");
0858: if (n.parameters != null) {
0859: for (Iterator<Parameter> i = n.parameters.iterator(); i
0860: .hasNext();) {
0861: Parameter p = i.next();
0862: p.accept(this , arg);
0863: if (i.hasNext()) {
0864: //printer.print(", ");
0865: }
0866: }
0867: }
0868: //printer.print(")");
0869:
0870: if (n.throws_ != null) {
0871: //printer.print(" throws ");
0872: for (Iterator<NameExpr> i = n.throws_.iterator(); i
0873: .hasNext();) {
0874: NameExpr name = i.next();
0875: name.accept(this , arg);
0876: if (i.hasNext()) {
0877: //printer.print(", ");
0878: }
0879:
0880: this .typeNamesUsed.add("" + name);
0881: }
0882: }
0883: //printer.print(" ");
0884: n.block.accept(this , arg);
0885: }
0886:
0887: public void visit(MethodDeclaration n, Object arg) {
0888: scanMemberAnnotations(n.annotations, arg);
0889: scanModifiers(n.modifiers);
0890:
0891: printTypeParameters(n.typeParameters, arg);
0892: if (n.typeParameters != null) {
0893: //printer.print(" ");
0894: }
0895:
0896: n.type.accept(this , arg);
0897: //printer.print(" ");
0898: //printer.print(n.name);
0899:
0900: //printer.print("(");
0901: if (n.parameters != null) {
0902: for (Iterator<Parameter> i = n.parameters.iterator(); i
0903: .hasNext();) {
0904: Parameter p = i.next();
0905: p.accept(this , arg);
0906: if (i.hasNext()) {
0907: //printer.print(", ");
0908: }
0909: }
0910: }
0911: //printer.print(")");
0912:
0913: for (int i = 0; i < n.arrayCount; i++) {
0914: //printer.print("[]");
0915: }
0916:
0917: if (n.throws_ != null) {
0918: //printer.print(" throws ");
0919: for (Iterator<NameExpr> i = n.throws_.iterator(); i
0920: .hasNext();) {
0921: NameExpr name = i.next();
0922: name.accept(this , arg);
0923: if (i.hasNext()) {
0924: //printer.print(", ");
0925: }
0926:
0927: this .typeNamesUsed.add("" + name);
0928: }
0929: }
0930: if (n.block == null) {
0931: //printer.print(";");
0932: } else {
0933: //printer.print(" ");
0934: n.block.accept(this , arg);
0935: }
0936: }
0937:
0938: public void visit(Parameter n, Object arg) {
0939: printAnnotations(n.annotations, arg);
0940: scanModifiers(n.modifiers);
0941:
0942: n.type.accept(this , arg);
0943: if (n.isVarArgs) {
0944: //printer.print("...");
0945: }
0946: //printer.print(" ");
0947: n.id.accept(this , arg);
0948: }
0949:
0950: public void visit(ExplicitConstructorInvocationStmt n, Object arg) {
0951: if (n.isThis) {
0952: printTypeArgs(n.typeArgs, arg);
0953: //printer.print("this");
0954: } else {
0955: if (n.expr != null) {
0956: n.expr.accept(this , arg);
0957: //printer.print(".");
0958: }
0959: printTypeArgs(n.typeArgs, arg);
0960: //printer.print("super");
0961: }
0962: //printer.print("(");
0963: if (n.args != null) {
0964: for (Iterator<Expression> i = n.args.iterator(); i
0965: .hasNext();) {
0966: Expression e = i.next();
0967: e.accept(this , arg);
0968: if (i.hasNext()) {
0969: //printer.print(", ");
0970: }
0971: }
0972: }
0973: //printer.print(");");
0974: }
0975:
0976: public void visit(VariableDeclarationExpr n, Object arg) {
0977: printAnnotations(n.annotations, arg);
0978: scanModifiers(n.modifiers);
0979:
0980: n.type.accept(this , arg);
0981: //printer.print(" ");
0982:
0983: for (Iterator<VariableDeclarator> i = n.vars.iterator(); i
0984: .hasNext();) {
0985: VariableDeclarator v = i.next();
0986: v.accept(this , arg);
0987: if (i.hasNext()) {
0988: //printer.print(", ");
0989: }
0990: }
0991: }
0992:
0993: public void visit(TypeDeclarationStmt n, Object arg) {
0994: n.typeDecl.accept(this , arg);
0995: }
0996:
0997: // ok
0998: public void visit(AssertStmt n, Object arg) {
0999: //printer.print("assert ");
1000: n.check.accept(this , arg);
1001: if (n.msg != null) {
1002: //printer.print(" : ");
1003: n.msg.accept(this , arg);
1004: }
1005: //printer.print(";");
1006: }
1007:
1008: // ok
1009: public void visit(BlockStmt n, Object arg) {
1010: //printer.printLn("{");
1011: if (n.stmts != null) {
1012: //printer.indent();
1013: for (Statement s : n.stmts) {
1014: s.accept(this , arg);
1015: //printer.printLn();
1016: }
1017: //printer.unindent();
1018: }
1019: //printer.print("}");
1020:
1021: }
1022:
1023: public void visit(LabeledStmt n, Object arg) {
1024: //printer.print(n.label);
1025: //printer.print(": ");
1026: n.stmt.accept(this , arg);
1027: }
1028:
1029: public void visit(EmptyStmt n, Object arg) {
1030: //printer.print(";");
1031: }
1032:
1033: public void visit(ExpressionStmt n, Object arg) {
1034: n.expr.accept(this , arg);
1035: //printer.print(";");
1036: }
1037:
1038: public void visit(SwitchStmt n, Object arg) {
1039: //printer.print("switch(");
1040: n.selector.accept(this , arg);
1041: //printer.printLn(") {");
1042: if (n.entries != null) {
1043: //printer.indent();
1044: for (SwitchEntryStmt e : n.entries) {
1045: e.accept(this , arg);
1046: }
1047: //printer.unindent();
1048: }
1049: //printer.print("}");
1050:
1051: }
1052:
1053: public void visit(SwitchEntryStmt n, Object arg) {
1054: if (n.label != null) {
1055: //printer.print("case ");
1056: n.label.accept(this , arg);
1057: //printer.print(":");
1058: } else {
1059: //printer.print("default:");
1060: }
1061: //printer.printLn();
1062: //printer.indent();
1063: if (n.stmts != null) {
1064: for (Statement s : n.stmts) {
1065: s.accept(this , arg);
1066: //printer.printLn();
1067: }
1068: }
1069: //printer.unindent();
1070: }
1071:
1072: // ok
1073: public void visit(BreakStmt n, Object arg) {
1074: //printer.print("break");
1075: if (n.id != null) {
1076: //printer.print(" ");
1077: //printer.print(n.id);
1078: }
1079: //printer.print(";");
1080: }
1081:
1082: public void visit(ReturnStmt n, Object arg) {
1083: //printer.print("return");
1084: if (n.expr != null) {
1085: //printer.print(" ");
1086: n.expr.accept(this , arg);
1087: }
1088: //printer.print(";");
1089: }
1090:
1091: public void visit(EnumDeclaration n, Object arg) {
1092: scanMemberAnnotations(n.annotations, arg);
1093: scanModifiers(n.modifiers);
1094:
1095: //printer.print("enum ");
1096: //printer.print(n.name);
1097:
1098: if (n.implements List != null) {
1099: //printer.print(" implements ");
1100: for (Iterator<ClassOrInterfaceType> i = n.implements List
1101: .iterator(); i.hasNext();) {
1102: ClassOrInterfaceType c = i.next();
1103: this .typeNamesUsed.add("" + c.name);
1104: c.accept(this , arg);
1105: if (i.hasNext()) {
1106: //printer.print(", ");
1107: }
1108: }
1109: }
1110:
1111: //printer.printLn(" {");
1112: //printer.indent();
1113: if (n.entries != null) {
1114: //printer.printLn();
1115: for (Iterator<EnumConstantDeclaration> i = n.entries
1116: .iterator(); i.hasNext();) {
1117: EnumConstantDeclaration e = i.next();
1118: e.accept(this , arg);
1119: if (i.hasNext()) {
1120: //printer.print(", ");
1121: }
1122: }
1123: }
1124: if (n.members != null) {
1125: //printer.printLn(";");
1126: printMembers(n.members, arg);
1127: } else {
1128: //printer.printLn();
1129: }
1130: //printer.unindent();
1131: //printer.print("}");
1132: }
1133:
1134: public void visit(EnumConstantDeclaration n, Object arg) {
1135: scanMemberAnnotations(n.annotations, arg);
1136: //printer.print(n.name);
1137:
1138: if (n.args != null) {
1139: //printer.print("(");
1140: for (Iterator<Expression> i = n.args.iterator(); i
1141: .hasNext();) {
1142: Expression e = i.next();
1143: e.accept(this , arg);
1144: if (i.hasNext()) {
1145: //printer.print(", ");
1146: }
1147: }
1148: //printer.print(")");
1149: }
1150:
1151: if (n.classBody != null) {
1152: //printer.printLn(" {");
1153: //printer.indent();
1154: printMembers(n.classBody, arg);
1155: //printer.unindent();
1156: //printer.printLn("}");
1157: }
1158: }
1159:
1160: public void visit(EmptyMemberDeclaration n, Object arg) {
1161: //printer.print(";");
1162: }
1163:
1164: public void visit(InitializerDeclaration n, Object arg) {
1165: //printer.print("static ");
1166: n.block.accept(this , arg);
1167: }
1168:
1169: public void visit(IfStmt n, Object arg) {
1170: //printer.print("if (");
1171: n.condition.accept(this , arg);
1172: //printer.print(") ");
1173: n.thenStmt.accept(this , arg);
1174: if (n.elseStmt != null) {
1175: //printer.print(" else ");
1176: n.elseStmt.accept(this , arg);
1177: }
1178: }
1179:
1180: public void visit(WhileStmt n, Object arg) {
1181: //printer.print("while (");
1182: n.condition.accept(this , arg);
1183: //printer.print(") ");
1184: n.body.accept(this , arg);
1185: }
1186:
1187: public void visit(ContinueStmt n, Object arg) {
1188: //printer.print("continue");
1189: if (n.id != null) {
1190: //printer.print(" ");
1191: //printer.print(n.id);
1192: }
1193: //printer.print(";");
1194: }
1195:
1196: public void visit(DoStmt n, Object arg) {
1197: //printer.print("do ");
1198: n.body.accept(this , arg);
1199: //printer.print(" while (");
1200: n.condition.accept(this , arg);
1201: //printer.print(");");
1202: }
1203:
1204: public void visit(ForeachStmt n, Object arg) {
1205: //printer.print("for (");
1206: n.var.accept(this , arg);
1207: //printer.print(" : ");
1208: n.iterable.accept(this , arg);
1209: //printer.print(") ");
1210: n.body.accept(this , arg);
1211: }
1212:
1213: public void visit(ForStmt n, Object arg) {
1214: //printer.print("for (");
1215: if (n.init != null) {
1216: for (Iterator<Expression> i = n.init.iterator(); i
1217: .hasNext();) {
1218: Expression e = i.next();
1219: e.accept(this , arg);
1220: if (i.hasNext()) {
1221: //printer.print(", ");
1222: }
1223: }
1224: }
1225: //printer.print("; ");
1226: if (n.compare != null) {
1227: n.compare.accept(this , arg);
1228: }
1229: //printer.print("; ");
1230: if (n.update != null) {
1231: for (Iterator<Expression> i = n.update.iterator(); i
1232: .hasNext();) {
1233: Expression e = i.next();
1234: e.accept(this , arg);
1235: if (i.hasNext()) {
1236: //printer.print(", ");
1237: }
1238: }
1239: }
1240: //printer.print(") ");
1241: n.body.accept(this , arg);
1242: }
1243:
1244: public void visit(ThrowStmt n, Object arg) {
1245: //printer.print("throw ");
1246: n.expr.accept(this , arg);
1247: //printer.print(";");
1248: }
1249:
1250: public void visit(SynchronizedStmt n, Object arg) {
1251: //printer.print("synchronized (");
1252: n.expr.accept(this , arg);
1253: //printer.print(") ");
1254: n.block.accept(this , arg);
1255: }
1256:
1257: public void visit(TryStmt n, Object arg) {
1258: //printer.print("try ");
1259: n.tryBlock.accept(this , arg);
1260: if (n.catchs != null) {
1261: for (CatchClause c : n.catchs) {
1262: c.accept(this , arg);
1263: }
1264: }
1265: if (n.finallyBlock != null) {
1266: //printer.print(" finally ");
1267: n.finallyBlock.accept(this , arg);
1268: }
1269: }
1270:
1271: // ok
1272: public void visit(CatchClause n, Object arg) {
1273: //printer.print(" catch (");
1274: n.except.accept(this , arg);
1275: //printer.print(") ");
1276: n.catchBlock.accept(this , arg);
1277:
1278: }
1279:
1280: // Has, in the members
1281: public void visit(AnnotationDeclaration n, Object arg) {
1282: scanMemberAnnotations(n.annotations, arg);
1283: scanModifiers(n.modifiers);
1284:
1285: //printer.print("@interface ");
1286: //this.typeNamesUsed.add(""+n.name); NO
1287: //printer.print(n.name);
1288: //printer.printLn(" {");
1289: //printer.indent();
1290: if (n.members != null) {
1291: printMembers(n.members, arg);
1292: }
1293: //printer.unindent();
1294: //printer.print("}");
1295: }
1296:
1297: // OK, in n.type
1298: public void visit(AnnotationMemberDeclaration n, Object arg) {
1299: scanMemberAnnotations(n.annotations, arg);
1300: scanModifiers(n.modifiers);
1301:
1302: n.type.accept(this , arg);
1303:
1304: //printer.print(" ");
1305: //printer.print(n.name);
1306: //printer.print("()");
1307: if (n.defaultValue != null) {
1308: //printer.print(" default ");
1309: n.defaultValue.accept(this , arg); // no
1310: }
1311: //printer.print(";");
1312: }
1313:
1314: //OK
1315: public void visit(MarkerAnnotationExpr n, Object arg) {
1316: //printer.print("@");
1317: n.name.accept(this , arg);
1318:
1319: //System.out.println("MarkerAnnotationExpr "+n.name);
1320: this .typeNamesUsed.add("" + n.name);
1321: }
1322:
1323: public void visit(SingleMemberAnnotationExpr n, Object arg) {
1324: //printer.print("@");
1325: n.name.accept(this , arg);
1326:
1327: this .typeNamesUsed.add("" + n.name);
1328:
1329: //printer.print("(");
1330: n.memberValue.accept(this , arg);
1331: //printer.print(")");
1332: }
1333:
1334: public void visit(NormalAnnotationExpr n, Object arg) {
1335: //printer.print("@");
1336: n.name.accept(this , arg);
1337:
1338: this .typeNamesUsed.add("" + n.name);
1339:
1340: //printer.print("(");
1341: for (Iterator<MemberValuePair> i = n.pairs.iterator(); i
1342: .hasNext();) {
1343: MemberValuePair m = i.next();
1344: m.accept(this , arg);
1345: if (i.hasNext()) {
1346: //printer.print(", ");
1347: }
1348: }
1349: //printer.print(")");
1350: }
1351:
1352: public void visit(MemberValuePair n, Object arg) {
1353: //printer.print(n.name);
1354: //printer.print(" = ");
1355: n.value.accept(this , arg);
1356: }
1357:
1358: final HashSet<SourceFile> dependencies = new HashSet<SourceFile>();
1359:
1360: /** replacement for DependenciesDetector...
1361: */
1362: public static JapaDependenciesDetector analyseDependencies(
1363: final SourceFile sf, JapaDependenciesDetector ref)
1364: throws Exception {
1365: // reuse big objects
1366: if (ref == null) {
1367: ref = new JapaDependenciesDetector();
1368: } else {
1369: ref.reset();
1370: }
1371:
1372: // Parse (or reuse)
1373: //
1374:
1375: ParserResult par = null;
1376:
1377: //CompilationUnit cu = null;
1378: if (sf.getParserResultIfAlreadyMade() != null
1379: && sf.getParserResultIfAlreadyMade().compilationUnit != null) {
1380: par = sf.getParserResultIfAlreadyMade();
1381: } else {
1382: final StringReader sr = new StringReader(sf.getContent());
1383: par = new ParserResult(JavaParser.parse(sr));
1384: }
1385:
1386: // visit (collects types and expression chains with ".")
1387:
1388: par.compilationUnit.accept(ref, null);
1389:
1390: final HashSet<String> typesFound = new HashSet<String>();
1391: typesFound.addAll(ref.typeNamesUsed);
1392: typesFound.addAll(ref.expressionsToResolve);
1393: typesFound.remove(sf.getJavaName());
1394:
1395: // "resolve" using importa
1396: //cu.imports
1397:
1398: SourcesTreeModel stm = MainEditorFrame.instance
1399: .getActualProject().sourcesTreeModel;
1400: fl: for (final String t : typesFound) {
1401: FileItem fi = stm.quickGet(t, true);
1402: if (fi == null) {
1403: fi = TypeLocator.locateUsingImports(sf, t);
1404: }
1405:
1406: if (fi == null) {
1407: // our identifier is AAA.BB.CC. Just try with AAA.BB and AAA, corresponding to an existing class (hopefully !)
1408: String startingName = t;
1409: wl: while (startingName.contains(".")) {
1410: startingName = StringUtils.removeAfterLastIncluded(
1411: startingName, ".");
1412: //System.out.println("try "+startingName);
1413:
1414: String ts = StringUtils
1415: .extractFromStartUpToFirstExcluded(t, ".");
1416: FileItem tfi = TypeLocator.locateUsingImports(sf,
1417: startingName);
1418: if (tfi != null && tfi.isJavaFile()) {
1419: fi = tfi;
1420: break wl;
1421: }
1422: }
1423: }
1424:
1425: if (fi == null) {
1426: /*
1427: // look if it is an inner class ot this source !
1428: for(TypeInterface ttt : sst.allTypes)
1429: {
1430: if(ttt.getTypeSimpleName().equals(t))
1431: {
1432: // ok, we are happy, this is an inner class of the source itself => not a dependency !
1433: continue fl;
1434: }
1435: }
1436:
1437: // not found !
1438: // the type parameters as in ClassA<K> { public Enumeration<K> keys() {...} } may be called
1439: // => we then let single letter class names now. (TODO)
1440: //
1441: if(t.length()==1) continue fl;
1442:
1443: // not found !
1444: // some times, the searched type is a (at least) protected class or the superclass (extends)
1445: // in this case: no problem. but we write it out
1446: // also a lot of noise comming from the names.
1447: if(writeOut)
1448: {
1449: MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc.appendErrorLine(sf.getJavaName()+".java:: Cannot locate type: "+t);
1450: MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc.appendLine("Declared types="+sst.allTypes);
1451: }
1452: */
1453:
1454: }
1455:
1456: if (fi != null) {
1457: if (fi.isDirectory()) {
1458: MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
1459: .appendErrorLine(sf.getJavaName()
1460: + ".java: not a type: " + t);
1461: }
1462: if (fi instanceof SourceFile) {
1463: ref.dependencies.add((SourceFile) fi);
1464: }
1465: }
1466: }
1467:
1468: // remove dependences on itself. (may have been resolved in a chain ...)
1469: ref.dependencies.remove(sf);
1470:
1471: return ref;
1472:
1473: }
1474:
1475: public static void main(final String[] args) throws Exception {
1476: final CompilationUnit cun = JavaParser.parse(new File(
1477: "c:/proj/tide/src/japa/dev/Test.java"));
1478: //getDeepestTypeAt(cun,0,0);
1479: final JapaDependenciesDetector dd = new JapaDependenciesDetector();
1480: cun.accept(dd, null);
1481: System.out.println("\nTypes found\n " + dd.typeNamesUsed);
1482: System.out
1483: .println("\nExpressions To analyse for undeclared usages\n "
1484: + dd.expressionsToResolve);
1485: dd.reset();
1486: }
1487: }
|