return false; return writes.contains(wanted) || (sym.flags() & Flags.HASINIT) == Flags.HASINIT;
/** @return all values of the given enum type, in declaration order. */ public static LinkedHashSet<String> enumValues(TypeSymbol enumType) { if (enumType.getKind() != ElementKind.ENUM) { throw new IllegalStateException(); } Scope scope = enumType.members(); Deque<String> values = new ArrayDeque<>(); for (Symbol sym : scope.getSymbols()) { if (sym instanceof VarSymbol) { VarSymbol var = (VarSymbol) sym; if ((var.flags() & Flags.ENUM) != 0) { /** * Javac gives us the members backwards, apparently. It's worth making an effort to * preserve declaration order because it's useful for diagnostics (e.g. in {@link * MissingCasesInEnumSwitch}). */ values.push(sym.name.toString()); } } } return new LinkedHashSet<>(values); }
|| (curr.getKind() == Kind.CLASS && parent.getKind() == Kind.BLOCK), (curr, unused) -> Objects.equals(var.owner, ASTHelpers.getSymbol(curr)))) { if ((var.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) == 0) { return false;
/** Do we need to track init/uninit state of this symbol? * I.e. is symbol either a local or a blank final variable? */ protected boolean trackable(VarSymbol sym) { return sym.pos >= startPos && ((sym.owner.kind == MTH || ((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL && classDef.sym.isEnclosedBy((ClassSymbol)sym.owner)))); }
/** Do we need to track init/uninit state of this symbol? * I.e. is symbol either a local or a blank final variable? */ boolean trackable(VarSymbol sym) { return (sym.owner.kind == MTH || ((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL && classDef.sym.isEnclosedBy((ClassSymbol)sym.owner))); }
boolean isFinalUninitializedField(VarSymbol sym) { return sym.owner.kind == TYP && ((sym.flags() & (FINAL | HASINIT | PARAMETER)) == FINAL && classDef.sym.isEnclosedBy((ClassSymbol)sym.owner)); }
boolean trackVar(VarSymbol var) { return (var.owner.kind == MTH && (var.flags() & (PARAMETER | HASINIT)) == 0 && analyzer.trackable(var)); }
/** Create a variable definition from a variable symbol and an initializer * expression. */ public JCVariableDecl VarDef(VarSymbol v, JCExpression init) { return (JCVariableDecl) new JCVariableDecl( Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())), v.name, Type(v.type), init, v).setPos(pos).setType(v.type); }
/** Create a variable definition from a variable symbol and an initializer * expression. */ public JCVariableDecl VarDef(VarSymbol v, JCExpression init) { return (JCVariableDecl) new JCVariableDecl( Modifiers(v.flags(), Annotations(v.getAnnotationMirrors())), v.name, Type(v.type), init, v).setPos(pos).setType(v.type); }
/** Create a variable definition from a variable symbol and an initializer * expression. */ public JCVariableDecl VarDef(VarSymbol v, JCExpression init) { return (JCVariableDecl) new JCVariableDecl( Modifiers(v.flags(), Annotations(v.getRawAttributes())), v.name, Type(v.type), init, v).setPos(pos).setType(v.type); }
if (lastFormalParam == null || (lastFormalParam.flags() & Flags.VARARGS) == 0) { return Description.NO_MATCH;
var -> !Flags.isStatic(var.sym) && (var.sym.flags() & Flags.FINAL) == 0 && ASTHelpers.isSameType(lhsType, var.type, state), state);
private boolean tryFinallyClose(VarSymbol var, TreePath path, VisitorState state) { if ((var.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) == 0) { return false;
@Override public boolean matches(ExpressionTree t, VisitorState state) { if (t.getKind() != Tree.Kind.IDENTIFIER) { return false; } Symbol.VarSymbol varSymbol = (Symbol.VarSymbol) ASTHelpers.getSymbol(t); Symbol owner = varSymbol.owner; ElementKind ownerKind = owner.getKind(); // Check that the identifier is a formal method/constructor parameter. if (ownerKind != ElementKind.METHOD && ownerKind != ElementKind.CONSTRUCTOR) { return false; } // Check that the symbol is final if ((varSymbol.flags() & Flags.FINAL) != Flags.FINAL && (varSymbol.flags() & Flags.EFFECTIVELY_FINAL) != Flags.EFFECTIVELY_FINAL) { return false; } // Check if the symbol has the @CompileTimeConstant annotation. if (hasCompileTimeConstantAnnotation(state, varSymbol)) { return true; } return false; } }
@Override public Description matchSynchronized(SynchronizedTree tree, VisitorState state) { Symbol symbol = ASTHelpers.getSymbol(stripParentheses(tree.getExpression())); if (!(symbol instanceof VarSymbol)) { return NO_MATCH; } // TODO(cushon): check that the receiver doesn't contain mutable state. // Currently 'this.locks[i].mu' is accepted if 'mu' is final but 'locks' is non-final. VarSymbol varSymbol = (VarSymbol) symbol; if (varSymbol.isLocal() || varSymbol.isStatic() || (varSymbol.flags() & Flags.FINAL) != 0) { return NO_MATCH; } if (ASTHelpers.hasAnnotation(varSymbol, LazyInit.class, state)) { return NO_MATCH; } Name ownerName = varSymbol.owner.enclClass().getQualifiedName(); if (Stream.of("java.io.Writer", "java.io.Reader").anyMatch(ownerName::contentEquals)) { // These classes contain a non-final 'lock' variable available to subclasses, and we can't // make these locks final. return NO_MATCH; } return describeMatch(tree.getExpression()); } }
@Override public Description matchMethod(MethodTree tree, VisitorState state) { if (tree.getBody() == null) { return NO_MATCH; } for (VariableTree parameter : tree.getParameters()) { VarSymbol sym = ASTHelpers.getSymbol(parameter); if (sym == null) { continue; } if (!CompileTimeConstantExpressionMatcher.hasCompileTimeConstantAnnotation(state, sym)) { continue; } if ((sym.flags() & FINAL) == FINAL || (sym.flags() & EFFECTIVELY_FINAL) == EFFECTIVELY_FINAL) { continue; } return describeMatch(parameter); } return NO_MATCH; } }
@Override public Void visitVariable(VariableTree variableTree, Void unused) { // Track variables assigned from our parameter. Tree initializer = variableTree.getInitializer(); VarSymbol symbol = getSymbol(variableTree); if ((symbol.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) != 0 && initializer instanceof InstanceOfTree) { InstanceOfTree instanceOf = (InstanceOfTree) initializer; if (instanceOf.getExpression() instanceof IdentifierTree && incomingVariableSymbols.contains(getSymbol(instanceOf.getExpression()))) { impliesNonNull.add(getSymbol(variableTree)); } } if (incomingVariableSymbols.contains(findVariable(variableTree.getInitializer()))) { incomingVariableSymbols.add(getSymbol(variableTree)); } return super.visitVariable(variableTree, null); }
private void saveConstValue(VariableTree tree, Scope scope) { VarSymbol sym = ASTHelpers.getSymbol(tree); if (sym == null) { return; } if ((sym.flags() & (Flags.EFFECTIVELY_FINAL | Flags.FINAL)) == 0) { return; } // heuristic: long string constants are generally more interesting than short ones, or // than non-string constants (e.g. `""`, `0`, or `false`). String constValue = ASTHelpers.constValue(tree.getInitializer(), String.class); if (constValue == null || constValue.length() <= 1) { return; } scope.put(state.getSourceForNode(tree.getInitializer()), sym); } }.scan(tree, new Scope(null));
public boolean isFinal() { return (symbol.flags() & Flags.FINAL) == Flags.FINAL; }
private static boolean isVariableTreeVarArgs(VariableTree variableTree) { return (ASTHelpers.getSymbol(variableTree).flags() & Flags.VARARGS) != 0; } }