Search in sources :

Example 31 with Class

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

the class ClassTransformer method transformAnnotationClass.

/**
     * Transforms an annotation class into a Java annotation type.
     * <pre>
     * annotation class Foo(String s, Integer i=1) {}
     * </pre>
     * is transformed into
     * <pre>
     * @Retention(RetentionPolicy.RUNTIME)
     * @interface Foo$annotation$ {
     *     String s();
     *     long i() default 1;
     * }
     * </pre>
     * If the annotation class is a subtype of SequencedAnnotation a wrapper
     * annotation is also generated:
     * <pre>
     * @Retention(RetentionPolicy.RUNTIME)
     * @interface Foo$annotations${
     *     Foo$annotation$[] value();
     * }
     * </pre>
     */
private List<JCTree> transformAnnotationClass(Tree.AnyClass def) {
    Class klass = (Class) def.getDeclarationModel();
    String annotationName = Naming.suffixName(Suffix.$annotation$, klass.getName());
    ClassDefinitionBuilder annoBuilder = ClassDefinitionBuilder.klass(this, annotationName, null, false);
    // annotations are never explicitly final in Java
    annoBuilder.modifiers(Flags.ANNOTATION | Flags.INTERFACE | (transformClassDeclFlags(klass) & ~FINAL));
    annoBuilder.getInitBuilder().modifiers(transformClassDeclFlags(klass) & ~FINAL);
    annoBuilder.annotations(makeAtRetention(RetentionPolicy.RUNTIME));
    annoBuilder.annotations(makeAtIgnore());
    annoBuilder.annotations(expressionGen().transformAnnotations(OutputElement.ANNOTATION_TYPE, def));
    for (Tree.Parameter p : def.getParameterList().getParameters()) {
        Parameter parameterModel = p.getParameterModel();
        annoBuilder.method(makeAnnotationMethod(p));
    }
    List<JCTree> result;
    if (isSequencedAnnotation(klass)) {
        result = annoBuilder.annotations(makeAtAnnotationTarget(EnumSet.noneOf(AnnotationTarget.class))).build();
        String wrapperName = Naming.suffixName(Suffix.$annotations$, klass.getName());
        ClassDefinitionBuilder sequencedBuilder = ClassDefinitionBuilder.klass(this, wrapperName, null, false);
        // annotations are never explicitely final in Java
        sequencedBuilder.modifiers(Flags.ANNOTATION | Flags.INTERFACE | (transformClassDeclFlags(klass) & ~FINAL));
        sequencedBuilder.annotations(makeAtRetention(RetentionPolicy.RUNTIME));
        MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, naming.getSequencedAnnotationMethodName());
        mdb.annotationFlags(Annotations.MODEL_AND_USER);
        mdb.modifiers(PUBLIC | ABSTRACT);
        mdb.resultType(null, make().TypeArray(makeJavaType(klass.getType(), JT_ANNOTATION)));
        mdb.noBody();
        ClassDefinitionBuilder sequencedAnnotation = sequencedBuilder.method(mdb);
        sequencedAnnotation.annotations(transformAnnotationConstraints(klass));
        sequencedAnnotation.annotations(makeAtIgnore());
        result = result.appendList(sequencedAnnotation.build());
    } else {
        result = annoBuilder.annotations(transformAnnotationConstraints(klass)).build();
    }
    return result;
}
Also used : JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTree(com.sun.tools.javac.tree.JCTree) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass)

Example 32 with Class

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

the class ClassTransformer method makeConstructorNameParameter.

private ParameterDefinitionBuilder makeConstructorNameParameter(Constructor ctor, DeclNameFlag... flags) {
    Class clz = (Class) ctor.getContainer();
    ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.implicitParameter(this, Naming.Unfix.$name$.toString());
    pdb.ignored();
    JCExpression type = naming.makeTypeDeclarationExpression(null, ctor, flags);
    pdb.type(type, null);
    return pdb;
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass)

Example 33 with Class

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

the class ExpressionTransformer method transform.

