@Override void process(JCNewClass oldTree, JCNewClass newTree, boolean hasErrors) { if (!hasErrors) { List<Type> inferredArgs, explicitArgs; if (oldTree.def != null) { inferredArgs = newTree.def.implementing.nonEmpty() ? newTree.def.implementing.get(0).type.getTypeArguments() : newTree.def.extending.type.getTypeArguments(); explicitArgs = oldTree.def.implementing.nonEmpty() ? oldTree.def.implementing.get(0).type.getTypeArguments() : oldTree.def.extending.type.getTypeArguments(); } else { inferredArgs = newTree.type.getTypeArguments(); explicitArgs = oldTree.type.getTypeArguments(); } for (Type t : inferredArgs) { if (!types.isSameType(t, explicitArgs.head)) { return; } explicitArgs = explicitArgs.tail; } //exact match log.warning(oldTree.clazz, Warnings.DiamondRedundantArgs); } }
private JCBlock resolutionExceptionBlock() { if (resolutionExceptionBlock == null) { JCExpression expClass = null; // Split the exception class name at dots for (String id : SPIResolutionException.class.getName().split("\\.")) { Name nm = names.fromString(id); if (expClass == null) { expClass = make.Ident(nm); } else { expClass = make.Select(expClass, nm); } } JCNewClass exp = make.NewClass(null, null, expClass, List.of(make.Literal(keyIndex)), null); resolutionExceptionBlock = make.Block(0L, List.of(make.Throw(exp))); } return resolutionExceptionBlock; }
@Override void process(JCNewClass oldTree, JCNewClass newTree, boolean hasErrors) { if (!hasErrors) { List<Type> inferredArgs, explicitArgs; if (oldTree.def != null) { inferredArgs = newTree.def.implementing.nonEmpty() ? newTree.def.implementing.get(0).type.getTypeArguments() : newTree.def.extending.type.getTypeArguments(); explicitArgs = oldTree.def.implementing.nonEmpty() ? oldTree.def.implementing.get(0).type.getTypeArguments() : oldTree.def.extending.type.getTypeArguments(); } else { inferredArgs = newTree.type.getTypeArguments(); explicitArgs = oldTree.type.getTypeArguments(); } for (Type t : inferredArgs) { if (!types.isSameType(t, explicitArgs.head)) { return; } explicitArgs = explicitArgs.tail; } //exact match log.warning(oldTree.clazz, "diamond.redundant.args"); } }
private JCBlock resolutionExceptionBlock() { if (resolutionExceptionBlock == null) { JCExpression expClass = null; // Split the exception class name at dots for (String id : SPIResolutionException.class.getName().split("\\.")) { Name nm = names.fromString(id); if (expClass == null) { expClass = make.Ident(nm); } else { expClass = make.Select(expClass, nm); } } JCNewClass exp = make.NewClass(null, null, expClass, List.of(make.Literal(keyIndex)), null); resolutionExceptionBlock = make.Block(0L, List.<JCStatement>of( make.Throw(exp))); } return resolutionExceptionBlock; }
private void printEnumMember(JCVariableDecl tree) { printAnnotations(tree.mods.annotations, true); print(tree.name); if (tree.init instanceof JCNewClass) { JCNewClass constructor = (JCNewClass) tree.init; if (constructor.args != null && constructor.args.nonEmpty()) { print("("); print(constructor.args, ", "); print(")"); } if (constructor.def != null && constructor.def.defs != null) { println(" {"); indent++; printClassMembers(constructor.def.defs, false, false); consumeComments(endPos(tree)); indent--; aPrint("}"); } } }
public void printEnumMember(JCVariableDecl tree) throws IOException { printAnnotations(tree.mods.annotations); print(tree.name); if (tree.init instanceof JCNewClass) { JCNewClass constructor = (JCNewClass) tree.init; if (constructor.args != null && constructor.args.nonEmpty()) { print("("); printExprs(constructor.args); print(")"); } if (constructor.def != null && constructor.def.defs != null) { print(" "); printBlock(constructor.def.defs, constructor.def); } } }
@Override public Pair<ASTRecord, Integer> visitNewClass(NewClassTree node, Insertion ins) { JCNewClass na = (JCNewClass) node; JCExpression className = na.clazz; // System.out.printf("classname %s (%s)%n", className, className.getClass()); while (! (className.getKind() == Tree.Kind.IDENTIFIER)) { // IdentifierTree if (className instanceof JCAnnotatedType) { className = ((JCAnnotatedType) className).underlyingType; } else if (className instanceof JCTypeApply) { className = ((JCTypeApply) className).clazz; } else if (className instanceof JCFieldAccess) { // This occurs for fully qualified names, e.g. "new java.lang.Object()". // I'm not quite sure why the field "selected" is taken, but "name" would // be a type mismatch. It seems to work, see NewPackage test case. className = ((JCFieldAccess) className).selected; } else { throw new Error(String.format("unrecognized JCNewClass.clazz (%s): %s%n" + " surrounding new class tree: %s%n", className.getClass(), className, node)); } // System.out.printf("classname %s (%s)%n", className, className.getClass()); } return visitIdentifier((IdentifierTree) className, ins); }
/** * Returns true if the expression is a member access on an instance, rather than a static type. * Supports member method invocations and field accesses. */ public static Matcher<ExpressionTree> selectedIsInstance() { return new Matcher<ExpressionTree>() { @Override public boolean matches(ExpressionTree expr, VisitorState state) { if (!(expr instanceof JCFieldAccess)) { // TODO(cushon): throw IllegalArgumentException? return false; } JCExpression selected = ((JCFieldAccess) expr).getExpression(); if (selected instanceof JCNewClass) { return true; } Symbol sym = ASTHelpers.getSymbol(selected); return sym instanceof VarSymbol; } }; }
/** * Gets the symbol for a tree. Returns null if this tree does not have a symbol because it is of * the wrong type, if {@code tree} is null, or if the symbol cannot be found due to a compilation * error. */ // TODO(eaftan): refactor other code that accesses symbols to use this method public static Symbol getSymbol(Tree tree) { if (tree instanceof JCFieldAccess) { return ((JCFieldAccess) tree).sym; } if (tree instanceof JCIdent) { return ((JCIdent) tree).sym; } if (tree instanceof JCMethodInvocation) { return ASTHelpers.getSymbol((MethodInvocationTree) tree); } if (tree instanceof JCNewClass) { return ASTHelpers.getSymbol((NewClassTree) tree); } if (tree instanceof MemberReferenceTree) { return ((JCMemberReference) tree).sym; } if (tree instanceof JCAnnotatedType) { return getSymbol(((JCAnnotatedType) tree).underlyingType); } return getDeclaredSymbol(tree); }
@Override public Description matchNewClass(NewClassTree tree, VisitorState state) { // check instantiations of `@ImmutableTypeParameter`s in generic constructor invocations checkInvocation( tree, ((JCNewClass) tree).constructorType, state, ((JCNewClass) tree).constructor); // check instantiations of `@ImmutableTypeParameter`s in class constructor invocations ImmutableAnalysis analysis = new ImmutableAnalysis(this, state, wellKnownMutability); Violation info = analysis.checkInstantiation( ASTHelpers.getSymbol(tree.getIdentifier()).getTypeParameters(), ASTHelpers.getType(tree).getTypeArguments()); if (info.isPresent()) { state.reportMatch(buildDescription(tree).setMessage(info.message()).build()); } return NO_MATCH; }
private static HeldLockSet handleMonitorGuards(VisitorState state, HeldLockSet locks) { JCNewClass newClassTree = ASTHelpers.findEnclosingNode(state.getPath(), JCNewClass.class); if (newClassTree == null) { return locks; } Symbol clazzSym = ASTHelpers.getSymbol(newClassTree.clazz); if (!(clazzSym instanceof ClassSymbol)) { return locks; } if (!((ClassSymbol) clazzSym).fullname.contentEquals(MONITOR_GUARD_CLASS)) { return locks; } Optional<GuardedByExpression> lockExpression = GuardedByBinder.bindExpression( Iterables.getOnlyElement(newClassTree.getArguments()), state); if (!lockExpression.isPresent()) { return locks; } return locks.plus(lockExpression.get()); }
/** ClassCreatorRest = Arguments [ClassBody] */ JCNewClass classCreatorRest(int newpos, JCExpression encl, List<JCExpression> typeArgs, JCExpression t) { List<JCExpression> args = arguments(); JCClassDecl body = null; if (S.token() == LBRACE) { int pos = S.pos(); List<JCTree> defs = classOrInterfaceBody(names.empty, false); JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); body = toP(F.at(pos).AnonymousClassDef(mods, defs)); } return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); }
@Override public boolean matches(NewClassTree newClassTree, VisitorState state) { /* TODO(eaftan): Don't catch NullPointerException. Need to do this right now * for internal use, but remember to remove later. */ try { JCNewClass newClass = (JCNewClass) newClassTree; String thisClassName = newClass.constructor.getEnclosingElement().toString(); com.sun.tools.javac.util.List<Type> thisParameterTypes = newClass.constructor.type.getParameterTypes(); List<String> thisParameterTypesAsStrings = new ArrayList<String>(thisParameterTypes.length()); for (Type t : thisParameterTypes) { thisParameterTypesAsStrings.add(t.toString()); } return thisClassName.equals(className) && thisParameterTypesAsStrings.equals(parameterTypes); } catch (NullPointerException e) { return false; } }
private boolean matchNewClass(JCNewClass t1, JCNewClass t2) { return t1.constructor == t2.constructor && treesMatch(t1.getIdentifier(), t2.getIdentifier()) && listsMatch(t1.typeargs, t2.typeargs) && listsMatch(t1.args, t2.args) && (t1.varargsElement == t2.varargsElement) && treesMatch(t1.def, t2.def); }
@Override public void visitNewClass(JCNewClass tree) { super.visitNewClass(tree); Symbol c = tree.constructor != null ? tree.constructor.owner : null; if (c != null && c != syms.noSymbol && c.hasOuterInstance()) { if (tree.encl == null && c.isLocal()) { checkThis(tree.pos(), c.type.getEnclosingType().tsym); } } }
@Override public void visitNewClass(JCNewClass tree) { super.visitNewClass(tree); if (tree.def != null && tree.def.sym == null) { try { Field envField = Attr.class.getDeclaredField("env"); envField.setAccessible(true); Env<AttrContext> env = (Env<AttrContext>) envField.get(this); env = env.dup(tree); attribStat(tree.def, env); } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { Logger.getLogger(NBAttr.class.getName()).log(Level.FINE, null, ex); } } }
private void copyNewClassAnnotationsToOwner(JCNewClass tree) { Symbol sym = tree.def.sym; TypeAnnotationPosition pos = new TypeAnnotationPosition(); ListBuffer<Attribute.TypeCompound> newattrs = new ListBuffer<Attribute.TypeCompound>(); for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) { newattrs.append(new Attribute.TypeCompound(old.type, old.values, pos)); } pos.type = TargetType.NEW; pos.pos = tree.pos; sym.owner.appendUniqueTypeAttributes(newattrs.toList()); }
@Override public void visitNewClass(JCNewClass tree) { if (tree.def != null && !tree.def.mods.annotations.isEmpty()) { JCClassDecl classdecl = tree.def; TypeAnnotationPosition pos = new TypeAnnotationPosition(); pos.type = TargetType.CLASS_EXTENDS; pos.pos = tree.pos; if (classdecl.extending == tree.clazz) { pos.type_index = -1; } else if (classdecl.implementing.contains(tree.clazz)) { pos.type_index = classdecl.implementing.indexOf(tree.clazz); } else { // In contrast to CLASS elsewhere, typarams cannot occur here. Assert.error("Could not determine position of tree " + tree); } Type before = classdecl.sym.type; separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos); copyNewClassAnnotationsToOwner(tree); // classdecl.sym.type now contains an annotated type, which // is not what we want there. // TODO: should we put this type somewhere in the superclass/interface? classdecl.sym.type = before; } scan(tree.encl); scan(tree.typeargs); scan(tree.clazz); scan(tree.args); // The class body will already be scanned. // scan(tree.def); }
private void copyNewClassAnnotationsToOwner(JCNewClass tree) { Symbol sym = tree.def.sym; final TypeAnnotationPosition pos = TypeAnnotationPosition.newObj(tree.pos); ListBuffer<Attribute.TypeCompound> newattrs = new ListBuffer<>(); for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) { newattrs.append(new Attribute.TypeCompound(old.type, old.values, pos)); } sym.owner.appendUniqueTypeAttributes(newattrs.toList()); }
@Override public void visitNewClass(JCNewClass tree) { if (tree.def != null && !tree.def.mods.annotations.isEmpty()) { JCClassDecl classdecl = tree.def; TypeAnnotationPosition pos; if (classdecl.extending == tree.clazz) { pos = TypeAnnotationPosition.classExtends(tree.pos); } else if (classdecl.implementing.contains(tree.clazz)) { final int index = classdecl.implementing.indexOf(tree.clazz); pos = TypeAnnotationPosition.classExtends(index, tree.pos); } else { // In contrast to CLASS elsewhere, typarams cannot occur here. throw new AssertionError("Could not determine position of tree " + tree); } Type before = classdecl.sym.type; separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos); copyNewClassAnnotationsToOwner(tree); // classdecl.sym.type now contains an annotated type, which // is not what we want there. // TODO: should we put this type somewhere in the superclass/interface? classdecl.sym.type = before; } scan(tree.encl); scan(tree.typeargs); if (tree.def == null) { scan(tree.clazz); } // else super type will already have been scanned in the context of the anonymous class. scan(tree.args); // The class body will already be scanned. // scan(tree.def); }
@Override public void visitNewClass(JCNewClass that) { if (TreeInfo.isDiamond(that)) { processArg(that, speculativeTree -> new ResolvedConstructorType(that, env, speculativeTree)); } else { //not a poly expression, just call Attr setResult(that, attr.attribTree(that, env, attr.unknownExprInfo)); } }
@Override JCNewClass map(JCNewClass oldTree, JCNewClass newTree) { if (newTree.clazz.hasTag(TYPEAPPLY)) { ((JCTypeApply)newTree.clazz).arguments = List.nil(); } return newTree; }
@Override boolean match (JCNewClass tree){ Type clazztype = tree.clazz.type; return tree.def != null && clazztype.hasTag(CLASS) && types.isFunctionalInterface(clazztype.tsym) && decls(tree.def).length() == 1; }
@Override JCLambda map (JCNewClass oldTree, JCNewClass newTree){ JCMethodDecl md = (JCMethodDecl)decls(newTree.def).head; List<JCVariableDecl> params = md.params; JCBlock body = md.body; return make.Lambda(params, body); }
@Override @DefinedBy(Api.COMPILER_TREE) public JCTree visitNewClass(NewClassTree node, Void aVoid) { JCNewClass oldNewClazz = (JCNewClass)node; JCNewClass newNewClazz = (JCNewClass)super.visitNewClass(node, aVoid); if (!oldNewClazz.args.isEmpty() && oldNewClazz.args.head.hasTag(NULLCHK)) { //workaround to Attr generating trees newNewClazz.encl = ((JCUnary)newNewClazz.args.head).arg; newNewClazz.args = newNewClazz.args.tail; } return newNewClazz; }
@Override public void visitNewClass(JCNewClass tree) { if (tree.def != null && !tree.def.mods.annotations.isEmpty()) { JCClassDecl classdecl = tree.def; TypeAnnotationPosition pos; if (classdecl.extending == tree.clazz) { pos = TypeAnnotationPosition.classExtends(tree.pos); } else if (classdecl.implementing.contains(tree.clazz)) { final int index = classdecl.implementing.indexOf(tree.clazz); pos = TypeAnnotationPosition.classExtends(index, tree.pos); } else { // In contrast to CLASS elsewhere, typarams cannot occur here. throw new AssertionError("Could not determine position of tree " + tree); } Type before = classdecl.sym.type; separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos); copyNewClassAnnotationsToOwner(tree); // classdecl.sym.type now contains an annotated type, which // is not what we want there. // TODO: should we put this type somewhere in the superclass/interface? classdecl.sym.type = before; } scan(tree.encl); scan(tree.typeargs); scan(tree.clazz); scan(tree.args); // The class body will already be scanned. // scan(tree.def); }
@Override public void visitNewClass(JCNewClass tree) { if (tree.encl != null) { print(tree.encl); print("."); } print("new "); if (!tree.typeargs.isEmpty()) { print("<"); print(tree.typeargs, ", "); print(">"); } print(tree.clazz); print("("); print(tree.args, ", "); print(")"); if (tree.def != null) { Name previousTypeName = currentTypeName; currentTypeName = null; println(" {"); indent++; print(tree.def.defs, ""); indent--; aPrint("}"); currentTypeName = previousTypeName; } }
public void visitNewClass(JCNewClass that) { try { print("JCNewClass:"); } catch (Exception e) { } super.visitNewClass(that); }
public void visitNewClass(JCNewClass tree) { try { if (tree.encl != null) { printExpr(tree.encl); print("."); } print("new "); if (!tree.typeargs.isEmpty()) { print("<"); printExprs(tree.typeargs); print(">"); } printExpr(tree.clazz); print("("); printExprs(tree.args); print(")"); if (tree.def != null) { Name enclClassNamePrev = enclClassName; enclClassName = tree.def.name != null ? tree.def.name : tree.type != null && tree.type.tsym.name != tree.type.tsym.name.table.fromChars(new char[0], 0, 0) ? tree.type.tsym.name : null; if ((tree.def.mods.flags & Flags.ENUM) != 0) print("/*enum*/"); printBlock(tree.def.defs, tree.def); enclClassName = enclClassNamePrev; } } catch (IOException e) { throw new UncheckedIOException(e); } }