protected int diffDoLoop(JCDoWhileLoop oldT, JCDoWhileLoop newT, int[] bounds) { int localPointer = bounds[0]; int[] bodyBounds = new int[] { localPointer, endPos(oldT.body) }; int oldIndent = newT.body.hasTag(Tag.BLOCK) ? -1 : printer.indent(); localPointer = diffTree(oldT.body, newT.body, bodyBounds, oldT.getKind()); if (!newT.body.hasTag(Tag.BLOCK)) printer.undent(oldIndent); int[] condBounds = getBounds(oldT.cond); if (oldT.body.getKind() != Kind.BLOCK && newT.body.getKind() == Kind.BLOCK) { moveBackToToken(tokenSequence, condBounds[0], JavaTokenId.WHILE); localPointer = tokenSequence.offset(); } else { copyTo(localPointer, condBounds[0]); localPointer = diffTree(oldT.cond, newT.cond, condBounds); } copyTo(localPointer, bounds[1]); return bounds[1]; }
protected int diffWhileLoop(JCWhileLoop oldT, JCWhileLoop newT, int[] bounds) { int localPointer = bounds[0]; // condition int[] condPos = getBounds(oldT.cond); copyTo(localPointer, condPos[0]); localPointer = diffTree(oldT.cond, newT.cond, condPos); // body int[] bodyPos = new int[] { localPointer, endPos(oldT.body) }; int oldIndent = newT.body.hasTag(Tag.BLOCK) ? -1 : printer.indent(); localPointer = diffTree(oldT.body, newT.body, bodyPos, oldT.getKind()); if (!newT.body.hasTag(Tag.BLOCK)) printer.undent(oldIndent); copyTo(localPointer, bounds[1]); return bounds[1]; }
protected int diffForeachLoop(JCEnhancedForLoop oldT, JCEnhancedForLoop newT, int[] bounds) { int localPointer = bounds[0]; // variable int[] varBounds = getBounds(oldT.var); copyTo(localPointer, varBounds[0]); localPointer = diffTree(oldT.var, newT.var, varBounds); // expression int[] exprBounds = getBounds(oldT.expr); copyTo(localPointer, exprBounds[0]); localPointer = diffTree(oldT.expr, newT.expr, exprBounds); // body int[] bodyBounds = new int[] { localPointer, endPos(oldT.body) }; int oldIndent = newT.body.hasTag(Tag.BLOCK) ? -1 : printer.indent(); localPointer = diffTree(oldT.body, newT.body, bodyBounds, oldT.getKind()); if (!newT.body.hasTag(Tag.BLOCK)) printer.undent(oldIndent); copyTo(localPointer, bounds[1]); return bounds[1]; }
protected int diffSynchronized(JCSynchronized oldT, JCSynchronized newT, int[] bounds) { int localPointer = bounds[0]; // lock int[] lockBounds = getBounds(oldT.lock); copyTo(localPointer, lockBounds[0]); localPointer = diffTree(oldT.lock, newT.lock, lockBounds); // body int[] bodyBounds = getBounds(oldT.body); copyTo(localPointer, bodyBounds[0]); int oldIndent = newT.body.hasTag(Tag.BLOCK) ? -1 : printer.indent(); localPointer = diffTree(oldT.body, newT.body, bodyBounds); if (!newT.body.hasTag(Tag.BLOCK)) printer.undent(oldIndent); copyTo(localPointer, bounds[1]); return bounds[1]; }
static int from(Tag tag, int opcode) { /** Map bytecode of binary operation to access code of corresponding * assignment operation. This is always an even number. */ switch (tag) { case PREINC: return AccessCode.PREINC.code; case PREDEC: return AccessCode.PREDEC.code; case POSTINC: return AccessCode.POSTINC.code; case POSTDEC: return AccessCode.POSTDEC.code; } if (iadd <= opcode && opcode <= lxor) { return (opcode - iadd) * 2 + FIRSTASGOP.code; } else if (opcode == string_add) { return (lxor + 1 - iadd) * 2 + FIRSTASGOP.code; } else if (ishll <= opcode && opcode <= lushrl) { return (opcode - ishll + lxor + 2 - iadd) * 2 + FIRSTASGOP.code; } return -1; }
void checkLegacyLogMethod(JCMethodInvocation tree) { Symbol method = TreeInfo.symbolFor(tree); if (method == null || method.kind != Kinds.Kind.MTH || !typeToCheck(method.owner.type) || !LEGACY_METHOD_NAMES.contains(method.name.toString()) || !((MethodSymbol) method).isVarArgs() || method.type.getParameterTypes().size() < 2) { return ; } JCExpression key = tree.args.get(method.type.getParameterTypes().size() - 2); if (key.hasTag(Tag.LITERAL)) { messages.error(tree, "crules.use.of.legacy.log.method", tree); } }
void run(Queue<Env<AttrContext>> list, Iterable<? extends Element> elements) { Set<Element> set = new HashSet<>(); for (Element item: elements) { set.add(item); } ListBuffer<Env<AttrContext>> defer = new ListBuffer<>(); while (list.peek() != null) { Env<AttrContext> env = list.remove(); Symbol test = null; if (env.tree.hasTag(Tag.MODULEDEF)) { test = ((JCModuleDecl) env.tree).sym; } else if (env.tree.hasTag(Tag.PACKAGEDEF)) { test = env.toplevel.packge; } else { ClassSymbol csym = env.enclClass.sym; if (csym != null) test = csym.outermostClass(); } if (test != null && set.contains(test)) process(env); else defer = defer.append(env); } list.addAll(defer); }
public int getAccessCode(Tag tag) { if (accessCode != Integer.MIN_VALUE && !tag.isIncOrDecUnaryOp()) { return accessCode; } accessCode = AccessCode.from(tag, opcode); return accessCode; }
private void checkCyclicDependencies(JCModuleDecl mod) { for (JCDirective d : mod.directives) { JCRequires rd; if (!d.hasTag(Tag.REQUIRES) || (rd = (JCRequires) d).directive == null) continue; Set<ModuleSymbol> nonSyntheticDeps = new HashSet<>(); List<ModuleSymbol> queue = List.of(rd.directive.module); while (queue.nonEmpty()) { ModuleSymbol current = queue.head; queue = queue.tail; if (!nonSyntheticDeps.add(current)) continue; current.complete(); if ((current.flags() & Flags.ACYCLIC) != 0) continue; Assert.checkNonNull(current.requires, current::toString); for (RequiresDirective dep : current.requires) { if (!dep.flags.contains(RequiresFlag.EXTRA)) queue = queue.prepend(dep.module); } } if (nonSyntheticDeps.contains(mod.sym)) { log.error(rd.moduleName.pos(), Errors.CyclicRequires(rd.directive.module)); } mod.sym.flags_field |= Flags.ACYCLIC; } }
/** * Entry point for resolving a unary operator given an operator tag and an argument type. */ OperatorSymbol resolveUnary(DiagnosticPosition pos, JCTree.Tag tag, Type op) { return resolve(tag, unaryOperators, unop -> unop.test(op), unop -> unop.resolve(op), () -> reportErrorIfNeeded(pos, tag, op)); }
/** * Entry point for resolving a binary operator given an operator tag and a pair of argument types. */ OperatorSymbol resolveBinary(DiagnosticPosition pos, JCTree.Tag tag, Type op1, Type op2) { return resolve(tag, binaryOperators, binop -> binop.test(op1, op2), binop -> binop.resolve(op1, op2), () -> reportErrorIfNeeded(pos, tag, op1, op2)); }
/** * Main operator lookup routine; lookup an operator (either unary or binary) in its corresponding * map. If there's a matching operator, its resolve routine is called and the result is returned; * otherwise the result of a fallback function is returned. */ private <O> OperatorSymbol resolve(Tag tag, Map<Name, List<O>> opMap, Predicate<O> opTestFunc, Function<O, OperatorSymbol> resolveFunc, Supplier<OperatorSymbol> noResultFunc) { return opMap.get(operatorName(tag)).stream() .filter(opTestFunc) .map(resolveFunc) .findFirst() .orElseGet(noResultFunc); }
/** * Report an operator lookup error. */ private OperatorSymbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) { if (Stream.of(args).noneMatch(Type::isErroneous)) { Name opName = operatorName(tag); JCDiagnostic.Error opError = (args.length) == 1 ? Errors.OperatorCantBeApplied(opName, args[0]) : Errors.OperatorCantBeApplied1(opName, args[0], args[1]); log.error(pos, opError); } return noOpSymbol; }
/** * Initialize all unary operators. */ private void initUnaryOperators() { initOperators(unaryOperators, new UnaryNumericOperator(Tag.POS) .addUnaryOperator(DOUBLE, DOUBLE, nop) .addUnaryOperator(FLOAT, FLOAT, nop) .addUnaryOperator(LONG, LONG, nop) .addUnaryOperator(INT, INT, nop), new UnaryNumericOperator(Tag.NEG) .addUnaryOperator(DOUBLE, DOUBLE, dneg) .addUnaryOperator(FLOAT, FLOAT, fneg) .addUnaryOperator(LONG, LONG, lneg) .addUnaryOperator(INT, INT, ineg), new UnaryNumericOperator(Tag.COMPL, Type::isIntegral) .addUnaryOperator(LONG, LONG, lxor) .addUnaryOperator(INT, INT, ixor), new UnaryPrefixPostfixOperator(Tag.POSTINC) .addUnaryOperator(DOUBLE, DOUBLE, dadd) .addUnaryOperator(FLOAT, FLOAT, fadd) .addUnaryOperator(LONG, LONG, ladd) .addUnaryOperator(INT, INT, iadd) .addUnaryOperator(CHAR, CHAR, iadd) .addUnaryOperator(SHORT, SHORT, iadd) .addUnaryOperator(BYTE, BYTE, iadd), new UnaryPrefixPostfixOperator(Tag.POSTDEC) .addUnaryOperator(DOUBLE, DOUBLE, dsub) .addUnaryOperator(FLOAT, FLOAT, fsub) .addUnaryOperator(LONG, LONG, lsub) .addUnaryOperator(INT, INT, isub) .addUnaryOperator(CHAR, CHAR, isub) .addUnaryOperator(SHORT, SHORT, isub) .addUnaryOperator(BYTE, BYTE, isub), new UnaryBooleanOperator(Tag.NOT) .addUnaryOperator(BOOLEAN, BOOLEAN, bool_not), new UnaryReferenceOperator(Tag.NULLCHK) .addUnaryOperator(OBJECT, OBJECT, nullchk)); }
/** * Initialize operator name array. */ private void initOperatorNames() { setOperatorName(Tag.POS, "+"); setOperatorName(Tag.NEG, "-"); setOperatorName(Tag.NOT, "!"); setOperatorName(Tag.COMPL, "~"); setOperatorName(Tag.PREINC, "++"); setOperatorName(Tag.PREDEC, "--"); setOperatorName(Tag.POSTINC, "++"); setOperatorName(Tag.POSTDEC, "--"); setOperatorName(Tag.NULLCHK, "<*nullchk*>"); setOperatorName(Tag.OR, "||"); setOperatorName(Tag.AND, "&&"); setOperatorName(Tag.EQ, "=="); setOperatorName(Tag.NE, "!="); setOperatorName(Tag.LT, "<"); setOperatorName(Tag.GT, ">"); setOperatorName(Tag.LE, "<="); setOperatorName(Tag.GE, ">="); setOperatorName(Tag.BITOR, "|"); setOperatorName(Tag.BITXOR, "^"); setOperatorName(Tag.BITAND, "&"); setOperatorName(Tag.SL, "<<"); setOperatorName(Tag.SR, ">>"); setOperatorName(Tag.USR, ">>>"); setOperatorName(Tag.PLUS, "+"); setOperatorName(Tag.MINUS, names.hyphen); setOperatorName(Tag.MUL, names.asterisk); setOperatorName(Tag.DIV, names.slash); setOperatorName(Tag.MOD, "%"); }
private void checkCyclicDependencies(JCModuleDecl mod) { for (JCDirective d : mod.directives) { if (!d.hasTag(Tag.REQUIRES)) continue; JCRequires rd = (JCRequires) d; Set<ModuleSymbol> nonSyntheticDeps = new HashSet<>(); List<ModuleSymbol> queue = List.of(rd.directive.module); while (queue.nonEmpty()) { ModuleSymbol current = queue.head; queue = queue.tail; if (!nonSyntheticDeps.add(current)) continue; if ((current.flags() & Flags.ACYCLIC) != 0) continue; current.complete(); Assert.checkNonNull(current.requires, () -> current.toString()); for (RequiresDirective dep : current.requires) { if (!dep.flags.contains(RequiresFlag.EXTRA)) queue = queue.prepend(dep.module); } } if (nonSyntheticDeps.contains(mod.sym)) { log.error(rd.moduleName.pos(), Errors.CyclicRequires(rd.directive.module)); } mod.sym.flags_field |= Flags.ACYCLIC; } }
/** * Entry point for resolving a unary operator given an operator tag and an argument type. */ Symbol resolveUnary(DiagnosticPosition pos, JCTree.Tag tag, Type op) { return resolve(tag, unaryOperators, unop -> unop.test(op), unop -> unop.resolve(op), () -> reportErrorIfNeeded(pos, tag, op)); }
/** * Entry point for resolving a binary operator given an operator tag and a pair of argument types. */ Symbol resolveBinary(DiagnosticPosition pos, JCTree.Tag tag, Type op1, Type op2) { return resolve(tag, binaryOperators, binop -> binop.test(op1, op2), binop -> binop.resolve(op1, op2), () -> reportErrorIfNeeded(pos, tag, op1, op2)); }
/** * Main operator lookup routine; lookup an operator (either unary or binary) in its corresponding * map. If there's a matching operator, its resolve routine is called and the result is returned; * otherwise the result of a fallback function is returned. */ private <O> Symbol resolve(Tag tag, Map<Name, List<O>> opMap, Predicate<O> opTestFunc, Function<O, Symbol> resolveFunc, Supplier<Symbol> noResultFunc) { return opMap.get(operatorName(tag)).stream() .filter(opTestFunc) .map(resolveFunc) .findFirst() .orElseGet(noResultFunc); }
/** * Report an operator lookup error. */ private Symbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) { if (Stream.of(args).noneMatch(Type::isErroneous)) { Name opName = operatorName(tag); JCDiagnostic.Error opError = (args.length) == 1 ? Errors.OperatorCantBeApplied(opName, args[0]) : Errors.OperatorCantBeApplied1(opName, args[0], args[1]); log.error(pos, opError); } return syms.noSymbol; }
@Override public JCTree visit(final UnaryExpr n, final Object arg) { // ARG0: int opcode Tag arg0; switch (n.getOperator()) { case positive: arg0 = JCTree.Tag.POS; break; case negative: arg0 = JCTree.Tag.NEG; break; case preIncrement: arg0 = JCTree.Tag.PREINC; break; case preDecrement: arg0 = JCTree.Tag.PREDEC; break; case not: arg0 = JCTree.Tag.NOT; break; case inverse: arg0 = JCTree.Tag.COMPL; break; case posIncrement: arg0 = JCTree.Tag.POSTINC; break; case posDecrement: arg0 = JCTree.Tag.POSTDEC; break; default: arg0 = JCTree.Tag.ERRONEOUS; } // ARG1: JCExpression arg JCExpression arg1 = (JCExpression) n.getExpr().accept(this, arg); return new AJCUnary(make.Unary(arg0, arg1), ((n.getComment() != null) ? n.getComment().getContent() : null)); }
@Override public Choice<State<JCBinary>> visitBinary(final BinaryTree node, State<?> state) { final Tag tag = ((JCBinary) node).getTag(); return chooseSubtrees( state, s -> unifyExpression(node.getLeftOperand(), s), s -> unifyExpression(node.getRightOperand(), s), (l, r) -> maker().Binary(tag, l, r)); }
@Override public Choice<State<JCUnary>> visitUnary(UnaryTree node, State<?> state) { final Tag tag = ((JCUnary) node).getTag(); return chooseSubtrees( state, s -> unifyExpression(node.getExpression(), s), expr -> maker().Unary(tag, expr)) .condition( s -> !MUTATING_UNARY_TAGS.contains(tag) || !(s.result().getExpression() instanceof PlaceholderParamIdent)); }
/** * Searches the annotation list for {@code @Test(expected=...)}. If found, deletes the exception * attribute from the annotation, and returns its value. */ private static JCExpression deleteExpectedException( SuggestedFix.Builder fix, List<JCAnnotation> annotations, VisitorState state) { Type testAnnotation = state.getTypeFromString(JUnitMatchers.JUNIT4_TEST_ANNOTATION); for (JCAnnotation annotationTree : annotations) { if (!ASTHelpers.isSameType(testAnnotation, annotationTree.type, state)) { continue; } com.sun.tools.javac.util.List<JCExpression> arguments = annotationTree.getArguments(); for (JCExpression arg : arguments) { if (!arg.hasTag(Tag.ASSIGN)) { continue; } JCAssign assign = (JCAssign) arg; if (assign.lhs.hasTag(Tag.IDENT) && ((JCIdent) assign.lhs).getName().contentEquals("expected")) { if (arguments.size() == 1) { fix.replace(annotationTree, "@Test"); } else { removeFromList(fix, state, arguments, assign); } return assign.rhs; } } } return null; }
protected int diffForLoop(JCForLoop oldT, JCForLoop newT, int[] bounds) { int localPointer; // initializer if (oldT.init.nonEmpty()) { // there is something in the init section, using start offset localPointer = getOldPos(oldT.init.head); } else { moveFwdToToken(tokenSequence, bounds[0], JavaTokenId.SEMICOLON); localPointer = tokenSequence.offset(); } copyTo(bounds[0], localPointer); if (!listsMatch(oldT.init, newT.init)) { boolean oldVariable = containsVariable(oldT.init); boolean newVariable = containsVariable(newT.init); if (oldVariable ^ newVariable) { int oldPrec = printer.setPrec(TreeInfo.noPrec); localPointer = diffParameterList(oldT.init, newT.init, null, localPointer, Measure.ARGUMENT); printer.setPrec(oldPrec); } else { if (oldVariable) { List<JCVariableDecl> oldInit = NbCollections.checkedListByCopy(oldT.init, JCVariableDecl.class, false); FieldGroupTree old = new FieldGroupTree(oldInit); List<JCVariableDecl> newInit = NbCollections.checkedListByCopy(newT.init, JCVariableDecl.class, false); FieldGroupTree nue = new FieldGroupTree(newInit); int[] initBounds = getBounds(oldT.init.head); JCTree last = oldT.init.get(oldT.init.size() - 1); long endPos = diffContext.trees.getSourcePositions().getEndPosition(oldTopLevel, last); initBounds[1] = (int) endPos; localPointer = diffTree(old, nue, initBounds); } else { localPointer = diffParameterList(oldT.init, newT.init, null, localPointer, Measure.ARGUMENT); } } } // condition if (oldT.cond != null) { copyTo(localPointer, localPointer = getOldPos(oldT.cond)); localPointer = diffTree(oldT.cond, newT.cond, getBounds(oldT.cond)); } else { moveFwdToToken(tokenSequence, localPointer, JavaTokenId.SEMICOLON); copyTo(localPointer, localPointer = tokenSequence.offset()); } // steps if (oldT.step.nonEmpty()) copyTo(localPointer, localPointer = getOldPos(oldT.step.head)); else { moveFwdToToken(tokenSequence, localPointer, JavaTokenId.SEMICOLON); tokenSequence.moveNext(); copyTo(localPointer, localPointer = tokenSequence.offset()); } localPointer = diffParameterList(oldT.step, newT.step, null, localPointer, Measure.ARGUMENT); // body int[] bodyBounds = new int[] { localPointer, endPos(oldT.body) }; int oldIndent = newT.body.hasTag(Tag.BLOCK) ? -1 : printer.indent(); localPointer = diffTree(oldT.body, newT.body, bodyBounds, oldT.getKind()); if (!newT.body.hasTag(Tag.BLOCK)) printer.undent(oldIndent); copyTo(localPointer, bounds[1]); return bounds[1]; }
private String operatorName(Tag tag) { // dummy instance, just to access a public method which should be static return new Pretty(null, false).operatorName(tag); }
AccessCode(int code, Tag tag) { this.code = code; this.tag = tag; }
StatementAnalyzer(AnalyzerMode mode, Tag tag) { this.mode = mode; this.tag = tag; }
/** * Return name of operator with given tree tag. */ public Name operatorName(JCTree.Tag tag) { return opname[tag.operatorIndex()]; }
@SuppressWarnings("varargs") OperatorHelper(Tag tag) { this.name = operatorName(tag); }
UnaryOperatorHelper(Tag tag) { super(tag); }
BinaryOperatorHelper(Tag tag) { super(tag); }
UnaryReferenceOperator(Tag tag) { super(tag); }
UnaryNumericOperator(Tag tag) { this(tag, Type::isNumeric); }
UnaryNumericOperator(Tag tag, Predicate<Type> numericTest) { super(tag); this.numericTest = numericTest; }
UnaryBooleanOperator(Tag tag) { super(tag); }
UnaryPrefixPostfixOperator(Tag tag) { super(tag); }