Search in sources :

Example 1 with Type

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

the class Lower method visitMethodDefInternal.

// where
private void visitMethodDefInternal(JCMethodDecl tree) {
    if (tree.name == names.init && (currentClass.isInner() || currentClass.isLocal())) {
        // We are seeing a constructor of an inner class.
        MethodSymbol m = tree.sym;
        // Push a new proxy scope for constructor parameters.
        // and create definitions for any this$n and proxy parameters.
        proxies = proxies.dup(m);
        List<VarSymbol> prevOuterThisStack = outerThisStack;
        List<VarSymbol> fvs = freevars(currentClass);
        JCVariableDecl otdef = null;
        if (currentClass.hasOuterInstance())
            otdef = outerThisDef(tree.pos, m);
        List<JCVariableDecl> fvdefs = freevarDefs(tree.pos, fvs, m, PARAMETER);
        // Recursively translate result type, parameters and thrown list.
        tree.restype = translate(tree.restype);
        tree.params = translateVarDefs(tree.params);
        tree.thrown = translate(tree.thrown);
        // when compiling stubs, don't process body
        if (tree.body == null) {
            result = tree;
            return;
        }
        // Add this$n (if needed) in front of and free variables behind
        // constructor parameter list.
        tree.params = tree.params.appendList(fvdefs);
        if (currentClass.hasOuterInstance())
            tree.params = tree.params.prepend(otdef);
        // If this is an initial constructor, i.e., it does not start with
        // this(...), insert initializers for this$n and proxies
        // before (pre-1.4, after) the call to superclass constructor.
        JCStatement selfCall = translate(tree.body.stats.head);
        List<JCStatement> added = List.nil();
        if (fvs.nonEmpty()) {
            List<Type> addedargtypes = List.nil();
            for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
                if (TreeInfo.isInitialConstructor(tree)) {
                    final Name pName = proxyName(l.head.name);
                    m.capturedLocals = m.capturedLocals.append((VarSymbol) (proxies.lookup(pName).sym));
                    added = added.prepend(initField(tree.body.pos, pName));
                }
                addedargtypes = addedargtypes.prepend(l.head.erasure(types));
            }
            Type olderasure = m.erasure(types);
            m.erasure_field = new MethodType(olderasure.getParameterTypes().appendList(addedargtypes), olderasure.getReturnType(), olderasure.getThrownTypes(), syms.methodClass);
        }
        if (currentClass.hasOuterInstance() && TreeInfo.isInitialConstructor(tree)) {
            added = added.prepend(initOuterThis(tree.body.pos));
        }
        // pop local variables from proxy stack
        proxies = proxies.leave();
        // recursively translate following local statements and
        // combine with this- or super-call
        List<JCStatement> stats = translate(tree.body.stats.tail);
        if (target.initializeFieldsBeforeSuper())
            tree.body.stats = stats.prepend(selfCall).prependList(added);
        else
            tree.body.stats = stats.prependList(added).prepend(selfCall);
        outerThisStack = prevOuterThisStack;
    } else {
        Map<Symbol, Symbol> prevLambdaTranslationMap = lambdaTranslationMap;
        try {
            lambdaTranslationMap = (tree.sym.flags() & SYNTHETIC) != 0 && tree.sym.name.startsWith(names.lambda) ? makeTranslationMap(tree) : null;
            super.visitMethodDef(tree);
        } finally {
            lambdaTranslationMap = prevLambdaTranslationMap;
        }
    }
    result = tree;
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Example 2 with Type

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

the class Lower method unbox.

/**
 * Unbox an object to a primitive value.
 */