public JCTree transform(Tree.TypeLiteral expr) {
    at(expr);
    if (!expr.getWantsDeclaration()) {
        if (expr.getDeclaration() instanceof Constructor) {
            JCExpression classLiteral = makeTypeLiteralCall(expr.getType().getTypeModel().getQualifyingType(), false, expr.getTypeModel());
            TypeDeclaration classModelDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(expr.getType().getTypeModel().getQualifyingType().getDeclaration().isMember() ? "MemberClass" : "Class");
            JCTypeCast typeCast = make().TypeCast(makeJavaType(classModelDeclaration.appliedType(null, List.of(expr.getType().getTypeModel().getQualifyingType(), typeFact().getNothingType()))), classLiteral);
            Type callableType = expr.getTypeModel().getFullType();
            JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
            return make().Apply(null, naming.makeQualIdent(typeCast, "getConstructor"), List.<JCExpression>of(reifiedArgumentsExpr, make().Literal(expr.getDeclaration().getName())));
        } else {
            return makeTypeLiteralCall(expr.getType().getTypeModel(), true, expr.getTypeModel());
        }
    } else if (expr.getDeclaration() instanceof TypeParameter) {
        // we must get it from its container
        TypeParameter declaration = (TypeParameter) expr.getDeclaration();
        Node node = expr;
        return makeTypeParameterDeclaration(node, declaration);
    } else if (expr.getDeclaration() instanceof Constructor || expr instanceof Tree.NewLiteral) {
        Constructor ctor;
        if (expr.getDeclaration() instanceof Constructor) {
            ctor = (Constructor) expr.getDeclaration();
        } else {
            ctor = Decl.getDefaultConstructor((Class) expr.getDeclaration());
        }
        JCExpression metamodelCall = makeTypeDeclarationLiteral(Decl.getConstructedClass(ctor));
        metamodelCall = make().TypeCast(makeJavaType(typeFact().getClassDeclarationType(), JT_RAW), metamodelCall);
        metamodelCall = make().Apply(null, naming.makeQualIdent(metamodelCall, "getConstructorDeclaration"), List.<JCExpression>of(make().Literal(ctor.getName() == null ? "" : ctor.getName())));
        if (Decl.isEnumeratedConstructor(ctor)) {
            metamodelCall = make().TypeCast(makeJavaType(typeFact().getValueConstructorDeclarationType(), JT_RAW), metamodelCall);
        } else /*else if (Decl.isDefaultConstructor(ctor)){
                metamodelCall = make().TypeCast(
                        makeJavaType(typeFact().getDefaultConstructorDeclarationType(), JT_RAW), metamodelCall);
            } */
        {
            metamodelCall = make().TypeCast(makeJavaType(typeFact().getCallableConstructorDeclarationType(), JT_RAW), metamodelCall);
        }
        return metamodelCall;
    } else if (expr.getDeclaration() instanceof ClassOrInterface || expr.getDeclaration() instanceof TypeAlias) {
        // use the generated class to get to the declaration literal
        JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) expr.getDeclaration());
        Type exprType = expr.getTypeModel().resolveAliases();
        // now cast if required
        if (!exprType.isExactly(((TypeDeclaration) typeFact().getLanguageModuleDeclarationDeclaration("NestableDeclaration")).getType())) {
            JCExpression type = makeJavaType(exprType, JT_NO_PRIMITIVES);
            return make().TypeCast(type, metamodelCall);
        }
        return metamodelCall;
    } else {
        return makeErroneous(expr, "compiler bug: " + expr.getDeclaration() + " is an unsupported declaration type");
    }
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Type(com.redhat.ceylon.model.typechecker.model.Type) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTypeCast(com.sun.tools.javac.tree.JCTree.JCTypeCast) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) Node(com.redhat.ceylon.compiler.typechecker.tree.Node) 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) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 34 with Class

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

the class ExpressionTransformer method transformConstructorDelegation.

/**
     * Transform a delegated constructor call ({@code extends XXX()})
     * which may be either a superclass initializer/constructor or a 
     * same-class constructor. 
     * @param extendedType
     * @param delegation The kind of delegation 
     * @param invocation
     * @param classBuilder
     * @return
     */
