Search in sources :

Example 76 with Interface

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

the class TypeUtils method encodeForRuntime.

public static void encodeForRuntime(final Node that, final Declaration d, final GenerateJsVisitor gen, final RuntimeMetamodelAnnotationGenerator annGen) {
    gen.out("function(){return{mod:$CCMM$");
    List<TypeParameter> tparms = d instanceof Generic ? d.getTypeParameters() : null;
    List<Type> satisfies = null;
    List<Type> caseTypes = null;
    if (d instanceof Class) {
        Class _cd = (Class) d;
        if (_cd.getExtendedType() != null) {
            gen.out(",'super':");
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), _cd.getExtendedType(), null, gen);
        }
        // Parameter types
        if (_cd.getParameterList() != null) {
            gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
            encodeParameterListForRuntime(false, that, _cd.getParameterList(), gen);
        }
        satisfies = _cd.getSatisfiedTypes();
        caseTypes = _cd.getCaseTypes();
    } else if (d instanceof Interface) {
        Interface _id = (Interface) d;
        satisfies = _id.getSatisfiedTypes();
        caseTypes = _id.getCaseTypes();
        if (_id.isAlias()) {
            ArrayList<Type> s2 = new ArrayList<>(satisfies.size() + 1);
            s2.add(_id.getExtendedType());
            s2.addAll(satisfies);
            satisfies = s2;
        }
    } else if (d instanceof FunctionOrValue) {
        gen.out(",", MetamodelGenerator.KEY_TYPE, ":");
        if (d instanceof Function && ((Function) d).getParameterLists().size() > 1) {
            Type callableType = ((Function) d).getTypedReference().getFullType();
            // This needs a new setting to resolve types but not type parameters
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), that.getUnit().getCallableReturnType(callableType), null, gen);
        } else {
            // This needs a new setting to resolve types but not type parameters
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), ((FunctionOrValue) d).getType(), null, gen);
        }
        if (d instanceof Function) {
            gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
            // Parameter types of the first parameter list
            encodeParameterListForRuntime(false, that, ((Function) d).getFirstParameterList(), gen);
            tparms = d.getTypeParameters();
        }
    } else if (d instanceof Constructor) {
        gen.out(",", MetamodelGenerator.KEY_PARAMS, ":");
        encodeParameterListForRuntime(false, that, ((Constructor) d).getFirstParameterList(), gen);
    }
    if (!d.isToplevel()) {
        // Find the first container that is a Declaration
        Declaration _cont = ModelUtil.getContainingDeclaration(d);
        // Skip over anonymous types/funs as well as local non-captured fields
        while (_cont.isAnonymous() || !(_cont.isToplevel() || _cont.isClassOrInterfaceMember() || _cont instanceof Value == false)) {
            // Neither do we skip classes, even if they're anonymous
            if ((_cont instanceof Value && (((Value) _cont).isJsCaptured())) || _cont instanceof Class) {
                break;
            }
            Declaration __d = ModelUtil.getContainingDeclaration(_cont);
            if (__d == null)
                break;
            _cont = __d;
        }
        gen.out(",$cont:");
        boolean generateName = true;
        if ((_cont.getName() != null && _cont.isAnonymous() && _cont instanceof Function) || (_cont instanceof Value && !((Value) _cont).isTransient())) {
            // Anon functions don't have metamodel so go up until we find a non-anon container
            Declaration _supercont = ModelUtil.getContainingDeclaration(_cont);
            while (_supercont != null && _supercont.getName() != null && _supercont.isAnonymous()) {
                _supercont = ModelUtil.getContainingDeclaration(_supercont);
            }
            if (_supercont == null) {
                // If the container is a package, add it because this isn't really toplevel
                generateName = false;
                gen.out("0");
            } else {
                _cont = _supercont;
            }
        }
        if (generateName) {
            if (_cont instanceof Value) {
                if (AttributeGenerator.defineAsProperty(_cont)) {
                    gen.qualify(that, _cont);
                }
                gen.out(gen.getNames().getter(_cont, true));
            } else if (_cont instanceof Setter) {
                gen.out("{setter:");
                if (AttributeGenerator.defineAsProperty(_cont)) {
                    gen.qualify(that, _cont);
                    gen.out(gen.getNames().getter(((Setter) _cont).getGetter(), true), ".set");
                } else {
                    gen.out(gen.getNames().setter(((Setter) _cont).getGetter()));
                }
                gen.out("}");
            } else {
                boolean inProto = gen.opts.isOptimize() && (_cont.getContainer() instanceof TypeDeclaration);
                final String path = gen.qualifiedPath(that, _cont, inProto);
                if (path != null && !path.isEmpty()) {
                    gen.out(path, ".");
                }
                final String contName = gen.getNames().name(_cont);
                gen.out(contName);
            }
        }
    }
    if (tparms != null && !tparms.isEmpty()) {
        gen.out(",", MetamodelGenerator.KEY_TYPE_PARAMS, ":{");
        encodeTypeParametersForRuntime(that, d, tparms, true, gen);
        gen.out("}");
    }
    if (satisfies != null && !satisfies.isEmpty()) {
        gen.out(",", MetamodelGenerator.KEY_SATISFIES, ":[");
        boolean first = true;
        for (Type st : satisfies) {
            if (!first)
                gen.out(",");
            first = false;
            metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), st, null, gen);
        }
        gen.out("]");
    }
    if (caseTypes != null && !caseTypes.isEmpty()) {
        gen.out(",of:[");
        boolean first = true;
        for (Type st : caseTypes) {
            // teeheehee
            final TypeDeclaration std = st.getDeclaration();
            if (!first)
                gen.out(",");
            first = false;
            if (ModelUtil.isConstructor(std)) {
                if (std.isAnonymous()) {
                    // Value constructor
                    gen.out(gen.getNames().name(d), ".", gen.getNames().valueConstructorName(std));
                } else {
                    gen.out("/*TODO callable constructor*/");
                }
            } else if (std.isAnonymous()) {
                if (std.isStatic()) {
                    gen.out(gen.getNames().name(ModelUtil.getContainingDeclaration(std)), ".$st$.", gen.getNames().objectName(std));
                } else {
                    gen.out(gen.getNames().getter(std, true));
                }
            } else {
                metamodelTypeNameOrList(false, that, d.getUnit().getPackage(), st, null, gen);
            }
        }
        gen.out("]");
    }
    if (annGen != null) {
        annGen.generateAnnotations();
    }
    // Path to its model
    gen.out(",d:");
    outputModelPath(d, gen);
    gen.out("};}");
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Generic(org.eclipse.ceylon.model.typechecker.model.Generic) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) NothingType(org.eclipse.ceylon.model.typechecker.model.NothingType) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Class(org.eclipse.ceylon.model.typechecker.model.Class) 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) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 77 with Interface

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

