Search in sources :

Example 96 with JCStatement

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

the class AbstractTransformer method makeGetterBlock.

JCBlock makeGetterBlock(TypedDeclaration declarationModel, final Tree.Block block, final Tree.SpecifierOrInitializerExpression expression) {
    List<JCStatement> stats;
    if (block != null) {
        stats = statementGen().transformBlock(block);
    } else {
        BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(declarationModel);
        Type type = declarationModel.getType();
        JCStatement transStat;
        HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getExpression());
        if (error != null) {
            transStat = this.makeThrowUnresolvedCompilationError(error);
        } else {
            transStat = make().Return(expressionGen().transformExpression(expression.getExpression(), boxing, type));
        }
        stats = List.<JCStatement>of(transStat);
    }
    JCBlock getterBlock = make().Block(0, stats);
    return getterBlock;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 97 with JCStatement

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

the class AbstractTransformer method makeLetExpr.

private JCExpression makeLetExpr(String varBaseName, List<JCStatement> statements, JCExpression... args) {
    String varName = null;
    ListBuffer<JCStatement> decls = ListBuffer.lb();
    int i;
    for (i = 0; (i + 1) < args.length; i += 2) {
        JCExpression typeExpr = args[i];
        JCExpression valueExpr = args[i + 1];
        varName = varBaseName + ((args.length > 3) ? "$" + i : "");
        JCVariableDecl varDecl = makeVar(varName, typeExpr, valueExpr);
        decls.append(varDecl);
    }
    JCExpression result;
    if (i == args.length) {
        result = makeUnquotedIdent(varName);
    } else {
        result = args[i];
    }
    if (statements != null) {
        decls.appendList(statements);
    }
    return make().LetExpr(decls.toList(), result);
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 98 with JCStatement

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

the class ClassTransformer method addRefinedThrowerAttribute.

/**
     * Adds a getter (and possibly a setter) to {@code classBuilder} 
     * which throws
     * @param classBuilder The class builder to add the method to
     * @param error The message
     * @param classModel The class which doesn't refine {@code formalAttribute}
     * @param formalAttribute The formal attribute that hasn't been refined in {@code classModel}
     */
private void addRefinedThrowerAttribute(ClassDefinitionBuilder classBuilder, String error, ClassOrInterface classModel, Value formalAttribute) {
    Value refined = refineValue(formalAttribute, formalAttribute.appliedTypedReference(null, null), classModel, classModel.getUnit());
    AttributeDefinitionBuilder getterBuilder = AttributeDefinitionBuilder.getter(this, refined.getName(), refined);
    getterBuilder.skipField();
    getterBuilder.modifiers(transformAttributeGetSetDeclFlags(refined, false));
    getterBuilder.getterBlock(make().Block(0, List.<JCStatement>of(makeThrowUnresolvedCompilationError(error))));
    classBuilder.attribute(getterBuilder);
    if (formalAttribute.isVariable()) {
        AttributeDefinitionBuilder setterBuilder = AttributeDefinitionBuilder.setter(this, refined.getName(), refined);
        setterBuilder.skipField();
        setterBuilder.modifiers(transformAttributeGetSetDeclFlags(refined, false));
        setterBuilder.setterBlock(make().Block(0, List.<JCStatement>of(makeThrowUnresolvedCompilationError(error))));
        classBuilder.attribute(setterBuilder);
    }
}
Also used : FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 99 with JCStatement

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

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(make().Type(syms().ceylonReachableReferenceType), null);
    mdb.parameter(pdb);
    mdb.resultType(null, make().Type(syms().objectType));
    /*
         * public void $set$(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 = ListBuffer.<JCCase>lb();
    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 = ListBuffer.<JCStatement>lb();
            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;
                if (CodegenUtil.needsLateInitField((Value) member, typeFact())) {
                    test = make().Unary(JCTree.NOT, naming.makeUnquotedIdent(Naming.getInitializationFieldName(member.getName())));
                } else {
                    test = make().Binary(JCTree.EQ, naming.makeQualifiedName(naming.makeThis(), (Value) member, Naming.NA_IDENT), makeNull());
                }
                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 = ListBuffer.lb();
    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 = ListBuffer.<JCStatement>lb();
    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 : SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCSwitch(com.sun.tools.javac.tree.JCTree.JCSwitch) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) Value(com.redhat.ceylon.model.typechecker.model.Value) 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) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) JCCase(com.sun.tools.javac.tree.JCTree.JCCase)

Example 100 with JCStatement

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

the class ClassTransformer method transformMethodBody.

private List<JCStatement> transformMethodBody(Tree.AnyMethod def) {
    List<JCStatement> body = null;
    final Function model = def.getDeclarationModel();
    if (model.isDeferred()) {
        // Uninitialized or deferred initialized method => Make a Callable field
        String fieldName = naming.selector(model);
        final Parameter initializingParameter = CodegenUtil.findParamForDecl(def);
        int mods = PRIVATE;
        JCExpression initialValue;
        if (initializingParameter != null) {
            mods |= FINAL;
            initialValue = makeUnquotedIdent(Naming.getAliasedParameterName(initializingParameter));
        } else {
            // The field isn't initialized by a parameter, but later in the block
            initialValue = makeNull();
        }
        Type callableType = model.getReference().getFullType();
        current().field(mods, fieldName, makeJavaType(callableType), initialValue, false);
        Invocation invocation = new CallableSpecifierInvocation(this, model, makeUnquotedIdent(fieldName), // but with deferred methods we can't define them so that they are erased so we're good
        null, def);
        invocation.handleBoxing(true);
        JCExpression call = expressionGen().transformInvocation(invocation);
        JCStatement stmt;
        if (!isVoid(def) || !Decl.isUnboxedVoid(model) || Strategy.useBoxedVoid((Function) model)) {
            stmt = make().Return(call);
        } else {
            stmt = make().Exec(call);
        }
        JCStatement result;
        if (initializingParameter == null) {
            // If the field isn't initialized by a parameter we have to 
            // cope with the possibility that it's never initialized
            final JCBinary cond = make().Binary(JCTree.EQ, makeUnquotedIdent(fieldName), makeNull());
            final JCStatement throw_ = make().Throw(make().NewClass(null, null, makeIdent(syms().ceylonUninitializedMethodErrorType), List.<JCExpression>nil(), null));
            result = make().If(cond, throw_, stmt);
        } else {
            result = stmt;
        }
        return List.<JCStatement>of(result);
    } else if (def instanceof Tree.MethodDefinition) {
        body = transformMethodBlock((Tree.MethodDefinition) def);
    } else if (def instanceof MethodDeclaration && ((MethodDeclaration) def).getSpecifierExpression() != null) {
        body = transformSpecifiedMethodBody((MethodDeclaration) def, ((MethodDeclaration) def).getSpecifierExpression());
    }
    return body;
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Function(com.redhat.ceylon.model.typechecker.model.Function) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

Aggregations

JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)112 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)82 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)37 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)33 JCTree (com.sun.tools.javac.tree.JCTree)32 Name (com.sun.tools.javac.util.Name)32 Type (com.redhat.ceylon.model.typechecker.model.Type)26 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)26 ListBuffer (com.sun.tools.javac.util.ListBuffer)25 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)23 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)18 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)16 JavacTreeMaker (lombok.javac.JavacTreeMaker)16 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)14 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)14 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)12 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)12 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)12 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)11 HasErrorException (com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException)10