Search in sources :

Example 1 with DeferredSpecification

use of org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification in project ceylon by eclipse.

the class ClassTransformer method transformRefinementSpecifierStatement.

public List<JCStatement> transformRefinementSpecifierStatement(SpecifierStatement op, ClassDefinitionBuilder classBuilder) {
    List<JCStatement> result = List.<JCStatement>nil();
    // Check if this is a shortcut form of formal attribute refinement
    if (op.getRefinement()) {
        Tree.Term baseMemberTerm = op.getBaseMemberExpression();
        if (baseMemberTerm instanceof Tree.ParameterizedExpression)
            baseMemberTerm = ((Tree.ParameterizedExpression) baseMemberTerm).getPrimary();
        Tree.BaseMemberExpression expr = (BaseMemberExpression) baseMemberTerm;
        Declaration decl = expr.getDeclaration();
        if (Decl.isValue(decl) || Decl.isGetter(decl)) {
            // Now build a "fake" declaration for the attribute
            Tree.AttributeDeclaration attrDecl = new Tree.AttributeDeclaration(null);
            attrDecl.setDeclarationModel((Value) decl);
            attrDecl.setIdentifier(expr.getIdentifier());
            attrDecl.setScope(op.getScope());
            attrDecl.setSpecifierOrInitializerExpression(op.getSpecifierExpression());
            attrDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
            // Make sure the boxing information is set correctly
            BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
            v.visit(attrDecl);
            // Generate the attribute
            transform(attrDecl, classBuilder);
        } else if (decl instanceof Function) {
            // Now build a "fake" declaration for the method
            Tree.MethodDeclaration methDecl = new Tree.MethodDeclaration(null);
            Function m = (Function) decl;
            methDecl.setDeclarationModel(m);
            methDecl.setIdentifier(expr.getIdentifier());
            methDecl.setScope(op.getScope());
            methDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
            Tree.SpecifierExpression specifierExpression = op.getSpecifierExpression();
            methDecl.setSpecifierExpression(specifierExpression);
            if (specifierExpression instanceof Tree.LazySpecifierExpression == false) {
                Tree.Expression expression = specifierExpression.getExpression();
                Tree.Term expressionTerm = Decl.unwrapExpressionsUntilTerm(expression);
                // we can optimise lambdas and static method calls
                if (!CodegenUtil.canOptimiseMethodSpecifier(expressionTerm, m)) {
                    // we need a field to save the callable value
                    String name = naming.getMethodSpecifierAttributeName(m);
                    JCExpression specifierType = makeJavaType(expression.getTypeModel());
                    JCExpression specifier = expressionGen().transformExpression(expression);
                    classBuilder.field(PRIVATE | FINAL, name, specifierType, specifier, false);
                }
            }
            java.util.List<Tree.ParameterList> parameterListTrees = null;
            if (op.getBaseMemberExpression() instanceof Tree.ParameterizedExpression) {
                parameterListTrees = new ArrayList<>(m.getParameterLists().size());
                parameterListTrees.addAll(((Tree.ParameterizedExpression) op.getBaseMemberExpression()).getParameterLists());
                Tree.Term term = specifierExpression.getExpression().getTerm();
                // and give it the given block of expr as it's specifier
                while (term instanceof Tree.FunctionArgument && m.getParameterLists().size() > 1) {
                    FunctionArgument functionArgument = (Tree.FunctionArgument) term;
                    specifierExpression.setExpression(functionArgument.getExpression());
                    parameterListTrees.addAll(functionArgument.getParameterLists());
                    term = functionArgument.getExpression().getTerm();
                }
            }
            int plIndex = 0;
            // copy from formal declaration
            for (ParameterList pl : m.getParameterLists()) {
                Tree.ParameterList parameterListTree = null;
                if (parameterListTrees != null)
                    parameterListTree = parameterListTrees.get(plIndex++);
                Tree.ParameterList tpl = new Tree.ParameterList(null);
                tpl.setModel(pl);
                int pIndex = 0;
                for (Parameter p : pl.getParameters()) {
                    Tree.Parameter parameterTree = null;
                    if (parameterListTree != null)
                        parameterTree = parameterListTree.getParameters().get(pIndex++);
                    Tree.Parameter tp = null;
                    if (p.getModel() instanceof Value) {
                        Tree.ValueParameterDeclaration tvpd = new Tree.ValueParameterDeclaration(null);
                        if (parameterTree != null)
                            tvpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
                        tvpd.setParameterModel(p);
                        tp = tvpd;
                    } else if (p.getModel() instanceof Function) {
                        Tree.FunctionalParameterDeclaration tfpd = new Tree.FunctionalParameterDeclaration(null);
                        if (parameterTree != null)
                            tfpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
                        tfpd.setParameterModel(p);
                        tp = tfpd;
                    } else {
                        throw BugException.unhandledDeclarationCase(p.getModel());
                    }
                    tp.setScope(p.getDeclaration().getContainer());
                    // tp.setIdentifier(makeIdentifier(p.getName()));
                    tpl.addParameter(tp);
                }
                methDecl.addParameterList(tpl);
            }
            // Make sure the boxing information is set correctly
            BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
            v.visit(methDecl);
            // Generate the method
            classBuilder.method(methDecl, Errors.GENERATE);
        }
    } else {
        // Normal case, just generate the specifier statement
        result = result.append(expressionGen().transform(op));
    }
    Tree.Term term = op.getBaseMemberExpression();
    if (term instanceof Tree.BaseMemberExpression) {
        Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
        DeferredSpecification ds = statementGen().getDeferredSpecification(bme.getDeclaration());
        if (ds != null && needsInnerSubstitution(term.getScope(), bme.getDeclaration())) {
            result = result.append(ds.openInnerSubstitution());
        }
    }
    return result;
}
Also used : SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) DeferredSpecification(org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification) ArrayList(java.util.ArrayList) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Function(org.eclipse.ceylon.model.typechecker.model.Function) 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) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)

Aggregations

ArrayList (java.util.ArrayList)1 DeferredSpecification (org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification)1 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)1 AnnotationList (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList)1 BaseMemberExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)1 FunctionArgument (org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument)1 MethodDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)1 SpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression)1 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)1 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)1 JCPrimitiveTypeTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree)1 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)1 List (org.eclipse.ceylon.langtools.tools.javac.util.List)1 JavaBeanValue (org.eclipse.ceylon.model.loader.model.JavaBeanValue)1 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)1 Function (org.eclipse.ceylon.model.typechecker.model.Function)1 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)1 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)1 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)1 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)1