Search in sources :

Example 71 with TypeDeclaration

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

the class TypeUtils method wrapAsIterableArguments.

public static Map<TypeParameter, Type> wrapAsIterableArguments(Type pt) {
    HashMap<TypeParameter, Type> r = new HashMap<TypeParameter, Type>();
    final TypeDeclaration iterable = pt.getDeclaration().getUnit().getIterableDeclaration();
    List<TypeParameter> typeParameters = iterable.getTypeParameters();
    r.put(typeParameters.get(0), pt);
    r.put(typeParameters.get(1), pt.getDeclaration().getUnit().getNullType());
    return r;
}
Also used : 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) HashMap(java.util.HashMap) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 72 with TypeDeclaration

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

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

the class TypeUtils method printTypeArguments.

/**
 * Prints the type arguments, usually for their reification.
 */
public static void printTypeArguments(final Node node, final Map<TypeParameter, Type> targs, final GenerateJsVisitor gen, final boolean skipSelfDecl, final Map<TypeParameter, SiteVariance> overrides) {
    if (targs == null)
        return;
    gen.out("{");
    boolean first = true;
    for (Map.Entry<TypeParameter, Type> e : targs.entrySet()) {
        if (first) {
            first = false;
        } else {
            gen.out(",");
        }
        gen.out(gen.getNames().typeParameterName(e.getKey()), ":");
        final Type pt = e.getValue() == null ? null : e.getValue().resolveAliases();
        if (pt == null) {
            gen.out("'", e.getKey().getName(), "'");
        } else if (!outputTypeList(node, pt, gen, skipSelfDecl)) {
            boolean hasParams = pt.getTypeArgumentList() != null && !pt.getTypeArgumentList().isEmpty();
            boolean closeBracket = false;
            final TypeDeclaration d = pt.getDeclaration();
            if (pt.isTypeParameter()) {
                resolveTypeParameter(node, (TypeParameter) d, gen, skipSelfDecl);
                if (((TypeParameter) d).isInvariant() && (e.getKey().isCovariant() || e.getKey().isContravariant())) {
                    gen.out("/*ORALE!", d.getQualifiedNameString(), " inv pero ", e.getKey().getQualifiedNameString(), e.getKey().isCovariant() ? " out" : " in", "*/");
                }
            } else {
                closeBracket = !pt.isTypeAlias();
                if (closeBracket)
                    gen.out("{t:");
                outputQualifiedTypename(node, node != null && gen.isImported(node.getUnit().getPackage(), pt.getDeclaration()), pt, gen, skipSelfDecl);
            }
            if (hasParams) {
                gen.out(",a:");
                printTypeArguments(node, pt.getTypeArguments(), gen, skipSelfDecl, pt.getVarianceOverrides());
            }
            SiteVariance siteVariance = overrides == null ? null : overrides.get(e.getKey());
            printSiteVariance(siteVariance, gen);
            if (closeBracket) {
                gen.out("}");
            }
        }
    }
    gen.out("}");
}
Also used : 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) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) HashMap(java.util.HashMap) Map(java.util.Map) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 74 with TypeDeclaration

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

the class JsIdentifierNames method getName.

