Search in sources :

Example 21 with Constructor

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

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

Example 23 with Constructor

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

the class TypeUtils method generateModelPath.

/**
 * Returns the list of keys to get from the package to the declaration, in the model.
 */
public static List<String> generateModelPath(final Declaration d) {
    final ArrayList<String> sb = new ArrayList<>();
    final Package pkg = d.getUnit().getPackage();
    sb.add(pkg.isLanguagePackage() ? "$" : pkg.getNameAsString());
    if (d.isToplevel()) {
        sb.add(d.getName());
        if (d instanceof Setter) {
            sb.add("$set");
        }
    } else {
        Declaration p = d;
        final int i = sb.size();
        while (p instanceof Declaration) {
            if (p instanceof Setter) {
                sb.add(i, "$set");
            }
            final String mname = TypeUtils.modelName(p);
            if (!(mname.startsWith("anon$") || mname.startsWith("anonymous#"))) {
                sb.add(i, mname);
                // Build the path in reverse
                if (!p.isToplevel()) {
                    if (p instanceof Class) {
                        sb.add(i, p.isAnonymous() ? MetamodelGenerator.KEY_OBJECTS : MetamodelGenerator.KEY_CLASSES);
                    } else if (p instanceof org.eclipse.ceylon.model.typechecker.model.Interface) {
                        sb.add(i, MetamodelGenerator.KEY_INTERFACES);
                    } else if (p instanceof Function) {
                        if (!p.isAnonymous()) {
                            sb.add(i, MetamodelGenerator.KEY_METHODS);
                        }
                    } else if (p instanceof TypeAlias || p instanceof Setter) {
                        sb.add(i, MetamodelGenerator.KEY_ATTRIBUTES);
                    } else if (p instanceof Constructor || ModelUtil.isConstructor(p)) {
                        sb.add(i, MetamodelGenerator.KEY_CONSTRUCTORS);
                    } else {
                        // It's a value
                        TypeDeclaration td = ((TypedDeclaration) p).getTypeDeclaration();
                        sb.add(i, (td != null && td.isAnonymous()) ? MetamodelGenerator.KEY_OBJECTS : MetamodelGenerator.KEY_ATTRIBUTES);
                    }
                }
            }
            p = ModelUtil.getContainingDeclaration(p);
            while (p != null && p instanceof ClassOrInterface == false && !(p.isToplevel() || p.isAnonymous() || p.isClassOrInterfaceMember() || p.isJsCaptured())) {
                p = ModelUtil.getContainingDeclaration(p);
            }
        }
    }
    return sb;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Function(org.eclipse.ceylon.model.typechecker.model.Function) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Class(org.eclipse.ceylon.model.typechecker.model.Class) Package(org.eclipse.ceylon.model.typechecker.model.Package) 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)

Example 24 with Constructor

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

the class RefinementVisitor method checkNonMember.

