Search in sources :

Example 11 with JCVariableDecl

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

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 = ModelUtil.getConstructedClass(ctor.getEnumerated());
    Value singletonModel = ctor.getDeclarationModel();
    // generate a field
    AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.singleton(gen, 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, ModelUtil.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null), BoxingStrategy.BOXED);
        classBuilder.defs(adb.build());
    } else if (clz.isClassMember()) {
        int mods = 0;
        if (!singletonModel.isShared()) {
            mods |= PRIVATE;
        }
        if (clz.isClassOrInterfaceMember() && clz.isStatic()) {
            mods |= STATIC;
        }
        adb.modifiers(mods);
        // lazy
        adb.initialValue(gen.makeNull(), BoxingStrategy.BOXED);
        List<JCStatement> l = List.<JCStatement>of(gen.make().If(gen.make().Binary(JCTree.Tag.EQ, field.makeIdent(), gen.makeNull()), gen.make().Exec(gen.make().Assign(field.makeIdent(), gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.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));
        long mods2 = PRIVATE | TRANSIENT;
        if (clz.isStatic()) {
            mods2 |= STATIC;
        }
        classBuilder.getContainingClassBuilder().defs(gen.makeVar(mods2, field, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.getConstructedClass(ctor.getEnumerated())), gen.makeNull()));
        classBuilder.getContainingClassBuilder().defs(adb.build());
    } else {
        // LOCAL
        // we have to first make an empty box
        JCNewClass initialValue = gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null);
        JCVariableDecl box = gen.makeVariableBoxDecl(gen.makeNull(), singletonModel);
        classBuilder.before(box);
        // then do the class, and after that, assign our instance to the box
        JCAssign assign = gen.make().Assign(gen.makeSelect(field.getName(), NamingBase.getGetterName(singletonModel)), initialValue);
        classBuilder.after(gen.make().Exec(assign));
    }
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCAssign(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAssign) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) List(org.eclipse.ceylon.langtools.tools.javac.util.List) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 12 with JCVariableDecl

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

the class NamedArgumentInvocation method bindMethodArgument.

private void bindMethodArgument(Tree.MethodArgument methodArg, Parameter declaredParam, Naming.SyntheticName argName) {
    ListBuffer<JCStatement> statements;
    Function model = methodArg.getDeclarationModel();
    List<JCStatement> body;
    boolean prevNoExpressionlessReturn = gen.statementGen().noExpressionlessReturn;
    boolean prevSyntheticClassBody = gen.expressionGen().withinSyntheticClassBody(Decl.isMpl(model) || gen.expressionGen().isWithinSyntheticClassBody());
    try {
        gen.expressionGen().withinSyntheticClassBody(true);
        gen.statementGen().noExpressionlessReturn = AbstractTransformer.isAnything(model.getType());
        if (methodArg.getBlock() != null) {
            body = gen.statementGen().transformBlock(methodArg.getBlock());
            if (!methodArg.getBlock().getDefinitelyReturns()) {
                if (AbstractTransformer.isAnything(model.getType())) {
                    body = body.append(gen.make().Return(gen.makeNull()));
                } else {
                    body = body.append(gen.make().Return(gen.makeErroneous(methodArg.getBlock(), "compiler bug: non-void method does not definitely return")));
                }
            }
        } else {
            Expression expr = methodArg.getSpecifierExpression().getExpression();
            BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(model);
            Type type = model.getType();
            JCExpression transExpr = gen.expressionGen().transformExpression(expr, boxing, type);
            JCReturn returnStat = gen.make().Return(transExpr);
            body = List.<JCStatement>of(returnStat);
        }
    } finally {
        gen.expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
        gen.statementGen().noExpressionlessReturn = prevNoExpressionlessReturn;
    }
    Type callableType = model.appliedReference(null, Collections.<Type>emptyList()).getFullType();
    CallableBuilder callableBuilder = CallableBuilder.methodArgument(gen.gen(), methodArg, model, callableType, Collections.singletonList(methodArg.getParameterLists().get(0)), gen.classGen().transformMplBody(methodArg.getParameterLists(), model, body));
    JCExpression callable = callableBuilder.build();
    gen.at(methodArg);
    JCExpression typeExpr = gen.makeJavaType(callableType, JT_RAW);
    JCVariableDecl varDecl = gen.makeVar(argName, typeExpr, callable);
    statements = ListBuffer.<JCStatement>of(varDecl);
    bind(declaredParam, argName, gen.makeJavaType(callableType), statements.toList());
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCReturn(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCReturn) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) QualifiedTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.QualifiedTypeExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) StaticMemberOrTypeExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.StaticMemberOrTypeExpression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) BoxingStrategy(org.eclipse.ceylon.compiler.java.codegen.AbstractTransformer.BoxingStrategy) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 13 with JCVariableDecl

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

the class NamedArgumentInvocation method bindSpecifiedArgument.

