Search in sources :

Example 41 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class Attr method checkMethod.

/**
 * Check that method arguments conform to its instantiation.
 */
public Type checkMethod(Type site, final Symbol sym, ResultInfo resultInfo, Env<AttrContext> env, final List<JCExpression> argtrees, List<Type> argtypes, List<Type> typeargtypes) {
    // an unchecked warning if its argument types change under erasure.
    if (allowGenerics && (sym.flags() & STATIC) == 0 && (site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
        Type s = types.asOuterSuper(site, sym.owner);
        if (s != null && s.isRaw() && !types.isSameTypes(sym.type.getParameterTypes(), sym.erasure(types).getParameterTypes())) {
            chk.warnUnchecked(env.tree.pos(), "unchecked.call.mbr.of.raw.type", sym, s);
        }
    }
    if (env.info.defaultSuperCallSite != null) {
        for (Type sup : types.interfaces(env.enclClass.type).prepend(types.supertype((env.enclClass.type)))) {
            if (!sup.tsym.isSubClass(sym.enclClass(), types) || types.isSameType(sup, env.info.defaultSuperCallSite))
                continue;
            List<MethodSymbol> icand_sup = types.interfaceCandidates(sup, (MethodSymbol) sym);
            if (icand_sup.nonEmpty() && icand_sup.head != sym && icand_sup.head.overrides(sym, icand_sup.head.enclClass(), types, true)) {
                log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite, diags.fragment("overridden.default", sym, sup));
                break;
            }
        }
        env.info.defaultSuperCallSite = null;
    }
    if (sym.isStatic() && site.isInterface() && env.tree.hasTag(APPLY)) {
        JCMethodInvocation app = (JCMethodInvocation) env.tree;
        if (app.meth.hasTag(SELECT) && !TreeInfo.isStaticSelector(((JCFieldAccess) app.meth).selected, names)) {
            log.error(env.tree.pos(), "illegal.static.intf.meth.call", site);
        }
    }
    // Compute the identifier's instantiated type.
    // For methods, we need to compute the instance type by
    // Resolve.instantiate from the symbol's type as well as
    // any type arguments and value arguments.
    noteWarner.clear();
    try {
        Type owntype = rs.checkMethod(env, site, sym, resultInfo, argtypes, typeargtypes, noteWarner);
        DeferredAttr.DeferredTypeMap checkDeferredMap = deferredAttr.new DeferredTypeMap(DeferredAttr.AttrMode.CHECK, sym, env.info.pendingResolutionPhase);
        argtypes = Type.map(argtypes, checkDeferredMap);
        if (noteWarner.hasNonSilentLint(LintCategory.UNCHECKED)) {
            chk.warnUnchecked(env.tree.pos(), "unchecked.meth.invocation.applied", kindName(sym), sym.name, rs.methodArguments(sym.type.getParameterTypes()), rs.methodArguments(Type.map(argtypes, checkDeferredMap)), kindName(sym.location()), sym.location());
            // Don't erase the return type of the instantiated method type
            // for Ceylon #1095
            owntype = new MethodType(owntype.getParameterTypes(), sourceLanguage.isCeylon() && typeargtypes != null && !typeargtypes.isEmpty() ? owntype.getReturnType() : types.erasure(owntype.getReturnType()), types.erasure(owntype.getThrownTypes()), syms.methodClass);
        }
        return chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(), resultInfo.checkContext.inferenceContext());
    } catch (Infer.InferenceException ex) {
        // invalid target type - propagate exception outwards or report error
        // depending on the current check context
        resultInfo.checkContext.report(env.tree.pos(), ex.getDiagnostic());
        return types.createErrorType(site);
    } catch (Resolve.InapplicableMethodException ex) {
        final JCDiagnostic diag = ex.getDiagnostic();
        Resolve.InapplicableSymbolError errSym = rs.new InapplicableSymbolError(null) {

            @Override
            protected Pair<Symbol, JCDiagnostic> errCandidate() {
                return new Pair<Symbol, JCDiagnostic>(sym, diag);
            }
        };
        List<Type> argtypes2 = Type.map(argtypes, rs.new ResolveDeferredRecoveryMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
        JCDiagnostic errDiag = errSym.getDiagnostic(JCDiagnostic.DiagnosticType.ERROR, env.tree, sym, site, sym.name, argtypes2, typeargtypes);
        log.report(errDiag);
        return types.createErrorType(site);
    }
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) List(org.eclipse.ceylon.langtools.tools.javac.util.List)

