Search in sources :

Example 66 with TypeDeclaration

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

the class JsonPackage method loadObject.

/**
 * Loads an object declaration, creating it if necessary, and returns its type declaration.
 */
@SuppressWarnings("unchecked")
TypeDeclaration loadObject(String name, Map<String, Object> m, Scope parent, List<TypeParameter> existing) {
    Value obj;
    if (m.get(KEY_METATYPE) instanceof Value) {
        obj = (Value) m.get(KEY_METATYPE);
    } else {
        obj = new Value();
        m.put(KEY_METATYPE, obj);
        obj.setName(name);
        obj.setContainer(parent);
        obj.setScope(parent);
        obj.setUnit(u2);
        org.eclipse.ceylon.model.typechecker.model.Class type = new org.eclipse.ceylon.model.typechecker.model.Class();
        type.setName(name);
        type.setAnonymous(true);
        type.setUnit(u2);
        type.setContainer(parent);
        type.setScope(parent);
        if (parent == this) {
            u2.addDeclaration(obj);
            u2.addDeclaration(type);
        }
        parent.addMember(obj);
        obj.setType(type.getType());
        setAnnotations(obj, (Integer) m.get(KEY_PACKED_ANNS), m.get(KEY_ANNOTATIONS));
        setAnnotations(obj.getTypeDeclaration(), (Integer) m.remove(KEY_PACKED_ANNS), m.remove(KEY_ANNOTATIONS));
        if (type.getExtendedType() == null) {
            if (m.containsKey("super")) {
                type.setExtendedType(getTypeFromJson((Map<String, Object>) m.remove("super"), parent instanceof Declaration ? (Declaration) parent : null, existing));
            } else {
                type.setExtendedType(getTypeFromJson(idobj, parent instanceof Declaration ? (Declaration) parent : null, existing));
            }
        }
        if (m.containsKey(KEY_SATISFIES)) {
            List<Map<String, Object>> stypes = (List<Map<String, Object>>) m.remove(KEY_SATISFIES);
            type.setSatisfiedTypes(parseTypeList(stypes, existing));
        }
        if (m.containsKey(KEY_INTERFACES)) {
            for (Map.Entry<String, Map<String, Object>> inner : ((Map<String, Map<String, Object>>) m.remove(KEY_INTERFACES)).entrySet()) {
                loadInterface(inner.getKey(), inner.getValue(), type, existing);
            }
        }
        if (m.containsKey(KEY_CLASSES)) {
            for (Map.Entry<String, Map<String, Object>> inner : ((Map<String, Map<String, Object>>) m.remove(KEY_CLASSES)).entrySet()) {
                loadClass(inner.getKey(), inner.getValue(), type, existing);
            }
        }
        if (m.containsKey(KEY_OBJECTS)) {
            for (Map.Entry<String, Map<String, Object>> inner : ((Map<String, Map<String, Object>>) m.remove(KEY_OBJECTS)).entrySet()) {
                loadObject(inner.getKey(), inner.getValue(), type, existing);
            }
        }
        addAttributesAndMethods(m, type, existing);
    }
    return obj.getTypeDeclaration();
}
Also used : Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) 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) Map(java.util.Map) HashMap(java.util.HashMap)

Example 67 with TypeDeclaration

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

the class JsonPackage method loadNestedType.

/**
 * Load a nested type that hasn't been loaded yet
 */
