Search in sources :

Example 46 with JCExpression

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.

the class ClassTransformer method generateIndirectGetterBlock.

private JCTree.JCBlock generateIndirectGetterBlock(Value v) {
    JCTree.JCExpression returnExpr;
    returnExpr = naming.makeQualIdent(naming.makeName(v, Naming.NA_WRAPPER), "get_");
    returnExpr = make().Apply(null, returnExpr, List.<JCExpression>nil());
    JCReturn returnValue = make().Return(returnExpr);
    List<JCStatement> stmts = List.<JCTree.JCStatement>of(returnValue);
    JCTree.JCBlock block = make().Block(0L, stmts);
    return block;
}
Also used : JCReturn(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCReturn) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)

Example 47 with JCExpression

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.

the class ClassTransformer method makeCompanionAccessor.

private MethodDefinitionBuilder makeCompanionAccessor(Interface iface, Type satisfiedType, Class currentType, boolean forImplementor) {
    MethodDefinitionBuilder thisMethod = MethodDefinitionBuilder.systemMethod(this, naming.getCompanionAccessorName(iface));
    thisMethod.noModelAnnotations();
    JCExpression typeExpr;
    if (!forImplementor && Decl.isAncestorLocal(iface)) {
        // For a local interface the return type cannot be a local
        // companion class, because that won't be visible at the
        // top level, so use Object instead
        typeExpr = make().Type(syms().objectType);
    } else {
        typeExpr = makeJavaType(satisfiedType, JT_COMPANION);
    }
    thisMethod.resultType(new TransformedType(typeExpr, null, makeAtNonNull()));
    if (forImplementor) {
        thisMethod.isOverride(true);
    } else {
        thisMethod.ignoreModelAnnotations();
    }
    thisMethod.modifiers(PUBLIC);
    if (forImplementor) {
        thisMethod.body(make().Return(naming.makeCompanionFieldName(iface)));
    } else {
        thisMethod.noBody();
    }
    return thisMethod;
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)

Example 48 with JCExpression

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.

the class ClassTransformer method makeMainForFunction.

/**
 * Makes a {@code main()} method which calls the given top-level method
 * @param method
 */
private MethodDefinitionBuilder makeMainForFunction(Function method) {
    at(null);
    JCExpression qualifiedName = naming.makeName(method, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER);
    List<JCExpression> arguments = makeBottomReifiedTypeParameters(method.getTypeParameters(), List.<JCExpression>nil());
    MethodDefinitionBuilder mainMethod = makeMainMethod(method, make().Apply(null, qualifiedName, arguments));
    return mainMethod;
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)

Example 49 with JCExpression

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.

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() && (ModelUtil.isCaptured(klass) || model.isCaptured())) {
            addWriteReplace(klass, objectClassBuilder);
        }
    }
    makeReadResolve(def, 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;
        naming.closeScopedSubstitutions(def.getScope());
    }
    addMissingUnrefinedMembers(def, klass, objectClassBuilder);
    satisfaction(satisfiesTypes, klass, objectClassBuilder);
    serialization(klass, objectClassBuilder);
    if (model != null && model.isToplevel() && def instanceof Tree.ObjectDefinition) {
        // generate a field and getter
        AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, model.getName(), model, true, null).userAnnotations(makeAtIgnore()).userAnnotationsSetter(makeAtIgnore()).immutable().initialValue(makeNewClass(naming.makeName(model, Naming.NA_FQ | Naming.NA_WRAPPER)), BoxingStrategy.BOXED).is(PUBLIC, klass.isShared()).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(childDefs);
    objectClassBuilder.getInitBuilder().modifiers(PRIVATE);
    objectClassBuilder.addGetTypeMethod(klass.getType());
    if (model != null)
        objectClassBuilder.modelAnnotations(model.getAnnotations()).modifiers(modifierTransformation().object(model));
    at(def);
    List<JCTree> result = objectClassBuilder.build();
    if (makeLocalInstance && !model.isStatic()) {
        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 && model.isClassOrInterfaceMember()) {
        boolean generateGetter = ModelUtil.isCaptured(model);
        JCExpression type = makeJavaType(klass.getType());
        if (generateGetter) {
            int modifiers = TRANSIENT | PRIVATE | (model.isStatic() ? STATIC : 0);
            JCExpression initialValue = makeNull();
            containingClassBuilder.field(modifiers, name, type, initialValue, false);
            AttributeDefinitionBuilder getter = AttributeDefinitionBuilder.getter(this, name, model).modifiers(modifierTransformation().getterSetter(model, false));
            if (def instanceof Tree.ObjectDefinition) {
                getter.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, ((Tree.ObjectDefinition) def)));
            }
            ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
            stmts.add(make().If(make().Binary(JCTree.Tag.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 | (model.isStatic() ? STATIC : 0);
            JCExpression initialValue = makeNewClass(makeJavaType(klass.getType()), null);
            containingClassBuilder.field(modifiers, name, type, initialValue, true);
        }
    }
    return result;
}
Also used : JCFieldAccess(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCFieldAccess) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)

