Search in sources :

Example 1 with SpecifierOrInitializerExpression

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.

the class StatementTransformer method transform.

// FIXME There is a similar implementation in ClassGen!
public List<JCStatement> transform(Tree.AttributeDeclaration decl) {
    ListBuffer<JCStatement> result = new ListBuffer<JCStatement>();
    // If the attribute is really from a parameter then don't generate a local variable
    Parameter parameter = CodegenUtil.findParamForDecl(decl);
    if (parameter == null) {
        final Name attrName = names().fromString(naming.substitute(decl.getDeclarationModel()));
        Type t = decl.getDeclarationModel().getType();
        JCExpression initialValue = null;
        SpecifierOrInitializerExpression initOrSpec = decl.getSpecifierOrInitializerExpression();
        if (initOrSpec != null) {
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(initOrSpec.getExpression().getTerm());
            if (error != null) {
                return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
            }
            int flags = CodegenUtil.downcastForSmall(initOrSpec.getExpression(), decl.getDeclarationModel()) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
            flags |= decl.getDeclarationModel().hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
            initialValue = expressionGen().transformExpression(initOrSpec.getExpression(), CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()), decl.getDeclarationModel().getType(), flags);
        } else if (decl.getDeclarationModel().isVariable()) {
            // Java's definite initialization doesn't always work
            // so give variable attribute declarations without
            // initializers a default value. See #1153.
            initialValue = makeDefaultExprForType(t);
            if (CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()) == BoxingStrategy.BOXED && canUnbox(t)) {
                initialValue = boxType(initialValue, t);
            }
        }
        List<JCAnnotation> annots = List.<JCAnnotation>nil();
        int modifiers = transformLocalFieldDeclFlags(decl);
        JCExpression typeExpr = makeJavaType(decl.getDeclarationModel(), t, modifiers);
        result.append(at(decl.getIdentifier()).VarDef(at(decl.getIdentifier()).Modifiers(modifiers, annots), attrName, typeExpr, initialValue));
        JCStatement outerSubs = openOuterSubstitutionIfNeeded(decl.getDeclarationModel(), t, modifiers);
        if (outerSubs != null) {
            result.append(outerSubs);
        }
    }
    return result.toList();
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) 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)

Example 2 with SpecifierOrInitializerExpression

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.

the class GenerateJsVisitor method initDefaultedParameters.

/**
 * Create special functions with the expressions for defaulted parameters in a parameter list.
 */
void initDefaultedParameters(final Tree.ParameterList params, Tree.AnyMethod container) {
    if (!(container instanceof Tree.MethodDeclaration || container.getDeclarationModel().isMember())) {
        return;
    }
    final boolean isMember = container.getDeclarationModel().isMember();
    for (final Tree.Parameter param : params.getParameters()) {
        Parameter pd = param.getParameterModel();
        if (pd.isDefaulted()) {
            final SpecifierOrInitializerExpression expr = getDefaultExpression(param);
            if (expr == null) {
                continue;
            }
            if (isMember) {
                qualify(params, container.getDeclarationModel());
                out(names.name(container.getDeclarationModel()), "$defs$", pd.getName(), "=function");
            } else {
                out("function ", names.name(container.getDeclarationModel()), "$defs$", pd.getName());
            }
            params.visit(this);
            out("{");
            initSelf(expr);
            out("return ");
            if (param instanceof Tree.ParameterDeclaration) {
                Tree.TypedDeclaration node = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
                if (node instanceof Tree.MethodDeclaration) {
                    // function parameter defaulted using "=>"
                    FunctionHelper.singleExprFunction(((Tree.MethodDeclaration) node).getParameterLists(), expr.getExpression(), null, true, true, this);
                } else if (!isNaturalLiteral(expr.getExpression().getTerm())) {
                    expr.visit(this);
                }
            } else if (!isNaturalLiteral(expr.getExpression().getTerm())) {
                expr.visit(this);
            }
            out(";}");
            endLine(true);
        }
    }
}
Also used : Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)

Example 3 with SpecifierOrInitializerExpression

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.

the class GenerateJsVisitor method getDefaultExpression.

/**
 * Get the specifier expression for a Parameter, if one is available.
 */
SpecifierOrInitializerExpression getDefaultExpression(final Tree.Parameter param) {
    final SpecifierOrInitializerExpression expr;
    if (param instanceof Tree.ParameterDeclaration || param instanceof Tree.InitializerParameter) {
        Tree.MethodDeclaration md = null;
        if (param instanceof Tree.ParameterDeclaration) {
            Tree.TypedDeclaration td = ((Tree.ParameterDeclaration) param).getTypedDeclaration();
            if (td instanceof AttributeDeclaration) {
                expr = ((Tree.AttributeDeclaration) td).getSpecifierOrInitializerExpression();
            } else if (td instanceof Tree.MethodDeclaration) {
                md = (Tree.MethodDeclaration) td;
                expr = md.getSpecifierExpression();
            } else {
                param.addUnexpectedError("Don't know what to do with TypedDeclaration " + td.getClass().getName(), Backend.JavaScript);
                expr = null;
            }
        } else {
            expr = ((Tree.InitializerParameter) param).getSpecifierExpression();
        }
    } else {
        param.addUnexpectedError("Don't know what to do with defaulted/sequenced param " + param, Backend.JavaScript);
        expr = null;
    }
    return expr;
}
Also used : Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)

