@Override public Void visitMethodInvocation(MethodInvocationTree node, Void p) { super.visitMethodInvocation(node, p); JCMethodInvocation apply = (JCMethodInvocation)node; JCIdent ident = (JCIdent)apply.meth; Symbol oldSym = ident.sym; if (!oldSym.isConstructor()) { Object[] staticArgs = new Object[arity.arity]; for (int i = 0; i < arity.arity ; i++) { staticArgs[i] = saks[i].getValue(syms, names, types); } ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, staticArgs); } return null; }
@Override public void visitIdent(final JCIdent node) { if (node.sym instanceof ClassSymbol) { // If this is a ClassSymbol, then we have the type. Apply // substitution if necessary. print(substitutionInventory.applyTypeSubstitution(node.type)); } else { // Not a type. // Attempt template field substitution. final String identifier = node.name.toString(); print(currentSubstitution() .filter(field -> substitutionInventory.isSubstitutableFieldName(identifier)) .orElse(identifier));// Neither a substitutable type nor a substitutable field. } }
/** * Turns an expression into a guessed intended literal. Only works for * literals, as you can imagine. * * Will for example turn a TrueLiteral into 'Boolean.valueOf(true)'. */ public static Object calculateGuess(JCExpression expr) { if (expr instanceof JCLiteral) { JCLiteral lit = (JCLiteral) expr; if (lit.getKind() == com.sun.source.tree.Tree.Kind.BOOLEAN_LITERAL) { return ((Number) lit.value).intValue() == 0 ? false : true; } return lit.value; } else if (expr instanceof JCIdent || expr instanceof JCFieldAccess) { String x = expr.toString(); if (x.endsWith(".class")) x = x.substring(0, x.length() - 6); else { int idx = x.lastIndexOf('.'); if (idx > -1) x = x.substring(idx + 1); } return x; } else return null; }
private boolean suppress(JCTree tree) { if (tree instanceof JCBlock) { JCBlock block = (JCBlock) tree; return (Position.NOPOS == block.pos) && block.stats.isEmpty(); } if (tree instanceof JCExpressionStatement) { JCExpression expr = ((JCExpressionStatement)tree).expr; if (expr instanceof JCMethodInvocation) { JCMethodInvocation inv = (JCMethodInvocation) expr; if (!inv.typeargs.isEmpty() || !inv.args.isEmpty()) return false; if (!(inv.meth instanceof JCIdent)) return false; return ((JCIdent) inv.meth).name.toString().equals("super"); } } return false; }
@Override public void visitAnnotation(JCAnnotation tree) { print("@"); print(tree.annotationType); if (tree.args.isEmpty()) return; print("("); boolean done = false; if (tree.args.length() == 1 && tree.args.get(0) instanceof JCAssign) { JCAssign arg1 = (JCAssign) tree.args.get(0); JCIdent arg1Name = arg1.lhs instanceof JCIdent ? ((JCIdent) arg1.lhs) : null; if (arg1Name != null && arg1Name.name == name_value(arg1Name.name)) { print(arg1.rhs); done = true; } } if (!done) print(tree.args, ", "); print(")"); }
public static boolean isConstructorCall(final JCStatement statement) { if (!(statement instanceof JCExpressionStatement)) return false; JCExpression expr = ((JCExpressionStatement) statement).expr; if (!(expr instanceof JCMethodInvocation)) return false; JCExpression invocation = ((JCMethodInvocation) expr).meth; String name; if (invocation instanceof JCFieldAccess) { name = ((JCFieldAccess) invocation).name.toString(); } else if (invocation instanceof JCIdent) { name = ((JCIdent) invocation).name.toString(); } else { name = ""; } return "super".equals(name) || "this".equals(name); }
private static void unpack(StringBuilder sb, JCExpression expr) { if (expr instanceof JCIdent) { sb.append(((JCIdent) expr).name.toString()); return; } if (expr instanceof JCFieldAccess) { JCFieldAccess jcfa = (JCFieldAccess) expr; unpack(sb, jcfa.selected); sb.append(".").append(jcfa.name.toString()); return; } if (expr instanceof JCTypeApply) { sb.setLength(0); sb.append("ERR:"); sb.append("@Builder(toBuilder=true) is not supported if returning a type with generics applied to an intermediate."); sb.append("__ERR__"); return; } sb.setLength(0); sb.append("ERR:"); sb.append("Expected a type of some sort, not a " + expr.getClass().getName()); sb.append("__ERR__"); }
@Override public JCTree visit(final PackageDeclaration n, final Object arg) { //ARG0: JCExpression // It returns a full qualified name JCExpression arg0 = (JCExpression) n.getName().accept(this, arg); /* TODO - Not supporting annotations if (n.getAnnotations() != null) { for (final AnnotationExpr a : n.getAnnotations()) { JCTree result = a.accept(this, arg); } } */ if (arg0 instanceof JCIdent) { return new AJCIdent((JCIdent) arg0, ((n.getComment() != null) ? n.getComment().getContent() : null)); } return new AJCFieldAccess((JCFieldAccess) arg0, ((n.getComment() != null) ? n.getComment().getContent() : null)); }
public void visitAnnotation(JCAnnotation tree) { try { print("@"); printExpr(tree.annotationType); if (tree.args.nonEmpty()) { print("("); if (tree.args.length() == 1 && tree.args.get(0) instanceof JCAssign) { JCExpression lhs = ((JCAssign)tree.args.get(0)).lhs; if (lhs instanceof JCIdent && ((JCIdent)lhs).name.toString().equals("value")) tree.args = List.of(((JCAssign)tree.args.get(0)).rhs); } printExprs(tree.args); print(")"); } } catch (IOException e) { throw new UncheckedIOException(e); } }
@Override public Object visitClass (ClassTree classTree, Trees trees) { Tree extendTree = classTree.getExtendsClause(); if (extendTree instanceof JCTypeApply) { //generic classes case JCTypeApply generic = (JCTypeApply) extendTree; extendTree = generic.clazz; } if (extendTree instanceof JCIdent) { JCIdent tree = (JCIdent) extendTree; Scope members = tree.sym.members(); if (checkScope(members)) return super.visitClass(classTree, trees); if (checkSuperTypes((ClassType) tree.type)) return super.visitClass(classTree, trees); } callSuperUsed = false; return super.visitClass(classTree, trees); }
@Override public boolean visitTypeReferencePart(TypeReferencePart node) { JCIdent ident = (JCIdent) toTree(node.astIdentifier()); List<JCExpression> typeArguments = toList(JCExpression.class, node.astTypeArguments()); if (typeArguments.isEmpty()) { return set(node, ident); } else { JCTypeApply typeApply = treeMaker.TypeApply(ident, typeArguments); Position jcOpenBracketPos = getConversionPositionInfo(node, "<"); if (jcOpenBracketPos == null) { setPos(posOfStructure(node, "<", true), node.getPosition().getEnd(), typeApply); } else { setPos(jcOpenBracketPos.getStart(), node.getPosition().getEnd(), typeApply); } return set(node, typeApply); } }
/** * This function walks into a tree with nodes of type JCBinary to search for * a string as one of the elements of the tree. * @param toTest The String searched as Element in the tree. * @param expression The bifurcation tree searched. * @return True if the string was found, or False. */ private boolean isThereInMiniTree(String toTest, JCTree expression) { if(expression instanceof JCParens){ if(isThereInMiniTree(toTest, ((JCParens) expression).expr)) return true; } else if(expression instanceof JCIdent){ if(((JCIdent) expression).name.toString().equals(toTest)) return true; } else if(expression instanceof JCBinary){ if(isThereInMiniTree(toTest, ((JCBinary) expression).rhs)) return true; if(isThereInMiniTree(toTest, ((JCBinary) expression).lhs)) return true; } return false; }
/** * Matches when the receiver of an instance method is the same reference as a particular argument * to the method. For example, receiverSameAsArgument(1) would match {@code obj.method("", obj)} * * @param argNum The number of the argument to compare against (zero-based. */ public static Matcher<? super MethodInvocationTree> receiverSameAsArgument(final int argNum) { return new Matcher<MethodInvocationTree>() { @Override public boolean matches(MethodInvocationTree t, VisitorState state) { List<? extends ExpressionTree> args = t.getArguments(); if (args.size() <= argNum) { return false; } ExpressionTree arg = args.get(argNum); JCExpression methodSelect = (JCExpression) t.getMethodSelect(); if (methodSelect instanceof JCFieldAccess) { JCFieldAccess fieldAccess = (JCFieldAccess) methodSelect; return ASTHelpers.sameVariable(fieldAccess.getExpression(), arg); } else if (methodSelect instanceof JCIdent) { // A bare method call: "equals(foo)". Receiver is implicitly "this". return "this".equals(arg.toString()); } return false; } }; }
/** * 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); }
/** * Returns the type of a receiver of a method call expression. Precondition: the expressionTree * corresponds to a method call. * * <p>Examples: * * <pre>{@code * a.b.foo() ==> type of a.b * a.bar().foo() ==> type of a.bar() * this.foo() ==> type of this * foo() ==> type of this * TheClass.aStaticMethod() ==> TheClass * aStaticMethod() ==> type of class in which method is defined * }</pre> */ public static Type getReceiverType(ExpressionTree expressionTree) { if (expressionTree instanceof JCFieldAccess) { JCFieldAccess methodSelectFieldAccess = (JCFieldAccess) expressionTree; return methodSelectFieldAccess.selected.type; } else if (expressionTree instanceof JCIdent) { JCIdent methodCall = (JCIdent) expressionTree; return methodCall.sym.owner.type; } else if (expressionTree instanceof JCMethodInvocation) { return getReceiverType(((JCMethodInvocation) expressionTree).getMethodSelect()); } else if (expressionTree instanceof JCMemberReference) { return ((JCMemberReference) expressionTree).getQualifierExpression().type; } throw new IllegalArgumentException( "Expected a JCFieldAccess or JCIdent from expression " + expressionTree); }
@Override public void visitIdent(JCIdent tree) { Symbol sym = tree.sym; if (sym == null) { return; } sym = sym.baseSymbol(); if (wildcardScope.includes(sym)) { if (sym.owner.getQualifiedName().contentEquals("java.lang")) { return; } switch (sym.kind) { case TYP: seen.add( TypeToImport.create(sym.getSimpleName().toString(), sym.owner, /* stat= */ false)); break; case VAR: case MTH: seen.add( TypeToImport.create(sym.getSimpleName().toString(), sym.owner, /* stat= */ true)); break; default: return; } } }
/** * Find the root variable identifiers from an arbitrary expression. * * <p>Examples: a.trim().intern() ==> {a} a.b.trim().intern() ==> {a} this.intValue.foo() ==> * {this} this.foo() ==> {this} intern() ==> {} String.format() ==> {} java.lang.String.format() * ==> {} x.y.z(s.t) ==> {x,s} */ static List<IdentifierTree> getVariableUses(ExpressionTree tree) { final List<IdentifierTree> freeVars = new ArrayList<>(); new TreeScanner<Void, Void>() { @Override public Void visitIdentifier(IdentifierTree node, Void v) { if (((JCIdent) node).sym instanceof VarSymbol) { freeVars.add(node); } return super.visitIdentifier(node, v); } }.scan(tree, null); return freeVars; }
/** Return the selected enumeration constant symbol, or null. */ private Symbol enumConstant(JCTree tree, Type enumType) { if (tree.getTag() != JCTree.IDENT) { log.error(tree.pos(), "enum.label.must.be.unqualified.enum"); return syms.errSymbol; } JCIdent ident = (JCIdent)tree; Name name = ident.name; for (Scope.Entry e = enumType.tsym.members().lookup(name); e.scope != null; e = e.next()) { if (e.sym.kind == VAR) { Symbol s = ident.sym = e.sym; ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated ident.type = s.type; return ((s.flags_field & Flags.ENUM) == 0) ? null : s; } } return null; }
/** * Matches when the receiver of an instance method is the same reference as a particular argument to the method. * For example, receiverSameAsArgument(1) would match {@code obj.method("", obj)} * * @param argNum The number of the argument to compare against (zero-based. */ public static Matcher<? super MethodInvocationTree> receiverSameAsArgument(final int argNum) { return new Matcher<MethodInvocationTree>() { @Override public boolean matches(MethodInvocationTree t, VisitorState state) { List<? extends ExpressionTree> args = t.getArguments(); if (args.size() <= argNum) { return false; } ExpressionTree arg = args.get(argNum); JCExpression methodSelect = (JCExpression) t.getMethodSelect(); if (methodSelect instanceof JCFieldAccess) { JCFieldAccess fieldAccess = (JCFieldAccess) methodSelect; return ASTHelpers.sameVariable(fieldAccess.getExpression(), arg); } else if (methodSelect instanceof JCIdent) { // A bare method call: "equals(foo)". Receiver is implicitly "this". return "this".equals(arg.toString()); } return false; } }; }
/** * Find the root variable identifiers from an arbitrary expression. * * Examples: * a.trim().intern() ==> {a} * a.b.trim().intern() ==> {a} * this.intValue.foo() ==> {this} * this.foo() ==> {this} * intern() ==> {} * String.format() ==> {} * java.lang.String.format() ==> {} * x.y.z(s.t) ==> {x,s} */ static List<IdentifierTree> getVariableUses(ExpressionTree tree) { final List<IdentifierTree> freeVars = new ArrayList<IdentifierTree>(); new TreeScanner<Void, Void>() { @Override public Void visitIdentifier(IdentifierTree node, Void v) { if (((JCIdent) node).sym instanceof VarSymbol) { freeVars.add(node); } return super.visitIdentifier(node, v); } }.scan(tree, null); return freeVars; }
private static boolean delegatingConstructor(List<JCStatement> stats) { if (stats.isEmpty()) { return false; } JCStatement stat = stats.get(0); if (stat.getKind() != Kind.EXPRESSION_STATEMENT) { return false; } JCExpression expr = ((JCExpressionStatement) stat).getExpression(); if (expr.getKind() != Kind.METHOD_INVOCATION) { return false; } JCExpression method = ((JCMethodInvocation) expr).getMethodSelect(); Name name; switch (method.getKind()) { case IDENTIFIER: name = ((JCIdent) method).getName(); break; case MEMBER_SELECT: name = ((JCFieldAccess) method).getIdentifier(); break; default: return false; } return name.contentEquals("this") || name.contentEquals("super"); }
@Override public Void visitVariable(VariableTree node, Void p) { if (!variables.isEmpty()) { variables .stream() .filter(r -> { if (r.getNodeKind() != Kind.IDENTIFIER) { return false; } JCIdent select = (JCIdent) r.getSource(); String owner = select.sym.owner.name.toString(); return owner.equals(currentUnit) && NameUtil.equals(r.getNodeName(),node.getName()); } ) .forEach(r -> { ExpressionTree init = node.getInitializer(); r.setSource(init); }); } return super.visitVariable(node, p); }
/** * Turns an expression into a guessed intended literal. Only works for literals, as you can imagine. * * Will for example turn a TrueLiteral into 'Boolean.valueOf(true)'. */ public static Object calculateGuess(JCExpression expr) { if (expr instanceof JCLiteral) { JCLiteral lit = (JCLiteral)expr; if (lit.getKind() == com.sun.source.tree.Tree.Kind.BOOLEAN_LITERAL) { return ((Number)lit.value).intValue() == 0 ? false : true; } return lit.value; } else if (expr instanceof JCIdent || expr instanceof JCFieldAccess) { String x = expr.toString(); if (x.endsWith(".class")) x = x.substring(0, x.length() - 6); else { int idx = x.lastIndexOf('.'); if (idx > -1) x = x.substring(idx + 1); } return x; } else return null; }
protected int diffAssign(JCAssign oldT, JCAssign newT, JCTree parent, int[] bounds) { int localPointer = bounds[0]; // lhs int[] lhsBounds = getBounds(oldT.lhs); if (lhsBounds[0] < 0) { lhsBounds[0] = getOldPos(oldT.rhs); lhsBounds[1] = -1; } copyTo(localPointer, lhsBounds[0]); localPointer = diffTree(oldT.lhs, newT.lhs, lhsBounds); int[] rhsBounds = getCommentCorrectedBounds(oldT.rhs); //#174552: '=' may be missing if this is a synthetic annotation attribute assignment (of attribute name "value"): if ( oldT.lhs.getKind() == Kind.IDENTIFIER && newT.lhs.getKind() == Kind.IDENTIFIER && !((JCIdent) oldT.lhs).name.equals(((JCIdent) newT.lhs).name)) { tokenSequence.move(rhsBounds[0]); moveToSrcRelevant(tokenSequence, Direction.BACKWARD); if (tokenSequence.token().id() != JavaTokenId.EQ) { boolean spaceAroundAssignOps = (parent.getKind() == Kind.ANNOTATION || parent.getKind() == Kind.TYPE_ANNOTATION) ? diffContext.style.spaceAroundAnnotationValueAssignOps() : diffContext.style.spaceAroundAssignOps(); if (spaceAroundAssignOps) printer.print(" = "); else printer.print("="); localPointer = lhsBounds[0]; } } //#174552 end // rhs copyTo(localPointer, rhsBounds[0]); localPointer = diffTree(oldT.rhs, newT.rhs, rhsBounds); copyTo(localPointer, bounds[1]); return bounds[1]; }
protected int diffIdent(JCIdent oldT, JCIdent newT, int[] bounds) { if (nameChanged(oldT.name, newT.name)) { copyTo(bounds[0], oldT.pos); printer.print(newT.name); diffInfo.put(oldT.pos, NbBundle.getMessage(CasualDiff.class,"TXT_UpdateReferenceTo",oldT.name)); } else { copyTo(bounds[0], bounds[1]); } return bounds[1]; }
protected void diffErroneous(JCErroneous oldT, JCErroneous newT, int[] bounds) { JCTree oldTident = oldT.getErrorTrees().get(0); JCTree newTident = newT.getErrorTrees().get(0); if (oldTident.getKind() == Kind.IDENTIFIER && newTident.getKind() == Kind.IDENTIFIER) { diffIdent((JCIdent) oldTident, (JCIdent) newTident, bounds); } }
@Override public String next() { Name name; if (next instanceof JCIdent) { name = ((JCIdent) next).name; next = null; } else { JCFieldAccess fa = (JCFieldAccess) next; name = fa.name; next = fa.selected; } return name.toString(); }
@Override public Void visitMethodInvocation(MethodInvocationTree node, Void p) { super.visitMethodInvocation(node, p); JCMethodInvocation apply = (JCMethodInvocation)node; JCIdent ident = (JCIdent)apply.meth; Symbol oldSym = ident.sym; if (!oldSym.isConstructor()) { ident.sym = new Symbol.DynamicMethodSymbol(oldSym.name, oldSym.owner, REF_invokeStatic, bsm, oldSym.type, new Object[0]); } return null; }
@Override public void visitSelect(final JCFieldAccess node) { // Attempt to resolve the entire selection expression final Optional<TypeName> maybeType = substitutionInventory .tryResolveClassByIdentifier(node.toString()) .map(type -> substitutionInventory.applyTypeSubstitution(type)); if (maybeType.isPresent()) { print(maybeType.get()); return;// We substituted the expression in its entirety; nothing more to output. } else if (node.selected instanceof JCIdent) { // If "selected" is an identifier, visitIdent won't attempt type resolution // so we do it here. final Optional<TypeName> maybeSelectedType = substitutionInventory .tryResolveClassByIdentifier(node.selected.toString()) .map(type -> substitutionInventory.applyTypeSubstitution(type)); if (maybeSelectedType.isPresent()) { print(maybeSelectedType.get()); } else { printExpr(node.selected, TreeInfo.postfixPrec); } } else { printExpr(node.selected, TreeInfo.postfixPrec); } print("."); final String selectionTarget = node.name.toString(); print(currentSubstitution() .filter(field -> substitutionInventory.isSubstitutableFieldName(selectionTarget)) .orElse(selectionTarget)); }
static String getPackageName(JCCompilationUnit cu) { try { Object pkg = packageNameMethod.invoke(cu); return (pkg instanceof JCFieldAccess || pkg instanceof JCIdent) ? pkg.toString() : null; } catch (Exception e) {} return null; }