Search in sources :

Example 26 with Class

use of com.redhat.ceylon.model.typechecker.model.Class in project ceylon-compiler by ceylon.

the class LinkRenderer method processAnnotationParam.

private String processAnnotationParam(String text) {
    if (text.equals("module")) {
        Module mod = getCurrentModule();
        if (mod != null) {
            return processModule(mod);
        }
    }
    if (text.startsWith("module ")) {
        String modName = text.substring(7);
        for (Module m : ceylonDocTool.getTypeChecker().getContext().getModules().getListOfModules()) {
            if (m.getNameAsString().equals(modName)) {
                return processModule(m);
            }
        }
    }
    if (text.equals("package")) {
        Package pkg = getCurrentPackage();
        if (pkg != null) {
            return processPackage(pkg);
        }
    }
    if (text.startsWith("package ")) {
        String pkgName = text.substring(8);
        for (Module m : ceylonDocTool.getTypeChecker().getContext().getModules().getListOfModules()) {
            if (pkgName.startsWith(m.getNameAsString() + ".")) {
                Package pkg = m.getPackage(pkgName);
                if (pkg != null) {
                    return processPackage(pkg);
                }
            }
        }
    }
    if (text.equals("interface")) {
        Interface interf = getCurrentInterface();
        if (interf != null) {
            return processProducedType(interf.getType());
        }
    }
    if (text.equals("class")) {
        Class clazz = getCurrentClass();
        if (clazz != null) {
            return processProducedType(clazz.getType());
        }
    }
    String declName;
    Scope currentScope;
    int pkgSeparatorIndex = text.indexOf("::");
    if (pkgSeparatorIndex == -1) {
        declName = text;
        currentScope = resolveScope(scope);
    } else {
        String pkgName = text.substring(0, pkgSeparatorIndex);
        declName = text.substring(pkgSeparatorIndex + 2, text.length());
        currentScope = ceylonDocTool.getCurrentModule().getPackage(pkgName);
    }
    String[] declNames = declName.split("\\.");
    Declaration currentDecl = null;
    boolean isNested = false;
    for (String currentDeclName : declNames) {
        currentDecl = resolveDeclaration(currentScope, currentDeclName, isNested);
        if (currentDecl != null) {
            if (isValueWithTypeObject(currentDecl)) {
                TypeDeclaration objectType = ((Value) currentDecl).getTypeDeclaration();
                currentScope = objectType;
                currentDecl = objectType;
            } else {
                currentScope = resolveScope(currentDecl);
            }
            isNested = true;
        } else {
            break;
        }
    }
    // we can't link to parameters yet, unless they're toplevel
    if (currentDecl != null && !isParameter(currentDecl)) {
        if (currentDecl instanceof TypeDeclaration) {
            return processProducedType(((TypeDeclaration) currentDecl).getType());
        } else {
            return processTypedDeclaration((TypedDeclaration) currentDecl);
        }
    } else {
        return getUnresolvableLink(text);
    }
}
Also used : Scope(com.redhat.ceylon.model.typechecker.model.Scope) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Class(com.redhat.ceylon.model.typechecker.model.Class) Package(com.redhat.ceylon.model.typechecker.model.Package) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Module(com.redhat.ceylon.model.typechecker.model.Module) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 27 with Class

use of com.redhat.ceylon.model.typechecker.model.Class in project ceylon-compiler by ceylon.

the class ClassTransformer method transform.

