@Override public Void visit(ObjectCreationExpr expr, AElement elem) { ClassOrInterfaceType type = expr.getType(); AClass clazz = scene.classes.vivify(type.getName()); Expression scope = expr.getScope(); List<Type> typeArgs = expr.getTypeArgs(); List<Expression> args = expr.getArgs(); List<BodyDeclaration> decls = expr.getAnonymousClassBody(); if (scope != null) { scope.accept(this, elem); } if (args != null) { for (Expression arg : args) { arg.accept(this, elem); } } if (typeArgs != null) { for (Type typeArg : typeArgs) { typeArg.accept(this, elem); } } type.accept(this, clazz); if (decls != null) { for (BodyDeclaration decl : decls) { decl.accept(this, clazz); } } return null; }
/** * Print a list of type arguments in between angle brackets. * * @param args type arguments * @param arg argument provided to the calling visitor method */ private void printTypeArgs(List<Type> args, Object arg) { if (args != null) { printer.print("<"); for (Iterator<Type> i = args.iterator(); i.hasNext(); ) { Type t = i.next(); t.accept(this, arg); if (i.hasNext()) { printer.print(", "); } } printer.print(">"); } }
/** Copies information from an AST type node to an {@link ATypeElement}. */ private Void visitType(Type type, final ATypeElement elem) { List<AnnotationExpr> exprs = type.getAnnotations(); if (exprs != null) { for (AnnotationExpr expr : exprs) { Annotation anno = extractAnnotation(expr); if (anno != null) { elem.tlAnnotationsHere.add(anno); } } } visitInnerTypes(type, elem); return null; }
/** * Computes a type's "binary name". * * @param type the type * @return the type's binary name */ private String getJVML(Type type) { return type.accept( new GenericVisitorAdapter<String, Void>() { @Override public String visit(ClassOrInterfaceType type, Void v) { String typeName = type.getName(); String name = resolve(typeName); if (name != null) { String[] parts = name.split("\\."); StringBuilder sb = new StringBuilder("L").append(parts[0]); for (int i = 1; i < parts.length; i++) { sb.append('/').append(parts[i]); } sb.append(";"); return sb.toString(); } return "L" + typeName + ";"; } @Override public String visit(PrimitiveType type, Void v) { switch (type.getType()) { case Boolean: return "Z"; case Byte: return "B"; case Char: return "C"; case Double: return "D"; case Float: return "F"; case Int: return "I"; case Long: return "J"; case Short: return "S"; default: throw new IllegalArgumentException( "baseTypeName(): unknown primitive type " + type); } } @Override public String visit(ReferenceType type, Void v) { String typeName = type.getType().accept(this, null); StringBuilder sb = new StringBuilder(); int n = type.getArrayCount(); while (--n >= 0) { sb.append("["); } sb.append(typeName); return sb.toString(); } @Override public String visit(VoidType type, Void v) { return "V"; } @Override public String visit(WildcardType type, Void v) { return "Ljava/lang/Object;"; } }, null); }
/** Copies information from an AST type node's inner type nodes to an {@link ATypeElement}. */ private static Void visitInnerTypes(Type type, final ATypeElement elem) { return type.accept( new GenericVisitorAdapter<Void, InnerTypeLocation>() { @Override public Void visit(ClassOrInterfaceType type, InnerTypeLocation loc) { int i = 0; for (Type inner : type.getTypeArgs()) { InnerTypeLocation ext = extendedTypePath(loc, 3, i++); visitInnerType(inner, ext); } return null; } @Override public Void visit(ReferenceType type, InnerTypeLocation loc) { InnerTypeLocation ext = loc; int n = type.getArrayCount(); for (int i = 0; i < n; i++) { ext = extendedTypePath(ext, 1, 0); for (AnnotationExpr expr : type.getAnnotationsAtLevel(i)) { ATypeElement typeElem = elem.innerTypes.vivify(ext); Annotation anno = extractAnnotation(expr); typeElem.tlAnnotationsHere.add(anno); } } return null; } @Override public Void visit(WildcardType type, InnerTypeLocation loc) { ReferenceType lower = type.getExtends(); ReferenceType upper = type.getSuper(); if (lower != null) { InnerTypeLocation ext = extendedTypePath(loc, 2, 0); visitInnerType(lower, ext); } if (upper != null) { InnerTypeLocation ext = extendedTypePath(loc, 2, 0); visitInnerType(upper, ext); } return null; } /** Copies information from an AST inner type node to an {@link ATypeElement}. */ private void visitInnerType(Type type, InnerTypeLocation loc) { ATypeElement typeElem = elem.innerTypes.vivify(loc); for (AnnotationExpr expr : type.getAnnotations()) { Annotation anno = extractAnnotation(expr); typeElem.tlAnnotationsHere.add(anno); type.accept(this, loc); } } /** * Extends type path by one element. * * @see TypePathEntry.fromBinary */ private InnerTypeLocation extendedTypePath(InnerTypeLocation loc, int tag, int arg) { List<TypePathEntry> path = new ArrayList<TypePathEntry>(loc.location.size() + 1); path.addAll(loc.location); path.add(TypePathEntry.fromBinary(tag, arg)); return new InnerTypeLocation(path); } }, InnerTypeLocation.EMPTY_INNER_TYPE_LOCATION); }