Search in sources :

Example 46 with TypeDeclaration

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

the class ClassTransformer method addMissingUnrefinedMembers.

/**
 * Recover from members not being refined in the class hierarchy
 * by generating a stub method that throws.
 */
private void addMissingUnrefinedMembers(Node def, Class classModel, ClassDefinitionBuilder classBuilder) {
    for (Reference unrefined : classModel.getUnimplementedFormals()) {
        // classModel.getMember(memberName, null, false);
        Declaration formalMember = unrefined.getDeclaration();
        String errorMessage = "formal member '" + formalMember.getName() + "' of '" + ((TypeDeclaration) formalMember.getContainer()).getName() + "' not implemented in class hierarchy";
        java.util.List<Type> params = new java.util.ArrayList<Type>();
        for (TypeParameter tp : formalMember.getTypeParameters()) {
            params.add(tp.getType());
        }
        if (formalMember instanceof Value) {
            addRefinedThrowerAttribute(classBuilder, errorMessage, def, classModel, (Value) formalMember);
        } else if (formalMember instanceof Function) {
            addRefinedThrowerMethod(classBuilder, errorMessage, classModel, (Function) formalMember);
        } else if (formalMember instanceof Class && formalMember.isClassMember()) {
            addRefinedThrowerInstantiatorMethod(classBuilder, errorMessage, classModel, (Class) formalMember, unrefined);
        }
    // formal member class of interface handled in
    // makeDelegateToCompanion()
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) ArrayList(java.util.ArrayList) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 47 with TypeDeclaration

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

the class ClassTransformer method serializationGet.

private void serializationGet(Class model, ClassDefinitionBuilder classBuilder) {
    MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$get$.toString());
    mdb.isOverride(true);
    mdb.ignoreModelAnnotations();
    mdb.modifiers(PUBLIC);
    ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(this, Unfix.reference.toString());
    pdb.modifiers(FINAL);
    pdb.type(new TransformedType(make().Type(syms().ceylonReachableReferenceType), null, makeAtNonNull()));
    mdb.parameter(pdb);
    mdb.resultType(new TransformedType(make().Type(syms().objectType), null, makeAtNonNull()));
    /*
         * public void $get$(Object reference, Object instance) {
         *     switch((String)reference) {
         *     case ("attr1")
         *           return ...;
         *     // ... other fields of this class
         *     case ("lateAttr1")
         *           if (!$init$lateAttr1) {
         *               return ceylon.language.serialization.uninitializedLateValue.get_();
         *           }
         *           return ...;
         *     case (null):
         *           return Outer.this;
         *     default:
         *           return super.get(reference);
         */
    ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
    boolean[] needsLookup = new boolean[] { false };
    for (Declaration member : model.getMembers()) {
        if (hasField(member)) {
            if (member instanceof Function)
                // TODO: This class is not serializable
                continue;
            ListBuffer<JCStatement> caseStmts = new ListBuffer<JCStatement>();
            if (member instanceof Value && ((Value) member).isLate()) {
                // TODO this should be encapsulated so the ADB and this
                // code can just call something common
                JCExpression test = AttributeDefinitionBuilder.field(this, null, member.getName(), (Value) member, false).buildUninitTest();
                if (test != null) {
                    caseStmts.add(make().If(test, make().Return(makeLanguageSerializationValue("uninitializedLateValue")), null));
                }
            }
            caseStmts.add(make().Return(makeSerializationGetter((Value) member)));
            cases.add(make().Case(make().Literal(member.getQualifiedNameString()), caseStmts.toList()));
        }
    }
    SyntheticName reference = naming.synthetic(Unfix.reference);
    ListBuffer<JCStatement> defaultCase = new ListBuffer<JCStatement>();
    if (extendsSerializable(model)) {
        // super.get(reference);
        defaultCase.add(make().Return(make().Apply(null, naming.makeQualIdent(naming.makeSuper(), Unfix.$get$.toString()), List.<JCExpression>of(reference.makeIdent()))));
    } else {
        // throw (or pass to something else to throw, based on policy)
        defaultCase.add(make().Throw(make().NewClass(null, null, naming.makeQuotedFQIdent("java.lang.RuntimeException"), List.<JCExpression>of(make().Literal("unknown attribute")), null)));
    }
    cases.add(make().Case(null, defaultCase.toList()));
    ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
    if (needsLookup[0]) {
        // if we needed to use a lookup object to reset final fields,
        // prepend that variable
        stmts.add(makeVar(FINAL, "lookup", naming.makeQualIdent(make().Type(syms().methodHandlesType), "Lookup"), make().Apply(null, naming.makeQuotedFQIdent("java.lang.invoke.MethodHandles.lookup"), List.<JCExpression>nil())));
    }
    JCSwitch swtch = make().Switch(make().Apply(null, naming.makeSelect(make().Apply(null, naming.makeSelect(make().TypeCast(make().Type(syms().ceylonMemberType), reference.makeIdent()), "getAttribute"), List.<JCExpression>nil()), "getQualifiedName"), List.<JCExpression>nil()), cases.toList());
    if (model.isMember() && !model.getExtendedType().getDeclaration().isMember()) {
        stmts.add(make().If(make().TypeTest(reference.makeIdent(), make().Type(syms().ceylonOuterType)), make().Return(expressionGen().makeOuterExpr(((TypeDeclaration) model.getContainer()).getType())), swtch));
    } else {
        stmts.add(swtch);
    }
    mdb.body(stmts.toList());
    classBuilder.method(mdb);
}
Also used : ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Function(org.eclipse.ceylon.model.typechecker.model.Function) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCSwitch(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCSwitch) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCCase(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCase)

