Search in sources :

Example 1 with SiteVariance

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

the class AbstractTransformer method makeReifiedTypeArgumentResolved.

private JCExpression makeReifiedTypeArgumentResolved(Type pt, boolean qualified, TypeArgumentAccessor typeArgumentAccessor, boolean wantsRaw) {
    if (pt.isUnion()) {
        // FIXME: refactor this shite
        List<JCExpression> typeTestArguments = List.nil();
        java.util.List<Type> typeParameters = pt.getCaseTypes();
        if (typeParameters.size() == 2) {
            Type alternative = null;
            if (typeParameters.get(0).isEmpty())
                alternative = typeParameters.get(1);
            else if (typeParameters.get(1).isEmpty())
                alternative = typeParameters.get(0);
            if (alternative != null && alternative.isTuple()) {
                JCExpression tupleType = makeTupleTypeDescriptor(alternative, true);
                if (tupleType != null)
                    return tupleType;
            }
        }
        for (int i = typeParameters.size() - 1; i >= 0; i--) {
            typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
        }
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "union"), typeTestArguments);
    } else if (pt.isIntersection()) {
        List<JCExpression> typeTestArguments = List.nil();
        java.util.List<Type> typeParameters = pt.getSatisfiedTypes();
        for (int i = typeParameters.size() - 1; i >= 0; i--) {
            typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
        }
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "intersection"), typeTestArguments);
    } else if (pt.isNothing()) {
        return makeNothingTypeDescriptor();
    }
    TypeDeclaration declaration = pt.getDeclaration();
    if (declaration instanceof Constructor) {
        pt = pt.getExtendedType();
        declaration = pt.getDeclaration();
    }
    if (pt.isClassOrInterface()) {
        // see if we have an alias for it
        if (supportsReifiedAlias((ClassOrInterface) declaration)) {
            JCExpression qualifier = naming.makeDeclarationName(declaration, DeclNameFlag.QUALIFIED);
            return makeSelect(qualifier, naming.getTypeDescriptorAliasName());
        }
        if (pt.isTuple()) {
            JCExpression tupleType = makeTupleTypeDescriptor(pt, false);
            if (tupleType != null)
                return tupleType;
        }
        // no alias, must build it
        List<JCExpression> typeTestArguments;
        JCExpression thisType = makeUnerasedClassLiteral(declaration);
        if (!wantsRaw) {
            typeTestArguments = makeReifiedTypeArgumentsResolved(pt.getTypeArgumentList(), qualified, typeArgumentAccessor);
            // do we have variance overrides?
            Map<TypeParameter, SiteVariance> varianceOverrides = pt.getVarianceOverrides();
            if (!varianceOverrides.isEmpty()) {
                // we need to pass them as second argument then, in an array
                ListBuffer<JCExpression> varianceElements = new ListBuffer<JCExpression>();
                for (TypeParameter typeParameter : declaration.getTypeParameters()) {
                    SiteVariance useSiteVariance = varianceOverrides.get(typeParameter);
                    String selector;
                    if (useSiteVariance != null) {
                        switch(useSiteVariance) {
                            case IN:
                                selector = "IN";
                                break;
                            case OUT:
                                selector = "OUT";
                                break;
                            default:
                                selector = "NONE";
                                break;
                        }
                    } else {
                        selector = "NONE";
                    }
                    JCExpression varianceElement = make().Select(makeIdent(syms().ceylonVarianceType), names().fromString(selector));
                    varianceElements.append(varianceElement);
                }
                JCNewArray varianceArray = make().NewArray(makeIdent(syms().ceylonVarianceType), List.<JCExpression>nil(), varianceElements.toList());
                typeTestArguments = typeTestArguments.prepend(varianceArray);
            }
        } else {
            typeTestArguments = List.nil();
        }
        typeTestArguments = typeTestArguments.prepend(thisType);
        JCExpression classDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "klass"), typeTestArguments);
        Type qualifyingType = pt.getQualifyingType();
        JCExpression containerType = null;
        if (qualifyingType == null) {
            // it may be contained in a function or value, and we want its type
            // or static class members may have no qualifying type but we want the TDs to treat
            // them as members anyway
            Declaration enclosingDeclaration = getDeclarationContainer(declaration);
            if (enclosingDeclaration instanceof TypedDeclaration)
                containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration, typeArgumentAccessor);
            else if (enclosingDeclaration instanceof TypeDeclaration) {
                qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
            }
        }
        if (qualifyingType != null && qualifyingType.isConstructor()) {
            qualifyingType = qualifyingType.getQualifyingType();
        }
        if (qualifyingType != null) {
            if (declaration.isStatic() && supportsReified(declaration)) {
                // There is no outer instance with a $reified$T field
                final Type t = pt;
                containerType = makeReifiedTypeArgumentResolved(qualifyingType, true, new TypeArgumentAccessor() {

                    public JCExpression getTypeDescriptor(TypeParameter tp, boolean qualified) {
                        return makeSelect(naming.makeQualifiedThis(makeJavaType(t, JT_RAW)), naming.getTypeArgumentDescriptorName(tp));
                    }
                }, false);
            } else {
                containerType = makeReifiedTypeArgumentResolved(qualifyingType, true, typeArgumentAccessor, // we want raw containers, since we can't capture their TPs
                declaration.isStatic());
            }
        }
        if (containerType == null) {
            return classDescriptor;
        } else {
            return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, classDescriptor));
        }
    } else if (pt.isTypeParameter()) {
        return typeArgumentAccessor.getTypeDescriptor((TypeParameter) declaration, qualified);
    } else {
        throw BugException.unhandledDeclarationCase(declaration);
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) ArrayList(java.util.ArrayList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) LinkedList(java.util.LinkedList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCNewArray(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray)

Example 2 with SiteVariance

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

the class AnalyzerUtil method getVariances.

static List<SiteVariance> getVariances(Tree.TypeArguments tas, List<TypeParameter> typeParameters) {
    if (tas instanceof Tree.TypeArgumentList) {
        Tree.TypeArgumentList tal = (Tree.TypeArgumentList) tas;
        int size = typeParameters.size();
        List<SiteVariance> variances = new ArrayList<SiteVariance>(size);
        List<Tree.Type> types = tal.getTypes();
        int count = types.size();
        for (int i = 0; i < count; i++) {
            Tree.Type type = types.get(i);
            if (type instanceof Tree.StaticType) {
                Tree.StaticType st = (Tree.StaticType) type;
                TypeVariance tv = st.getTypeVariance();
                if (tv != null) {
                    boolean contra = tv.getText().equals("in");
                    variances.add(contra ? IN : OUT);
                } else {
                    variances.add(null);
                }
            } else {
                variances.add(null);
            }
        }
        return variances;
    } else {
        return emptyList();
    }
}
Also used : ArrayList(java.util.ArrayList) TypeVariance(org.eclipse.ceylon.compiler.typechecker.tree.Tree.TypeVariance) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 3 with SiteVariance

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.BaseType that) {
    super.visit(that);
    final Scope scope = that.getScope();
    final String name = name(that.getIdentifier());
    if (inExtends) {
        final Tree.TypeArgumentList tal = that.getTypeArgumentList();
        final boolean packageQualified = that.getPackageQualified();
        Type t = new LazyType(unit) {

            @Override
            public TypeDeclaration initDeclaration() {
                return packageQualified ? getPackageTypeDeclaration(name, null, false, unit) : getTypeDeclaration(scope, name, null, false, unit);
            }

            @Override
            public Map<TypeParameter, Type> initTypeArguments() {
                TypeDeclaration dec = getDeclaration();
                List<TypeParameter> tps = dec.getTypeParameters();
                return getTypeArgumentMap(dec, null, AnalyzerUtil.getTypeArguments(tal, null, tps));
            }

            @Override
            public Map<TypeParameter, SiteVariance> initVarianceOverrides() {
                TypeDeclaration dec = getDeclaration();
                List<TypeParameter> tps = dec.getTypeParameters();
                return getVarianceMap(dec, null, AnalyzerUtil.getVariances(tal, tps));
            }
        };
        that.setTypeModel(t);
    }
}
Also used : IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) TypeVisitor.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeVisitor.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ConditionScope(org.eclipse.ceylon.model.typechecker.model.ConditionScope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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 4 with SiteVariance

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.QualifiedType that) {
    super.visit(that);
    final String name = name(that.getIdentifier());
    final Tree.StaticType outerType = that.getOuterType();
    if (inExtends) {
        final Tree.TypeArgumentList tal = that.getTypeArgumentList();
        Type t = new LazyType(unit) {

            @Override
            public TypeDeclaration initDeclaration() {
                if (outerType == null) {
                    return null;
                } else {
                    TypeDeclaration dec = outerType.getTypeModel().getDeclaration();
                    return AnalyzerUtil.getTypeMember(dec, name, null, false, unit, scope);
                }
            }

            @Override
            public Map<TypeParameter, Type> initTypeArguments() {
                if (outerType == null) {
                    return emptyMap();
                } else {
                    TypeDeclaration dec = getDeclaration();
                    List<TypeParameter> tps = dec.getTypeParameters();
                    Type ot = outerType.getTypeModel();
                    return getTypeArgumentMap(dec, ot, AnalyzerUtil.getTypeArguments(tal, ot, tps));
                }
            }

            @Override
            public Map<TypeParameter, SiteVariance> initVarianceOverrides() {
                TypeDeclaration dec = getDeclaration();
                List<TypeParameter> tps = dec.getTypeParameters();
                Type ot = outerType.getTypeModel();
                return getVarianceMap(dec, ot, AnalyzerUtil.getVariances(tal, tps));
            }
        };
        that.setTypeModel(t);
    }
}
Also used : IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) TypeVisitor.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeVisitor.getTupleType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) 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 5 with SiteVariance

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