private TypeDeclaration loadNestedType(final String fqn, List<TypeParameter> typeParams) {
    try {
        String[] path = fqn.split("\\.");
        @SuppressWarnings("unchecked") Map<String, Object> typeMap = (Map<String, Object>) model.get(path[0]);
        if (typeMap.get(KEY_METATYPE) instanceof TypeDeclaration == false) {
            load(path[0], typeParams);
        }
        TypeDeclaration td = (TypeDeclaration) typeMap.get(KEY_METATYPE);
        for (int i = 1; i < path.length; i++) {
            @SuppressWarnings("unchecked") Map<String, Object> subtypes = (Map<String, Object>) typeMap.get(KEY_INTERFACES);
            Map<String, Object> childMap = null;
            int type = 0;
            if (subtypes != null) {
                childMap = (Map<String, Object>) subtypes.get(path[i]);
                type = 1;
            }
            if (childMap == null) {
                subtypes = (Map<String, Object>) typeMap.get(KEY_CLASSES);
                if (subtypes != null) {
                    childMap = (Map<String, Object>) subtypes.get(path[i]);
                    type = 2;
                }
            }
            Declaration member = td.getDirectMember(path[i], null, false);
            TypeDeclaration child;
            if (member instanceof Value && ((Value) member).getTypeDeclaration() instanceof Constructor)
                child = ((Value) member).getTypeDeclaration().getExtendedType().getDeclaration();
            else
                child = (TypeDeclaration) member;
            if (child == null) {
                switch(type) {
                    case 1:
                        child = loadInterface(path[i], childMap, td, typeParams);
                        break;
                    case 2:
                        child = loadClass(path[i], childMap, td, typeParams);
                        break;
                }
            }
            td = child;
        }
        return td;
    } catch (RuntimeException x) {
        throw new RuntimeException("Failed to load inner type " + fqn + " in package " + getQualifiedNameString(), x);
    }
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Map(java.util.Map) HashMap(java.util.HashMap) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 68 with TypeDeclaration

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

the class MetamodelGenerator method encodeClass.

@SuppressWarnings("unchecked")
public Map<String, Object> encodeClass(org.eclipse.ceylon.model.typechecker.model.Class d) {
    final Map<String, Object> m = new HashMap<>();
    m.put(KEY_METATYPE, METATYPE_CLASS);
    m.put(KEY_NAME, TypeUtils.modelName(d));
    // Type parameters
    List<Map<String, Object>> tpl = typeParameters(d.getTypeParameters(), d);
    if (tpl != null) {
        m.put(KEY_TYPE_PARAMS, tpl);
    }
    // self type
    if (d.getSelfType() != null) {
        m.put(KEY_SELF_TYPE, d.getSelfType().getDeclaration().getName());
    }
    // Extends
    if (d.getExtendedType() != null) {
        m.put("super", typeMap(d.getExtendedType(), d));
    }
    // Satisfies
    encodeTypes(d.getSatisfiedTypes(), m, KEY_SATISFIES, d);
    // Initializer parameters
    final List<Map<String, Object>> inits = parameterListMap(d.getParameterList(), d);
    if (inits != null && !inits.isEmpty()) {
        m.put(KEY_PARAMS, inits);
    }
    // Case types
    encodeTypes(d.getCaseTypes(), m, "of", d);
    // Annotations
    encodeAnnotations(d.getAnnotations(), d, m);
    if (d.isAnonymous()) {
        m.put("$anon", 1);
    }
    if (d.isAlias()) {
        m.put("$alias", 1);
        TypeDeclaration constructor = ((ClassAlias) d).getConstructor();
        if (constructor instanceof Constructor) {
            m.put(KEY_CONSTRUCTOR, ((Constructor) constructor).getName());
        }
    // else, it's the default "constructor", and will be the (Class) d.getExtendedType().getDeclaration()
    }
    Map<String, Object> parent = findParent(d);
    if (parent != null) {
        if (parent != getPackageMap(d.getUnit().getPackage())) {
            if (!parent.containsKey(KEY_CLASSES)) {
                parent.put(KEY_CLASSES, new HashMap<>());
            }
            parent = (Map<String, Object>) parent.get(KEY_CLASSES);
        }
        parent.put(TypeUtils.modelName(d), m);
    }
    return m;
}
Also used : ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) HashMap(java.util.HashMap) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) HashMap(java.util.HashMap) Map(java.util.Map) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 69 with TypeDeclaration

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

the class TypeUtils method qualifiedNameSkippingMethods.

/**
 * Returns the qualified name of a declaration, skipping any containing methods.
 */
public static String qualifiedNameSkippingMethods(Declaration d) {
    final StringBuilder p = new StringBuilder(d.getName());
    Scope s = d.getContainer();
    while (s != null) {
        if (s instanceof org.eclipse.ceylon.model.typechecker.model.Package) {
            final String pkname = ((org.eclipse.ceylon.model.typechecker.model.Package) s).getNameAsString();
            if (!pkname.isEmpty()) {
                p.insert(0, "::");
                p.insert(0, pkname);
            }
        } else if (s instanceof TypeDeclaration) {
            p.insert(0, '.');
            p.insert(0, ((TypeDeclaration) s).getName());
        }
        s = s.getContainer();
    }
    return p.toString();
}
Also used : Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 70 with TypeDeclaration

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