JCExpression unbox(JCExpression tree, Type primitive) {
    Type unboxedType = types.unboxedType(tree.type);
    if (unboxedType.hasTag(NONE)) {
        unboxedType = primitive;
        if (!unboxedType.isPrimitive())
            throw new AssertionError(unboxedType);
        make_at(tree.pos());
        tree = make.TypeCast(types.boxedClass(unboxedType).type, tree);
    } else {
        // There must be a conversion from unboxedType to primitive.
        if (!types.isSubtype(unboxedType, primitive))
            throw new AssertionError(tree);
    }
    make_at(tree.pos());
    Symbol valueSym = lookupMethod(tree.pos(), // x.intValue()
    unboxedType.tsym.name.append(names.Value), tree.type, List.<Type>nil());
    return make.App(make.Select(tree, valueSym));
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 3 with Type

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

the class Lower method visitEnumDef.

/**
 * Translate an enum class.
 */
private void visitEnumDef(JCClassDecl tree) {
    make_at(tree.pos());
    // add the supertype, if needed
    if (tree.extending == null)
        tree.extending = make.Type(types.supertype(tree.type));
    // classOfType adds a cache field to tree.defs unless
    // target.hasClassLiterals().
    JCExpression e_class = classOfType(tree.sym.type, tree.pos()).setType(types.erasure(syms.classType));
    // process each enumeration constant, adding implicit constructor parameters
    int nextOrdinal = 0;
    ListBuffer<JCExpression> values = new ListBuffer<JCExpression>();
    ListBuffer<JCTree> enumDefs = new ListBuffer<JCTree>();
    ListBuffer<JCTree> otherDefs = new ListBuffer<JCTree>();
    for (List<JCTree> defs = tree.defs; defs.nonEmpty(); defs = defs.tail) {
        if (defs.head.hasTag(VARDEF) && (((JCVariableDecl) defs.head).mods.flags & ENUM) != 0) {
            JCVariableDecl var = (JCVariableDecl) defs.head;
            visitEnumConstantDef(var, nextOrdinal++);
            values.append(make.QualIdent(var.sym));
            enumDefs.append(var);
        } else {
            otherDefs.append(defs.head);
        }
    }
    // private static final T[] #VALUES = { a, b, c };
    Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
    while (// avoid name clash
    tree.sym.members().lookup(valuesName).scope != null) valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
    Type arrayType = new ArrayType(types.erasure(tree.type), syms.arrayClass);
    VarSymbol valuesVar = new VarSymbol(PRIVATE | FINAL | STATIC | SYNTHETIC, valuesName, arrayType, tree.type.tsym);
    JCNewArray newArray = make.NewArray(make.Type(types.erasure(tree.type)), List.<JCExpression>nil(), values.toList());
    newArray.type = arrayType;
    enumDefs.append(make.VarDef(valuesVar, newArray));
    tree.sym.members().enter(valuesVar);
    Symbol valuesSym = lookupMethod(tree.pos(), names.values, tree.type, List.<Type>nil());
    List<JCStatement> valuesBody;
    if (useClone()) {
        // return (T[]) $VALUES.clone();
        JCTypeCast valuesResult = make.TypeCast(valuesSym.type.getReturnType(), make.App(make.Select(make.Ident(valuesVar), syms.arrayCloneMethod)));
        valuesBody = List.<JCStatement>of(make.Return(valuesResult));
    } else {
        // template: T[] $result = new T[$values.length];
        Name resultName = names.fromString(target.syntheticNameChar() + "result");
        while (// avoid name clash
        tree.sym.members().lookup(resultName).scope != null) resultName = names.fromString(resultName + "" + target.syntheticNameChar());
        VarSymbol resultVar = new VarSymbol(FINAL | SYNTHETIC, resultName, arrayType, valuesSym);
        JCNewArray resultArray = make.NewArray(make.Type(types.erasure(tree.type)), List.of(make.Select(make.Ident(valuesVar), syms.lengthVar)), null);
        resultArray.type = arrayType;
        JCVariableDecl decl = make.VarDef(resultVar, resultArray);
        // template: System.arraycopy($VALUES, 0, $result, 0, $VALUES.length);
        if (systemArraycopyMethod == null) {
            systemArraycopyMethod = new MethodSymbol(PUBLIC | STATIC, names.fromString("arraycopy"), new MethodType(List.<Type>of(syms.objectType, syms.intType, syms.objectType, syms.intType, syms.intType), syms.voidType, List.<Type>nil(), syms.methodClass), syms.systemType.tsym);
        }
        JCStatement copy = make.Exec(make.App(make.Select(make.Ident(syms.systemType.tsym), systemArraycopyMethod), List.of(make.Ident(valuesVar), make.Literal(0), make.Ident(resultVar), make.Literal(0), make.Select(make.Ident(valuesVar), syms.lengthVar))));
        // template: return $result;
        JCStatement ret = make.Return(make.Ident(resultVar));
        valuesBody = List.<JCStatement>of(decl, copy, ret);
    }
    JCMethodDecl valuesDef = make.MethodDef((MethodSymbol) valuesSym, make.Block(0, valuesBody));
    enumDefs.append(valuesDef);
    if (debugLower)
        System.err.println(tree.sym + ".valuesDef = " + valuesDef);
    /**
     * The template for the following code is:
     *
     *     public static E valueOf(String name) {
     *         return (E)Enum.valueOf(E.class, name);
     *     }
     *
     *  where E is tree.sym
     */
    MethodSymbol valueOfSym = lookupMethod(tree.pos(), names.valueOf, tree.sym.type, List.of(syms.stringType));
    Assert.check((valueOfSym.flags() & STATIC) != 0);
    VarSymbol nameArgSym = valueOfSym.params.head;
    JCIdent nameVal = make.Ident(nameArgSym);
    JCStatement enum_ValueOf = make.Return(make.TypeCast(tree.sym.type, makeCall(make.Ident(syms.enumSym), names.valueOf, List.of(e_class, nameVal))));
    JCMethodDecl valueOf = make.MethodDef(valueOfSym, make.Block(0, List.of(enum_ValueOf)));
    nameVal.sym = valueOf.params.head.sym;
    if (debugLower)
        System.err.println(tree.sym + ".valueOf = " + valueOf);
    enumDefs.append(valueOf);
    enumDefs.appendList(otherDefs.toList());
    tree.defs = enumDefs.toList();
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Example 4 with Type

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

the class Lower method visitNewClass.

public void visitNewClass(JCNewClass tree) {
    ClassSymbol c = (ClassSymbol) tree.constructor.owner;
    // Box arguments, if necessary
    boolean isEnum = (tree.constructor.owner.flags() & ENUM) != 0;
    List<Type> argTypes = tree.constructor.type.getParameterTypes();
    if (isEnum)
        argTypes = argTypes.prepend(syms.intType).prepend(syms.stringType);
    tree.args = boxArgs(argTypes, tree.args, tree.varargsElement);
    tree.varargsElement = null;
    // explicit constructor arguments.
    if (c.isLocal()) {
        tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
    }
    // If an access constructor is used, append null as a last argument.
    Symbol constructor = accessConstructor(tree.pos(), tree.constructor);
    if (constructor != tree.constructor) {
        tree.args = tree.args.append(makeNull());
        tree.constructor = constructor;
    }
    // correct outer instance as first argument.
    if (c.hasOuterInstance()) {
        JCExpression thisArg;
        if (tree.encl != null) {
            thisArg = attr.makeNullCheck(translate(tree.encl));
            thisArg.type = tree.encl.type;
        } else if (c.isLocal()) {
            // local class
            thisArg = makeThis(tree.pos(), c.type.getEnclosingType().tsym);
        } else {
            // nested class
            thisArg = makeOwnerThis(tree.pos(), c, false);
        }
        tree.args = tree.args.prepend(thisArg);
    }
    tree.encl = null;
    // than the class or interface following new.
    if (tree.def != null) {
        translate(tree.def);
        tree.clazz = access(make_at(tree.clazz.pos()).Ident(tree.def.sym));
        tree.def = null;
    } else {
        tree.clazz = access(c, tree.clazz, enclOp, false);
    }
    result = tree;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol)

Example 5 with Type

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

the class MemberEnter method importNamedStatic.

/**
 * Import statics types of a given name.  Non-types are handled in Attr.
 *  @param pos           Position to be used for error reporting.
 *  @param tsym          The class from which the name is imported.
 *  @param name          The (simple) name being imported.
 *  @param env           The environment containing the named import
 *                  scope to add to.
 */
private void importNamedStatic(final DiagnosticPosition pos, final TypeSymbol tsym, final Name name, final Env<AttrContext> env) {
    if (tsym.kind != TYP) {
        log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces");
        return;
    }
    final Scope toScope = env.toplevel.namedImportScope;
    final PackageSymbol packge = env.toplevel.packge;
    final TypeSymbol origin = tsym;
    // enter imported types immediately
    new Object() {

        Set<Symbol> processed = new HashSet<Symbol>();

        void importFrom(TypeSymbol tsym) {
            if (tsym == null || !processed.add(tsym))
                return;
            // also import inherited names
            importFrom(types.supertype(tsym.type).tsym);
            for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
            for (Scope.Entry e = tsym.members().lookup(name); e.scope != null; e = e.next()) {
                Symbol sym = e.sym;
                if (sym.isStatic() && sym.kind == TYP && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types) && chk.checkUniqueStaticImport(pos, sym, toScope))
                    toScope.enter(sym, sym.owner.members(), origin.members(), true);
            }
        }
    }.importFrom(tsym);
    // enter non-types before annotations that might use them
    annotate.earlier(new Annotate.Worker() {

        Set<Symbol> processed = new HashSet<Symbol>();

        boolean found = false;

        public String toString() {
            return "import static " + tsym + "." + name;
        }

        void importFrom(TypeSymbol tsym) {
            if (tsym == null || !processed.add(tsym))
                return;
            // also import inherited names
            importFrom(types.supertype(tsym.type).tsym);
            for (Type t : types.interfaces(tsym.type)) importFrom(t.tsym);
            for (Scope.Entry e = tsym.members().lookup(name); e.scope != null; e = e.next()) {
                Symbol sym = e.sym;
                if (sym.isStatic() && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types)) {
                    found = true;
                    if (sym.kind != TYP) {
                        toScope.enter(sym, sym.owner.members(), origin.members(), true);
                    }
                }
            }
        }

        public void run() {
            JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
            try {
                importFrom(tsym);
                if (!found) {
                    log.error(pos, "cant.resolve.location", KindName.STATIC, name, List.<Type>nil(), List.<Type>nil(), Kinds.typeKindName(tsym.type), tsym.type);
                }
            } finally {
                log.useSource(prev);
            }
        }
    });
}
Also used : Symbol(org.eclipse.ceylon.langtools.tools.javac.code.Symbol) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) HashSet(java.util.HashSet)

Aggregations

Type (org.eclipse.ceylon.langtools.tools.javac.code.Type)164 Symbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol)46 DeferredType (org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType)13 DiagnosticType (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType)13 ArrayType (org.eclipse.ceylon.langtools.tools.javac.code.Type.ArrayType)10 MethodType (org.eclipse.ceylon.langtools.tools.javac.code.Type.MethodType)10 ClassSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.ClassSymbol)9 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)9 MethodSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.MethodSymbol)8 JavaFileObject (org.eclipse.ceylon.javax.tools.JavaFileObject)7 TypeSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.TypeSymbol)7 DiagnosticPosition (org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition)7 JavacType (org.eclipse.ceylon.compiler.java.loader.mirror.JavacType)5 PackageSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.PackageSymbol)5 FunctionalInterfaceType (org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType)5 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)5 HashSet (java.util.HashSet)4 CompletionFailure (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.CompletionFailure)4 VarSymbol (org.eclipse.ceylon.langtools.tools.javac.code.Symbol.VarSymbol)4 FreeTypeListener (org.eclipse.ceylon.langtools.tools.javac.comp.Infer.FreeTypeListener)4