Search in sources :

Example 51 with Function

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

the class JsonPackage method loadMethod.

@SuppressWarnings("unchecked")
Function loadMethod(String name, Map<String, Object> m, Scope parent, final List<TypeParameter> existing) {
    Function md = new Function();
    md.setName(name);
    m.remove(KEY_NAME);
    md.setContainer(parent);
    md.setScope(parent);
    setAnnotations(md, (Integer) m.remove(KEY_PACKED_ANNS), m.remove(KEY_ANNOTATIONS));
    md.setUnit(u2);
    if (parent == this) {
        // Top-level declarations are directly added to the unit
        u2.addDeclaration(md);
        addMember(null);
    }
    if (m.containsKey(KEY_FLAGS)) {
        int flags = (int) m.remove(KEY_FLAGS);
        md.setDeclaredVoid((flags & 1) > 0);
        md.setDeferred((flags & 2) > 0);
    }
    md.setDynamic(m.remove(KEY_DYNAMIC) != null);
    final List<TypeParameter> tparms = parseTypeParameters((List<Map<String, Object>>) m.get(KEY_TYPE_PARAMS), md, existing);
    final List<TypeParameter> allparms = JsonPackage.merge(tparms, existing);
    md.setType(getTypeFromJson((Map<String, Object>) m.remove(KEY_TYPE), parent instanceof Declaration ? (Declaration) parent : null, allparms));
    List<List<Map<String, Object>>> paramLists = (List<List<Map<String, Object>>>) m.remove(KEY_PARAMS);
    if (paramLists == null) {
        md.addParameterList(new ParameterList());
    } else {
        boolean first = true;
        for (List<Map<String, Object>> plist : paramLists) {
            ParameterList _params = parseParameters(plist, md, allparms);
            _params.setNamedParametersSupported(first);
            first = false;
            md.addParameterList(_params);
            for (Parameter p : _params.getParameters()) {
                md.addMember(p.getModel());
            }
        }
    }
    return md;
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Function(org.eclipse.ceylon.model.typechecker.model.Function) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) 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 52 with Function

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

the class JsonPackage method loadClass.

/**
 * Loads a class from the specified map. To avoid circularities, when the class is being created it is
 * added to the map, and once it's been fully loaded, all other keys are removed.
 */
