use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class FieldMissingNullable method matchVariable.
@Override
public Description matchVariable(VariableTree tree, VisitorState state) {
Symbol assigned = ASTHelpers.getSymbol(tree);
if (assigned == null || assigned.getKind() != ElementKind.FIELD || assigned.type.isPrimitive()) {
// not a field of nullable type
return Description.NO_MATCH;
}
ExpressionTree expression = tree.getInitializer();
if (expression == null || ASTHelpers.constValue(expression) != null) {
// This should include literals such as "true" or a string
return Description.NO_MATCH;
}
if (TrustingNullnessAnalysis.hasNullableAnnotation(assigned)) {
// field already annotated
return Description.NO_MATCH;
}
// Don't need dataflow to tell us that null is nullable
if (expression.getKind() == Tree.Kind.NULL_LITERAL) {
return makeFix(tree, tree, "Initializing field with null literal");
}
// OK let's see what dataflow says
// TODO(kmb): Merge this method with matchAssignment once we unify nullness analysis entry point
Nullness nullness = TrustingNullnessAnalysis.instance(state.context).getFieldInitializerNullness(state.getPath(), state.context);
switch(nullness) {
case BOTTOM:
case NONNULL:
return Description.NO_MATCH;
case NULL:
return makeFix(tree, tree, "Initializing field with null");
case NULLABLE:
return makeFix(tree, tree, "May initialize field with null");
default:
throw new AssertionError("Impossible: " + nullness);
}
}
use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class ParameterNotNullable method matchDereference.
private Description matchDereference(ExpressionTree dereferencedExpression, VisitorState state) {
Symbol dereferenced = ASTHelpers.getSymbol(dereferencedExpression);
if (dereferenced == null || dereferenced.getKind() != ElementKind.PARAMETER || dereferenced.type.isPrimitive()) {
// not a parameter dereference
return Description.NO_MATCH;
}
if (!TrustingNullnessAnalysis.hasNullableAnnotation(dereferenced)) {
return Description.NO_MATCH;
}
Nullness nullness = TrustingNullnessAnalysis.instance(state.context).getNullness(new TreePath(state.getPath(), dereferencedExpression), state.context);
if (nullness != Nullness.NULLABLE) {
return Description.NO_MATCH;
}
for (AnnotationTree anno : findDeclaration(state, dereferenced).getModifiers().getAnnotations()) {
if (ASTHelpers.getSymbol(anno).type.toString().endsWith(".Nullable")) {
return buildDescription(dereferencedExpression).setMessage("Nullable parameter not checked for null").addFix(SuggestedFix.delete(anno)).build();
}
}
// Shouldn't get here
return Description.NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class StrictFormatStringValidation method validateFormatStringVariable.
/**
* Helps {@code validate()} validate a format string that is a variable, but not a parameter. This
* method assumes that the format string variable has already been asserted to be final or
* effectively final.
*/
private static ValidationResult validateFormatStringVariable(ExpressionTree formatStringTree, final Symbol formatStringSymbol, final List<? extends ExpressionTree> args, final VisitorState state) {
if (formatStringSymbol.getKind() != ElementKind.LOCAL_VARIABLE) {
return ValidationResult.create(null, String.format("Variables used as format strings that are not local variables must be compile time" + " consant.\n%s is not a local variable and is not compile time constant.", formatStringTree));
}
// Find the Tree for the block in which the variable is defined. If it is not defined in this
// class (though it may have been in a super class). We require compile time constant values in
// that case.
Symbol owner = formatStringSymbol.owner;
TreePath path = TreePath.getPath(state.getPath(), formatStringTree);
while (path != null && ASTHelpers.getSymbol(path.getLeaf()) != owner) {
path = path.getParentPath();
}
// impossible.
if (path == null) {
throw new IllegalStateException(String.format("Could not find the Tree where local variable %s is declared. " + "This should be impossible.", formatStringTree));
}
// Scan down from the scope where the variable was declared
ValidationResult result = path.getLeaf().accept(new TreeScanner<ValidationResult, Void>() {
@Override
public ValidationResult visitVariable(VariableTree node, Void unused) {
if (ASTHelpers.getSymbol(node) == formatStringSymbol) {
if (node.getInitializer() == null) {
return ValidationResult.create(null, String.format("Variables used as format strings must be initialized when they are" + " declared.\nInvalid declaration: %s", node));
}
return validateStringFromAssignment(node, node.getInitializer(), args, state);
}
return super.visitVariable(node, unused);
}
@Override
public ValidationResult reduce(ValidationResult r1, ValidationResult r2) {
if (r1 == null && r2 == null) {
return null;
}
return MoreObjects.firstNonNull(r1, r2);
}
}, null);
return result;
}
use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class StrictFormatStringValidation method isFormatStringParameter.
/**
* Returns whether an input {@link Symbol} is a format string in a {@link FormatMethod}. This is
* true if the {@link Symbol} is a {@link String} parameter in a {@link FormatMethod} and is
* either:
*
* <ol>
* <li>Annotated with {@link FormatString}
* <li>The first {@link String} parameter in the method with no other parameters annotated {@link
* FormatString}.
* </ol>
*/
private static boolean isFormatStringParameter(Symbol formatString, VisitorState state) {
Type stringType = state.getSymtab().stringType;
// The input symbol must be a String and a parameter of a @FormatMethod to be a @FormatString.
if (!ASTHelpers.isSameType(formatString.type, stringType, state) || !(formatString.owner instanceof MethodSymbol) || !ASTHelpers.hasAnnotation(formatString.owner, FormatMethod.class, state)) {
return false;
}
// If the format string is annotated @FormatString in a @FormatMethod, it is a format string.
if (ASTHelpers.hasAnnotation(formatString, FormatString.class, state)) {
return true;
}
// Check if format string is the first string with no @FormatString params in the @FormatMethod.
MethodSymbol owner = (MethodSymbol) formatString.owner;
boolean formatStringFound = false;
for (Symbol param : owner.getParameters()) {
if (param == formatString) {
formatStringFound = true;
}
if (ASTHelpers.isSameType(param.type, stringType, state)) {
// format string since it wasn't annotated @FormatString.
if (!formatStringFound) {
return false;
} else if (ASTHelpers.hasAnnotation(param, FormatString.class, state)) {
return false;
}
}
}
return true;
}
use of com.sun.tools.javac.code.Symbol in project error-prone by google.
the class StaticGuardedByInstance method matchSynchronized.
@Override
public Description matchSynchronized(SynchronizedTree tree, VisitorState state) {
Symbol lock = ASTHelpers.getSymbol(TreeInfo.skipParens((JCTree) tree.getExpression()));
if (!(lock instanceof VarSymbol)) {
return Description.NO_MATCH;
}
if (lock.isStatic()) {
return Description.NO_MATCH;
}
Multimap<VarSymbol, Tree> writes = WriteVisitor.scan(tree.getBlock());
for (Entry<VarSymbol, Tree> write : writes.entries()) {
if (!write.getKey().isStatic()) {
continue;
}
state.reportMatch(buildDescription(write.getValue()).setMessage(String.format(MESSAGE, lock)).build());
}
return Description.NO_MATCH;
}
Aggregations