JCStatement transformConstructorDelegation(Node extendedType, CtorDelegation delegation, Tree.InvocationExpression invocation, ClassDefinitionBuilder classBuilder, boolean forDelegationConstructor) {
    if (delegation != null && delegation.isError()) {
        return delegation.makeThrow(this);
    }
    Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) invocation.getPrimary()).getDeclaration();
    java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
    if (paramLists.isEmpty()) {
        classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: super class " + primaryDeclaration.getName() + " is missing parameter list")));
        return null;
    }
    SuperInvocation builder = new SuperInvocation(this, classBuilder.getForDefinition(), delegation, invocation, paramLists.get(0), forDelegationConstructor);
    CallBuilder callBuilder = CallBuilder.instance(this);
    boolean prevFnCall = withinInvocation(true);
    try {
        if (invocation.getPrimary() instanceof Tree.StaticMemberOrTypeExpression) {
            transformTypeArguments(callBuilder, (Tree.StaticMemberOrTypeExpression) invocation.getPrimary());
        }
        at(builder.getNode());
        JCExpression expr = null;
        Scope outerDeclaration;
        if (Decl.isConstructor(primaryDeclaration)) {
            outerDeclaration = builder.getPrimaryDeclaration().getContainer().getContainer();
        } else {
            outerDeclaration = builder.getPrimaryDeclaration().getContainer();
        }
        if ((Strategy.generateInstantiator(builder.getPrimaryDeclaration()) || builder.getPrimaryDeclaration() instanceof Class) && outerDeclaration instanceof Interface) {
            // If the subclass is inner to an interface then it will be 
            // generated inner to the companion and we need to qualify the 
            // super(), *unless* the subclass is nested within the same 
            // interface as it's superclass.
            Scope outer = builder.getSub().getContainer();
            while (!(outer instanceof Package)) {
                if (outer == outerDeclaration) {
                    expr = naming.makeSuper();
                    break;
                }
                outer = outer.getContainer();
            }
            if (expr == null) {
                if (delegation.isSelfDelegation()) {
                    throw new BugException();
                }
                Interface iface = (Interface) outerDeclaration;
                JCExpression superQual;
                if (Decl.getClassOrInterfaceContainer(classBuilder.getForDefinition(), false) instanceof Interface) {
                    superQual = naming.makeCompanionAccessorCall(naming.makeQuotedThis(), iface);
                } else {
                    superQual = naming.makeCompanionFieldName(iface);
                }
                expr = naming.makeQualifiedSuper(superQual);
            }
        } else {
            expr = delegation.isSelfDelegation() ? naming.makeThis() : naming.makeSuper();
        }
        final List<JCExpression> superArguments = transformSuperInvocationArguments(classBuilder, builder, callBuilder);
        JCExpression superExpr = callBuilder.invoke(expr).arguments(superArguments).build();
        return at(extendedType).Exec(superExpr);
    //classBuilder.getInitBuilder().superCall(at(extendedType).Exec(superExpr));
    } finally {
        withinInvocation(prevFnCall);
    }
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Scope(com.redhat.ceylon.model.typechecker.model.Scope) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) 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) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Package(com.redhat.ceylon.model.typechecker.model.Package) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 35 with Class

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

the class ExpressionTransformer method makeJavaStaticInvocation.

JCExpression makeJavaStaticInvocation(CeylonTransformer gen, final Functional methodOrClass, Reference producedReference, final ParameterList parameterList) {
    CallBuilder callBuilder = CallBuilder.instance(gen);
    if (methodOrClass instanceof Function) {
        callBuilder.invoke(gen.naming.makeName((Function) methodOrClass, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED));
    } else if (methodOrClass instanceof Class) {
        callBuilder.instantiate(gen.makeJavaType(((Class) methodOrClass).getType(), JT_RAW | JT_NO_PRIMITIVES));
    }
    ListBuffer<ExpressionAndType> reified = ListBuffer.lb();
    DirectInvocation.addReifiedArguments(gen, producedReference, reified);
    for (ExpressionAndType reifiedArgument : reified) {
        callBuilder.argument(reifiedArgument.expression);
    }
    for (Parameter parameter : parameterList.getParameters()) {
        callBuilder.argument(gen.naming.makeQuotedIdent(parameter.getName()));
    }
    JCExpression innerInvocation = callBuilder.build();
    return innerInvocation;
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) 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)

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