@SuppressWarnings("unchecked")
org.eclipse.ceylon.model.typechecker.model.Class loadClass(String name, Map<String, Object> m, Scope parent, final List<TypeParameter> existing) {
    org.eclipse.ceylon.model.typechecker.model.Class cls;
    m.remove(KEY_NAME);
    if (m.get(KEY_METATYPE) instanceof org.eclipse.ceylon.model.typechecker.model.Class) {
        cls = (org.eclipse.ceylon.model.typechecker.model.Class) m.get(KEY_METATYPE);
        if (m.size() <= 3) {
            // It's been fully loaded
            return cls;
        }
    } else {
        // It's not there, so create it
        if (m.containsKey("$alias")) {
            cls = new org.eclipse.ceylon.model.typechecker.model.ClassAlias();
        } else {
            cls = new org.eclipse.ceylon.model.typechecker.model.Class();
        }
        cls.setAbstract(m.remove("abstract") != null);
        cls.setAnonymous(m.remove("$anon") != null);
        cls.setDynamic(m.remove(KEY_DYNAMIC) != null);
        cls.setContainer(parent);
        cls.setScope(parent);
        cls.setName(name);
        cls.setUnit(u2);
        if (parent == this) {
            u2.addDeclaration(cls);
        }
        parent.addMember(cls);
        m.put(KEY_METATYPE, cls);
        setAnnotations(cls, (Integer) m.remove(KEY_PACKED_ANNS), m.remove(KEY_ANNOTATIONS));
    }
    // Type parameters are about the first thing we need to load
    final List<TypeParameter> tparms = parseTypeParameters((List<Map<String, Object>>) m.remove(KEY_TYPE_PARAMS), cls, existing);
    final List<TypeParameter> allparms = JsonPackage.merge(tparms, existing);
    if (m.containsKey(KEY_SELF_TYPE)) {
        for (TypeParameter t : tparms) {
            if (t.getName().equals(m.get(KEY_SELF_TYPE))) {
                cls.setSelfType(t.getType());
            }
        }
    }
    // This is to avoid circularity
    if (!(isLanguagePackage() && ("Nothing".equals(name) || "Anything".equals(name)))) {
        if (cls.getExtendedType() == null) {
            if (m.containsKey("super")) {
                Type father = getTypeFromJson((Map<String, Object>) m.get("super"), parent instanceof Declaration ? (Declaration) parent : null, allparms);
                if (father != null) {
                    m.remove("super");
                    cls.setExtendedType(father);
                }
            } else {
                cls.setExtendedType(getTypeFromJson(idobj, parent instanceof Declaration ? (Declaration) parent : null, allparms));
            }
        }
    }
    if (cls instanceof ClassAlias) {
        ClassAlias ca = (ClassAlias) cls;
        if (m.containsKey(KEY_CONSTRUCTOR)) {
            String constructorName = (String) m.get(KEY_CONSTRUCTOR);
            Function ctorFn = (Function) ca.getExtendedType().getDeclaration().getDirectMember(constructorName, null, false);
            ca.setConstructor(ctorFn.getType().getDeclaration());
        } else {
            ca.setConstructor(ca.getExtendedType().getDeclaration());
        }
    }
    if (m.containsKey(KEY_CONSTRUCTORS)) {
        final Map<String, Map<String, Object>> constructors = (Map<String, Map<String, Object>>) m.remove(KEY_CONSTRUCTORS);
        for (Map.Entry<String, Map<String, Object>> cons : constructors.entrySet()) {
            Constructor cnst = new Constructor();
            cnst.setName("$def".equals(cons.getKey()) ? null : cons.getKey());
            cnst.setContainer(cls);
            cnst.setScope(cls);
            cnst.setUnit(cls.getUnit());
            cnst.setExtendedType(cls.getType());
            cnst.setDynamic(cons.getValue().remove(KEY_DYNAMIC) != null);
            setAnnotations(cnst, (Integer) cons.getValue().remove(KEY_PACKED_ANNS), cons.getValue().remove(KEY_ANNOTATIONS));
            final List<Map<String, Object>> modelPlist = (List<Map<String, Object>>) cons.getValue().remove(KEY_PARAMS);
            cls.addMember(cnst);
            if (modelPlist == null) {
                // It's a value constructor
                cls.setEnumerated(true);
                Value cv = new Value();
                cv.setName(cnst.getName());
                cv.setType(cnst.getType());
                cv.setContainer(cls);
                cv.setScope(cls);
                cv.setUnit(cls.getUnit());
                cv.setVisibleScope(cls.getVisibleScope());
                cv.setShared(cls.isShared());
                cv.setDeprecated(cls.isDeprecated());
                cls.addMember(cv);
            } else {
                cls.setConstructors(true);
                final ParameterList plist = parseParameters(modelPlist, cnst, allparms);
                cnst.addParameterList(plist);
                plist.setNamedParametersSupported(true);
                Function cf = new Function();
                cf.setName(cnst.getName());
                final Type ft = cnst.appliedType(cnst.getExtendedType(), Collections.<Type>emptyList());
                cf.setType(ft);
                cf.addParameterList(plist);
                cf.setContainer(cls);
                cf.setScope(cls);
                cf.setUnit(cls.getUnit());
                cf.setVisibleScope(cnst.getVisibleScope());
                cf.setShared(cnst.isShared());
                cf.setDeprecated(cnst.isDeprecated());
                cf.setDynamic(cnst.isDynamic());
                cls.addMember(cf);
            }
            if (cons.getValue().containsKey(KEY_JS_TSENUM)) {
                cnst.setTypescriptEnum((String) cons.getValue().get(KEY_JS_TSENUM));
            }
        }
    } else {
        ParameterList plist = parseParameters((List<Map<String, Object>>) m.remove(KEY_PARAMS), cls, allparms);
        plist.setNamedParametersSupported(true);
        cls.setParameterList(plist);
    }
    if (m.containsKey("of") && cls.getCaseTypes() == null) {
        cls.setCaseTypes(parseTypeList((List<Map<String, Object>>) m.get("of"), allparms));
        m.remove("of");
    }
    if (m.containsKey(KEY_SATISFIES)) {
        List<Map<String, Object>> stypes = (List<Map<String, Object>>) m.remove(KEY_SATISFIES);
        cls.setSatisfiedTypes(parseTypeList(stypes, allparms));
    }
    if (m.containsKey(KEY_OBJECTS)) {
        for (Map.Entry<String, Map<String, Object>> inner : ((Map<String, Map<String, Object>>) m.get(KEY_OBJECTS)).entrySet()) {
            loadObject(inner.getKey(), inner.getValue(), cls, allparms);
        }
        m.remove(KEY_OBJECTS);
    }
    addAttributesAndMethods(m, cls, allparms);
    if (m.containsKey(KEY_INTERFACES)) {
        Map<String, Map<String, Object>> cdefs = (Map<String, Map<String, Object>>) m.get(KEY_INTERFACES);
        for (Map.Entry<String, Map<String, Object>> cdef : cdefs.entrySet()) {
            loadInterface(cdef.getKey(), cdef.getValue(), cls, allparms);
        }
        m.remove(KEY_INTERFACES);
    }
    if (m.containsKey(KEY_CLASSES)) {
        Map<String, Map<String, Object>> cdefs = (Map<String, Map<String, Object>>) m.get(KEY_CLASSES);
        for (Map.Entry<String, Map<String, Object>> cdef : cdefs.entrySet()) {
            loadClass(cdef.getKey(), cdef.getValue(), cls, allparms);
        }
        m.remove(KEY_CLASSES);
    }
    if (cls.isDynamic() && (getModule().getJsMajor() < 9 || (getModule().getJsMajor() == 9 && getModule().getJsMinor() < 1))) {
        // previous versions did not set dynamic flag on members
        cls.makeMembersDynamic();
    }
    return cls;
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Function(org.eclipse.ceylon.model.typechecker.model.Function) 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) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) 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 53 with Function

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

