use of com.sun.tools.javac.code.Symbol.TypeVariableSymbol in project error-prone by google.
the class TypeParameterShadowing method renameTypeVariable.
private static SuggestedFix renameTypeVariable(Tree sourceTree, List<? extends TypeParameterTree> typeParameters, Name typeVariable, String typeVarReplacement, VisitorState state) {
TypeParameterTree matchingTypeParam = typeParameters.stream().filter(t -> t.getName().contentEquals(typeVariable)).collect(MoreCollectors.onlyElement());
Symbol typeVariableSymbol = ASTHelpers.getSymbol(matchingTypeParam);
// replace only the type parameter name (and not any upper bounds)
String name = matchingTypeParam.getName().toString();
int pos = ((JCTree) matchingTypeParam).getStartPosition();
SuggestedFix.Builder fixBuilder = SuggestedFix.builder().replace(pos, pos + name.length(), typeVarReplacement);
((JCTree) sourceTree).accept(new TreeScanner() {
@Override
public void visitIdent(JCTree.JCIdent tree) {
Symbol identSym = ASTHelpers.getSymbol(tree);
if (Objects.equal(identSym, typeVariableSymbol)) {
// }
if (Objects.equal(state.getSourceForNode(tree), name)) {
fixBuilder.replace(tree, typeVarReplacement);
}
}
}
});
return fixBuilder.build();
}
use of com.sun.tools.javac.code.Symbol.TypeVariableSymbol in project error-prone by google.
the class ImmutableChecker method matchTypeParameter.
@Override
public Description matchTypeParameter(TypeParameterTree tree, VisitorState state) {
Symbol sym = ASTHelpers.getSymbol(tree);
if (sym == null) {
return NO_MATCH;
}
ImmutableAnalysis analysis = new ImmutableAnalysis(this, state, wellKnownMutability);
if (!analysis.isImmutableTypeParameter((TypeVariableSymbol) sym)) {
return NO_MATCH;
}
switch(sym.owner.getKind()) {
case METHOD:
case CONSTRUCTOR:
return NO_MATCH;
// fall out
default:
}
AnnotationInfo info = analysis.getImmutableAnnotation(sym.owner, state);
if (info == null) {
return buildDescription(tree).setMessage("@Immutable is only supported on immutable classes").build();
}
return NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol.TypeVariableSymbol in project error-prone by google.
the class ThreadSafety method getAnnotation.
private AnnotationInfo getAnnotation(Symbol sym, VisitorState state, String annotation, @Nullable Class<? extends Annotation> elementAnnotation) {
if (sym == null) {
return null;
}
Symbol annosym = state.getSymbolFromString(annotation);
Optional<Compound> attr = sym.getAnnotationMirrors().stream().filter(a -> a.getAnnotationType().asElement().equals(annosym)).findAny();
if (attr.isPresent()) {
ImmutableList<String> containerElements = containerOf(state, attr.get());
if (elementAnnotation != null && containerElements.isEmpty()) {
containerElements = sym.getTypeParameters().stream().filter(p -> p.getAnnotation(elementAnnotation) != null).map(p -> p.getSimpleName().toString()).collect(toImmutableList());
}
return AnnotationInfo.create(sym.getQualifiedName().toString(), containerElements);
}
// @ThreadSafe is inherited from supertypes
if (!(sym instanceof ClassSymbol)) {
return null;
}
Type superClass = ((ClassSymbol) sym).getSuperclass();
AnnotationInfo superAnnotation = getInheritedAnnotation(superClass.asElement(), state);
if (superAnnotation == null) {
return null;
}
// If an annotated super-type was found, look for any type arguments to the super-type that
// are in the super-type's containerOf spec, and where the arguments are type parameters
// of the current class.
// E.g. for `Foo<X> extends Super<X>` if `Super<Y>` is annotated
// `@ThreadSafeContainerAnnotation Y`
// then `Foo<X>` is has X implicitly annotated `@ThreadSafeContainerAnnotation X`
ImmutableList.Builder<String> containerOf = ImmutableList.builder();
for (int i = 0; i < superClass.getTypeArguments().size(); i++) {
Type arg = superClass.getTypeArguments().get(i);
TypeVariableSymbol formal = superClass.asElement().getTypeParameters().get(i);
if (!arg.hasTag(TypeTag.TYPEVAR)) {
continue;
}
TypeSymbol argSym = arg.asElement();
if (argSym.owner == sym && superAnnotation.containerOf().contains(formal.getSimpleName().toString())) {
containerOf.add(argSym.getSimpleName().toString());
}
}
return AnnotationInfo.create(superAnnotation.typeName(), containerOf.build());
}
use of com.sun.tools.javac.code.Symbol.TypeVariableSymbol 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.sun.tools.javac.code.Symbol.TypeVariableSymbol in project error-prone by google.
the class CompatibleWithMisuse method matchAnnotation.
@Override
public Description matchAnnotation(AnnotationTree annoTree, VisitorState state) {
if (!IS_COMPATIBLE_WITH_ANNOTATION.matches(annoTree, state)) {
return Description.NO_MATCH;
}
// Hunt for type args on the declared method
// TODO(glorioso): Once annotation is TYPE_USE, make sure that the node is actually a method
// parameter
MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
MethodSymbol declaredMethod = ASTHelpers.getSymbol(methodTree);
// This restriction may need to be removed to allow more complex declaration hierarchies.
for (MethodSymbol methodSymbol : ASTHelpers.findSuperMethods(declaredMethod, state.getTypes())) {
if (methodSymbol.params().stream().anyMatch(p -> ASTHelpers.hasAnnotation(p, CompatibleWith.class, state))) {
return describeWithMessage(annoTree, String.format("This method overrides a method in %s that already has @CompatibleWith", methodSymbol.owner.getSimpleName()));
}
}
List<TypeVariableSymbol> potentialTypeVars = new ArrayList<>(declaredMethod.getTypeParameters());
// Check enclosing types (not superclasses)
ClassSymbol cs = (ClassSymbol) declaredMethod.owner;
do {
potentialTypeVars.addAll(cs.getTypeParameters());
cs = cs.isInner() ? cs.owner.enclClass() : null;
} while (cs != null);
if (potentialTypeVars.isEmpty()) {
return describeWithMessage(annoTree, "There are no type arguments in scope to match against.");
}
Set<String> validNames = potentialTypeVars.stream().map(TypeVariableSymbol::getSimpleName).map(Object::toString).collect(toImmutableSet());
String constValue = valueArgumentFromCompatibleWithAnnotation(annoTree);
if (constValue == null || constValue.isEmpty()) {
return describeWithMessage(annoTree, String.format("The value of @CompatibleWith must not be empty (valid arguments are %s)", printTypeArgs(validNames)));
}
return validNames.contains(constValue) ? Description.NO_MATCH : describeWithMessage(annoTree, String.format("%s is not a valid type argument. Valid arguments are: %s", constValue, printTypeArgs(validNames)));
}
Aggregations