Search in sources :

Example 6 with Type

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

the class MemberEnter method DefaultConstructor.

/* ***************************************************************************
 * tree building
 ****************************************************************************/
/**
 * Generate default constructor for given class. For classes different
 *  from java.lang.Object, this is:
 *
 *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
 *      super(x_0, ..., x_n)
 *    }
 *
 *  or, if based == true:
 *
 *    c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
 *      x_0.super(x_1, ..., x_n)
 *    }
 *
 *  @param make     The tree factory.
 *  @param c        The class owning the default constructor.
 *  @param argtypes The parameter types of the constructor.
 *  @param thrown   The thrown exceptions of the constructor.
 *  @param based    Is first parameter a this$n?
 */
JCTree DefaultConstructor(TreeMaker make, ClassSymbol c, MethodSymbol baseInit, List<Type> typarams, List<Type> argtypes, List<Type> thrown, long flags, boolean based) {
    JCTree result;
    if ((c.flags() & ENUM) != 0 && (types.supertype(c.type).tsym == syms.enumSym)) {
        // constructors of true enums are private
        flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
    } else
        flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
    if (c.name.isEmpty()) {
        flags |= ANONCONSTR;
    }
    Type mType = new MethodType(argtypes, null, thrown, c);
    Type initType = typarams.nonEmpty() ? new ForAll(typarams, mType) : mType;
    MethodSymbol init = new MethodSymbol(flags, names.init, initType, c);
    init.params = createDefaultConstructorParams(make, baseInit, init, argtypes, based);
    List<JCVariableDecl> params = make.Params(argtypes, init);
    List<JCStatement> stats = List.nil();
    if (c.type != syms.objectType) {
        stats = stats.prepend(SuperCall(make, typarams, params, based));
    }
    result = make.MethodDef(init, make.Block(0, stats));
    return result;
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)

Example 7 with Type

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

the class MemberEnter method signature.

/**
 * Construct method type from method signature.
 *  @param typarams    The method's type parameters.
 *  @param params      The method's value parameters.
 *  @param res             The method's result type,
 *                 null if it is a constructor.
 *  @param recvparam       The method's receiver parameter,
 *                 null if none given; TODO: or already set here?
 *  @param thrown      The method's thrown exceptions.
 *  @param env             The method's (local) environment.
 */
Type signature(MethodSymbol msym, List<JCTypeParameter> typarams, List<JCVariableDecl> params, JCTree res, JCVariableDecl recvparam, List<JCExpression> thrown, Env<AttrContext> env) {
    // Enter and attribute type parameters.
    List<Type> tvars = enter.classEnter(typarams, env);
    attr.attribTypeVariables(typarams, env);
    // Enter and attribute value parameters.
    ListBuffer<Type> argbuf = new ListBuffer<Type>();
    for (List<JCVariableDecl> l = params; l.nonEmpty(); l = l.tail) {
        memberEnter(l.head, env);
        argbuf.append(l.head.vartype.type);
    }
    // Attribute result type, if one is given.
    Type restype = res == null ? syms.voidType : attr.attribType(res, env);
    // Attribute receiver type, if one is given.
    Type recvtype;
    if (recvparam != null) {
        memberEnter(recvparam, env);
        recvtype = recvparam.vartype.type;
    } else {
        recvtype = null;
    }
    // Attribute thrown exceptions.
    ListBuffer<Type> thrownbuf = new ListBuffer<Type>();
    for (List<JCExpression> l = thrown; l.nonEmpty(); l = l.tail) {
        Type exc = attr.attribType(l.head, env);
        if (!exc.hasTag(TYPEVAR)) {
            exc = chk.checkClassType(l.head.pos(), exc);
        } else if (exc.tsym.owner == msym) {
            // mark inference variables in 'throws' clause
            exc.tsym.flags_field |= THROWS;
        }
        thrownbuf.append(exc);
    }
    MethodType mtype = new MethodType(argbuf.toList(), restype, thrownbuf.toList(), syms.methodClass);
    mtype.recvtype = recvtype;
    return tvars.isEmpty() ? mtype : new ForAll(tvars, mtype);
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type)

Example 8 with Type

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

the class MemberEnter method complete.

/* ********************************************************************
 * Source completer
 *********************************************************************/
/**
 * Complete entering a class.
 *  @param sym         The symbol of the class to be completed.
 */
