Search in sources :

Example 86 with JCTree

use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.

the class CeylonTransformer method transformAttributeGetter.

public JCExpression transformAttributeGetter(TypedDeclaration declarationModel, final JCExpression expression) {
    final String attrName = declarationModel.getName();
    final String attrClassName = Naming.getAttrClassName(declarationModel, 0);
    JCBlock getterBlock = makeGetterBlock(expression);
    // For everything else generate a getter/setter method
    AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.indirect(this, attrClassName, attrName, declarationModel, declarationModel.isToplevel()).getterBlock(getterBlock).immutable();
    List<JCTree> attr = builder.build();
    JCNewClass newExpr = makeNewClass(attrClassName, false, null);
    JCExpression result = makeLetExpr(naming.temp(), List.<JCStatement>of((JCStatement) attr.get(0)), newExpr);
    return result;
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 87 with JCTree

use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.

the class ClassTransformer method transformObject.

private List<JCTree> transformObject(Node def, Tree.Declaration annotated, Tree.SatisfiedTypes satisfiesTypes, Value model, Class klass, ClassDefinitionBuilder containingClassBuilder, boolean makeLocalInstance) {
    naming.clearSubstitutions(klass);
    String name = klass.getName();
    String javaClassName = Naming.quoteClassName(name);
    ClassDefinitionBuilder objectClassBuilder = ClassDefinitionBuilder.object(this, javaClassName, name, Decl.isLocal(klass)).forDefinition(klass);
    if (Strategy.introduceJavaIoSerializable(klass, typeFact().getJavaIoSerializable())) {
        objectClassBuilder.introduce(make().QualIdent(syms().serializableType.tsym));
        if (def instanceof Tree.ObjectDefinition && klass.isMember() && (klass.isShared() || klass.isCaptured() || model.isCaptured())) {
            addWriteReplace(klass, objectClassBuilder);
        }
    }
    makeReadResolve(objectClassBuilder, klass, model);
    // Make sure top types satisfy reified type
    addReifiedTypeInterface(objectClassBuilder, klass);
    if (supportsReifiedAlias(klass))
        objectClassBuilder.reifiedAlias(klass.getType());
    CeylonVisitor visitor = gen().visitor;
    final ListBuffer<JCTree> prevDefs = visitor.defs;
    final boolean prevInInitializer = visitor.inInitializer;
    final ClassDefinitionBuilder prevClassBuilder = visitor.classBuilder;
    List<JCStatement> childDefs;
    try {
        visitor.defs = new ListBuffer<JCTree>();
        visitor.inInitializer = true;
        visitor.classBuilder = objectClassBuilder;
        def.visitChildren(visitor);
        childDefs = (List<JCStatement>) visitor.getResult().toList();
    } finally {
        visitor.classBuilder = prevClassBuilder;
        visitor.inInitializer = prevInInitializer;
        visitor.defs = prevDefs;
    }
    addMissingUnrefinedMembers(def, klass, objectClassBuilder);
    satisfaction(satisfiesTypes, klass, objectClassBuilder);
    serialization(klass, objectClassBuilder);
    if (model != null && Decl.isToplevel(model) && def instanceof Tree.ObjectDefinition) {
        // generate a field and getter
        AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, null, objectClassBuilder, model.getName(), model, true).userAnnotations(makeAtIgnore()).userAnnotationsSetter(makeAtIgnore()).immutable().initialValue(makeNewClass(naming.makeName(model, Naming.NA_FQ | Naming.NA_WRAPPER))).is(PUBLIC, Decl.isShared(klass)).is(STATIC, true);
        if (annotated != null) {
            builder.fieldAnnotations(expressionGen().transformAnnotations(OutputElement.FIELD, annotated));
            builder.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, annotated));
        }
        objectClassBuilder.defs(builder.build());
    }
    if (annotated != null) {
        objectClassBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, annotated));
        objectClassBuilder.getInitBuilder().userAnnotations(expressionGen().transformAnnotations(OutputElement.CONSTRUCTOR, annotated));
    }
    // make sure we set the container in case we move it out
    addAtContainer(objectClassBuilder, klass);
    objectClassBuilder.annotations(makeAtObject()).satisfies(klass.getSatisfiedTypes()).defs((List) childDefs);
    objectClassBuilder.getInitBuilder().modifiers(PRIVATE);
    objectClassBuilder.addGetTypeMethod(klass.getType());
    if (model != null)
        objectClassBuilder.modelAnnotations(model.getAnnotations()).modifiers(transformObjectDeclFlags(model));
    List<JCTree> result = objectClassBuilder.build();
    if (makeLocalInstance) {
        if (model.isSelfCaptured()) {
            // if it's captured we need to box it and define the var before the class, so it can access it
            JCNewClass newInstance = makeNewClass(objectClassBuilder.getClassName(), false, null);
            JCFieldAccess setter = naming.makeSelect(Naming.getLocalValueName(model), Naming.getSetterName(model));
            JCStatement assign = make().Exec(make().Assign(setter, newInstance));
            result = result.prepend(assign);
            JCVariableDecl localDecl = makeVariableBoxDecl(null, model);
            result = result.prepend(localDecl);
        } else {
            // not captured, we can define the var after the class
            JCVariableDecl localDecl = makeLocalIdentityInstance(name, objectClassBuilder.getClassName(), false);
            result = result.append(localDecl);
        }
    } else if (model != null && Decl.withinClassOrInterface(model)) {
        boolean generateGetter = Decl.isCaptured(model);
        JCExpression type = makeJavaType(klass.getType());
        if (generateGetter) {
            int modifiers = TRANSIENT | PRIVATE;
            JCExpression initialValue = makeNull();
            containingClassBuilder.field(modifiers, name, type, initialValue, false);
            AttributeDefinitionBuilder getter = AttributeDefinitionBuilder.getter(this, name, model).modifiers(transformAttributeGetSetDeclFlags(model, false));
            if (def instanceof Tree.ObjectDefinition) {
                getter.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, ((Tree.ObjectDefinition) def)));
            }
            ListBuffer<JCStatement> stmts = ListBuffer.<JCStatement>lb();
            stmts.add(make().If(make().Binary(JCTree.EQ, naming.makeUnquotedIdent(Naming.quoteFieldName(name)), makeNull()), make().Exec(make().Assign(naming.makeUnquotedIdent(Naming.quoteFieldName(name)), makeNewClass(makeJavaType(klass.getType()), null))), null));
            stmts.add(make().Return(naming.makeUnquotedIdent(Naming.quoteFieldName(name))));
            getter.getterBlock(make().Block(0, stmts.toList()));
            result = result.appendList(getter.build());
        } else {
            int modifiers = FINAL;
            JCExpression initialValue = makeNewClass(makeJavaType(klass.getType()), null);
            containingClassBuilder.field(modifiers, name, type, initialValue, true);
        }
    }
    return result;
}
Also used : JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass)