public List<JCTree> transform(final Tree.ClassOrInterface def) {
    final ClassOrInterface model = def.getDeclarationModel();
    // in that case
    if (model.isAlias() && Decl.isAncestorLocal(def))
        return List.nil();
    naming.clearSubstitutions(model);
    final String javaClassName;
    String ceylonClassName = def.getIdentifier().getText();
    if (def instanceof Tree.AnyInterface) {
        javaClassName = naming.makeTypeDeclarationName(model, QUALIFIED).replaceFirst(".*\\.", "");
    } else {
        javaClassName = Naming.quoteClassName(ceylonClassName);
    }
    ClassDefinitionBuilder instantiatorImplCb;
    ClassDefinitionBuilder instantiatorDeclCb;
    if (Decl.withinInterface(model)) {
        instantiatorImplCb = gen().current().getCompanionBuilder((Interface) model.getContainer());
        instantiatorDeclCb = gen().current();
    } else {
        instantiatorImplCb = gen().current();
        instantiatorDeclCb = null;
    }
    ClassDefinitionBuilder classBuilder = ClassDefinitionBuilder.klass(this, javaClassName, ceylonClassName, Decl.isLocal(model)).forDefinition(model).hasDelegatingConstructors(CodegenUtil.hasDelegatingConstructors(def));
    // Very special case for Anything
    if ("ceylon.language::Anything".equals(model.getQualifiedNameString())) {
        classBuilder.extending(model.getType(), null);
    }
    if (def instanceof Tree.AnyClass) {
        classBuilder.getInitBuilder().modifiers(transformConstructorDeclFlags(model));
        Tree.AnyClass classDef = (Tree.AnyClass) def;
        Class cls = classDef.getDeclarationModel();
        // Member classes need a instantiator method
        boolean generateInstantiator = Strategy.generateInstantiator(cls);
        if (!cls.hasConstructors()) {
            classBuilder.getInitBuilder().userAnnotations(expressionGen().transformAnnotations(OutputElement.CONSTRUCTOR, def));
        }
        if (generateInstantiator && !cls.hasConstructors() && !cls.hasEnumerated()) {
            classBuilder.getInitBuilder().modifiers(PROTECTED);
            generateInstantiators(classBuilder, cls, null, instantiatorDeclCb, instantiatorImplCb, classDef, classDef.getParameterList());
        }
        classBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, def));
        if (def instanceof Tree.ClassDefinition) {
            transformClass((Tree.ClassDefinition) def, cls, classBuilder, classDef.getParameterList(), generateInstantiator, instantiatorDeclCb, instantiatorImplCb);
        } else {
            // class alias
            classBuilder.getInitBuilder().modifiers(PRIVATE);
            transformClassAlias((Tree.ClassDeclaration) def, classBuilder);
        }
        addMissingUnrefinedMembers(def, cls, classBuilder);
    }
    if (def instanceof Tree.AnyInterface) {
        classBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, def));
        if (def instanceof Tree.InterfaceDefinition) {
            transformInterface(def, (Interface) model, classBuilder);
        } else {
            // interface alias
            classBuilder.annotations(makeAtAlias(model.getExtendedType(), null));
            classBuilder.isAlias(true);
        }
        classBuilder.isDynamic(model.isDynamic());
    }
    // make sure we set the container in case we move it out
    addAtContainer(classBuilder, model);
    // Transform the class/interface members
    List<JCStatement> childDefs = visitClassOrInterfaceDefinition(def, classBuilder);
    // everything else is synthetic
    at(null);
    TransformationPlan plan = errors().hasDeclarationError(def);
    if (plan instanceof ThrowerCatchallConstructor) {
        MethodDefinitionBuilder initBuilder = classBuilder.addConstructor();
        initBuilder.body(statementGen().makeThrowUnresolvedCompilationError(plan.getErrorMessage().getMessage()));
        // Although we have the class pl which we could use we don't know 
        // that it won't collide with the default named constructor's pl
        // which would cause a javac error about two constructors with the same sig
        // so we generate a Object... here. There's still a risk of collision though
        // when the default constructor has pl (ObjectArray).
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.implicitParameter(this, "ignored");
        pdb.modifiers(VARARGS);
        pdb.type(make().TypeArray(make().Type(syms().objectType)), null);
        initBuilder.parameter(pdb);
    }
    // If it's a Class without initializer parameters...
    if (Strategy.generateMain(def)) {
        // ... then add a main() method
        classBuilder.method(makeMainForClass(model));
    }
    classBuilder.modelAnnotations(model.getAnnotations()).modifiers(transformClassDeclFlags(model)).satisfies(model.getSatisfiedTypes()).caseTypes(model.getCaseTypes(), model.getSelfType()).defs((List) childDefs);
    // aliases and native headers don't need a $getType method
    if (!model.isAlias()) {
        // only classes get a $getType method
        if (model instanceof Class)
            classBuilder.addGetTypeMethod(model.getType());
        if (supportsReifiedAlias(model))
            classBuilder.reifiedAlias(model.getType());
    }
    // we can add things which depend on knowing all the fields
    if (Strategy.generateJpaCtor(def)) {
        buildJpaConstructor((Class) def.getDeclarationModel(), classBuilder);
    }
    if (model instanceof Class && !(model instanceof ClassAlias)) {
        Class c = (Class) model;
        if (Strategy.introduceJavaIoSerializable(c, typeFact().getJavaIoSerializable())) {
            classBuilder.introduce(make().QualIdent(syms().serializableType.tsym));
            if (Strategy.useSerializationProxy(c) && noValueConstructorErrors((Tree.ClassDefinition) def)) {
                addWriteReplace(c, classBuilder);
            }
        }
        serialization(c, classBuilder);
    }
    // reset position before initializer constructor is generated. 
    at(def);
    List<JCTree> result;
    if (Decl.isAnnotationClass(def)) {
        ListBuffer<JCTree> trees = ListBuffer.lb();
        trees.addAll(transformAnnotationClass((Tree.AnyClass) def));
        transformAnnotationClassConstructor((Tree.AnyClass) def, classBuilder);
        // you only need that method if you satisfy Annotation which is erased to j.l.a.Annotation
        if (model.inherits(typeFact().getAnnotationDeclaration()))
            classBuilder.addAnnotationTypeMethod(model.getType());
        trees.addAll(classBuilder.build());
        result = trees.toList();
    } else {
        result = classBuilder.build();
    }
    return result;
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) ClassAlias(com.redhat.ceylon.model.typechecker.model.ClassAlias) JCTree(com.sun.tools.javac.tree.JCTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) ThrowerCatchallConstructor(com.redhat.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface) TransformationPlan(com.redhat.ceylon.compiler.java.codegen.recovery.TransformationPlan)