public void complete(Symbol sym) throws CompletionFailure {
    // Suppress some (recursive) MemberEnter invocations
    if (!completionEnabled) {
        // Re-install same completer for next time around and return.
        Assert.check((sym.flags() & Flags.COMPOUND) == 0);
        sym.completer = this;
        return;
    }
    ClassSymbol c = (ClassSymbol) sym;
    ClassType ct = (ClassType) c.type;
    Env<AttrContext> env = typeEnvs.get(c);
    JCClassDecl tree = (JCClassDecl) env.tree;
    boolean wasFirst = isFirst;
    isFirst = false;
    try {
        annotate.enterStart();
        JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
        DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
        try {
            // Save class environment for later member enter (2) processing.
            halfcompleted.append(env);
            // Mark class as not yet attributed.
            c.flags_field |= UNATTRIBUTED;
            // clauses have been seen.
            if (c.owner.kind == PCK) {
                memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
                todo.append(env);
            }
            if (c.owner.kind == TYP)
                c.owner.complete();
            // create an environment for evaluating the base clauses
            Env<AttrContext> baseEnv = baseEnv(tree, env);
            if (tree.extending != null)
                typeAnnotate(tree.extending, baseEnv, sym, tree.pos());
            for (JCExpression impl : tree.implementing) typeAnnotate(impl, baseEnv, sym, tree.pos());
            annotate.flush();
            // Determine supertype.
            Type supertype = (tree.extending != null) ? attr.attribBase(tree.extending, baseEnv, true, false, true) : ((tree.mods.flags & Flags.ENUM) != 0) ? attr.attribBase(enumBase(tree.pos, c), baseEnv, true, false, false) : (c.fullname == names.java_lang_Object) ? Type.noType : syms.objectType;
            ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
            // Determine interfaces.
            ListBuffer<Type> interfaces = new ListBuffer<Type>();
            // lazy init
            ListBuffer<Type> all_interfaces = null;
            Set<Type> interfaceSet = new HashSet<Type>();
            List<JCExpression> interfaceTrees = tree.implementing;
            for (JCExpression iface : interfaceTrees) {
                Type i = attr.attribBase(iface, baseEnv, false, true, true);
                if (i.hasTag(CLASS)) {
                    interfaces.append(i);
                    if (all_interfaces != null)
                        all_interfaces.append(i);
                    chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
                } else {
                    if (all_interfaces == null)
                        all_interfaces = new ListBuffer<Type>().appendList(interfaces);
                    all_interfaces.append(modelMissingTypes(i, iface, true));
                }
            }
            if ((c.flags_field & Flags.ANNOTATION) != 0) {
                ct.interfaces_field = List.of(syms.annotationType);
                ct.all_interfaces_field = ct.interfaces_field;
            } else {
                ct.interfaces_field = interfaces.toList();
                ct.all_interfaces_field = (all_interfaces == null) ? ct.interfaces_field : all_interfaces.toList();
            }
            if (c.fullname == names.java_lang_Object) {
                if (tree.extending != null) {
                    chk.checkNonCyclic(tree.extending.pos(), supertype);
                    ct.supertype_field = Type.noType;
                } else if (tree.implementing.nonEmpty()) {
                    chk.checkNonCyclic(tree.implementing.head.pos(), ct.interfaces_field.head);
                    ct.interfaces_field = List.nil();
                }
            }
            // Annotations.
            // In general, we cannot fully process annotations yet,  but we
            // can attribute the annotation types and then check to see if the
            // @Deprecated annotation is present.
            attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
            if (hasDeprecatedAnnotation(tree.mods.annotations))
                c.flags_field |= DEPRECATED;
            annotateLater(tree.mods.annotations, baseEnv, c, tree.pos());
            // class type parameters use baseEnv but everything uses env
            chk.checkNonCyclicDecl(tree);
            attr.attribTypeVariables(tree.typarams, baseEnv);
            // Do this here, where we have the symbol.
            for (JCTypeParameter tp : tree.typarams) typeAnnotate(tp, baseEnv, sym, tree.pos());
            // Add default constructor if needed.
            if ((c.flags() & INTERFACE) == 0 && !TreeInfo.hasConstructors(tree.defs)) {
                List<Type> argtypes = List.nil();
                List<Type> typarams = List.nil();
                List<Type> thrown = List.nil();
                long ctorFlags = 0;
                boolean based = false;
                boolean addConstructor = true;
                JCNewClass nc = null;
                if (c.name.isEmpty()) {
                    nc = (JCNewClass) env.next.tree;
                    if (nc.constructor != null) {
                        addConstructor = nc.constructor.kind != ERR;
                        Type superConstrType = types.memberType(c.type, nc.constructor);
                        argtypes = superConstrType.getParameterTypes();
                        typarams = superConstrType.getTypeArguments();
                        ctorFlags = nc.constructor.flags() & VARARGS;
                        if (nc.encl != null) {
                            argtypes = argtypes.prepend(nc.encl.type);
                            based = true;
                        }
                        thrown = superConstrType.getThrownTypes();
                    }
                }
                if (addConstructor) {
                    MethodSymbol basedConstructor = nc != null ? (MethodSymbol) nc.constructor : null;
                    JCTree constrDef = DefaultConstructor(make.at(tree.pos), c, basedConstructor, typarams, argtypes, thrown, ctorFlags, based);
                    tree.defs = tree.defs.prepend(constrDef);
                }
            }
            // enter symbols for 'this' into current scope.
            VarSymbol thisSym = new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
            thisSym.pos = Position.FIRSTPOS;
            env.info.scope.enter(thisSym);
            // if this is a class, enter symbol for 'super' into current scope.
            if ((c.flags_field & INTERFACE) == 0 && ct.supertype_field.hasTag(CLASS)) {
                VarSymbol superSym = new VarSymbol(FINAL | HASINIT, names._super, ct.supertype_field, c);
                superSym.pos = Position.FIRSTPOS;
                env.info.scope.enter(superSym);
            }
            // name as a top-level package.
            if (checkClash && c.owner.kind == PCK && c.owner != syms.unnamedPackage && reader.packageExists(c.fullname)) {
                log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
            }
            if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 && !env.toplevel.sourcefile.isNameCompatible(c.name.toString(), JavaFileObject.Kind.SOURCE)) {
                c.flags_field |= AUXILIARY;
            }
        } catch (CompletionFailure ex) {
            chk.completionError(tree.pos(), ex);
        } finally {
            deferredLintHandler.setPos(prevLintPos);
            log.useSource(prev);
        }
        // classes in a second phase.
        if (wasFirst) {
            try {
                while (halfcompleted.nonEmpty()) {
                    Env<AttrContext> toFinish = halfcompleted.next();
                    finish(toFinish);
                    if (allowTypeAnnos) {
                        typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
                        typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl) toFinish.tree);
                    }
                }
            } finally {
                isFirst = true;
            }
        }
    } finally {
        annotate.enterDone();
    }
}
Also used : JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JavaFileObject(org.eclipse.ceylon.javax.tools.JavaFileObject) Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DiagnosticPosition(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticPosition) HashSet(java.util.HashSet)

