Search in sources :

Example 96 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project mockito by mockito.

the class AbstractMockitoAnyForPrimitiveType method matchMethodInvocation.

@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
    if (!matcher().matches(tree, state)) {
        return NO_MATCH;
    }
    MethodSymbol method = ASTHelpers.getSymbol(tree);
    Type matcherType = method.getReturnType();
    // It is expected that the call to anyX() is itself the argument to another call which is
    // the one being mocked, e.g. something like this:
    // when(mock.call(..., anyInt(), ...))...
    TreePath path = state.getPath();
    Tree parentTree = path.getParentPath().getLeaf();
    if (!(parentTree instanceof MethodInvocationTree)) {
        // TODO: Support casting.
        return NO_MATCH;
    }
    MethodInvocationTree parentCall = (MethodInvocationTree) parentTree;
    MethodSymbol parentMethod = ASTHelpers.getSymbol(parentCall);
    // Find the index of the argument in the parent call.
    int argumentIndex = -1;
    List<? extends ExpressionTree> parentArguments = parentCall.getArguments();
    for (int i = 0; i < parentArguments.size(); i++) {
        ExpressionTree argumentTree = parentArguments.get(i);
        if (argumentTree == tree) {
            argumentIndex = i;
            break;
        }
    }
    if (argumentIndex == -1) {
        throw new IllegalStateException("Cannot find argument " + state.getSourceForNode(tree) + " in argument list from " + state.getSourceForNode(parentTree));
    }
    Type parameterType = getParameterType(parentMethod, argumentIndex);
    TypeKind parameterTypeKind = parameterType.getKind();
    if (parameterTypeKind.isPrimitive() && parameterTypeKind != matcherType.getKind()) {
        String expectedTypeAsString = parameterType.toString();
        String replacementName = "any" + Character.toUpperCase(expectedTypeAsString.charAt(0)) + expectedTypeAsString.substring(1);
        String message = formatMessage(expectedTypeAsString, matcherType, replacementName);
        SuggestedFix.Builder fixBuilder = SuggestedFix.builder();
        ExpressionTree methodSelect = tree.getMethodSelect();
        String replacement;
        if (methodSelect instanceof MemberSelectTree) {
            MemberSelectTree qualifier = (MemberSelectTree) methodSelect;
            replacement = state.getSourceForNode(qualifier.getExpression()) + "." + replacementName;
        } else {
            replacement = replacementName;
            String staticImport = method.owner + "." + replacementName;
            fixBuilder.addStaticImport(staticImport);
        }
        SuggestedFix fix = fixBuilder.replace(tree, replacement + "()").build();
        return buildDescription(tree).setMessage(message).addFix(fix).build();
    }
    return NO_MATCH;
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) TypeKind(javax.lang.model.type.TypeKind) ArrayType(com.sun.tools.javac.code.Type.ArrayType) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) TreePath(com.sun.source.util.TreePath) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 97 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.

the class Attr method visitBlock.

public void visitBlock(JCBlock tree) {
    if (env.info.scope.owner.kind == TYP) {
        // Block is a static or instance initializer;
        // let the owner of the environment be a freshly
        // created BLOCK-method.
        Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
        localEnv.info.scope.owner = new MethodSymbol(tree.flags | BLOCK, names.empty, null, env.info.scope.owner);
        if ((tree.flags & STATIC) != 0)
            localEnv.info.staticLevel++;
        // see https://github.com/ceylon/ceylon-compiler/issues/1165
        if (sourceLanguage.isCeylon())
            completeLocalTypes(tree.stats, localEnv);
        attribStats(tree.stats, localEnv);
    } else {
        // Create a new local environment with a local scope.
        Env<AttrContext> localEnv = env.dup(tree, env.info.dup(env.info.scope.dup()));
        // see https://github.com/ceylon/ceylon-compiler/issues/1165
        if (sourceLanguage.isCeylon())
            completeLocalTypes(tree.stats, localEnv);
        attribStats(tree.stats, localEnv);
        localEnv.info.scope.leave();
    }
    result = null;
}
Also used : DynamicMethodSymbol(com.sun.tools.javac.code.Symbol.DynamicMethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol)

Example 98 with MethodSymbol

use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.

the class Attr method resolveIndyCall.