Example 42 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class Attr method visitSelect.

/*
    // Added by Ceylon
    private Symbol resolveIndyCall(JCIndyIdent tree, List<Type> parameterTypes) {
        return resolveIndyCall(tree, tree.indyReturnType, tree.indyParameterTypes, tree.name, 
                               tree.bsmType, tree.bsmName, tree.bsmStatic,
                               parameterTypes);
    }
    */
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, new ResultInfo(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.hasTag(ARRAY)) elt = ((ArrayType) elt.unannotatedType()).elemtype;
        if (elt.hasTag(TYPEVAR)) {
            log.error(tree.pos(), "type.var.cant.be.deref");
            result = tree.type = types.createErrorType(tree.name, site.tsym, site);
            tree.sym = tree.type.tsym;
            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;
    // Determine the symbol represented by the selection.
    env.info.pendingResolutionPhase = null;
    Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
    if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) {
        log.error(tree.selected.pos(), "not.encl.class", site.tsym);
        sym = syms.errSymbol;
    }
    if (sym.exists() && !isType(sym) && (pkind() & (PCK | TYP)) != 0) {
        site = capture(site);
        sym = selectSym(tree, sitesym, site, env, resultInfo);
    }
    boolean varArgs = env.info.lastResolveVarargs();
    tree.sym = sym;
    if (site.hasTag(TYPEVAR) && !isType(sym) && sym.kind != ERR) {
        while (site.hasTag(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, new ResultInfo(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 && !env.next.tree.hasTag(REFERENCE) && sym.name != names._super && (sym.kind == VAR || sym.kind == MTH)) {
                rs.accessBase(rs.new StaticError(sym), tree.pos(), site, sym.name, true);
            }
        }
        if (!allowStaticInterfaceMethods && sitesym.isInterface() && sym.isStatic() && sym.kind == MTH) {
            log.error(tree.pos(), sourceLanguage.isCeylon() ? "ceylon.static.interface.method.call" : "static.intf.method.invoke.not.supported.in.source", sourceName);
        }
    } 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;
        }
    }
    if (env.info.isSerializable) {
        chk.checkElemAccessFromSerializableLambda(tree);
    }
    // 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, resultInfo);
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 43 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class LambdaToMethod method makeMetafactoryIndyCall.

/**
 * Generate an indy method call to the meta factory
 */
private JCExpression makeMetafactoryIndyCall(LambdaAnalyzerPreprocessor.TranslationContext<?> context, int refKind, Symbol refSym, List<JCExpression> indy_args) {
    JCFunctionalExpression tree = context.tree;
    // determine the static bsm args
    MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym);
    List<Object> staticArgs = List.<Object>of(typeToMethodType(samSym.type), new Pool.MethodHandle(refKind, refSym, types), typeToMethodType(tree.getDescriptorType(types)));
    // computed indy arg types
    ListBuffer<Type> indy_args_types = new ListBuffer<>();
    for (JCExpression arg : indy_args) {
        indy_args_types.append(arg.type);
    }
    // finally, compute the type of the indy call
    MethodType indyType = new MethodType(indy_args_types.toList(), tree.type, List.<Type>nil(), syms.methodClass);
    Name metafactoryName = context.needsAltMetafactory() ? names.altMetafactory : names.metafactory;
    if (context.needsAltMetafactory()) {
        ListBuffer<Object> markers = new ListBuffer<>();
        for (Type t : tree.targets.tail) {
            if (t.tsym != syms.serializableType.tsym) {
                markers.append(t.tsym);
            }
        }
        int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0;
        boolean hasMarkers = markers.nonEmpty();
        boolean hasBridges = context.bridges.nonEmpty();
        if (hasMarkers) {
            flags |= FLAG_MARKERS;
        }
        if (hasBridges) {
            flags |= FLAG_BRIDGES;
        }
        staticArgs = staticArgs.append(flags);
        if (hasMarkers) {
            staticArgs = staticArgs.append(markers.length());
            staticArgs = staticArgs.appendList(markers.toList());
        }
        if (hasBridges) {
            staticArgs = staticArgs.append(context.bridges.length() - 1);
            for (Symbol s : context.bridges) {
                Type s_erasure = s.erasure(types);
                if (!types.isSameType(s_erasure, samSym.erasure(types))) {
                    staticArgs = staticArgs.append(s.erasure(types));
                }
            }
        }
        if (context.isSerializable()) {
            int prevPos = make.pos;
            try {
                make.at(kInfo.clazz);
                addDeserializationCase(refKind, refSym, tree.type, samSym, tree, staticArgs, indyType);
            } finally {
                make.at(prevPos);
            }
        }
    }
    return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name);
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) VarSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol) MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)