the class TypeUtils method metamodelTypeNameOrList.

/**
 * Prints out an object with a type constructor under the property "t" and its type arguments under
 * the property "a", or a union/intersection type with "u" or "i" under property "t" and the list
 * of types that compose it in an array under the property "l", or a type parameter as a reference to
 * already existing params.
 * @param resolveTargsFromScope Indicates whether to resolve a type argument if it's within reach in the
 * node's scope. This is useful for parameters of JsCallables but must be disabled for metamodel functions.
 * @param node The node to use as starting point for resolution of other references.
 * @param pkg The package of the current declaration
 * @param pt The produced type for which a name must be output.
 * @param gen The generator to use for output.
 */
static void metamodelTypeNameOrList(final boolean resolveTargsFromScope, final Node node, final org.eclipse.ceylon.model.typechecker.model.Package pkg, Type pt, SiteVariance useSiteVariance, GenerateJsVisitor gen) {
    if (pt == null) {
        // In dynamic blocks we sometimes get a null producedType
        gen.out("'$U'");
        return;
    }
    if (!outputMetamodelTypeList(resolveTargsFromScope, node, pkg, pt, gen)) {
        TypeDeclaration type = pt.getDeclaration();
        if (pt.isTypeParameter()) {
            final TypeParameter tparm = (TypeParameter) type;
            final Declaration tpowner = tparm.getDeclaration();
            final boolean nodeIsDecl = node instanceof Tree.Declaration;
            boolean rtafs = tpowner instanceof TypeDeclaration == false && (nodeIsDecl ? ((Tree.Declaration) node).getDeclarationModel() != tpowner : true);
            if (rtafs && ModelUtil.contains((Scope) tpowner, node.getScope())) {
                // Attempt to resolve this to an argument if the scope allows for it
                if (tpowner instanceof TypeDeclaration) {
                    gen.out(gen.getNames().self((TypeDeclaration) tpowner), ".$$targs$$.", gen.getNames().typeParameterName(tparm));
                } else if (tpowner instanceof Function) {
                    gen.out(gen.getNames().typeArgsParamName((Function) tpowner), ".", gen.getNames().typeParameterName(tparm));
                }
            } else if (resolveTargsFromScope && tpowner instanceof TypeDeclaration && (nodeIsDecl ? ((Tree.Declaration) node).getDeclarationModel() == tpowner : true) && ModelUtil.contains((Scope) tpowner, node.getScope())) {
                typeNameOrList(node, tparm.getType(), gen, false);
            } else {
                gen.out("'", gen.getNames().typeParameterName(tparm), "'");
            }
        } else if (pt.isTypeAlias()) {
            outputQualifiedTypename(node, gen.isImported(pkg, type), pt, gen, false);
        } else {
            gen.out("{t:");
            // For constructors, output the type of the class
            final Type qt = type instanceof Constructor ? pt.getQualifyingType() : pt;
            outputQualifiedTypename(node, gen.isImported(pkg, type), qt, gen, false);
            // Type Parameters
            if (!pt.getTypeArguments().isEmpty()) {
                gen.out(",a:{");
                boolean first = true;
                for (Map.Entry<TypeParameter, Type> e : pt.getTypeArguments().entrySet()) {
                    if (first)
                        first = false;
                    else
                        gen.out(",");
                    gen.out(gen.getNames().typeParameterName(e.getKey()), ":");
                    metamodelTypeNameOrList(resolveTargsFromScope, node, pkg, e.getValue(), pt.getVarianceOverrides().get(e.getKey()), gen);
                }
                gen.out("}");
            }
            printSiteVariance(useSiteVariance, gen);
            gen.out("}");
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) 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) 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)

Aggregations

TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)303 Type (org.eclipse.ceylon.model.typechecker.model.Type)180 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)88 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)86 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)80 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)70 Class (org.eclipse.ceylon.model.typechecker.model.Class)68 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)65 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)57 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)57 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)55 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)51 Test (org.junit.Test)51 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)49 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)49 ArrayList (java.util.ArrayList)48 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)44 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)43 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)39 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)34