the class MetamodelGenerator method putTypeArguments.

private void putTypeArguments(Map<String, Object> container, Type pt, Declaration from) {
    int tparmSize = 0;
    Type t = pt;
    while (t != null) {
        tparmSize += t.getTypeArgumentList() == null ? 0 : t.getTypeArgumentList().size();
        t = t.getQualifyingType();
    }
    if (tparmSize > 0) {
        final Map<String, Map<String, Object>> targs = new HashMap<>(tparmSize);
        t = pt;
        while (t != null) {
            final Map<TypeParameter, SiteVariance> usv = t.getVarianceOverrides();
            if (t.getTypeArgumentList() != null && !t.getTypeArgumentList().isEmpty()) {
                for (Map.Entry<TypeParameter, Type> targ : t.getTypeArguments().entrySet()) {
                    final Map<String, Object> tpmap = typeMap(targ.getValue(), from);
                    final SiteVariance variance = usv.get(targ.getKey());
                    if (variance != null) {
                        tpmap.put(MetamodelGenerator.KEY_US_VARIANCE, variance.ordinal());
                    }
                    targs.put(partiallyQualifiedName(targ.getKey().getDeclaration()) + "." + targ.getKey().getName(), tpmap);
                }
            }
            t = t.getQualifyingType();
        }
        container.put(KEY_TYPE_ARGS, targs);
    }
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

SiteVariance (org.eclipse.ceylon.model.typechecker.model.SiteVariance)20 Type (org.eclipse.ceylon.model.typechecker.model.Type)18 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)18 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)11 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)8 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)8 ArrayList (java.util.ArrayList)7 HashMap (java.util.HashMap)7 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)7 NothingType (org.eclipse.ceylon.model.typechecker.model.NothingType)6 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)5 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)5 Map (java.util.Map)4 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)4 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 LinkedHashMap (java.util.LinkedHashMap)3 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)3 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)3 TypeParser (org.eclipse.ceylon.model.loader.TypeParser)3 LazyType (org.eclipse.ceylon.model.typechecker.model.LazyType)3