Search in sources :

Example 66 with Constructor

use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.

the class TypeUtils method resolveTypeParameter.

/**
 * Finds the owner of the type parameter and outputs a reference to the corresponding type argument.
 */
static void resolveTypeParameter(final Node node, final TypeParameter tp, final GenerateJsVisitor gen, final boolean skipSelfDecl) {
    Scope parent = ModelUtil.getRealScope(node.getScope());
    int outers = 0;
    while (parent != null && parent != tp.getContainer()) {
        if (parent instanceof TypeDeclaration && !(parent instanceof Constructor || ((TypeDeclaration) parent).isAnonymous())) {
            outers++;
        }
        parent = parent.getScope();
    }
    if (tp.getContainer() instanceof ClassOrInterface) {
        if (parent == tp.getContainer()) {
            if (!skipSelfDecl) {
                TypeDeclaration ontoy = ModelUtil.getContainingClassOrInterface(node.getScope());
                while (ontoy.isAnonymous()) ontoy = ModelUtil.getContainingClassOrInterface(ontoy.getScope());
                gen.out(gen.getNames().self(ontoy));
                if (ontoy == parent)
                    outers--;
                for (int i = 0; i < outers; i++) {
                    gen.out(".outer$");
                }
                gen.out(".");
            }
            gen.out("$$targs$$.", gen.getNames().typeParameterName(tp));
        } else {
            // This can happen in expressions such as Singleton(n) when n is dynamic
            gen.out("{/*NO PARENT*/t:", gen.getClAlias(), "Anything}");
        }
    } else if (tp.getContainer() instanceof TypeAlias) {
        if (parent == tp.getContainer()) {
            gen.out("'", gen.getNames().typeParameterName(tp), "'");
        } else {
            // This can happen in expressions such as Singleton(n) when n is dynamic
            gen.out("{/*NO PARENT ALIAS*/t:", gen.getClAlias(), "Anything}");
        }
    } else {
        // it has to be a method, right?
        // We need to find the index of the parameter where the argument occurs
        // ...and it could be null...
        Type type = null;
        for (Iterator<ParameterList> iter0 = ((Function) tp.getContainer()).getParameterLists().iterator(); type == null && iter0.hasNext(); ) {
            for (Iterator<Parameter> iter1 = iter0.next().getParameters().iterator(); iter1.hasNext(); ) {
                type = typeContainsTypeParameter(iter1.next().getType(), tp);
            }
        }
        // A type argument of the argument's type, in which case we must get the reified generic from the argument
        if (tp.getContainer() == parent) {
            gen.out(gen.getNames().typeArgsParamName((Function) tp.getContainer()), ".", gen.getNames().typeParameterName(tp));
        } else {
            if (parent == null && node instanceof Tree.StaticMemberOrTypeExpression) {
                if (tp.getContainer() == ((Tree.StaticMemberOrTypeExpression) node).getDeclaration()) {
                    type = ((Tree.StaticMemberOrTypeExpression) node).getTarget().getTypeArguments().get(tp);
                    typeNameOrList(node, type, gen, skipSelfDecl);
                    return;
                }
            }
            gen.out("'", gen.getNames().typeParameterName(tp), "'");
        // gen.out.spitOut("Passing reference to " + tp.getQualifiedNameString() + " as a string...");
        // gen.out("/*Please report this to the ceylon-js team: METHOD TYPEPARM plist ",
        // Integer.toString(plistCount), "#", tp.getName(), "*/'", type.getProducedTypeQualifiedName(),
        // "' container " + tp.getContainer() + " at " + node);
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Iterator(java.util.Iterator) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 67 with Constructor

use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.

the class Singletons method defineObject.

/**
 * Generate an object definition, that is, define an anonymous class and then a function
 * to return a single instance of it.
 * @param that The node with the definition (can be ObjectDefinition, ObjectExpression, ObjectArgument)
 * @param d The Value declaration for the object
 * @param sats The list of satisfied types of the anonymous class
 * @param superType The supertype of the anonymous class
 * @param superCall The invocation of the supertype (object bla extends Foo(x))
 * @param body The object definition's body
 * @param annots The annotations (in case of ObjectDefinition)
 * @param gen The main visitor/generator.
 */
static void defineObject(final Node that, final Value d, final List<Type> sats, final Tree.SimpleType superType, final Tree.InvocationExpression superCall, final Tree.Body body, final Tree.AnnotationList annots, final GenerateJsVisitor gen, InitDeferrer initDeferrer) {
    final boolean addToPrototype = gen.opts.isOptimize() && d != null && d.isClassOrInterfaceMember();
    final boolean isObjExpr = that instanceof Tree.ObjectExpression;
    final TypeDeclaration _td = isObjExpr ? ((Tree.ObjectExpression) that).getAnonymousClass() : d.getTypeDeclaration();
    final Class c = (Class) (_td instanceof Constructor ? _td.getContainer() : _td);
    final String className = gen.getNames().name(c);
    final String objectName = gen.getNames().name(d);
    final String selfName = gen.getNames().self(c);
    final Value natd = d == null ? null : (Value) ModelUtil.getNativeDeclaration(d, Backend.JavaScript);
    if (that instanceof Tree.Declaration) {
        if (NativeUtil.isNativeHeader((Tree.Declaration) that) && natd != null) {
            // It's a native header, remember it for later when we deal with its implementation
            gen.saveNativeHeader((Tree.Declaration) that);
            return;
        }
        if (!(NativeUtil.isForBackend((Tree.Declaration) that, Backend.JavaScript) || NativeUtil.isHeaderWithoutBackend((Tree.Declaration) that, Backend.JavaScript))) {
            return;
        }
    }
    final List<Tree.Statement> stmts;
    if (d != null && NativeUtil.isForBackend(d, Backend.JavaScript)) {
        Tree.Declaration nh = gen.getNativeHeader(d);
        if (nh == null && NativeUtil.hasNativeMembers(c) && that instanceof Tree.Declaration) {
            nh = (Tree.Declaration) that;
        }
        stmts = NativeUtil.mergeStatements(body, nh, Backend.JavaScript);
    } else {
        stmts = body.getStatements();
    }
    Map<TypeParameter, Type> targs = new HashMap<>();
    if (sats != null) {
        for (Type st : sats) {
            Map<TypeParameter, Type> stargs = st.getTypeArguments();
            if (stargs != null && !stargs.isEmpty()) {
                targs.putAll(stargs);
            }
        }
    }
    gen.out(GenerateJsVisitor.function, className, targs.isEmpty() ? "()" : "($$targs$$)");
    gen.beginBlock();
    if (isObjExpr) {
        gen.out("var ", selfName, "=new ", className, ".$$;");
        final ClassOrInterface coi = ModelUtil.getContainingClassOrInterface(c.getContainer());
        if (coi != null) {
            gen.out(selfName, ".outer$=", gen.getNames().self(coi));
            gen.endLine(true);
        }
    } else {
        if (c.isMember() && !d.isStatic()) {
            gen.initSelf(that);
        }
        gen.instantiateSelf(c);
        gen.referenceOuter(c);
    }
    // TODO should we generate all this code for native headers?
    // Really we should merge the body of the header with that of the impl
    // It's the only way to make this shit work in lexical scope mode
    final List<Declaration> superDecs = new ArrayList<>();
    if (!gen.opts.isOptimize()) {
        final SuperVisitor superv = new SuperVisitor(superDecs);
        for (Tree.Statement st : stmts) {
            st.visit(superv);
        }
    }
    if (!targs.isEmpty()) {
        gen.out(selfName, ".$$targs$$=$$targs$$");
        gen.endLine(true);
    }
    TypeGenerator.callSupertypes(sats, superType, c, that, superDecs, superCall, superType == null ? null : ((Class) c.getExtendedType().getDeclaration()).getParameterList(), gen);
    gen.visitStatements(stmts);
    gen.out("return ", selfName, ";");
    gen.endBlock();
    gen.out(";", className, ".$crtmm$=");
    TypeUtils.encodeForRuntime(that, c, gen);
    gen.endLine(true);
    TypeGenerator.initializeType(that, gen, initDeferrer);
    final String objvar = (addToPrototype ? "this." : "") + gen.getNames().createTempVariable();
    if (d != null && !addToPrototype) {
        gen.out("var ", objvar);
        // If it's a property, create the object here
        if (AttributeGenerator.defineAsProperty(d)) {
            gen.out("=", className, "(");
            if (!targs.isEmpty()) {
                TypeUtils.printTypeArguments(that, targs, gen, false, null);
            }
            gen.out(")");
        }
        gen.endLine(true);
    }
    if (d != null && AttributeGenerator.defineAsProperty(d)) {
        gen.out(gen.getClAlias(), "atr$(");
        gen.outerSelf(d);
        gen.out(",'", objectName, "',function(){return ");
        if (addToPrototype) {
            gen.out("this.", gen.getNames().privateName(d));
        } else {
            gen.out(objvar);
        }
        gen.out(";},undefined,");
        TypeUtils.encodeForRuntime(that, d, annots, gen);
        gen.out(")");
        gen.endLine(true);
    } else if (d != null) {
        final String objectGetterName = gen.getNames().getter(d, false);
        gen.out(GenerateJsVisitor.function, objectGetterName, "()");
        gen.beginBlock();
        // Create the object lazily
        final String oname = gen.getNames().objectName(c);
        gen.out("if(", objvar, "===", gen.getClAlias(), "INIT$)");
        gen.generateThrow(gen.getClAlias() + "InitializationError", "Cyclic initialization trying to read the value of '" + d.getName() + "' before it was set", that);
        gen.endLine(true);
        gen.out("if(", objvar, "===undefined){", objvar, "=", gen.getClAlias(), "INIT$;", objvar, "=$init$", oname);
        if (!oname.endsWith("()")) {
            gen.out("()");
        }
        gen.out("(");
        if (!targs.isEmpty()) {
            TypeUtils.printTypeArguments(that, targs, gen, false, null);
        }
        gen.out(");", objvar, ".$crtmm$=", objectGetterName, ".$crtmm$;}");
        gen.endLine();
        gen.out("return ", objvar, ";");
        gen.endBlockNewLine();
        if (addToPrototype || d.isShared()) {
            gen.outerSelf(d);
            gen.out(".", objectGetterName, "=", objectGetterName);
            gen.endLine(true);
        }
        if (!d.isToplevel()) {
            if (gen.outerSelf(d))
                gen.out(".");
        }
        gen.out(objectGetterName, ".$crtmm$=");
        TypeUtils.encodeForRuntime(that, d, annots, gen);
        gen.endLine(true);
        gen.out(gen.getNames().getter(c, true), "=", objectGetterName);
        gen.endLine(true);
        if (d.isToplevel()) {
            final String objectGetterNameMM = gen.getNames().getter(d, true);
            gen.out("ex$.", objectGetterNameMM, "=", objectGetterNameMM);
            gen.endLine(true);
        }
    } else if (isObjExpr) {
        gen.out("return ", className, "();");
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) SuperVisitor(org.eclipse.ceylon.compiler.js.GenerateJsVisitor.SuperVisitor) HashMap(java.util.HashMap) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 68 with Constructor

use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.

the class TypeGenerator method typeFunctionName.

/**
 * Returns the name of the type or its $init$ function if it's local.
 */
static String typeFunctionName(final Tree.StaticType type, final ClassOrInterface coi, final GenerateJsVisitor gen) {
    TypeDeclaration d = type.getTypeModel().getDeclaration();
    final boolean removeAlias = d == null || !d.isClassOrInterfaceMember() || d instanceof Interface;
    if ((removeAlias && d.isAlias()) || d instanceof Constructor) {
        Type extendedType = d.getExtendedType();
        d = extendedType == null ? null : extendedType.getDeclaration();
    }
    Declaration cont = ModelUtil.getContainingDeclaration(d);
    final boolean inProto = gen.opts.isOptimize() && cont instanceof TypeDeclaration;
    final boolean imported = gen.isImported(type.getUnit().getPackage(), d);
    String dname = gen.getNames().name(d);
    if (d.isAlias()) {
        TypeDeclaration d2 = d;
        while (d2.isAlias()) {
            d2 = d2.getExtendedType().getDeclaration();
        }
        dname = gen.getNames().name(d2);
    }
    final String initName = "$init$" + dname + "()";
    if (!imported && !d.isClassOrInterfaceMember()) {
        return initName;
    }
    if (inProto && coi.isMember() && !d.isAlias() && (coi.getContainer() == cont || ModelUtil.contains(d, coi))) {
        // use its $init$ function
        return initName;
    }
    String tfn;
    // #628 If coi is anonymous and inside cont, qualify the path from cont instead
    if (coi != null && coi.isAnonymous() && cont instanceof Scope && ModelUtil.contains((Scope) cont, coi)) {
        tfn = gen.qualifiedPath(type, cont, inProto);
    } else if (inProto && d.isClassOrInterfaceMember()) {
        return pathToType(type, d, gen);
    } else {
        tfn = gen.qualifiedPath(type, d, inProto);
    }
    tfn = gen.memberAccessBase(type, d, false, tfn);
    if (removeAlias && !imported) {
        int idx = tfn.lastIndexOf('.');
        if (idx > 0) {
            tfn = tfn.substring(0, idx + 1) + initName;
        } else {
            tfn = initName;
        }
    }
    return tfn;
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) StaticType(org.eclipse.ceylon.compiler.typechecker.tree.Tree.StaticType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Example 69 with Constructor

use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.

the class JsonPackage method getTypeFromJson.

/**
 * Looks up a type from model data, creating it if necessary. The returned type will have its
 * type parameters substituted if needed.
 */
private Type getTypeFromJson(Map<String, Object> m, Declaration container, List<TypeParameter> typeParams) {
    TypeDeclaration td = null;
    if (m.get(KEY_METATYPE) instanceof TypeDeclaration) {
        td = (TypeDeclaration) m.get(KEY_METATYPE);
        if (td instanceof ClassOrInterface && td.getUnit().getPackage() instanceof JsonPackage) {
            ((JsonPackage) td.getUnit().getPackage()).load(td.getName(), typeParams);
        }
    }
    final String tname = (String) m.get(KEY_NAME);
    if ("$U".equals(tname)) {
        m.put(KEY_METATYPE, unknown);
        return unknown.getType();
    }
    if (td == null && m.containsKey("comp")) {
        @SuppressWarnings("unchecked") final List<Map<String, Object>> tmaps = (List<Map<String, Object>>) m.get(KEY_TYPES);
        final ArrayList<Type> types = new ArrayList<>(tmaps.size());
        if ("u".equals(m.get("comp"))) {
            UnionType ut = new UnionType(u2);
            for (Map<String, Object> tmap : tmaps) {
                types.add(getTypeFromJson(tmap, container, typeParams));
            }
            ut.setCaseTypes(types);
            td = ut;
        } else if ("i".equals(m.get("comp"))) {
            IntersectionType it = new IntersectionType(u2);
            for (Map<String, Object> tmap : tmaps) {
                types.add(getTypeFromJson(tmap, container, typeParams));
            }
            it.setSatisfiedTypes(types);
            td = it;
        } else {
            throw new IllegalArgumentException("Invalid composite type '" + m.get("comp") + "'");
        }
    } else if (td == null) {
        final String pname = (String) m.get(KEY_PACKAGE);
        if (pname == null) {
            // It's a ref to a type parameter
            final List<TypeParameter> containerTypeParameters;
            if (container instanceof Constructor) {
                containerTypeParameters = ((Generic) container.getContainer()).getTypeParameters();
            } else if (container instanceof Generic) {
                containerTypeParameters = container.getTypeParameters();
            } else {
                containerTypeParameters = null;
            }
            if (containerTypeParameters != null) {
                for (TypeParameter typeParam : containerTypeParameters) {
                    if (typeParam.getName().equals(tname)) {
                        td = typeParam;
                    }
                }
            }
            if (td == null && typeParams != null) {
                for (TypeParameter typeParam : typeParams) {
                    if (typeParam.getName().equals(tname)) {
                        td = typeParam;
                    }
                }
            }
        } else {
            String mname = (String) m.get(KEY_MODULE);
            if ("$".equals(mname)) {
                mname = LANGUAGE_MODULE_NAME;
            }
            org.eclipse.ceylon.model.typechecker.model.Package rp;
            if ("$".equals(pname) || LANGUAGE_MODULE_NAME.equals(pname)) {
                // Language module package
                rp = isLanguagePackage() ? this : getModule().getLanguageModule().getDirectPackage(LANGUAGE_MODULE_NAME);
            } else if (mname == null) {
                // local type
                if (".".equals(pname)) {
                    rp = this;
                    if (container instanceof TypeDeclaration && tname.equals(container.getName())) {
                        td = (TypeDeclaration) container;
                    }
                } else {
                    rp = getModule().getDirectPackage(pname);
                }
            } else {
                rp = getModule().getPackage(pname);
            }
            if (rp == null) {
                throw new CompilerErrorException("Package not found: " + pname);
            }
            if (rp != this && rp instanceof JsonPackage && !((JsonPackage) rp).loaded) {
                ((JsonPackage) rp).loadIfNecessary();
            }
            final boolean nested = tname.indexOf('.') > 0;
            final String level1 = nested ? tname.substring(0, tname.indexOf('.')) : tname;
            if (rp != null && !nested) {
                Declaration d = rp.getDirectMember(tname, null, false);
                if (d instanceof TypeDeclaration) {
                    td = (TypeDeclaration) d;
                    if (td.isTuple()) {
                        if (m.containsKey(KEY_TYPES)) {
                            @SuppressWarnings("unchecked") List<Map<String, Object>> elemaps = (List<Map<String, Object>>) m.get(KEY_TYPES);
                            ArrayList<Type> elems = new ArrayList<>(elemaps.size());
                            for (Map<String, Object> elem : elemaps) {
                                elems.add(getTypeFromJson(elem, container, typeParams));
                            }
                            Type tail = elems.get(elems.size() - 1);
                            if ((tail.isSequence() || tail.isSequential()) && !tail.isTuple() && !tail.isEmpty()) {
                                elems.remove(elems.size() - 1);
                            } else {
                                tail = null;
                            }
                            return u2.getTupleType(elems, tail, -1);
                        } else if (m.containsKey("count")) {
                            @SuppressWarnings("unchecked") Map<String, Object> elem = (Map<String, Object>) m.get(KEY_TYPE);
                            Type[] elems = new Type[(int) m.remove("count")];
                            Arrays.fill(elems, getTypeFromJson(elem, container, typeParams));
                            return u2.getTupleType(Arrays.asList(elems), null, -1);
                        }
                    }
                } else if (d instanceof FunctionOrValue) {
                    td = ((FunctionOrValue) d).getTypeDeclaration();
                }
            }
            if (td == null && rp instanceof JsonPackage) {
                if (nested) {
                    td = ((JsonPackage) rp).loadNestedType(tname, typeParams);
                } else {
                    td = (TypeDeclaration) ((JsonPackage) rp).load(tname, typeParams);
                }
            }
            // Then look in the top-level declarations
            if (nested && td == null) {
                for (Declaration d : rp.getMembers()) {
                    if (d instanceof TypeDeclaration && level1.equals(d.getName())) {
                        td = (TypeDeclaration) d;
                    }
                }
                final String[] path = tname.split("\\.");
                for (int i = 1; i < path.length; i++) {
                    td = (TypeDeclaration) td.getDirectMember(path[i], null, false);
                }
            }
        }
    }
    // From 1.2.3 we stored type arguments in maps
    final Type newType = loadTypeArguments(m, td, container, typeParams);
    if (newType != null) {
        return newType;
    }
    // This is the old pre 1.2.3 stuff
    @SuppressWarnings("unchecked") final List<Map<String, Object>> modelParms = (List<Map<String, Object>>) m.get(KEY_TYPE_PARAMS);
    if (td != null && modelParms != null) {
        // Substitute type parameters
        final HashMap<TypeParameter, Type> concretes = new HashMap<>();
        HashMap<TypeParameter, SiteVariance> variances = null;
        if (td.getTypeParameters().size() < modelParms.size()) {
            if (td.getUnit().getPackage() == this) {
                parseTypeParameters(modelParms, td, null);
            }
        }
        final Iterator<TypeParameter> viter = td.getTypeParameters().iterator();
        for (Map<String, Object> ptparm : modelParms) {
            TypeParameter _cparm = viter.next();
            if (ptparm.containsKey(KEY_PACKAGE) || ptparm.containsKey(KEY_TYPES)) {
                // Substitute for proper type
                final Type _pt = getTypeFromJson(ptparm, container, typeParams);
                concretes.put(_cparm, _pt);
            } else if (ptparm.containsKey(KEY_NAME) && typeParams != null) {
                // Look for type parameter with same name
                for (TypeParameter typeParam : typeParams) {
                    if (typeParam.getName().equals(ptparm.get(KEY_NAME))) {
                        concretes.put(_cparm, typeParam.getType());
                    }
                }
            }
            Integer usv = (Integer) ptparm.get(KEY_US_VARIANCE);
            if (usv != null) {
                if (variances == null) {
                    variances = new HashMap<>();
                }
                variances.put(_cparm, SiteVariance.values()[usv]);
            }
        }
        if (!concretes.isEmpty()) {
            return td.getType().substitute(concretes, variances);
        }
    }
    if (td == null) {
        try {
            throw new IllegalArgumentException(String.format("Couldn't find type %s::%s for %s in %s<%s> (FROM pkg %s)", m.get(KEY_PACKAGE), m.get(KEY_NAME), m.get(KEY_MODULE), m, typeParams, getNameAsString()));
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        }
    }
    return td.getType();
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) HashMap(java.util.HashMap) Generic(org.eclipse.ceylon.model.typechecker.model.Generic) ArrayList(java.util.ArrayList) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) CompilerErrorException(org.eclipse.ceylon.compiler.js.CompilerErrorException) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Map(java.util.Map) HashMap(java.util.HashMap) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 70 with Constructor

use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.

the class MetamodelGenerator method encodeAnnotations.

/**
 * Encodes all annotations as a map which is then stored under the
 * {@link #KEY_ANNOTATIONS} key in the specified map.
 * If the map is null, only the bitset annotations are calculated and returned.
 * @return The bitmask for the bitset annotations.
 */
public static int encodeAnnotations(List<Annotation> annotations, Object d, Map<String, Object> m) {
    List<Map<String, List<String>>> anns = m == null ? null : new ArrayList<Map<String, List<String>>>(annotations.size());
    int bits = 0;
    for (Annotation a : annotations) {
        String name = a.getName();
        int idx = "native".equals(name) ? -1 : annotationBits.indexOf(name);
        if (idx >= 0) {
            bits |= (1 << idx);
        } else if (anns != null) {
            List<String> args = a.getPositionalArguments();
            if (args == null) {
                args = Collections.emptyList();
            }
            anns.add(Collections.singletonMap(name, args));
        }
    }
    if (d instanceof Value && ((Value) d).isVariable()) {
        // Sometimes the value is not annotated, it only has a defined Setter
        bits |= (1 << annotationBits.indexOf("variable"));
    } else if (d instanceof org.eclipse.ceylon.model.typechecker.model.Class && ((org.eclipse.ceylon.model.typechecker.model.Class) d).isAbstract()) {
        bits |= (1 << annotationBits.indexOf("abstract"));
    } else if (d instanceof Constructor && ((Constructor) d).isAbstract()) {
        bits |= (1 << annotationBits.indexOf("abstract"));
    }
    if (bits > 0 && m != null) {
        String key = d instanceof Module ? "$mod-pa" : d instanceof org.eclipse.ceylon.model.typechecker.model.Package ? "$pkg-pa" : KEY_PACKED_ANNS;
        m.put(key, bits);
    }
    if (anns != null && m != null && !anns.isEmpty()) {
        String key = d instanceof Module ? "$mod-anns" : d instanceof org.eclipse.ceylon.model.typechecker.model.Package ? "$pkg-anns" : KEY_ANNOTATIONS;
        m.put(key, anns);
    }
    return bits;
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) List(java.util.List) Module(org.eclipse.ceylon.model.typechecker.model.Module) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)95 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Type (org.eclipse.ceylon.model.typechecker.model.Type)45 Class (org.eclipse.ceylon.model.typechecker.model.Class)42 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)42 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)27 Value (org.eclipse.ceylon.model.typechecker.model.Value)27 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)25 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 ModelUtil.isConstructor (org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor)21 ArrayList (java.util.ArrayList)20 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)19 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)17 AnalyzerUtil.unwrapAliasedTypeConstructor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor)16 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)14 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)14