Search in sources :

Example 1 with MethodType

use of com.sun.tools.javac.code.Type.MethodType in project error-prone by google.

the class Template method infer.

/**
 * Returns the inferred method type of the template based on the given actual argument types.
 *
 * @throws InferException if no instances of the specified type variables would allow the {@code
 *     actualArgTypes} to match the {@code expectedArgTypes}
 */
private Type infer(Warner warner, Inliner inliner, List<Type> freeTypeVariables, List<Type> expectedArgTypes, Type returnType, List<Type> actualArgTypes) throws InferException {
    Symtab symtab = inliner.symtab();
    Type methodType = new MethodType(expectedArgTypes, returnType, List.<Type>nil(), symtab.methodClass);
    if (!freeTypeVariables.isEmpty()) {
        methodType = new ForAll(freeTypeVariables, methodType);
    }
    Enter enter = inliner.enter();
    MethodSymbol methodSymbol = new MethodSymbol(0, inliner.asName("__m__"), methodType, symtab.unknownSymbol);
    Type site = symtab.methodClass.type;
    Env<AttrContext> env = enter.getTopLevelEnv(TreeMaker.instance(inliner.getContext()).TopLevel(List.<JCTree>nil()));
    // Set up the resolution phase:
    try {
        Field field = AttrContext.class.getDeclaredField("pendingResolutionPhase");
        field.setAccessible(true);
        field.set(env.info, newMethodResolutionPhase(autoboxing()));
    } catch (ReflectiveOperationException e) {
        throw new LinkageError(e.getMessage(), e);
    }
    Object resultInfo;
    try {
        Class<?> resultInfoClass = Class.forName("com.sun.tools.javac.comp.Attr$ResultInfo");
        Constructor<?> resultInfoCtor = resultInfoClass.getDeclaredConstructor(Attr.class, KindSelector.class, Type.class);
        resultInfoCtor.setAccessible(true);
        resultInfo = resultInfoCtor.newInstance(Attr.instance(inliner.getContext()), KindSelector.PCK, Type.noType);
    } catch (ReflectiveOperationException e) {
        throw new LinkageError(e.getMessage(), e);
    }
    // Type inference sometimes produces diagnostics, so we need to catch them to avoid interfering
    // with the enclosing compilation.
    Log.DeferredDiagnosticHandler handler = new Log.DeferredDiagnosticHandler(Log.instance(inliner.getContext()));
    try {
        MethodType result = callCheckMethod(warner, inliner, resultInfo, actualArgTypes, methodSymbol, site, env);
        if (!handler.getDiagnostics().isEmpty()) {
            throw new InferException(handler.getDiagnostics());
        }
        return result;
    } finally {
        Log.instance(inliner.getContext()).popDiagnosticHandler(handler);
    }
}
Also used : MethodType(com.sun.tools.javac.code.Type.MethodType) Log(com.sun.tools.javac.util.Log) JCTree(com.sun.tools.javac.tree.JCTree) AttrContext(com.sun.tools.javac.comp.AttrContext) Symtab(com.sun.tools.javac.code.Symtab) Field(java.lang.reflect.Field) MethodType(com.sun.tools.javac.code.Type.MethodType) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Enter(com.sun.tools.javac.comp.Enter) ForAll(com.sun.tools.javac.code.Type.ForAll)

Example 2 with MethodType

use of com.sun.tools.javac.code.Type.MethodType in project ceylon-compiler by ceylon.

the class Attr method visitApply.

/**
 * Visitor method for method invocations.
 *  NOTE: The method part of an application will have in its type field
 *        the return type of the method, not the method's type itself!
 */
