Search in sources :

Example 6 with ClassAlias

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

the class Strategy method generateJpaCtor.

static boolean generateJpaCtor(ClassOrInterface declarationModel) {
    if (declarationModel instanceof Class && !(declarationModel instanceof ClassAlias) && declarationModel.isToplevel()) {
        Class cls = (Class) declarationModel;
        if (cls.getCaseValues() != null && !cls.getCaseValues().isEmpty()) {
            return false;
        }
        if (hasNullaryNonJpaConstructor(cls)) {
            // The class will already have a nullary ctor
            return false;
        }
        for (Annotation annotation : cls.getAnnotations()) {
            Declaration annoDecl = cls.getUnit().getImportedDeclaration(annotation.getName(), null, false);
            if (annoDecl != null && annoDecl.getQualifiedNameString().equals("java.lang::nonbean")) {
                return false;
            }
        }
        boolean hasDelegatableSuper = false;
        Class superClass = (Class) cls.getExtendedType().getDeclaration();
        if (superClass instanceof LazyClass && !((LazyClass) superClass).isCeylon()) {
            if (superClass.isAbstraction()) {
                for (Declaration s : superClass.getOverloads()) {
                    if (s instanceof Class && isNullary((Class) s)) {
                        hasDelegatableSuper = true;
                        break;
                    }
                }
            } else {
                // If the superclass is Java then generate a Jpa constructor
                // if there's a nullary superclass constructor we can call
                hasDelegatableSuper = isNullary(superClass);
            }
        } else {
            hasDelegatableSuper = hasNullaryNonJpaConstructor(superClass) || hasJpaConstructor(superClass);
        }
        boolean constrained = cls.getCaseValues() != null && !cls.getCaseValues().isEmpty() || cls.hasEnumerated() && Decl.hasOnlyValueConstructors(cls);
        return hasDelegatableSuper && !constrained;
    } else {
        return false;
    }
}
Also used : ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation)

Example 7 with ClassAlias

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

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

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

the class TypeVisitor method visit.

@Override
public void visit(Tree.ClassDeclaration that) {
    ClassAlias td = (ClassAlias) that.getDeclarationModel();
    td.setExtendedType(null);
    super.visit(that);
    Tree.ClassSpecifier cs = that.getClassSpecifier();
    if (cs == null) {
        that.addError("missing class body or aliased class reference");
    } else {
        Tree.ExtendedType et = that.getExtendedType();
        if (et != null) {
            et.addError("class alias may not extend a type");
        }
        Tree.SatisfiedTypes sts = that.getSatisfiedTypes();
        if (sts != null) {
            sts.addError("class alias may not satisfy a type");
        }
        Tree.CaseTypes cts = that.getCaseTypes();
        if (cts != null) {
            that.addError("class alias may not have cases or a self type");
        }
        Tree.SimpleType ct = cs.getType();
        if (ct == null) {
        // that.addError("malformed aliased class");
        } else if (!(ct instanceof Tree.StaticType)) {
            ct.addError("aliased type must be a class");
        } else {
            Type type = ct.getTypeModel();
            if (type != null && !type.isUnknown()) {
                TypeDeclaration dec = type.getDeclaration();
                td.setConstructor(dec);
                if (dec instanceof Constructor) {
                    if (dec.isValueConstructor()) {
                        ct.addError("aliases a value constructor");
                    } else if (dec.isAbstract()) {
                        ct.addError("aliases a partial constructor: '" + dec.getName(unit) + "' is declared abstract");
                    }
                    if (td.isShared() && !dec.isShared()) {
                        ct.addError("shared alias of an unshared constructor: '" + dec.getName(unit) + "' is not shared");
                    }
                    type = type.getExtendedType();
                    dec = dec.getExtendedType().getDeclaration();
                }
                if (dec instanceof Class) {
                    td.setExtendedType(type);
                } else {
                    ct.addError("not a class: '" + dec.getName(unit) + "'");
                }
                TypeDeclaration etd = ct.getDeclarationModel();
                if (etd == td) {
                    ct.addError("directly aliases itself: '" + td.getName() + "'");
                }
            }
        }
    }
}
Also used : ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) AnalyzerUtil.setTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.setTypeConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) AnalyzerUtil.unwrapAliasedTypeConstructor(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)

Example 10 with ClassAlias

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

the class Strategy method getEffectiveTypeParameters.

private static List<TypeParameter> getEffectiveTypeParameters(Declaration original, Declaration decl) {
    if (Decl.isConstructor(original)) {
        original = ModelUtil.getConstructedClass(original);
    }
    if (Decl.isConstructor(decl)) {
        decl = ModelUtil.getConstructedClass(decl);
    }
    Scope container = decl.getContainer();
    if (decl instanceof Value) {
        if (decl.isStatic()) {
            return getEffectiveTypeParameters(original, (Declaration) container);
        } else {
            return Collections.emptyList();
        }
    }
    if (decl instanceof Function) {
        if (original instanceof ClassAlias || decl.isStatic() && isCeylon(decl)) {
            ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration) container));
            copyDown.addAll(decl.getTypeParameters());
            return copyDown;
        } else {
            return decl.getTypeParameters();
        }
    } else if (decl instanceof ClassAlias) {
        // TODO
        /*if (container instanceof Declaration) {
                ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration)container));
                copyDown.addAll(((Class)decl).getTypeParameters());
                return copyDown;
            } else*/
        {
            return ((ClassAlias) decl).getTypeParameters();
        }
    } else if (decl instanceof Class) {
        if (((Class) decl).isStatic() && ((Class) decl).isMember() && isCeylon(decl)) {
            // TODO and isCeylon
            ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration) container));
            copyDown.addAll(((Class) decl).getTypeParameters());
            return copyDown;
        } else {
            return ((Class) decl).getTypeParameters();
        }
    } else if (decl instanceof Interface) {
        /*if (((Interface) decl).isMember()) {
                ArrayList<TypeParameter> copyDown = new ArrayList<TypeParameter>(getEffectiveTypeParameters(original, (Declaration)container));
                copyDown.addAll(((Interface)decl).getTypeParameters());
                return copyDown;
            } else*/
        {
            return ((Interface) decl).getTypeParameters();
        }
    } else if (decl instanceof TypeAlias) {
        return ((TypeAlias) decl).getTypeParameters();
    } else {
        throw BugException.unhandledDeclarationCase((Declaration) decl);
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Value(org.eclipse.ceylon.model.typechecker.model.Value) ArrayList(java.util.ArrayList) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Aggregations

ClassAlias (org.eclipse.ceylon.model.typechecker.model.ClassAlias)12 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)8 Class (org.eclipse.ceylon.model.typechecker.model.Class)6 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)6 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)4 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 ArrayList (java.util.ArrayList)3 ThrowerCatchallConstructor (org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor)3 Function (org.eclipse.ceylon.model.typechecker.model.Function)3 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)3 Type (org.eclipse.ceylon.model.typechecker.model.Type)3 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 AnalyzerUtil.isVeryAbstractClass (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass)2 MethodDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)2 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)2 LazyClass (org.eclipse.ceylon.model.loader.model.LazyClass)2 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)2 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)2