Example 4 with SpecifierOrInitializerExpression

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.

the class MethodOrValueReferenceVisitor method visit.

@Override
public void visit(Tree.AttributeDeclaration that) {
    final SpecifierOrInitializerExpression specifier = that.getSpecifierOrInitializerExpression();
    Value model = that.getDeclarationModel();
    boolean lse = inLazySpecifierExpression;
    if (specifier != null && model.isLate() && model.isClassMember()) {
        model.setCaptured(true);
        inLazySpecifierExpression = true;
    }
    super.visit(that);
    inLazySpecifierExpression = lse;
}
Also used : FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)

Example 5 with SpecifierOrInitializerExpression

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression in project ceylon by eclipse.

the class GenerateJsVisitor method initParameters.

/**
 * Initialize the sequenced, defaulted and captured parameters in a type declaration.
 * @return The defaulted parameters that belong to a class, since their values have to be
 * set later on.
 */
List<Tree.Parameter> initParameters(final Tree.ParameterList params, TypeDeclaration typeDecl, Functional m) {
    List<Tree.Parameter> rparams = null;
    for (final Tree.Parameter param : params.getParameters()) {
        Parameter pd = param.getParameterModel();
        String paramName = names.name(pd);
        if (pd.isDefaulted() || pd.isSequenced()) {
            out("if(", paramName, "===undefined){", paramName, "=");
            if (pd.isDefaulted()) {
                boolean done = false;
                if (m instanceof Function) {
                    Function mf = (Function) m;
                    if (mf.getRefinedDeclaration() != mf) {
                        mf = (Function) mf.getRefinedDeclaration();
                        if (mf.isMember() || !mf.isImplemented()) {
                            qualify(params, mf);
                            out(names.name(mf), "$defs$", pd.getName(), "(");
                            boolean firstParam = true;
                            for (Parameter p : m.getFirstParameterList().getParameters()) {
                                if (firstParam) {
                                    firstParam = false;
                                } else
                                    out(",");
                                out(names.name(p));
                            }
                            out(")");
                            done = true;
                        }
                    }
                } else if (pd.getDeclaration() instanceof Class) {
                    Class cdec = (Class) pd.getDeclaration().getRefinedDeclaration();
                    out(TypeGenerator.pathToType(params, cdec, this), ".$defs$", pd.getName(), "(", names.self(cdec));
                    for (Parameter p : ((Class) pd.getDeclaration()).getParameterList().getParameters()) {
                        if (!p.equals(pd)) {
                            out(",", names.name(p));
                        }
                    }
                    out(")");
                    if (rparams == null) {
                        rparams = new ArrayList<>(3);
                    }
                    rparams.add(param);
                    done = true;
                }
                if (!done) {
                    final SpecifierOrInitializerExpression expr = getDefaultExpression(param);
                    if (expr == null) {
                        param.addUnexpectedError("Default expression missing for " + pd.getName(), Backend.JavaScript);
                        out("undefined");
                    } else {
                        generateParameterExpression(param, expr, pd.getDeclaration() instanceof Scope ? (Scope) pd.getDeclaration() : null);
                    }
                }
            } else {
                out(getClAlias(), "empty()");
            }
            out(";}");
            endLine();
        }
        if (typeDecl != null && !(typeDecl instanceof ClassAlias) && (pd.getModel().isJsCaptured() || pd.getDeclaration() instanceof Class)) {
            out(names.self(typeDecl), ".", names.valueName(pd.getModel()), "=", paramName);
            if (!opts.isOptimize() && pd.isHidden()) {
                // belt and suspenders...
                out(";", names.self(typeDecl), ".", paramName, "=", paramName);
            }
            endLine(true);
        }
    }
    return rparams;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) ClassAlias(org.eclipse.ceylon.model.typechecker.model.ClassAlias) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ArrayList(java.util.ArrayList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)

Aggregations

SpecifierOrInitializerExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)7 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)5 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)5 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)3 Class (org.eclipse.ceylon.model.typechecker.model.Class)2 Function (org.eclipse.ceylon.model.typechecker.model.Function)2 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)2 Value (org.eclipse.ceylon.model.typechecker.model.Value)2 ArrayList (java.util.ArrayList)1 CName (org.eclipse.ceylon.compiler.java.codegen.Naming.CName)1 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)1 HasErrorException (org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException)1 AttributeDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)1 AttributeSetterDefinition (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeSetterDefinition)1 LazySpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)1 JCAnnotation (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)1 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)1 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)1 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)1 Name (org.eclipse.ceylon.langtools.tools.javac.util.Name)1