public void visitApply(JCMethodInvocation tree) {
    // The local environment of a method application is
    // a new environment nested in the current one.
    Env<AttrContext> localEnv = env.dup(tree, env.info.dup());
    // The types of the actual method arguments.
    List<Type> argtypes;
    // The types of the actual method type arguments.
    List<Type> typeargtypes = null;
    Name methName = TreeInfo.name(tree.meth);
    boolean isConstructorCall = methName == names._this || methName == names._super;
    if (isConstructorCall) {
        // Check that this is the first statement in a constructor.
        if (checkFirstConstructorStat(tree, env)) {
            // Record the fact
            // that this is a constructor call (using isSelfCall).
            localEnv.info.isSelfCall = true;
            // Attribute arguments, yielding list of argument types.
            argtypes = attribArgs(tree.args, localEnv);
            typeargtypes = attribTypes(tree.typeargs, localEnv);
            // Variable `site' points to the class in which the called
            // constructor is defined.
            Type site = env.enclClass.sym.type;
            if (methName == names._super) {
                if (site == syms.objectType) {
                    log.error(tree.meth.pos(), "no.superclass", site);
                    site = types.createErrorType(syms.objectType);
                } else {
                    site = types.supertype(site);
                }
            }
            if (site.tag == CLASS) {
                Type encl = site.getEnclosingType();
                while (encl != null && encl.tag == TYPEVAR) encl = encl.getUpperBound();
                if (encl.tag == CLASS) {
                    if (tree.meth.getTag() == JCTree.SELECT) {
                        JCTree qualifier = ((JCFieldAccess) tree.meth).selected;
                        // We are seeing a prefixed call, of the form
                        // <expr>.super(...).
                        // Check that the prefix expression conforms
                        // to the outer instance type of the class.
                        chk.checkRefType(qualifier.pos(), attribExpr(qualifier, localEnv, encl));
                    } else if (methName == names._super) {
                        // qualifier omitted; check for existence
                        // of an appropriate implicit qualifier.
                        rs.resolveImplicitThis(tree.meth.pos(), localEnv, site, true);
                    }
                } else if (tree.meth.getTag() == JCTree.SELECT) {
                    log.error(tree.meth.pos(), "illegal.qual.not.icls", site.tsym);
                }
                // prefix the implicit String and int parameters
                if (site.tsym == syms.enumSym && allowEnums)
                    argtypes = argtypes.prepend(syms.intType).prepend(syms.stringType);
                // Resolve the called constructor under the assumption
                // that we are referring to a superclass instance of the
                // current instance (JLS ???).
                boolean selectSuperPrev = localEnv.info.selectSuper;
                localEnv.info.selectSuper = true;
                localEnv.info.varArgs = false;
                Symbol sym = rs.resolveConstructor(tree.meth.pos(), localEnv, site, argtypes, typeargtypes);
                localEnv.info.selectSuper = selectSuperPrev;
                // Set method symbol to resolved constructor...
                TreeInfo.setSymbol(tree.meth, sym);
                // ...and check that it is legal in the current context.
                // (this will also set the tree's type)
                Type mpt = newMethTemplate(argtypes, typeargtypes);
                checkId(tree.meth, site, sym, localEnv, MTH, mpt, tree.varargsElement != null);
            }
        // Otherwise, `site' is an error type and we do nothing
        }
        result = tree.type = syms.voidType;
    } else {
        // Otherwise, we are seeing a regular method call.
        // Attribute the arguments, yielding list of argument types, ...
        argtypes = attribArgs(tree.args, localEnv);
        typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
        // ... and attribute the method using as a prototype a methodtype
        // whose formal argument types is exactly the list of actual
        // arguments (this will also set the method symbol).
        Type mpt = newMethTemplate(argtypes, typeargtypes);
        localEnv.info.varArgs = false;
        Type mtype = attribExpr(tree.meth, localEnv, mpt);
        if (localEnv.info.varArgs)
            Assert.check(mtype.isErroneous() || tree.varargsElement != null);
        // Compute the result type.
        Type restype = mtype.getReturnType();
        if (restype.tag == WILDCARD)
            throw new AssertionError(mtype);
        // the same as static type of the array being cloned
        if (tree.meth.getTag() == JCTree.SELECT && allowCovariantReturns && methName == names.clone && types.isArray(((JCFieldAccess) tree.meth).selected.type))
            restype = ((JCFieldAccess) tree.meth).selected.type;
        // as a special case, x.getClass() has type Class<? extends |X|>
        if (allowGenerics && methName == names.getClass && tree.args.isEmpty()) {
            Type qualifier = (tree.meth.getTag() == JCTree.SELECT) ? ((JCFieldAccess) tree.meth).selected.type : env.enclClass.sym.type;
            restype = new ClassType(restype.getEnclosingType(), List.<Type>of(new WildcardType(types.erasure(qualifier), BoundKind.EXTENDS, syms.boundClass)), restype.tsym);
        }
        chk.checkRefTypes(tree.typeargs, typeargtypes);
        // Check that value of resulting type is admissible in the
        // current context.  Also, capture the return type
        result = check(tree, capture(restype), VAL, pkind, pt);
    }
    chk.validate(tree.typeargs, localEnv);
}
Also used : 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) WildcardType(com.sun.tools.javac.code.Type.WildcardType) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) 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) JCTree(com.sun.tools.javac.tree.JCTree) ClassType(com.sun.tools.javac.code.Type.ClassType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) Kinds.kindName(com.sun.tools.javac.code.Kinds.kindName) Name(com.sun.tools.javac.util.Name)

Example 3 with MethodType

use of com.sun.tools.javac.code.Type.MethodType in project lombok by rzwitserloot.

the class JavacHandlerUtil method fixMethodMirror.

private static void fixMethodMirror(Context context, Element typeMirror, long access, Name methodName, List<Type> paramTypes, Type returnType) {
    if (typeMirror == null || paramTypes == null || returnType == null)
        return;
    ClassSymbol cs = (ClassSymbol) typeMirror;
    MethodSymbol methodSymbol = new MethodSymbol(access, methodName, new MethodType(paramTypes, returnType, List.<Type>nil(), Symtab.instance(context).methodClass), cs);
    ClassSymbolMembersField.enter(cs, methodSymbol);
}
Also used : MethodType(com.sun.tools.javac.code.Type.MethodType) NullCheckExceptionType(lombok.core.configuration.NullCheckExceptionType) MethodType(com.sun.tools.javac.code.Type.MethodType) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol)