Example 48 with TypeDeclaration

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

the class ClassTransformer method transformTypeParameters.

<T> void transformTypeParameters(GenericBuilder<T> classBuilder, Declaration model) {
    java.util.List<TypeParameter> typeParameters = Strategy.getEffectiveTypeParameters(model);
    if (typeParameters != null) {
        for (TypeParameter param : typeParameters) {
            Scope cont = param.getContainer();
            if (cont instanceof TypeDeclaration) {
                TypeDeclaration container = (TypeDeclaration) cont;
                classBuilder.typeParameter(param);
                if (classBuilder instanceof ClassDefinitionBuilder) {
                    // Copy to the companion too
                    ClassDefinitionBuilder companionBuilder = ((ClassDefinitionBuilder) classBuilder).getCompanionBuilder(container);
                    if (companionBuilder != null)
                        companionBuilder.typeParameter(param);
                }
            }
        }
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 49 with TypeDeclaration

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

the class ClassTransformer method addAtContainer.

private void addAtContainer(ClassDefinitionBuilder classBuilder, TypeDeclaration model) {
    Scope scope = Decl.getNonSkippedContainer((Scope) model);
    Scope declarationScope = Decl.getFirstDeclarationContainer((Scope) model);
    boolean inlineObjectInToplevelAttr = Decl.isTopLevelObjectExpressionType(model);
    if (scope == null || (scope instanceof Package && !inlineObjectInToplevelAttr) && scope == declarationScope)
        return;
    if (scope instanceof ClassOrInterface && scope == declarationScope && !inlineObjectInToplevelAttr && // we do not check for types inside initialiser section which are private and not captured because we treat them as members
    !(model instanceof Interface && Decl.hasLocalNotInitializerAncestor(model))) {
        ClassOrInterface container = (ClassOrInterface) scope;
        List<JCAnnotation> atContainer = makeAtContainer(container.getType(), model.isStatic());
        classBuilder.annotations(atContainer);
    } else {
        if (model instanceof Interface)
            classBuilder.annotations(makeLocalContainerPath((Interface) model));
        Declaration declarationContainer = getDeclarationContainer(model);
        classBuilder.annotations(makeAtLocalDeclaration(model.getQualifier(), declarationContainer == null));
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Package(org.eclipse.ceylon.model.typechecker.model.Package) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)

Example 50 with TypeDeclaration

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

the class ClassTransformer method transformClassAlias.

private void transformClassAlias(final Tree.ClassDeclaration def, ClassDefinitionBuilder classBuilder) {
    ClassAlias model = (ClassAlias) def.getDeclarationModel();
    Type aliasedClass = model.getExtendedType();
    TypeDeclaration classOrCtor = def.getClassSpecifier().getType().getDeclarationModel();
    while (classOrCtor instanceof ClassAlias) {
        classOrCtor = ((ClassAlias) classOrCtor).getConstructor();
    }
    classBuilder.annotations(makeAtAlias(aliasedClass, classOrCtor instanceof Constructor ? (Constructor) classOrCtor : null));
    classBuilder.isAlias(true);
    MethodDefinitionBuilder instantiator = transformClassAliasInstantiator(def, model, aliasedClass);
    ClassDefinitionBuilder cbInstantiator = null;
    switch(Strategy.defaultParameterMethodOwner(model)) {
        case STATIC:
            cbInstantiator = classBuilder;
            break;
        case OUTER:
            cbInstantiator = classBuilder.getContainingClassBuilder();
            break;
        case OUTER_COMPANION:
            cbInstantiator = classBuilder.getContainingClassBuilder().getCompanionBuilder(ModelUtil.getClassOrInterfaceContainer(model, true));
            break;
        default:
            throw BugException.unhandledEnumCase(Strategy.defaultParameterMethodOwner(model));
    }
    cbInstantiator.method(instantiator);
}
Also used : ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) Type(org.eclipse.ceylon.model.typechecker.model.Type) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) 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