private void checkNonMember(Tree.Declaration that, Declaration dec) {
    boolean mayBeShared = !(dec instanceof TypeParameter);
    boolean nonTypeMember = !dec.isClassOrInterfaceMember();
    String name = dec.getName();
    if (dec.isStatic()) {
        if (nonTypeMember) {
            that.addError("static declaration is not a member of a class or interface: '" + name + "' is not defined directly in the body of a class or interface");
        } else {
            ClassOrInterface type = (ClassOrInterface) dec.getContainer();
            if (!type.isToplevel()) {
                that.addError("static declaration belongs to a nested a class or interface: '" + name + "' is a member of nested type '" + type.getName() + "'");
            }
        }
    }
    if (nonTypeMember && mayBeShared) {
        if (dec.isActual()) {
            that.addError("actual declaration is not a member of a class or interface: '" + name + "'", 1301);
        }
        if (dec.isFormal()) {
            that.addError("formal declaration is not a member of a class or interface: '" + name + "'", 1302);
        }
        if (dec.isDefault()) {
            that.addError("default declaration is not a member of a class or interface: '" + name + "'", 1303);
        }
    } else if (!dec.isShared() && mayBeShared) {
        if (dec.isActual()) {
            that.addError("actual declaration must be shared: '" + name + "'", 701);
        }
        if (dec.isFormal()) {
            that.addError("formal declaration must be shared: '" + name + "'", 702);
        }
        if (dec.isDefault()) {
            that.addError("default declaration must be shared: '" + name + "'", 703);
        }
    } else {
        if (dec.isActual()) {
            that.addError("declaration may not be actual: '" + name + "'", 1301);
        }
        if (dec.isFormal()) {
            that.addError("declaration may not be formal: '" + name + "'", 1302);
        }
        if (dec.isDefault()) {
            that.addError("declaration may not be default: '" + name + "'", 1303);
        }
    }
    if (isOverloadedVersion(dec)) {
        if (isConstructor(dec)) {
            checkOverloadedAnnotation(that, dec);
            checkOverloadedParameters(that, dec);
        } else {
            that.addError("duplicate declaration: the name '" + name + "' is not unique in this scope");
        }
    } else if (isAbstraction(dec)) {
        // that is considered overloaded in the model
        if (that instanceof Tree.ClassDefinition && !that.hasErrors()) {
            Tree.ClassDefinition def = (Tree.ClassDefinition) that;
            // this is an abstraction
            Class abs = (Class) dec;
            // correctly located)
            for (Tree.Statement st : def.getClassBody().getStatements()) {
                if (st instanceof Tree.Constructor) {
                    Tree.Constructor node = (Tree.Constructor) st;
                    if (node.getIdentifier() == null) {
                        Constructor con = node.getConstructor();
                        // get the corresponding overloaded version
                        Class cla = classOverloadForConstructor(abs, con);
                        checkOverloadedAnnotation(node, con);
                        checkOverloadedParameters(node, cla);
                    }
                }
            }
        }
    }
    if (isConstructor(dec) && dec.isShared()) {
        Scope container = dec.getContainer();
        if (container instanceof Class) {
            Class clazz = (Class) container;
            Declaration member = intersectionOfSupertypes(clazz).getDeclaration().getMember(name, null, false);
            if (member != null && member.isShared() && !isConstructor(member)) {
                Declaration supertype = (Declaration) member.getContainer();
                that.addError("constructor has same name as an inherited member '" + clazz.getName() + "' inherits '" + member.getName() + "' from '" + supertype.getName(that.getUnit()) + "'");
            }
        }
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 25 with Constructor

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

the class RefinementVisitor method checkOverloadedAnnotation.

private void checkOverloadedAnnotation(Tree.Declaration that, Declaration member) {
    // non-actual overloaded methods
    // must be annotated 'overloaded'
    boolean marked = false;
    Unit unit = that.getUnit();
    for (Tree.Annotation a : that.getAnnotationList().getAnnotations()) {
        Tree.Primary p = a.getPrimary();
        if (p instanceof Tree.BaseMemberExpression) {
            Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) p;
            String aname = bme.getIdentifier().getText();
            Declaration ad = p.getScope().getMemberOrParameter(unit, aname, null, false);
            if (ad != null && isOverloadedAnnotation(ad)) {
                marked = true;
            }
        }
    }
    if (!marked) {
        if (member.isActual()) {
            that.addUsageWarning(Warning.unknownWarning, "overloaded function should be declared with the 'overloaded' annotation in 'java.lang'");
        } else {
            if (member instanceof Constructor) {
                // default constructors are the only
                // thing that can legally have no name
                that.addError("duplicate default constructor (overloaded default constructor must be declared with the 'overloaded' annotation in 'java.lang')");
            } else if (member instanceof Function) {
                // functions are the only thing
                // that can legally have a name
                // and be overloaded
                that.addError("duplicate declaration: the name '" + member.getName() + "' is not unique in this scope " + "(overloaded function must be declared with the 'overloaded' annotation in 'java.lang')");
            }
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Unit(org.eclipse.ceylon.model.typechecker.model.Unit)

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