Example 4 with MethodType

use of com.sun.tools.javac.code.Type.MethodType in project error-prone by google.

the class AbstractToString method checkToString.

/**
 * Tests if the given expression is converted to a String by its parent (i.e. its parent is a
 * string concat expression, {@code String.format}, or {@code println(Object)}).
 */
private Description checkToString(ExpressionTree tree, VisitorState state) {
    Symbol sym = ASTHelpers.getSymbol(tree);
    if (!(sym instanceof VarSymbol || sym instanceof MethodSymbol)) {
        return NO_MATCH;
    }
    Type type = ASTHelpers.getType(tree);
    if (type instanceof MethodType) {
        type = type.getReturnType();
    }
    Tree parent = state.getPath().getParentPath().getLeaf();
    ToStringKind toStringKind = isToString(parent, tree, state);
    if (toStringKind == ToStringKind.NONE) {
        return NO_MATCH;
    }
    Optional<Fix> fix;
    switch(toStringKind) {
        case IMPLICIT:
            fix = implicitToStringFix(tree, state);
            break;
        case EXPLICIT:
            fix = toStringFix(parent, tree, state);
            break;
        default:
            throw new AssertionError(toStringKind);
    }
    if (!typePredicate().apply(type, state)) {
        return NO_MATCH;
    }
    return maybeFix(tree, fix);
}
Also used : MethodType(com.sun.tools.javac.code.Type.MethodType) MethodType(com.sun.tools.javac.code.Type.MethodType) Type(com.sun.tools.javac.code.Type) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Fix(com.google.errorprone.fixes.Fix) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Symbol(com.sun.tools.javac.code.Symbol) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol)

Example 5 with MethodType

use of com.sun.tools.javac.code.Type.MethodType in project error-prone by google.

the class Template method callCheckMethod.

/**
 * Reflectively invoke Resolve.checkMethod(), which despite being package-private is apparently
 * the only useful entry-point into javac8's type inference implementation.
 */
private MethodType callCheckMethod(Warner warner, Inliner inliner, Object resultInfo, List<Type> actualArgTypes, MethodSymbol methodSymbol, Type site, Env<AttrContext> env) throws InferException {
    try {
        Method checkMethod;
        checkMethod = Resolve.class.getDeclaredMethod("checkMethod", Env.class, Type.class, Symbol.class, Class.forName(// ResultInfo is package-private
        "com.sun.tools.javac.comp.Attr$ResultInfo"), List.class, List.class, Warner.class);
        checkMethod.setAccessible(true);
        return (MethodType) checkMethod.invoke(Resolve.instance(inliner.getContext()), env, site, methodSymbol, resultInfo, actualArgTypes, /*freeTypeVariables=*/
        List.<Type>nil(), warner);
    } catch (InvocationTargetException e) {
        if (e.getCause() instanceof Resolve.InapplicableMethodException) {
            throw new InferException(ImmutableList.of(((Resolve.InapplicableMethodException) e.getTargetException()).getDiagnostic()));
        }
        throw new LinkageError(e.getMessage(), e.getCause());
    } catch (ReflectiveOperationException e) {
        throw new LinkageError(e.getMessage(), e);
    }
}
Also used : MethodType(com.sun.tools.javac.code.Type.MethodType) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) Symbol(com.sun.tools.javac.code.Symbol) Method(java.lang.reflect.Method) Env(com.sun.tools.javac.comp.Env) Resolve(com.sun.tools.javac.comp.Resolve) InvocationTargetException(java.lang.reflect.InvocationTargetException) Warner(com.sun.tools.javac.util.Warner) MethodType(com.sun.tools.javac.code.Type.MethodType) Type(com.sun.tools.javac.code.Type) List(com.sun.tools.javac.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList)

Aggregations

Type (com.sun.tools.javac.code.Type)7 MethodType (com.sun.tools.javac.code.Type.MethodType)7 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)6 Symbol (com.sun.tools.javac.code.Symbol)4 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)3 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)3 ArrayType (com.sun.tools.javac.code.Type.ArrayType)3 ClassType (com.sun.tools.javac.code.Type.ClassType)3 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)3 WildcardType (com.sun.tools.javac.code.Type.WildcardType)3 JCTree (com.sun.tools.javac.tree.JCTree)3 DynamicMethodSymbol (com.sun.tools.javac.code.Symbol.DynamicMethodSymbol)2 OperatorSymbol (com.sun.tools.javac.code.Symbol.OperatorSymbol)2 PackageSymbol (com.sun.tools.javac.code.Symbol.PackageSymbol)2 TypeSymbol (com.sun.tools.javac.code.Symbol.TypeSymbol)2 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)2 Warner (com.sun.tools.javac.util.Warner)2 ImmutableList (com.google.common.collect.ImmutableList)1 Fix (com.google.errorprone.fixes.Fix)1 ExpressionTree (com.sun.source.tree.ExpressionTree)1