Example 9 with Type

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

the class MemberEnter method importStaticAll.

/**
 * Import all static members of a class or package on demand.
 *  @param pos           Position to be used for error reporting.
 *  @param tsym          The class or package the members of which are imported.
 *  @param env           The env in which the imported classes will be entered.
 */
private void importStaticAll(int pos, final TypeSymbol tsym, Env<AttrContext> env) {
    final JavaFileObject sourcefile = env.toplevel.sourcefile;
    final Scope toScope = env.toplevel.starImportScope;
    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);
            final Scope fromScope = tsym.members();
            for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
                Symbol sym = e.sym;
                if (sym.kind == TYP && (sym.flags() & STATIC) != 0 && staticImportAccessible(sym, packge) && sym.isMemberOf(origin, types) && !toScope.includes(sym))
                    toScope.enter(sym, fromScope, 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>();

        public String toString() {
            return "import static " + tsym + ".*" + " in " + sourcefile;
        }

        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);
            final Scope fromScope = tsym.members();
            for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
                Symbol sym = e.sym;
                if (sym.isStatic() && sym.kind != TYP && staticImportAccessible(sym, packge) && !toScope.includes(sym) && sym.isMemberOf(origin, types)) {
                    toScope.enter(sym, fromScope, origin.members(), true);
                }
            }
        }

        public void run() {
            importFrom(tsym);
        }
    });
}
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)

Example 10 with Type

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

the class Resolve method mostSpecificReturnType.

// where
Type mostSpecificReturnType(Type mt1, Type mt2) {
    Type rt1 = mt1.getReturnType();
    Type rt2 = mt2.getReturnType();
    if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
        // if both are generic methods, adjust return type ahead of subtyping check
        rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
    }
    // first use subtyping, then return type substitutability
    if (types.isSubtype(rt1, rt2)) {
        return mt1;
    } else if (types.isSubtype(rt2, rt1)) {
        return mt2;
    } else if (types.returnTypeSubstitutable(mt1, mt2)) {
        return mt1;
    } else if (types.returnTypeSubstitutable(mt2, mt1)) {
        return mt2;
    } else {
        return null;
    }
}
Also used : Type(org.eclipse.ceylon.langtools.tools.javac.code.Type) DeferredType(org.eclipse.ceylon.langtools.tools.javac.comp.DeferredAttr.DeferredType) DiagnosticType(org.eclipse.ceylon.langtools.tools.javac.util.JCDiagnostic.DiagnosticType)

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