private void bindSpecifiedArgument(Tree.SpecifiedArgument specifiedArg, Parameter declaredParam, Naming.SyntheticName argName) {
    ListBuffer<JCStatement> statements;
    Tree.Expression expr = specifiedArg.getSpecifierExpression().getExpression();
    Type type = parameterType(declaredParam, expr.getTypeModel(), AbstractTransformer.TP_TO_BOUND);
    final BoxingStrategy boxType = getNamedParameterBoxingStrategy(declaredParam);
    int jtFlags = 0;
    int exprFlags = 0;
    if (boxType == BoxingStrategy.BOXED)
        jtFlags |= JT_TYPE_ARGUMENT;
    if (!isParameterRaw(declaredParam)) {
        exprFlags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_NOT_RAW;
    }
    if (isParameterWithConstrainedTypeParameters(declaredParam)) {
        exprFlags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
        // we can't just generate types like Foo<?> if the target type param is not raw because the bounds will
        // not match, so we go raw
        jtFlags |= JT_RAW;
    }
    if (isParameterWithDependentCovariantTypeParameters(declaredParam)) {
        exprFlags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_DEPENDENT_COVARIANT_TYPE_PARAMETERS;
    }
    if (erasedArgument(TreeUtil.unwrapExpressionUntilTerm(expr))) {
        exprFlags |= ExpressionTransformer.EXPR_DOWN_CAST;
    }
    if (CodegenUtil.downcastForSmall(expr, specifiedArg.getParameter().getModel())) {
        exprFlags |= ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK;
    }
    JCExpression typeExpr = gen.makeJavaType(type, jtFlags);
    gen.at(specifiedArg);
    JCExpression argExpr = gen.expressionGen().transformExpression(expr, boxType, type, exprFlags);
    gen.at(specifiedArg);
    JCVariableDecl varDecl = gen.makeVar(argName, typeExpr, argExpr);
    statements = ListBuffer.<JCStatement>of(varDecl);
    bind(declaredParam, argName, gen.makeJavaType(type, jtFlags), statements.toList());
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) BoxingStrategy(org.eclipse.ceylon.compiler.java.codegen.AbstractTransformer.BoxingStrategy) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 14 with JCVariableDecl

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

the class NamedArgumentInvocation method appendVarsForReifiedTypeArguments.

