Search in sources :

Example 11 with TypeSymbol

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;
}
Also used : Types(com.sun.tools.javac.code.Types) MethodTree(com.sun.source.tree.MethodTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) SimpleTreeVisitor(com.sun.source.util.SimpleTreeVisitor) ClassTree(com.sun.source.tree.ClassTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ReturnTree(com.sun.source.tree.ReturnTree) VisitorState(com.google.errorprone.VisitorState) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) BlockTree(com.sun.source.tree.BlockTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 12 with TypeSymbol

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);
}
Also used : Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 13 with TypeSymbol

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"));
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Retention(java.lang.annotation.Retention)

Example 14 with TypeSymbol

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;
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) MethodTree(com.sun.source.tree.MethodTree) MethodTree(com.sun.source.tree.MethodTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol)

Example 15 with TypeSymbol

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;
}
Also used : TypeVar(com.sun.tools.javac.code.Type.TypeVar) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) Name(com.sun.tools.javac.util.Name)

Aggregations

TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)21 Symbol (com.sun.tools.javac.code.Symbol)11 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)11 Type (com.sun.tools.javac.code.Type)11 MethodTree (com.sun.source.tree.MethodTree)6 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)6 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)4 JCTree (com.sun.tools.javac.tree.JCTree)4 VisitorState (com.google.errorprone.VisitorState)3 ClassTree (com.sun.source.tree.ClassTree)3 Tree (com.sun.source.tree.Tree)3 CompletionFailure (com.sun.tools.javac.code.Symbol.CompletionFailure)3 ArrayList (java.util.ArrayList)3 UnknownType (com.redhat.ceylon.model.typechecker.model.UnknownType)2 IdentifierTree (com.sun.source.tree.IdentifierTree)2 MemberSelectTree (com.sun.source.tree.MemberSelectTree)2 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)2 TreePath (com.sun.source.util.TreePath)2 Scope (com.sun.tools.javac.code.Scope)2 ClassType (com.sun.tools.javac.code.Type.ClassType)2