// Added by Ceylon
private Symbol resolveIndyCall(JCTree tree, JCExpression indyReturnTypeExpression, List<JCExpression> indyParameterTypeExpressions, Name indyName, JCExpression bsmType, Name bsmName, List<Object> bsmStatic, List<Type> parameterTypes) {
    // build the list of static bsm arguments
    List<Type> bsm_staticArgs = List.of(syms.methodHandleLookupType, syms.stringType, syms.methodTypeType).appendList(bsmStaticArgToTypes(bsmStatic));
    // find the type of the bootstrap method class
    Type bsmSite = attribTree(bsmType, env, TYP, Infer.anyPoly);
    // find the bsm method
    Symbol bsm = rs.resolveInternalMethod(tree.pos(), env, bsmSite, bsmName, bsm_staticArgs, List.<Type>nil());
    if (!bsm.isStatic())
        log.error(tree.pos(), "ceylon", "Bootstrap method must be static: " + bsmName.toString());
    // find the type of the indy call
    Type indyReturnType = attribTree(indyReturnTypeExpression, env, TYP, Infer.anyPoly);
    ListBuffer<Type> indyParameterTypes = new ListBuffer<Type>();
    int c = 0;
    List<Type> givenParameterTypes = parameterTypes;
    for (JCExpression expectedParamTypeExpr : indyParameterTypeExpressions) {
        // also check that the parameter types we are passing to the method are compatible with the declared type
        Type givenParameterType = givenParameterTypes.head;
        if (givenParameterType == null) {
            log.error(tree.pos(), "ceylon", "Indy declared method expects more parameters than given. Expecting " + indyParameterTypeExpressions.size() + ", but given " + c);
            return syms.errSymbol;
        }
        Type paramType = attribTree(expectedParamTypeExpr, env, TYP, Infer.anyPoly);
        if (!types.isAssignable(givenParameterType, paramType)) {
            log.error(tree.pos(), "ceylon", "Indy given method parameter " + c + " not compatible with expected parameter type: " + paramType + ", but given " + givenParameterType);
            return syms.errSymbol;
        }
        indyParameterTypes.append(paramType);
        c++;
        givenParameterTypes = givenParameterTypes.tail;
    }
    if (!givenParameterTypes.isEmpty()) {
        log.error(tree.pos(), "ceylon", "Indy declared method expects less parameters than given. Expecting " + indyParameterTypeExpressions.size() + ", but given " + parameterTypes.size());
        return syms.errSymbol;
    }
    MethodType indyType = new MethodType(indyParameterTypes.toList(), indyReturnType, List.<Type>nil(), syms.methodClass);
    // make an indy symbol for it
    DynamicMethodSymbol dynSym = new DynamicMethodSymbol(indyName, syms.noSymbol, bsm.isStatic() ? ClassFile.REF_invokeStatic : ClassFile.REF_invokeVirtual, (MethodSymbol) bsm, indyType, bsmStatic.toArray());
    return dynSym;
}
Also used : MethodType(com.sun.tools.javac.code.Type.MethodType) ClassType(com.sun.tools.javac.code.Type.ClassType) MethodType(com.sun.tools.javac.code.Type.MethodType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) ArrayType(com.sun.tools.javac.code.Type.ArrayType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) PackageSymbol(com.sun.tools.javac.code.Symbol.PackageSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) DynamicMethodSymbol(com.sun.tools.javac.code.Symbol.DynamicMethodSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) OperatorSymbol(com.sun.tools.javac.code.Symbol.OperatorSymbol) ListBuffer(com.sun.tools.javac.util.ListBuffer) DynamicMethodSymbol(com.sun.tools.javac.code.Symbol.DynamicMethodSymbol) Lint(com.sun.tools.javac.code.Lint)

Aggregations

MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)98 Symbol (com.sun.tools.javac.code.Symbol)35 Type (com.sun.tools.javac.code.Type)32 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)27 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)22 MethodTree (com.sun.source.tree.MethodTree)22 Tree (com.sun.source.tree.Tree)21 ArrayList (java.util.ArrayList)18 ExpressionTree (com.sun.source.tree.ExpressionTree)17 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)13 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)13 Description (com.google.errorprone.matchers.Description)11 ClassTree (com.sun.source.tree.ClassTree)11 VisitorState (com.google.errorprone.VisitorState)10 JCTree (com.sun.tools.javac.tree.JCTree)9 Types (com.sun.tools.javac.code.Types)8 BugPattern (com.google.errorprone.BugPattern)7 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)7 MemberSelectTree (com.sun.source.tree.MemberSelectTree)7 MethodType (com.sun.tools.javac.code.Type.MethodType)7