the class MetamodelGenerator method parameterListMap.

/**
 * Create a list of maps for the parameter list. Each map will be a parameter, including
 * name, type, default value (if any), and whether it's sequenced.
 */
private List<Map<String, Object>> parameterListMap(ParameterList plist, Declaration from) {
    if (plist == null) {
        // Possibly an anonymous class for an anonymous object
        return null;
    }
    List<Parameter> parms = plist.getParameters();
    if (parms.size() > 0) {
        List<Map<String, Object>> p = new ArrayList<>(parms.size());
        for (Parameter parm : parms) {
            Map<String, Object> pm = new HashMap<>();
            pm.put(KEY_NAME, parm.getName());
            pm.put(KEY_METATYPE, METATYPE_PARAMETER);
            if (parm.isSequenced()) {
                pm.put("seq", 1);
            }
            if (parm.isDefaulted()) {
                pm.put(KEY_DEFAULT, 1);
            }
            if (parm.isAtLeastOne()) {
                pm.put("$min1", 1);
            }
            final FunctionOrValue parmtype = parm.getModel();
            if (parmtype != null && parmtype.getDeclarationKind() == DeclarationKind.TYPE_PARAMETER) {
                pm.put(KEY_TYPE, parmtype.getName());
            } else {
                pm.put(KEY_TYPE, typeMap(parm.getType(), from));
            }
            if (parm.isHidden()) {
                pm.put("$hdn", 1);
            }
            if (parmtype instanceof Function) {
                pm.put("$pt", "f");
                List<List<Map<String, Object>>> _paramLists = new ArrayList<>(((Function) parmtype).getParameterLists().size());
                for (ParameterList subplist : ((Function) parmtype).getParameterLists()) {
                    List<Map<String, Object>> params = parameterListMap(subplist, from);
                    if (params == null) {
                        params = Collections.emptyList();
                    }
                    _paramLists.add(params);
                }
                if (_paramLists.size() > 1 || !_paramLists.get(0).isEmpty()) {
                    pm.put(KEY_PARAMS, _paramLists);
                }
            }
            // TODO do these guys need anything else?
            /*if (parm.getDefaultArgument() != null) {
                    //This could be compiled to JS...
                    pm.put(ANN_DEFAULT, parm.getDefaultArgument().getSpecifierExpression().getExpression().getTerm().getText());
                }*/
            encodeAnnotations(parm.getModel().getAnnotations(), parm.getModel(), pm);
            p.add(pm);
        }
        return p;
    }
    return null;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Function(org.eclipse.ceylon.model.typechecker.model.Function) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 54 with Function

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

the class MetamodelVisitor method visit.

@Override
public void visit(Tree.SpecifierStatement st) {
    TypedDeclaration d = ((Tree.SpecifierStatement) st).getDeclaration();
    // Just add shared and actual annotations to this declaration
    if (!isNativeHeader(d))
        return;
    if (d != null) {
        Annotation ann = new Annotation();
        ann.setName("shared");
        d.getAnnotations().add(ann);
        ann = new Annotation();
        ann.setName("actual");
        d.getAnnotations().add(ann);
        if (d instanceof Function) {
            gen.encodeMethod((Function) d);
        } else if (d instanceof Value) {
            gen.encodeAttributeOrGetter((Value) d);
        } else {
            throw new RuntimeException("JS compiler doesn't know how to encode " + d.getClass().getName() + " into model");
        }
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Function(org.eclipse.ceylon.model.typechecker.model.Function) Value(org.eclipse.ceylon.model.typechecker.model.Value) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation)

Example 55 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function 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

Function (org.eclipse.ceylon.model.typechecker.model.Function)167 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)71 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)70 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)69 Type (org.eclipse.ceylon.model.typechecker.model.Type)68 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)62 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)57 Value (org.eclipse.ceylon.model.typechecker.model.Value)50 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)46 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)43 Class (org.eclipse.ceylon.model.typechecker.model.Class)39 ArrayList (java.util.ArrayList)32 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)29 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)26 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)23 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)23 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21