use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class FunctionalInterfaceMethodChanged method matchMethod.
@Override
public Description matchMethod(MethodTree tree, VisitorState state) {
ClassTree enclosingClazz = ASTHelpers.findEnclosingNode(state.getPath(), ClassTree.class);
if (tree.getModifiers().getFlags().contains(Modifier.DEFAULT) && IS_FUNCTIONAL_INTERFACE.matches(enclosingClazz, state)) {
Types types = Types.instance(state.context);
Set<Symbol> functionalSuperInterfaceSams = enclosingClazz.getImplementsClause().stream().filter(t -> IS_FUNCTIONAL_INTERFACE.matches(t, state)).map(ASTHelpers::getSymbol).map(TypeSymbol.class::cast).map(// TypeSymbol to single abstract method of the type
types::findDescriptorSymbol).collect(toImmutableSet());
// We designate an override of a superinterface SAM "behavior preserving" if it just
// calls the SAM of this interface.
Symbol thisInterfaceSam = types.findDescriptorSymbol(ASTHelpers.getSymbol(enclosingClazz));
// relatively crude: doesn't verify that the same args are passed in the same order
// so it can get false positives for behavior-preservingness (false negatives for the check)
TreeVisitor<Boolean, VisitorState> behaviorPreserving = new SimpleTreeVisitor<Boolean, VisitorState>(false) {
@Override
public Boolean visitMethod(MethodTree node, VisitorState state) {
return node.getBody() != null && node.getBody().accept(this, state);
}
@Override
public Boolean visitBlock(BlockTree node, VisitorState state) {
return node.getStatements().size() == 1 && Iterables.getOnlyElement(node.getStatements()).accept(this, state);
}
@Override
public Boolean visitExpressionStatement(ExpressionStatementTree node, VisitorState state) {
return node.getExpression().accept(this, state);
}
@Override
public Boolean visitReturn(ReturnTree node, VisitorState state) {
return node.getExpression().accept(this, state);
}
@Override
public Boolean visitMethodInvocation(MethodInvocationTree node, VisitorState state) {
return ASTHelpers.getSymbol(node) == thisInterfaceSam;
}
};
if (!Collections.disjoint(ASTHelpers.findSuperMethods(ASTHelpers.getSymbol(tree), types), functionalSuperInterfaceSams) && !tree.accept(behaviorPreserving, state)) {
return describeMatch(tree);
}
}
return Description.NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class InputStreamSlowMultibyteRead method matchClass.
@Override
public Description matchClass(ClassTree classTree, VisitorState state) {
if (!IS_INPUT_STREAM.matches(classTree, state)) {
return Description.NO_MATCH;
}
TypeSymbol thisClassSymbol = ASTHelpers.getSymbol(classTree);
if (thisClassSymbol.getKind() != ElementKind.CLASS) {
return Description.NO_MATCH;
}
// Find the method that overrides the single-byte read. It should also override the multibyte
// read.
MethodTree readByteMethod = classTree.getMembers().stream().filter(MethodTree.class::isInstance).map(MethodTree.class::cast).filter(m -> READ_INT_METHOD.matches(m, state)).findFirst().orElse(null);
if (readByteMethod == null) {
return Description.NO_MATCH;
}
Type byteArrayType = state.arrayTypeForType(state.getSymtab().byteType);
Type intType = state.getSymtab().intType;
MethodSymbol multiByteReadMethod = ASTHelpers.resolveExistingMethod(state, thisClassSymbol, state.getName("read"), ImmutableList.of(byteArrayType, intType, intType), ImmutableList.of());
return multiByteReadMethod.owner.equals(thisClassSymbol) ? Description.NO_MATCH : maybeMatchReadByte(readByteMethod, state);
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class NonRuntimeAnnotation method matchMethodInvocation.
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (!instanceMethod().onDescendantOf("java.lang.Class").named("getAnnotation").matches(tree, state)) {
return Description.NO_MATCH;
}
MemberSelectTree memTree = (MemberSelectTree) tree.getArguments().get(0);
TypeSymbol annotation = ASTHelpers.getSymbol(memTree.getExpression()).type.tsym;
Retention retention = ASTHelpers.getAnnotation(annotation, Retention.class);
if (retention != null && retention.value().equals(RUNTIME)) {
return Description.NO_MATCH;
}
return describeMatch(tree, SuggestedFix.replace(tree, "null"));
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class EqualsHashCode method matchClass.
@Override
public Description matchClass(ClassTree classTree, VisitorState state) {
TypeSymbol symbol = ASTHelpers.getSymbol(classTree);
if (symbol.getKind() != ElementKind.CLASS) {
return Description.NO_MATCH;
}
MethodTree equals = null;
for (Tree member : classTree.getMembers()) {
if (!(member instanceof MethodTree)) {
continue;
}
MethodTree methodTree = (MethodTree) member;
if (EQUALS_MATCHER.matches(methodTree, state)) {
equals = methodTree;
}
}
if (equals == null) {
return Description.NO_MATCH;
}
MethodSymbol hashCodeSym = ASTHelpers.resolveExistingMethod(state, symbol, state.getName("hashCode"), ImmutableList.<Type>of(), ImmutableList.<Type>of());
if (hashCodeSym.owner.equals(state.getSymtab().objectType.tsym)) {
return describeMatch(equals);
}
return Description.NO_MATCH;
}
use of com.sun.tools.javac.code.Symbol.TypeSymbol in project error-prone by google.
the class Inliner method inlineAsVar.
public TypeVar inlineAsVar(UTypeVar var) throws CouldNotResolveImportException {
/*
* In order to handle recursively bounded type variables without a stack overflow,
* we first cache a type var with no bounds, then we inline the bounds.
*/
TypeVar typeVar = typeVarCache.get(var.getName());
if (typeVar != null) {
return typeVar;
}
Name name = asName(var.getName());
TypeSymbol sym = new TypeVariableSymbol(0, name, null, symtab().noSymbol);
typeVar = new TypeVar(sym, null, null);
sym.type = typeVar;
typeVarCache.put(var.getName(), typeVar);
// Any recursive uses of var will point to the same TypeVar object generated above.
typeVar.bound = var.getUpperBound().inline(this);
typeVar.lower = var.getLowerBound().inline(this);
return typeVar;
}
Aggregations