the class TypeGenerator method typeFunctionName.

/**
 * Returns the name of the type or its $init$ function if it's local.
 */
static String typeFunctionName(final Tree.StaticType type, final ClassOrInterface coi, final GenerateJsVisitor gen) {
    TypeDeclaration d = type.getTypeModel().getDeclaration();
    final boolean removeAlias = d == null || !d.isClassOrInterfaceMember() || d instanceof Interface;
    if ((removeAlias && d.isAlias()) || d instanceof Constructor) {
        Type extendedType = d.getExtendedType();
        d = extendedType == null ? null : extendedType.getDeclaration();
    }
    Declaration cont = ModelUtil.getContainingDeclaration(d);
    final boolean inProto = gen.opts.isOptimize() && cont instanceof TypeDeclaration;
    final boolean imported = gen.isImported(type.getUnit().getPackage(), d);
    String dname = gen.getNames().name(d);
    if (d.isAlias()) {
        TypeDeclaration d2 = d;
        while (d2.isAlias()) {
            d2 = d2.getExtendedType().getDeclaration();
        }
        dname = gen.getNames().name(d2);
    }
    final String initName = "$init$" + dname + "()";
    if (!imported && !d.isClassOrInterfaceMember()) {
        return initName;
    }
    if (inProto && coi.isMember() && !d.isAlias() && (coi.getContainer() == cont || ModelUtil.contains(d, coi))) {
        // use its $init$ function
        return initName;
    }
    String tfn;
    // #628 If coi is anonymous and inside cont, qualify the path from cont instead
    if (coi != null && coi.isAnonymous() && cont instanceof Scope && ModelUtil.contains((Scope) cont, coi)) {
        tfn = gen.qualifiedPath(type, cont, inProto);
    } else if (inProto && d.isClassOrInterfaceMember()) {
        return pathToType(type, d, gen);
    } else {
        tfn = gen.qualifiedPath(type, d, inProto);
    }
    tfn = gen.memberAccessBase(type, d, false, tfn);
    if (removeAlias && !imported) {
        int idx = tfn.lastIndexOf('.');
        if (idx > 0) {
            tfn = tfn.substring(0, idx + 1) + initName;
        } else {
            tfn = initName;
        }
    }
    return tfn;
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) StaticType(org.eclipse.ceylon.compiler.typechecker.tree.Tree.StaticType) 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) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)

