use of com.sun.tools.javac.code.Symbol.VarSymbol in project error-prone by google.
the class FormatStringAnnotationChecker method matchInvocation.
/**
* Matches a method or constructor invocation. The input symbol should match the invoked method or
* contructor and the args should be the parameters in the invocation.
*/
private Description matchInvocation(ExpressionTree tree, MethodSymbol symbol, List<? extends ExpressionTree> args, VisitorState state) {
if (!ASTHelpers.hasAnnotation(symbol, FormatMethod.class, state)) {
return Description.NO_MATCH;
}
Type stringType = state.getSymtab().stringType;
List<VarSymbol> params = symbol.getParameters();
int firstStringIndex = -1;
int formatString = -1;
for (int i = 0; i < params.size(); i++) {
VarSymbol param = params.get(i);
if (ASTHelpers.hasAnnotation(param, FormatString.class, state)) {
formatString = i;
break;
}
if (firstStringIndex < 0 && ASTHelpers.isSameType(params.get(i).type, stringType, state)) {
firstStringIndex = i;
}
}
if (formatString < 0) {
formatString = firstStringIndex;
}
FormatStringValidation.ValidationResult result = StrictFormatStringValidation.validate(args.get(formatString), args.subList(formatString + 1, args.size()), state);
if (result != null) {
return buildDescription(tree).setMessage(result.message()).build();
} else {
return Description.NO_MATCH;
}
}
use of com.sun.tools.javac.code.Symbol.VarSymbol in project error-prone by google.
the class StrictFormatStringValidation method validate.
@Nullable
public static ValidationResult validate(ExpressionTree formatStringTree, List<? extends ExpressionTree> args, VisitorState state) {
if (MOCKITO_ARGUMENT_MATCHER.matches(formatStringTree, state)) {
// that people can verify @FormatMethod methods.
return null;
}
Stream<String> formatStringValues = FormatStringValidation.constValues(formatStringTree);
// so don't bother with annotations and just check if the parameters match the format string.
if (formatStringValues != null) {
return FormatStringValidation.validate(ImmutableList.<ExpressionTree>builder().add(formatStringTree).addAll(args).build(), state);
}
// The format string is not a compile time constant. Check if it is an @FormatString method
// parameter or is in an @FormatMethod method.
Symbol formatStringSymbol = ASTHelpers.getSymbol(formatStringTree);
if (!(formatStringSymbol instanceof VarSymbol)) {
return ValidationResult.create(null, String.format("Format strings must be either a literal or a variable. Other expressions" + " are not valid.\n" + "Invalid format string: %s", formatStringTree));
}
if ((formatStringSymbol.flags() & (Flags.FINAL | Flags.EFFECTIVELY_FINAL)) == 0) {
return ValidationResult.create(null, "All variables passed as @FormatString must be final or effectively final");
}
if (formatStringSymbol.getKind() == ElementKind.PARAMETER) {
return validateFormatStringParamter(formatStringTree, formatStringSymbol, args, state);
} else {
// works with the format arguments.
return validateFormatStringVariable(formatStringTree, formatStringSymbol, args, state);
}
}
use of com.sun.tools.javac.code.Symbol.VarSymbol in project error-prone by google.
the class UnsafeFinalization method getFinalizer.
private static Symbol getFinalizer(VisitorState state, ClassSymbol enclosing) {
Type finalizerType = state.getTypeFromString("com.google.common.labs.base.Finalizer");
Optional<VarSymbol> finalizerField = state.getTypes().closure(enclosing.asType()).stream().flatMap(s -> getFields(s.asElement())).filter(s -> ASTHelpers.isSameType(finalizerType, s.asType(), state)).findFirst();
if (finalizerField.isPresent()) {
return finalizerField.get();
}
return ASTHelpers.resolveExistingMethod(state, enclosing.enclClass(), state.getName("finalize"), /* argTypes= */
ImmutableList.of(), /* tyargTypes= */
ImmutableList.of());
}
use of com.sun.tools.javac.code.Symbol.VarSymbol in project error-prone by google.
the class ImmutableAnalysis method areFieldsImmutable.
/**
* Check a single class' fields for immutability.
*
* @param immutableTyParams the in-scope immutable type parameters
* @param classType the type to check the fields of
*/
Violation areFieldsImmutable(Optional<ClassTree> tree, ImmutableSet<String> immutableTyParams, ClassType classType, ViolationReporter reporter) {
ClassSymbol classSym = (ClassSymbol) classType.tsym;
if (classSym.members() == null) {
return Violation.absent();
}
Filter<Symbol> instanceFieldFilter = new Filter<Symbol>() {
@Override
public boolean accepts(Symbol symbol) {
return symbol.getKind() == ElementKind.FIELD && !symbol.isStatic();
}
};
Map<Symbol, Tree> declarations = new HashMap<>();
if (tree.isPresent()) {
for (Tree member : tree.get().getMembers()) {
Symbol sym = ASTHelpers.getSymbol(member);
if (sym != null) {
declarations.put(sym, member);
}
}
}
// javac gives us members in reverse declaration order
// handling them in declaration order leads to marginally better diagnostics
List<Symbol> members = ImmutableList.copyOf(classSym.members().getSymbols(instanceFieldFilter)).reverse();
for (Symbol member : members) {
Optional<Tree> memberTree = Optional.ofNullable(declarations.get(member));
Violation info = isFieldImmutable(memberTree, immutableTyParams, classSym, classType, (VarSymbol) member, reporter);
if (info.isPresent()) {
return info;
}
}
return Violation.absent();
}
use of com.sun.tools.javac.code.Symbol.VarSymbol in project error-prone by google.
the class SynchronizeOnNonFinalField method matchSynchronized.
@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)) {
// make these locks final.
return NO_MATCH;
}
return describeMatch(tree.getExpression());
}
Aggregations