Example 28 with Class

use of com.redhat.ceylon.model.typechecker.model.Class in project ceylon-compiler by ceylon.

the class CeylonVisitor method transformSingletonConstructor.

protected void transformSingletonConstructor(HashMap<Constructor, CtorDelegation> delegates, Tree.Enumerated ctor) {
    // generate a constructor
    transformConstructor(ctor, //ctor.getParameterList(), 
    null, ctor.getDelegatedConstructor(), ctor.getBlock(), ctor.getEnumerated(), delegates);
    Class clz = Decl.getConstructedClass(ctor.getEnumerated());
    Value singletonModel = ctor.getDeclarationModel();
    // generate a field
    AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.singleton(gen, //gen.naming.makeTypeDeclarationName(Decl.getConstructedClass(ctor.getEnumerated())), 
    null, null, singletonModel.getName(), singletonModel, false);
    adb.modelAnnotations(gen.makeAtEnumerated());
    adb.modelAnnotations(gen.makeAtIgnore());
    adb.userAnnotations(gen.expressionGen().transformAnnotations(OutputElement.GETTER, ctor));
    adb.fieldAnnotations(gen.expressionGen().transformAnnotations(OutputElement.FIELD, ctor));
    // not setter
    adb.immutable();
    SyntheticName field = gen.naming.getValueConstructorFieldName(singletonModel);
    if (clz.isToplevel()) {
        adb.modifiers((singletonModel.isShared() ? PUBLIC : PRIVATE) | STATIC | FINAL);
        adb.initialValue(gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, Decl.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null));
        classBuilder.defs(adb.build());
    } else if (clz.isClassMember()) {
        adb.modifiers(singletonModel.isShared() ? 0 : PRIVATE);
        // lazy
        adb.initialValue(gen.makeNull());
        List<JCStatement> l = List.<JCStatement>of(gen.make().If(gen.make().Binary(JCTree.EQ, field.makeIdent(), gen.makeNull()), gen.make().Exec(gen.make().Assign(field.makeIdent(), gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, Decl.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null))), null), gen.make().Return(field.makeIdent()));
        adb.getterBlock(gen.make().Block(0, l));
        classBuilder.getContainingClassBuilder().defs(gen.makeVar(PRIVATE | TRANSIENT, field, gen.naming.makeTypeDeclarationExpression(null, Decl.getConstructedClass(ctor.getEnumerated())), gen.makeNull()));
        classBuilder.getContainingClassBuilder().defs(adb.build());
    } else {
        // LOCAL
        classBuilder.after(gen.makeVar(FINAL, field, gen.naming.makeTypeDeclarationExpression(null, Decl.getConstructedClass(ctor.getEnumerated())), gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, Decl.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null)));
        gen.naming.addVariableSubst(singletonModel, field.getName());
    }
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Value(com.redhat.ceylon.model.typechecker.model.Value) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) Class(com.redhat.ceylon.model.typechecker.model.Class) List(com.sun.tools.javac.util.List)

Example 29 with Class

use of com.redhat.ceylon.model.typechecker.model.Class in project ceylon-compiler by ceylon.

the class ClassTransformer method addAmbiguousMember.