Example 78 with Interface

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

Example 79 with Interface

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

the class AbstractModelLoader method getRepeatableContainer.

public Interface getRepeatableContainer(Class c) {
    if (c instanceof AnnotationProxyClass) {
        AnnotationMirror mirror = ((AnnotationProxyClass) c).iface.classMirror.getAnnotation("java.lang.annotation.Repeatable");
        if (mirror != null) {
            TypeMirror m = (TypeMirror) mirror.getValue();
            Module module = findModuleForClassMirror(m.getDeclaredClass());
            return (Interface) convertDeclaredTypeToDeclaration(module, m, DeclarationType.TYPE);
        }
    }
    return null;
}
Also used : AnnotationMirror(org.eclipse.ceylon.model.loader.mirror.AnnotationMirror) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 80 with Interface

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

the class AbstractModelLoader method setExtendedType.

private void setExtendedType(ClassOrInterface klass, ClassMirror classMirror) {
    // look at its super type
    TypeMirror superClass = classMirror.getSuperclass();
    Type extendedType;
    if (klass instanceof Interface) {
        // interfaces need to have their superclass set to Object
        if (superClass == null || superClass.getKind() == TypeKind.NONE)
            extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_OBJECT_TYPE, klass);
        else
            extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
    } else if (klass instanceof Class && ((Class) klass).isOverloaded()) {
        // if the class is overloaded we already have it stored
        extendedType = klass.getExtendedType();
    } else {
        String className = classMirror.getQualifiedName();
        String superClassName = superClass == null ? null : superClass.getQualifiedName();
        if (className.equals("ceylon.language.Anything")) {
            // ceylon.language.Anything has no super type
            extendedType = null;
        } else if (className.equals("java.lang.Object")) {
            // we pretend its superclass is something else, but note that in theory we shouldn't
            // be seeing j.l.Object at all due to unerasure
            extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
        } else {
            // read it from annotation first
            String annotationSuperClassName = getAnnotationStringValue(classMirror, CEYLON_CLASS_ANNOTATION, "extendsType");
            if (annotationSuperClassName != null && !annotationSuperClassName.isEmpty()) {
                extendedType = decodeType(annotationSuperClassName, klass, ModelUtil.getModuleContainer(klass), "extended type");
            } else {
                // now deal with type erasure, avoid having Object as superclass
                if ("java.lang.Object".equals(superClassName)) {
                    extendedType = getNonPrimitiveType(getLanguageModule(), CEYLON_BASIC_TYPE, klass);
                } else if (superClass != null) {
                    try {
                        extendedType = getNonPrimitiveType(ModelUtil.getModule(klass), superClass, klass);
                    } catch (ModelResolutionException x) {
                        extendedType = logModelResolutionException(x, klass, "Error while resolving extended type of " + klass.getQualifiedNameString());
                    }
                } else {
                    // FIXME: should this be UnknownType?
                    extendedType = null;
                }
            }
        }
    }
    if (extendedType != null)
        klass.setExtendedType(extendedType);
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) TypeMirror(org.eclipse.ceylon.model.loader.mirror.TypeMirror) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Aggregations

Interface (org.eclipse.ceylon.model.typechecker.model.Interface)105 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)99 Type (org.eclipse.ceylon.model.typechecker.model.Type)64 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)58 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)40 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)35 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)34 Class (org.eclipse.ceylon.model.typechecker.model.Class)32 ModelUtil.getContainingClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface)32 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)32 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)29 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)21 ModelUtil.getOuterClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getOuterClassOrInterface)20 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)20 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)19 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)19 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)18 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)18 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)18