Search in sources :

Example 1 with ForAll

use of com.sun.tools.javac.code.Type.ForAll 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 ForAll

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

the class Attr method visitSelect.

public void visitSelect(JCFieldAccess tree) {
    // Determine the expected kind of the qualifier expression.
    int skind = 0;
    if (tree.name == names._this || tree.name == names._super || tree.name == names._class) {
        skind = TYP;
    } else {
        if ((pkind & PCK) != 0)
            skind = skind | PCK;
        if ((pkind & TYP) != 0)
            skind = skind | TYP | PCK;
        if ((pkind & (VAL | MTH)) != 0)
            skind = skind | VAL | TYP;
    }
    // Attribute the qualifier expression, and determine its symbol (if any).
    Type site = attribTree(tree.selected, env, skind, Infer.anyPoly);
    if ((pkind & (PCK | TYP)) == 0)
        // Capture field access
        site = capture(site);
    // don't allow T.class T[].class, etc
    if (skind == TYP) {
        Type elt = site;
        while (elt.tag == ARRAY) elt = ((ArrayType) elt).elemtype;
        if (elt.tag == TYPEVAR) {
            log.error(tree.pos(), "type.var.cant.be.deref");
            result = types.createErrorType(tree.type);
            return;
        }
    }
    // If qualifier symbol is a type or `super', assert `selectSuper'
    // for the selection. This is relevant for determining whether
    // protected symbols are accessible.
    Symbol sitesym = TreeInfo.symbol(tree.selected);
    boolean selectSuperPrev = env.info.selectSuper;
    env.info.selectSuper = sitesym != null && sitesym.name == names._super;
    // they can be added later (in Attr.checkId and Infer.instantiateMethod).
    if (tree.selected.type.tag == FORALL) {
        ForAll pstype = (ForAll) tree.selected.type;
        env.info.tvars = pstype.tvars;
        site = tree.selected.type = pstype.qtype;
    }
    // Determine the symbol represented by the selection.
    env.info.varArgs = false;
    Symbol sym = selectSym(tree, sitesym, site, env, pt, pkind);
    if (sym.exists() && !isType(sym) && (pkind & (PCK | TYP)) != 0) {
        site = capture(site);
        sym = selectSym(tree, sitesym, site, env, pt, pkind);
    }
    boolean varArgs = env.info.varArgs;
    tree.sym = sym;
    if (site.tag == TYPEVAR && !isType(sym) && sym.kind != ERR) {
        while (site.tag == TYPEVAR) site = site.getUpperBound();
        site = capture(site);
    }
    // If that symbol is a variable, ...
    if (sym.kind == VAR) {
        VarSymbol v = (VarSymbol) sym;
        // ..., evaluate its initializer, if it has one, and check for
        // illegal forward reference.
        checkInit(tree, env, v, true);
        // that the variable is assignable in the current environment.
        if (pkind == VAR)
            checkAssignable(tree.pos(), v, tree.selected, env);
    }
    if (sitesym != null && sitesym.kind == VAR && ((VarSymbol) sitesym).isResourceVariable() && sym.kind == MTH && sym.name.equals(names.close) && sym.overrides(syms.autoCloseableClose, sitesym.type.tsym, types, true) && env.info.lint.isEnabled(LintCategory.TRY)) {
        log.warning(LintCategory.TRY, tree, "try.explicit.close.call");
    }
    // Disallow selecting a type from an expression
    if (isType(sym) && (sitesym == null || (sitesym.kind & (TYP | PCK)) == 0)) {
        tree.type = check(tree.selected, pt, sitesym == null ? VAL : sitesym.kind, TYP | PCK, pt);
    }
    if (isType(sitesym)) {
        if (sym.name == names._this) {
            // C.this' does not appear in a call to a super(...)
            if (env.info.isSelfCall && site.tsym == env.enclClass.sym) {
                chk.earlyRefError(tree.pos(), sym);
            }
        } else {
            // Check if type-qualified fields or methods are static (JLS)
            if ((sym.flags() & STATIC) == 0 && sym.name != names._super && (sym.kind == VAR || sym.kind == MTH)) {
                rs.access(rs.new StaticError(sym), tree.pos(), site, sym.name, true);
            }
        }
    } else if (sym.kind != ERR && (sym.flags() & STATIC) != 0 && sym.name != names._class) {
        // If the qualified item is not a type and the selected item is static, report
        // a warning. Make allowance for the class of an array type e.g. Object[].class)
        chk.warnStatic(tree, "static.not.qualified.by.type", Kinds.kindName(sym.kind), sym.owner);
    }
    // If we are selecting an instance member via a `super', ...
    if (env.info.selectSuper && (sym.flags() & STATIC) == 0) {
        // Check that super-qualified symbols are not abstract (JLS)
        rs.checkNonAbstract(tree.pos(), sym);
        if (site.isRaw()) {
            // Determine argument types for site.
            Type site1 = types.asSuper(env.enclClass.sym.type, site.tsym);
            if (site1 != null)
                site = site1;
        }
    }
    // Ceylon: error if we try to select an interface static in < 1.8
    if (sym != null && sym.isStatic() && (sym.kind & Kinds.MTH) != 0 && sitesym != null && sitesym.isInterface()) {
        chk.checkStaticInterfaceMethodCall(tree);
    }
    env.info.selectSuper = selectSuperPrev;
    result = checkId(tree, site, sym, env, pkind, pt, varArgs);
    env.info.tvars = List.nil();
}
Also used : ArrayType(com.sun.tools.javac.code.Type.ArrayType) 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) 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) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ForAll(com.sun.tools.javac.code.Type.ForAll) Lint(com.sun.tools.javac.code.Lint)