private void addAmbiguousMember(ClassDefinitionBuilder classBuilder, Interface model, String name) {
    Declaration member = model.getMember(name, null, false);
    Type satisfiedType = model.getType().getSupertype(model);
    if (member instanceof Class) {
        Class klass = (Class) member;
        if (Strategy.generateInstantiator(member) && !klass.hasConstructors()) {
            // instantiator method implementation
            generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, null, model.getType(), false);
        }
        if (klass.hasConstructors()) {
            for (Declaration m : klass.getMembers()) {
                if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
                    Constructor ctor = (Constructor) m;
                    generateInstantiatorDelegate(classBuilder, satisfiedType, model, klass, ctor, model.getType(), false);
                }
            }
        }
    } else if (member instanceof Function) {
        Function method = (Function) member;
        final TypedReference typedMember = satisfiedType.getTypedMember(method, Collections.<Type>emptyList());
        java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, method);
        final java.util.List<TypeParameter> typeParameters = method.getTypeParameters();
        final java.util.List<Parameter> parameters = method.getFirstParameterList().getParameters();
        for (Parameter param : parameters) {
            if (Strategy.hasDefaultParameterOverload(param)) {
                MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(null, MethodDefinitionBuilder.method(this, method), typedMember, true).makeOverload(method.getFirstParameterList(), param, typeParameters);
                overload.modifiers(PUBLIC | ABSTRACT);
                classBuilder.method(overload);
            }
        }
        final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, method.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, DelegateType.OTHER, false);
        classBuilder.method(concreteMemberDelegate);
    } else if (member instanceof Value || member instanceof Setter) {
        TypedDeclaration attr = (TypedDeclaration) member;
        final TypedReference typedMember = satisfiedType.getTypedMember(attr, Collections.<Type>emptyList());
        if (member instanceof Value) {
            final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(attr), Collections.<Parameter>emptyList(), attr.getTypeErased(), null, DelegateType.OTHER, false);
            classBuilder.method(getterDelegate);
        }
        if (member instanceof Setter) {
            final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(null, typedMember, model.getType(), PUBLIC | ABSTRACT, Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(((Setter) member).getParameter()), ((Setter) member).getTypeErased(), null, DelegateType.OTHER, false);
            classBuilder.method(setterDelegate);
        }
    }
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) ThrowerCatchallConstructor(com.redhat.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Setter(com.redhat.ceylon.model.typechecker.model.Setter) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) ArrayList(java.util.ArrayList) AnnotationList(com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(com.sun.tools.javac.util.List) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)

Example 30 with Class

use of com.redhat.ceylon.model.typechecker.model.Class in project ceylon-compiler by ceylon.

the class ClassTransformer method buildFieldInits.

protected void buildFieldInits(Class model, ClassDefinitionBuilder classBuilder, final ListBuffer<JCStatement> stmts) {
    final HashSet<String> excludeFields = new HashSet<String>();
    // initialize reified type arguments to according to parameters
    for (TypeParameter tp : model.getTypeParameters()) {
        excludeFields.add(naming.getTypeArgumentDescriptorName(tp));
        stmts.add(makeReifiedTypeParameterAssignment(tp));
    }
    // initialize companion instances to a new companion instance
    if (!model.getSatisfiedTypes().isEmpty()) {
        SatisfactionVisitor visitor = new SatisfactionVisitor() {

            @Override
            public void satisfiesDirectly(Class model, Interface iface, boolean alreadySatisfied) {
                if (!alreadySatisfied) {
                    assignCompanion(model, iface);
                }
            }

            @Override
            public void satisfiesIndirectly(Class model, Interface iface, boolean alreadySatisfied) {
                if (!alreadySatisfied) {
                    assignCompanion(model, iface);
                }
            }

            private void assignCompanion(Class model, Interface iface) {
                if (hasImpl(iface) && excludeFields.add(getCompanionFieldName(iface))) {
                    stmts.add(makeCompanionInstanceAssignment(model, iface, model.getType().getSupertype(iface)));
                }
            }

            @Override
            public void satisfiesIndirectlyViaClass(Class model, Interface iface, Class via, boolean alreadySatisfied) {
            // don't care
            }
        };
        walkSatisfiedInterfaces(model, model.getType(), visitor);
    }
    // initialize attribute fields to null or a zero
    appendDefaultFieldInits(classBuilder, stmts, excludeFields);
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface) HashSet(java.util.HashSet)

Aggregations

Class (com.redhat.ceylon.model.typechecker.model.Class)81 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)52 Type (com.redhat.ceylon.model.typechecker.model.Type)45 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)37 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)28 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)26 Function (com.redhat.ceylon.model.typechecker.model.Function)23 IntersectionType (com.redhat.ceylon.model.typechecker.model.IntersectionType)22 UnionType (com.redhat.ceylon.model.typechecker.model.UnionType)22 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)22 TypeParser (com.redhat.ceylon.model.loader.TypeParser)21 Test (org.junit.Test)21 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)20 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)19 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)19 Value (com.redhat.ceylon.model.typechecker.model.Value)19 JCTree (com.sun.tools.javac.tree.JCTree)19 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)17 Interface (com.redhat.ceylon.model.typechecker.model.Interface)17 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)14