private String getName(Declaration decl, boolean forGetterSetter, boolean priv) {
    if (decl == null) {
        return null;
    }
    String name = decl.getName();
    if (name == null && ModelUtil.isConstructor(decl)) {
        return "$c$";
    }
    if (name.startsWith("anonymous#")) {
        name = "anon$" + name.substring(10);
    }
    if (decl.isDynamic()) {
        return JsUtils.escapeStringLiteral(decl.getName());
    }
    boolean nonLocal = !priv;
    if (nonLocal) {
        // check if it's a shared member or a toplevel function
        nonLocal = decl.isMember() ? decl.isShared() || decl instanceof TypeDeclaration : decl.isToplevel() && (forGetterSetter || decl instanceof Function || decl instanceof ClassOrInterface || decl instanceof TypeAlias);
    }
    if (nonLocal && decl instanceof Class && ((Class) decl).isAnonymous() && !forGetterSetter) {
        // A lower-case class name belongs to an object and is not public.
        nonLocal = false;
    }
    if (nonLocal) {
        // The identifier might be accessed from other .js files, so it must
        // be reliably reproducible. In most cases simply using the original
        // name is ok because otherwise it would result in a name collision in
        // Ceylon too. We just have to take care of a few exceptions:
        String suffix = nestingSuffix(decl, false);
        if (suffix.length() > 0) {
            // nested type
            name += suffix;
        } else if ((!forGetterSetter && !ModelUtil.isConstructor(decl) && reservedWords.contains(name)) || isJsGlobal(decl)) {
            // JavaScript keyword or global declaration
            name = "$_" + name;
        }
    } else {
        // The identifier will not be used outside the generated .js file,
        // so we can simply disambiguate it with a numeric ID.
        name = uniquePrivateName(decl, priv);
    }
    // Fix #204 - same top-level declarations in different packages
    final Package declPkg = decl.getUnit().getPackage();
    if (decl.isToplevel() && !declPkg.equals(declPkg.getModule().getRootPackage())) {
        final Package raiz = declPkg.getModule().getRootPackage();
        // rootPackage can be null when compiling from IDE
        String rootName = raiz == null ? (declPkg.getModule().isDefaultModule() ? "" : declPkg.getModule().getNameAsString()) : raiz.getNameAsString();
        String pkgName = declPkg.getNameAsString();
        rootName = pkgName.substring(rootName.length()).replaceAll("\\.", "\\$");
        if (rootName.length() > 0 && rootName.charAt(0) != '$') {
            rootName = '$' + rootName;
        }
        name += rootName;
    }
    if (decl instanceof TypeAlias) {
        name += "()";
    }
    return JsUtils.escapeStringLiteral(name);
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Class(org.eclipse.ceylon.model.typechecker.model.Class) Package(org.eclipse.ceylon.model.typechecker.model.Package) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 75 with TypeDeclaration

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

the class RefinementVisitor method checkRefiningMemberUpperBounds.

private List<Type> checkRefiningMemberUpperBounds(Tree.Declaration that, ClassOrInterface ci, Declaration refined, List<TypeParameter> refinedTypeParams, List<TypeParameter> refiningTypeParams) {
    int refiningSize = refiningTypeParams.size();
    int refinedSize = refinedTypeParams.size();
    int max = refiningSize <= refinedSize ? refiningSize : refinedSize;
    if (max == 0) {
        return NO_TYPE_ARGS;
    }
    // we substitute the type parameters of the refined
    // declaration into the bounds of the refining
    // declaration
    Map<TypeParameter, Type> substitution = new HashMap<TypeParameter, Type>();
    for (int i = 0; i < max; i++) {
        TypeParameter refinedTypeParam = refinedTypeParams.get(i);
        TypeParameter refiningTypeParam = refiningTypeParams.get(i);
        substitution.put(refiningTypeParam, refinedTypeParam.getType());
    }
    Map<TypeParameter, SiteVariance> noVariances = emptyMap();
    TypeDeclaration rc = (TypeDeclaration) refined.getContainer();
    // we substitute the type arguments of the subtype's
    // instantiation of the supertype into the bounds of
    // the refined declaration
    Type supertype = ci.getType().getSupertype(rc);
    Map<TypeParameter, Type> args = supertype.getTypeArguments();
    Map<TypeParameter, SiteVariance> variances = supertype.getVarianceOverrides();
    List<Type> typeArgs = new ArrayList<Type>(max);
    for (int i = 0; i < max; i++) {
        TypeParameter refinedTypeParam = refinedTypeParams.get(i);
        TypeParameter refiningTypeParam = refiningTypeParams.get(i);
        refiningTypeParam.setReified(refinedTypeParam.isReified());
        Type refinedProducedType = refinedTypeParam.getType();
        List<Type> refinedBounds = refinedTypeParam.getSatisfiedTypes();
        List<Type> refiningBounds = refiningTypeParam.getSatisfiedTypes();
        Unit unit = that.getUnit();
        for (Type bound : refiningBounds) {
            Type refiningBound = bound.substitute(substitution, noVariances);
            // for every type constraint of the refining member, there must
            // be at least one type constraint of the refined member which
            // is assignable to it, guaranteeing that the intersection of
            // the refined member bounds is assignable to the intersection
            // of the refining member bounds
            // TODO: would it be better to just form the intersections and
            // test assignability directly (the error messages might
            // not be as helpful, but it might be less restrictive)
            boolean ok = false;
            for (Type refinedBound : refinedBounds) {
                refinedBound = refinedBound.substitute(args, variances);
                if (refinedBound.isSubtypeOf(refiningBound)) {
                    ok = true;
                }
            }
            if (!ok) {
                that.addError("refining member type parameter '" + refiningTypeParam.getName() + "' has upper bound which refined member type parameter '" + refinedTypeParam.getName() + "' of " + message(refined) + " does not satisfy: '" + bound.asString(unit) + "' ('" + refiningTypeParam.getName() + "' should be upper bounded by '" + intersectionOfSupertypes(refinedTypeParam).substitute(args, variances).asString(unit) + "')");
            }
        }
        for (Type bound : refinedBounds) {
            Type refinedBound = bound.substitute(args, variances);
            boolean ok = false;
            for (Type refiningBound : refiningBounds) {
                refiningBound = refiningBound.substitute(substitution, noVariances);
                if (refinedBound.isSubtypeOf(refiningBound)) {
                    ok = true;
                }
            }
            if (!ok) {
                that.addUnsupportedError("refined member type parameter '" + refinedTypeParam.getName() + "' of " + message(refined) + " has upper bound which refining member type parameter '" + refiningTypeParam.getName() + "' does not satisfy: '" + bound.asString(unit) + "' ('" + refiningTypeParam.getName() + "' should be upper bounded by '" + intersectionOfSupertypes(refinedTypeParam).substitute(args, variances).asString(unit) + "')");
            }
        }
        typeArgs.add(refinedProducedType);
    }
    return typeArgs;
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.erasedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.erasedType) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) 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