Example 3 with ForAll

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

the class Attr method attribDiamond.

Type attribDiamond(Env<AttrContext> env, JCNewClass tree, Type clazztype, Pair<Scope, Scope> mapping, List<Type> argtypes, List<Type> typeargtypes) {
    if (clazztype.isErroneous() || clazztype.isInterface() || mapping == erroneousMapping) {
        // mapping, return the (possibly erroneous) type unchanged
        return clazztype;
    }
    // dup attribution environment and augment the set of inference variables
    Env<AttrContext> localEnv = env.dup(tree);
    localEnv.info.tvars = clazztype.tsym.type.getTypeArguments();
    // if the type of the instance creation expression is a class type
    // apply method resolution inference (JLS 15.12.2.7). The return type
    // of the resolved constructor will be a partially instantiated type
    ((ClassSymbol) clazztype.tsym).members_field = mapping.snd;
    Symbol constructor;
    try {
        constructor = rs.resolveDiamond(tree.pos(), localEnv, clazztype.tsym.type, argtypes, typeargtypes);
    } finally {
        ((ClassSymbol) clazztype.tsym).members_field = mapping.fst;
    }
    if (constructor.kind == MTH) {
        ClassType ct = new ClassType(clazztype.getEnclosingType(), clazztype.tsym.type.getTypeArguments(), clazztype.tsym);
        clazztype = checkMethod(ct, constructor, localEnv, tree.args, argtypes, typeargtypes, localEnv.info.varArgs).getReturnType();
    } else {
        clazztype = syms.errType;
    }
    if (clazztype.tag == FORALL && !pt.isErroneous()) {
        // bounds (JLS 15.12.2.8).
        try {
            clazztype = infer.instantiateExpr((ForAll) clazztype, pt.tag == NONE ? syms.objectType : pt, Warner.noWarnings);
        } catch (Infer.InferenceException ex) {
            // an error occurred while inferring uninstantiated type-variables
            log.error(tree.clazz.pos(), "cant.apply.diamond.1", diags.fragment("diamond", clazztype.tsym), ex.diagnostic);
        }
    }
    return chk.checkClassType(tree.clazz.pos(), clazztype, true);
}
Also used : 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) ClassType(com.sun.tools.javac.code.Type.ClassType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) ForAll(com.sun.tools.javac.code.Type.ForAll)

Example 4 with ForAll

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

the class Attr method checkId.

/**
 * Determine type of identifier or select expression and check that
 *  (1) the referenced symbol is not deprecated
 *  (2) the symbol's type is safe (@see checkSafe)
 *  (3) if symbol is a variable, check that its type and kind are
 *      compatible with the prototype and protokind.
 *  (4) if symbol is an instance field of a raw type,
 *      which is being assigned to, issue an unchecked warning if its
 *      type changes under erasure.
 *  (5) if symbol is an instance method of a raw type, issue an
 *      unchecked warning if its argument types change under erasure.
 *  If checks succeed:
 *    If symbol is a constant, return its constant type
 *    else if symbol is a method, return its result type
 *    otherwise return its type.
 *  Otherwise return errType.
 *
 *  @param tree       The syntax tree representing the identifier
 *  @param site       If this is a select, the type of the selected
 *                    expression, otherwise the type of the current class.
 *  @param sym        The symbol representing the identifier.
 *  @param env        The current environment.
 *  @param pkind      The set of expected kinds.
 *  @param pt         The expected type.
 */