Example 50 with JCExpression

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression in project ceylon by eclipse.

the class ClassTransformer method makeCompanionInstanceAssignment.

/**
 * Returns the companion instances assignment expression used in the constructor,
 * e.g.
 * <pre>
 * this.$ceylon$language$Enumerable$this$ = new .ceylon.language.Enumerable$impl<.org.eclipse.ceylon.compiler.java.test.structure.klass.SerializableEnumerable>(.org.eclipse.ceylon.compiler.java.test.structure.klass.SerializableEnumerable.$TypeDescriptor$, this);
 * </pre>
 * @param classBuilder
 * @return
 */
private JCExpressionStatement makeCompanionInstanceAssignment(final Class model, final Interface iface, final Type satisfiedType) {
    final Type bestSatisfiedType = getBestSatisfiedType(model.getType(), iface);
    JCExpression containerInstance = null;
    if (!iface.isToplevel() && !Decl.isLocal(iface)) {
        // if it's a member type we need to qualify the new instance with its $impl container
        ClassOrInterface interfaceContainer = ModelUtil.getClassOrInterfaceContainer(iface, false);
        if (interfaceContainer instanceof Interface) {
            ClassOrInterface modelContainer = model;
            // first try to find exactly the interface we are looking for
            while ((modelContainer = ModelUtil.getClassOrInterfaceContainer(modelContainer, false)) != null && !modelContainer.equals(interfaceContainer)) {
            // keep searching
            }
            // then find one that inherits it
            if (modelContainer == null) {
                modelContainer = model;
                while ((modelContainer = ModelUtil.getClassOrInterfaceContainer(modelContainer, false)) != null && modelContainer.getType().getSupertype(interfaceContainer) == null) {
                // keep searching
                }
            }
            if (modelContainer == null) {
                throw new BugException("Could not find container that satisfies interface " + iface.getQualifiedNameString() + " to find qualifying instance for companion instance for " + model.getQualifiedNameString());
            }
            // if it's an interface we just qualify it properly
            if (modelContainer instanceof Interface) {
                JCExpression containerType = makeJavaType(modelContainer.getType(), JT_COMPANION | JT_SATISFIES | JT_RAW);
                containerInstance = makeSelect(containerType, "this");
            } else {
                // it's a class: find the right field used for the interface container impl
                String containerFieldName = getCompanionFieldName((Interface) interfaceContainer);
                JCExpression containerType = makeJavaType(modelContainer.getType(), JT_SATISFIES);
                containerInstance = makeSelect(makeSelect(containerType, "this"), containerFieldName);
            }
        }
    }
    List<JCExpression> state = List.nil();
    // pass all reified type info to the constructor
    for (JCExpression t : makeReifiedTypeArguments(satisfiedType)) {
        state = state.append(t);
    }
    // pass the instance of this
    state = state.append(expressionGen().applyErasureAndBoxing(naming.makeThis(), model.getType(), false, true, BoxingStrategy.BOXED, bestSatisfiedType, ExpressionTransformer.EXPR_FOR_COMPANION));
    final JCExpression ifaceImplType;
    if (!iface.isToplevel() && !Decl.isLocal(iface) && ModelUtil.getClassOrInterfaceContainer(iface, false) instanceof Interface) {
        ifaceImplType = makeJavaType(bestSatisfiedType, JT_COMPANION | JT_CLASS_NEW | JT_NON_QUALIFIED);
    } else {
        ifaceImplType = makeJavaType(bestSatisfiedType, JT_COMPANION | JT_CLASS_NEW);
    }
    JCExpression newInstance = make().NewClass(containerInstance, null, ifaceImplType, state, null);
    JCExpressionStatement companionInstanceAssign = make().Exec(make().Assign(// TODO Use qualified name for quoting?
    makeSelect("this", getCompanionFieldName(iface)), newInstance));
    return companionInstanceAssign;
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCExpressionStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpressionStatement) 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

JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)224 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)95 Type (org.eclipse.ceylon.model.typechecker.model.Type)95 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)74 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)53 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)53 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)45 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)41 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)39 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)38 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)33 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)32 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)30 JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)28 Function (org.eclipse.ceylon.model.typechecker.model.Function)26 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 Value (org.eclipse.ceylon.model.typechecker.model.Value)22 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)21 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)21 Class (org.eclipse.ceylon.model.typechecker.model.Class)17