Example 88 with JCTree

use of com.sun.tools.javac.tree.JCTree in project ceylon-compiler by ceylon.

the class ClassTransformer method transformConstructorName.

protected void transformConstructorName(ClassDefinitionBuilder classBuilder, ListBuffer<JCTree> result, Constructor ctor, Class clz, int classMods, String ctorName, DeclNameFlag... declFlags) {
    ClassDefinitionBuilder constructorNameClass = ClassDefinitionBuilder.klass(this, ctorName, null, true);
    JCVariableDecl constructorNameConst;
    if (Decl.isEnumeratedConstructor(ctor)) {
        if (clz.isToplevel()) {
            classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
            classMods |= PRIVATE | STATIC | FINAL;
        } else if (clz.isMember() && Decl.isToplevel((Declaration) clz.getContainer())) {
            classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
            classMods |= FINAL;
            if (!Decl.isAncestorLocal(ctor)) {
                classMods |= STATIC;
            }
            if (!ctor.isShared()) {
                classMods |= PRIVATE;
            }
        } else {
            classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
            classMods |= FINAL;
        }
        constructorNameConst = null;
    } else {
        if (clz.isToplevel() || (clz.isMember() && Decl.isToplevel((Declaration) clz.getContainer()))) {
            classMods |= STATIC | FINAL;
            constructorNameConst = make().VarDef(make().Modifiers(classMods, makeAtIgnore()), names().fromString(ctorName), naming.makeTypeDeclarationExpression(null, ctor, declFlags), makeNull());
        } else {
            classMods &= ~(PRIVATE | PROTECTED | PUBLIC);
            constructorNameConst = null;
        }
    }
    constructorNameClass.modifiers(classMods);
    constructorNameClass.annotations(makeAtIgnore());
    constructorNameClass.annotations(makeAtConstructorName(ctor.getName(), contains(declFlags, DeclNameFlag.DELEGATION)));
    constructorNameClass.getInitBuilder().modifiers(PRIVATE);
    List<JCTree> ctorNameClassDecl = constructorNameClass.build();
    if (clz.isToplevel()) {
        result.addAll(ctorNameClassDecl);
        classBuilder.defs(constructorNameConst);
    } else if (clz.isClassMember()) {
        classBuilder.getContainingClassBuilder().defs(ctorNameClassDecl);
        classBuilder.getContainingClassBuilder().defs(constructorNameConst);
    } else if (clz.isInterfaceMember()) {
        classBuilder.getContainingClassBuilder().getCompanionBuilder(clz).defs(ctorNameClassDecl);
        classBuilder.getContainingClassBuilder().getCompanionBuilder(clz).defs(constructorNameConst);
    } else {
        classBuilder.defs(ctorNameClassDecl);
    }
}
Also used : JCTree(com.sun.tools.javac.tree.JCTree) 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) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 89 with JCTree

use of com.sun.tools.javac.tree.JCTree 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 90 with JCTree

use of com.sun.tools.javac.tree.JCTree 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)

Aggregations

JCTree (com.sun.tools.javac.tree.JCTree)183 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)28 Symbol (com.sun.tools.javac.code.Symbol)22 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)22 Type (com.sun.tools.javac.code.Type)19 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)17 Tree (com.sun.source.tree.Tree)15 ExpressionTree (com.sun.source.tree.ExpressionTree)14 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)14 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)11 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)11 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)10 ArrayList (java.util.ArrayList)10 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)9 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)9 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)8 ListBuffer (com.sun.tools.javac.util.ListBuffer)8 Type (com.redhat.ceylon.model.typechecker.model.Type)7 ClassTree (com.sun.source.tree.ClassTree)7 MemberSelectTree (com.sun.source.tree.MemberSelectTree)7