Type checkId(JCTree tree, Type site, Symbol sym, Env<AttrContext> env, int pkind, Type pt, boolean useVarargs) {
    if (pt.isErroneous())
        return types.createErrorType(site);
    // The computed type of this identifier occurrence.
    Type owntype;
    switch(sym.kind) {
        case TYP:
            // For types, the computed type equals the symbol's type,
            // except for two situations:
            owntype = sym.type;
            if (owntype.tag == CLASS) {
                Type ownOuter = owntype.getEnclosingType();
                // We recover generic outer type later in visitTypeApply.
                if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
                    owntype = types.erasure(owntype);
                } else // Tree<Point>.Visitor.
                if (ownOuter.tag == CLASS && site != ownOuter) {
                    Type normOuter = site;
                    if (normOuter.tag == CLASS)
                        normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
                    if (// perhaps from an import
                    normOuter == null)
                        normOuter = types.erasure(ownOuter);
                    if (normOuter != ownOuter)
                        owntype = new ClassType(normOuter, List.<Type>nil(), owntype.tsym);
                }
            }
            break;
        case VAR:
            VarSymbol v = (VarSymbol) sym;
            // its type changes under erasure.
            if (allowGenerics && pkind == VAR && v.owner.kind == TYP && (v.flags() & STATIC) == 0 && (site.tag == CLASS || site.tag == TYPEVAR)) {
                Type s = types.asOuterSuper(site, v.owner);
                if (s != null && s.isRaw() && !types.isSameType(v.type, v.erasure(types))) {
                    chk.warnUnchecked(tree.pos(), "unchecked.assign.to.var", v, s);
                }
            }
            // The computed type of a variable is the type of the
            // variable symbol, taken as a member of the site type.
            owntype = (sym.owner.kind == TYP && sym.name != names._this && sym.name != names._super) ? types.memberType(site, sym) : sym.type;
            if (env.info.tvars.nonEmpty()) {
                Type owntype1 = new ForAll(env.info.tvars, owntype);
                for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail) if (!owntype.contains(l.head)) {
                    log.error(tree.pos(), "undetermined.type", owntype1);
                    owntype1 = types.createErrorType(owntype1);
                }
                owntype = owntype1;
            }
            // computed type.
            if (v.getConstValue() != null && isStaticReference(tree))
                owntype = owntype.constType(v.getConstValue());
            if (pkind == VAL) {
                // capture "names as expressions"
                owntype = capture(owntype);
            }
            break;
        case MTH:
            {
                JCMethodInvocation app = (JCMethodInvocation) env.tree;
                owntype = checkMethod(site, sym, env, app.args, pt.getParameterTypes(), pt.getTypeArguments(), env.info.varArgs);
                break;
            }
        case PCK:
        case ERR:
            owntype = sym.type;
            break;
        default:
            throw new AssertionError("unexpected kind: " + sym.kind + " in tree " + tree);
    }
    if (sym.name != names.init) {
        chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
        chk.checkSunAPI(tree.pos(), sym);
    }
    // kind are compatible with the prototype and protokind.
    return check(tree, owntype, sym.kind, pkind, pt);
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) 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) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) ForAll(com.sun.tools.javac.code.Type.ForAll)

Aggregations

ForAll (com.sun.tools.javac.code.Type.ForAll)4 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)3 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)3 Type (com.sun.tools.javac.code.Type)3 ClassType (com.sun.tools.javac.code.Type.ClassType)3 MethodType (com.sun.tools.javac.code.Type.MethodType)3 UnionClassType (com.sun.tools.javac.code.Type.UnionClassType)3 Symbol (com.sun.tools.javac.code.Symbol)2 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)2 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 ArrayType (com.sun.tools.javac.code.Type.ArrayType)2 WildcardType (com.sun.tools.javac.code.Type.WildcardType)2 Lint (com.sun.tools.javac.code.Lint)1 Symtab (com.sun.tools.javac.code.Symtab)1 AttrContext (com.sun.tools.javac.comp.AttrContext)1 Enter (com.sun.tools.javac.comp.Enter)1 JCTree (com.sun.tools.javac.tree.JCTree)1