Example 44 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class LambdaToMethod method deserTest.

private JCExpression deserTest(JCExpression prev, String func, String lit) {
    MethodType eqmt = new MethodType(List.of(syms.objectType), syms.booleanType, List.<Type>nil(), syms.methodClass);
    Symbol eqsym = rs.resolveQualifiedMethod(null, attrEnv, syms.objectType, names.equals, List.of(syms.objectType), List.<Type>nil());
    JCMethodInvocation eqtest = make.Apply(List.<JCExpression>nil(), make.Select(deserGetter(func, syms.stringType), eqsym).setType(eqmt), List.<JCExpression>of(make.Literal(lit)));
    eqtest.setType(syms.booleanType);
    JCBinary compound = make.Binary(JCTree.Tag.AND, prev, eqtest);
    compound.operator = rs.resolveBinaryOperator(null, JCTree.Tag.AND, attrEnv, syms.booleanType, syms.booleanType);
    compound.setType(syms.booleanType);
    return compound;
}
Also used : MethodType(org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType) VarSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)

Example 45 with Symbol

use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.

the class LambdaToMethod method visitReference.

/**
 * Translate a method reference into an invokedynamic call to the
 * meta-factory.
 * @param tree
 */
@Override
public void visitReference(JCMemberReference tree) {
    LambdaAnalyzerPreprocessor.ReferenceTranslationContext localContext = (LambdaAnalyzerPreprocessor.ReferenceTranslationContext) context;
    // first determine the method symbol to be used to generate the sam instance
    // this is either the method reference symbol, or the bridged reference symbol
    Symbol refSym = localContext.isSignaturePolymorphic() ? localContext.sigPolySym : tree.sym;
    // the qualifying expression is treated as a special captured arg
    JCExpression init;
    switch(tree.kind) {
        case IMPLICIT_INNER:
        /**
         * Inner :: new
         */
        case SUPER:
            /**
             * super :: instMethod
             */
            init = makeThis(localContext.owner.enclClass().asType(), localContext.owner.enclClass());
            break;
        case BOUND:
            /**
             * Expr :: instMethod
             */
            init = tree.getQualifierExpression();
            init = attr.makeNullCheck(init);
            break;
        case UNBOUND:
        /**
         * Type :: instMethod
         */
        case STATIC:
        /**
         * Type :: staticMethod
         */
        case TOPLEVEL:
        /**
         * Top level :: new
         */
        case ARRAY_CTOR:
            /**
             * ArrayType :: new
             */
            init = null;
            break;
        default:
            throw new InternalError("Should not have an invalid kind");
    }
    List<JCExpression> indy_args = init == null ? List.<JCExpression>nil() : translate(List.of(init), localContext.prev);
    // build a sam instance using an indy call to the meta-factory
    result = makeMetafactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args);
}
Also used : LambdaAnalyzerPreprocessor(org.eclipse.ceylon.langtools.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor) VarSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol) MethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) TypeSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol) DynamicMethodSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol) ClassSymbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)

Aggregations

Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)115 Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)42 ClassSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)16 MethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol)15 VarSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)12 TypeSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)11 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)11 DeferredAttrContext (org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredAttrContext)8 DeferredType (org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType)8 DiagnosticType (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType)8 DynamicMethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.DynamicMethodSymbol)6 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)6 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)5 DiagnosticPosition (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)4 ErrorType (org.eclipse.ceylon.javax.lang.model.type.ErrorType)3 Scope (org.eclipse.ceylon.langtools.tools.javac.code.Scope)3 PackageSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol)3 HashSet (java.util.HashSet)2 LinkedList (java.util.LinkedList)2 DeclaredType (org.eclipse.ceylon.javax.lang.model.type.DeclaredType)2