use of com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation in project error-prone by google.
the class ImmutableChecker method checkInvocation.
private Description checkInvocation(Tree tree, Type methodType, VisitorState state, Symbol symbol) {
ImmutableAnalysis analysis = new ImmutableAnalysis(this, state, wellKnownMutability);
Violation info = analysis.checkInvocation(methodType, symbol);
if (info.isPresent()) {
state.reportMatch(buildDescription(tree).setMessage(info.message()).build());
}
return NO_MATCH;
}
use of com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation in project error-prone by google.
the class ImmutableChecker method handleAnonymousClass.
// Anonymous classes
/**
* Check anonymous implementations of {@code @Immutable} types.
*/
private Description handleAnonymousClass(ClassTree tree, VisitorState state, ImmutableAnalysis analysis) {
ClassSymbol sym = ASTHelpers.getSymbol(tree);
if (sym == null) {
return NO_MATCH;
}
Type superType = immutableSupertype(sym, state);
if (superType == null) {
return NO_MATCH;
}
// We don't need to check that the superclass has an immutable instantiation.
// The anonymous instance can only be referred to using a superclass type, so
// the type arguments will be validated at any type use site where we care about
// the instance's immutability.
//
// Also, we have no way to express something like:
//
// public static <@Immutable T> ImmutableBox<T> create(T t) {
// return new ImmutableBox<>(t);
// }
ImmutableSet<String> typarams = immutableTypeParametersInScope(sym, state, analysis);
Violation info = analysis.areFieldsImmutable(Optional.of(tree), typarams, ASTHelpers.getType(tree), new ViolationReporter() {
@Override
public Builder describe(Tree tree, Violation info) {
return describeAnonymous(tree, superType, info);
}
});
if (!info.isPresent()) {
return NO_MATCH;
}
return describeAnonymous(tree, superType, info).build();
}
use of com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation in project error-prone by google.
the class ImmutableEnumChecker method matchClass.
@Override
public Description matchClass(ClassTree tree, VisitorState state) {
ClassSymbol symbol = getSymbol(tree);
if (symbol == null || !symbol.isEnum()) {
return NO_MATCH;
}
if (ASTHelpers.hasAnnotation(symbol, Immutable.class, state) && !implementsImmutableInterface(symbol)) {
AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(tree.getModifiers().getAnnotations(), "Immutable");
if (annotation != null) {
state.reportMatch(buildDescription(annotation).setMessage(ANNOTATED_ENUM_MESSAGE).addFix(SuggestedFix.delete(annotation)).build());
} else {
state.reportMatch(buildDescription(tree).setMessage(ANNOTATED_ENUM_MESSAGE).build());
}
}
Violation info = new ImmutableAnalysis(this, state, wellKnownMutability, ImmutableSet.of(Immutable.class.getName(), javax.annotation.concurrent.Immutable.class.getName())).checkForImmutability(Optional.of(tree), ImmutableSet.of(), getType(tree), this::describe);
if (!info.isPresent()) {
return NO_MATCH;
}
return describe(tree, info).build();
}
use of com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation in project error-prone by google.
the class ThreadSafety method threadSafeInstantiation.
/**
* Check that a type-use of an {@code @ThreadSafe}-annotated type is instantiated with threadsafe
* type arguments where required by its annotation's containerOf element.
*
* @param containerTypeParameters the in-scope threadsafe type parameters, declared on some
* enclosing class.
* @param annotation the type's {@code @ThreadSafe} info
* @param type the type to check
*/
public Violation threadSafeInstantiation(Set<String> containerTypeParameters, AnnotationInfo annotation, Type type) {
if (!annotation.containerOf().isEmpty() && type.tsym.getTypeParameters().size() != type.getTypeArguments().size()) {
return Violation.of(String.format("'%s' required instantiation of '%s' with type parameters, but was raw", getPrettyName(type.tsym), Joiner.on(", ").join(annotation.containerOf())));
}
for (int i = 0; i < type.tsym.getTypeParameters().size(); i++) {
TypeVariableSymbol typaram = type.tsym.getTypeParameters().get(i);
boolean immutableTypeParameter = isThreadSafeTypeParameter(typaram);
if (annotation.containerOf().contains(typaram.getSimpleName().toString()) || immutableTypeParameter) {
Type tyarg = type.getTypeArguments().get(i);
if (suppressAnnotation != null && tyarg.getAnnotationMirrors().stream().anyMatch(a -> ((ClassSymbol) a.getAnnotationType().asElement()).flatName().contentEquals(suppressAnnotation.getName()))) {
continue;
}
Violation info = isThreadSafeType(!immutableTypeParameter, containerTypeParameters, tyarg);
if (info.isPresent()) {
return info.plus(String.format("'%s' was instantiated with mutable type for '%s'", getPrettyName(type.tsym), typaram.getSimpleName()));
}
}
}
return Violation.absent();
}
use of com.google.errorprone.bugpatterns.threadsafety.ThreadSafety.Violation in project error-prone by google.
the class ImmutableAnalysis method checkSuper.
private Violation checkSuper(ImmutableSet<String> immutableTyParams, ClassType type) {
ClassType superType = (ClassType) state.getTypes().supertype(type);
if (superType.getKind() == TypeKind.NONE || state.getTypes().isSameType(state.getSymtab().objectType, superType)) {
return Violation.absent();
}
if (WellKnownMutability.isAnnotation(state, type)) {
// TODO(b/25630189): add enforcement
return Violation.absent();
}
AnnotationInfo superannotation = getImmutableAnnotation(superType.tsym, state);
String message = String.format("'%s' extends '%s'", threadSafety.getPrettyName(type.tsym), threadSafety.getPrettyName(superType.tsym));
if (superannotation != null) {
// If the superclass does happen to be immutable, we don't need to recursively
// inspect it. We just have to check that it's instantiated correctly:
Violation info = threadSafety.checkSuperInstantiation(immutableTyParams, superannotation, superType);
if (!info.isPresent()) {
return Violation.absent();
}
return info.plus(message);
}
// Recursive case: check if the supertype is 'effectively' immutable.
Violation info = checkForImmutability(Optional.<ClassTree>empty(), immutableTyParams, superType, new ViolationReporter() {
@Override
public Description.Builder describe(Tree tree, Violation info) {
return BugChecker.buildDescriptionFromChecker(tree, bugChecker).setMessage(info.plus(info.message()).message());
}
});
if (!info.isPresent()) {
return Violation.absent();
}
return info.plus(message);
}
Aggregations