private void appendVarsForReifiedTypeArguments() {
    java.util.List<JCExpression> reifiedTypeArgs = gen.makeReifiedTypeArguments(producedReference);
    int index = 0;
    for (JCExpression reifiedTypeArg : reifiedTypeArgs) {
        Naming.SyntheticName argName = reifiedTypeArgName(index);
        JCVariableDecl varDecl = gen.makeVar(argName, gen.makeTypeDescriptorType(), reifiedTypeArg);
        this.vars.append(varDecl);
        index++;
    }
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Example 15 with JCVariableDecl

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

the class StatementTransformer method transformCaseMatch.

private JCStatement transformCaseMatch(Naming.SyntheticName selectorAlias, Tree.SwitchClause switchClause, Tree.CaseClause caseClause, String tmpVar, Tree.Term outerExpression, Type expectedType, Tree.MatchCase matchCase, JCStatement last, Type switchType, boolean primitiveSelector) {
    at(matchCase);
    JCVariableDecl decl2 = null;
    Substitution prevSubst2 = null;
    if (matchCase.getVariable() != null) {
        // Use the type of the variable, which is more precise than the type we test for.
        Type varType = matchCase.getVariable().getDeclarationModel().getType();
        String name = matchCase.getVariable().getIdentifier().getText();
        TypedDeclaration varDecl = matchCase.getVariable().getDeclarationModel();
        Naming.SyntheticName tmpVarName = selectorAlias;
        Name substVarName = naming.aliasName(name);
        // Want raw type for instanceof since it can't be used with generic types
        JCExpression rawToTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES | JT_RAW);
        // Substitute variable with the correct type to use in the rest of the code block
        JCExpression tmpVarExpr = at(matchCase).TypeCast(rawToTypeExpr, tmpVarName.makeIdent());
        JCExpression toTypeExpr;
        if (isCeylonBasicType(varType) && varDecl.getUnboxed() == true) {
            toTypeExpr = makeJavaType(varType);
            tmpVarExpr = unboxType(tmpVarExpr, varType);
        } else {
            toTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES);
        }
        // The variable holding the result for the code inside the code block
        decl2 = at(matchCase).VarDef(make().Modifiers(FINAL), substVarName, toTypeExpr, tmpVarExpr);
        // Prepare for variable substitution in the following code block
        prevSubst2 = naming.addVariableSubst(varDecl, substVarName.toString());
    }
    JCExpression tests = null;
    java.util.List<Tree.Expression> expressions = matchCase.getExpressionList().getExpressions();
    for (Tree.Expression expr : expressions) {
        Tree.Term term = ExpressionTransformer.eliminateParens(expr.getTerm());
        boolean unboxedEquality = primitiveSelector || isCeylonBasicType(typeFact().getDefiniteType(switchType));
        Type type = term.getTypeModel();
        JCExpression transformedExpression = expressionGen().transformExpression(term, unboxedEquality ? BoxingStrategy.UNBOXED : BoxingStrategy.BOXED, type);
        JCExpression test;
        if (term instanceof Tree.Literal || term instanceof Tree.NegativeOp) {
            if (unboxedEquality) {
                if (term instanceof Tree.StringLiteral) {
                    test = make().Apply(null, makeSelect(unboxType(selectorAlias.makeIdent(), type), "equals"), List.<JCExpression>of(transformedExpression));
                } else {
                    test = make().Binary(JCTree.Tag.EQ, primitiveSelector ? selectorAlias.makeIdent() : unboxType(selectorAlias.makeIdent(), type), transformedExpression);
                }
            } else {
                test = make().Apply(null, makeSelect(selectorAlias.makeIdent(), "equals"), List.<JCExpression>of(transformedExpression));
            }
            if (isOptional(switchType)) {
                test = make().Binary(JCTree.Tag.AND, make().Binary(JCTree.Tag.NE, selectorAlias.makeIdent(), makeNull()), test);
            }
        } else {
            JCExpression selectorExpr;
            if (!primitiveSelector && isCeylonBasicType(typeFact().getDefiniteType(switchType))) {
                selectorExpr = unboxType(selectorAlias.makeIdent(), type);
            } else {
                selectorExpr = selectorAlias.makeIdent();
            }
            if (term instanceof Tree.Tuple) {
                if (type.isEmpty()) {
                    test = make().TypeTest(selectorAlias.makeIdent(), makeJavaType(typeFact().getEmptyType(), JT_RAW));
                } else {
                    test = make().Apply(null, makeSelect(selectorExpr, "equals"), List.<JCExpression>of(transformedExpression));
                    test = make().Binary(Tag.AND, make().TypeTest(selectorAlias.makeIdent(), make().QualIdent(syms().ceylonTupleType.tsym)), test);
                }
            } else if (type.isString()) {
                test = make().Apply(null, makeSelect(selectorExpr, "equals"), List.<JCExpression>of(transformedExpression));
            } else {
                test = make().Binary(JCTree.Tag.EQ, selectorExpr, transformedExpression);
            }
        }
        if (tests == null) {
            tests = test;
        } else if (isNull(type)) {
            // ensure we do any null check as the first operation in the ||-ed expression
            tests = make().Binary(JCTree.Tag.OR, test, tests);
        } else {
            tests = make().Binary(JCTree.Tag.OR, tests, test);
        }
    }
    java.util.List<Tree.Type> types = matchCase.getExpressionList().getTypes();
    for (Tree.Type caseType : types) {
        // note: There's no point using makeOptimizedTypeTest() because cases are disjoint
        // anyway and the cheap cases get evaluated first.
        Type type = caseType.getTypeModel();
        JCExpression cond = makeTypeTest(null, selectorAlias, type, type);
        if (tests == null) {
            tests = cond;
        } else if (isNull(type)) {
            // ensure we do any null check as the first operation in the ||-ed expression
            tests = make().Binary(JCTree.Tag.OR, cond, tests);
        } else {
            tests = make().Binary(JCTree.Tag.OR, tests, cond);
        }
    }
    Substitution prevSubst = null;
    if (switchClause.getSwitched().getVariable() != null) {
        // Prepare for variable substitution in the following code block
        prevSubst = naming.addVariableSubst(switchClause.getSwitched().getVariable().getDeclarationModel(), selectorAlias.toString());
    }
    JCBlock block;
    if (decl2 != null) {
        List<JCStatement> stats = List.<JCStatement>of(decl2);
        stats = stats.appendList(transformCaseClause(caseClause, tmpVar, outerExpression, expectedType));
        block = at(matchCase).Block(0, stats);
    } else {
        block = transformCaseClauseBlock(caseClause, tmpVar, outerExpression, expectedType);
    }
    if (prevSubst2 != null) {
        // Deactivate the above variable substitution
        prevSubst2.close();
    }
    if (prevSubst != null) {
        // Deactivate the above variable substitution
        prevSubst.close();
    }
    return at(caseClause).If(tests, block, last);
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) CName(org.eclipse.ceylon.compiler.java.codegen.Naming.CName) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) Substitution(org.eclipse.ceylon.compiler.java.codegen.Naming.Substitution) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

Aggregations

JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)31 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)25 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)21 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)16 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)14 Type (org.eclipse.ceylon.model.typechecker.model.Type)12 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)10 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)7 JCBlock (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock)6 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)6 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)5 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)5 JCCatch (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCatch)5 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)5 Name (org.eclipse.ceylon.langtools.tools.javac.util.Name)5 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 CName (org.eclipse.ceylon.compiler.java.codegen.Naming.CName)3 Variable (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Variable)3 JCAssign (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAssign)3 JCMethodDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCMethodDecl)3