Search in sources :

Example 1 with SpecifierExpression

use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression 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)

Example 2 with SpecifierExpression

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

the class MethodOrValueReferenceVisitor method visit.

@Override
public void visit(Tree.ForComprehensionClause that) {
    super.visit(that);
    final SpecifierExpression specifier = that.getForIterator().getSpecifierExpression();
    if (specifier != null) {
        final Expression expr = specifier.getExpression();
        final Term term = expr.getTerm();
        if (term instanceof Tree.Primary) {
            capture((Tree.Primary) term, true);
        }
    }
    that.getComprehensionClause().visit(this);
}
Also used : SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) Primary(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Primary) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term)

Example 3 with SpecifierExpression

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

the class MethodOrValueReferenceVisitor method visit.

@Override
public void visit(Tree.MethodDeclaration that) {
    super.visit(that);
    final SpecifierExpression specifier = that.getSpecifierExpression();
    if (specifier != null && specifier instanceof Tree.LazySpecifierExpression) {
        boolean cs = enterCapturingScope();
        specifier.visit(this);
        exitCapturingScope(cs);
    }
}
Also used : LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 4 with SpecifierExpression

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

the class ClassTransformer method transform.

List<MethodDefinitionBuilder> transform(Tree.AnyMethod def, ClassDefinitionBuilder classBuilder, List<JCStatement> body) {
    final Function model = def.getDeclarationModel();
    List<MethodDefinitionBuilder> result = List.<MethodDefinitionBuilder>nil();
    if (!model.isInterfaceMember() || model.isStatic()) {
        // Transform to the class
        TypedDeclaration rd = (TypedDeclaration) model.getRefinedDeclaration();
        boolean refinedResultType = !model.getType().isExactly(rd.getType());
        result = transformMethod(def, true, true, true, transformMplBodyUnlessSpecifier(def, model, body), refinedResultType && !rd.isInterfaceMember() ? new DaoSuper() : new DaoThis(def, def.getParameterLists().get(0)), !Strategy.defaultParameterMethodOnSelf(model) && !Strategy.defaultParameterMethodStatic(model));
    } else {
        // Is within interface
        // Transform the definition to the companion class, how depends
        // on what kind of method it is
        List<MethodDefinitionBuilder> companionDefs;
        if (def instanceof Tree.MethodDeclaration) {
            final SpecifierExpression specifier = ((Tree.MethodDeclaration) def).getSpecifierExpression();
            if (specifier == null) {
                // formal or abstract
                // (still need overloads and DPMs on the companion)
                companionDefs = transformMethod(def, false, true, true, null, new DaoCompanion(def, def.getParameterLists().get(0)), false);
            } else {
                companionDefs = transformMethod(def, true, false, !model.isShared(), transformMplBodyUnlessSpecifier(def, model, body), new DaoCompanion(def, def.getParameterLists().get(0)), false);
            }
        } else if (def instanceof Tree.MethodDefinition) {
            companionDefs = transformMethod(def, true, false, !model.isShared(), transformMplBodyUnlessSpecifier(def, model, body), new DaoCompanion(def, def.getParameterLists().get(0)), false);
        } else {
            throw BugException.unhandledNodeCase(def);
        }
        if (!companionDefs.isEmpty())
            classBuilder.getCompanionBuilder((TypeDeclaration) model.getContainer()).methods(companionDefs);
        // but only if it's shared and not java native
        if (model.isShared() && !model.isJavaNative()) {
            result = transformMethod(def, true, true, true, null, daoAbstract, !Strategy.defaultParameterMethodOnSelf(model));
        }
    }
    return result;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) 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)

Example 5 with SpecifierExpression

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

the class BoxingDeclarationVisitor method visit.

@Override
public void visit(Tree.MethodDeclaration that) {
    super.visit(that);
    Function model = that.getDeclarationModel();
    visitMethod(that.getDeclarationModel(), that);
    SpecifierExpression specifierExpression = that.getSpecifierExpression();
    // See ClassTransformer.transformSpecifiedMethodBody for this logic
    if (model != null && model.isMember() && specifierExpression != null && specifierExpression.getExpression() != null) {
        boolean isLazy = specifierExpression instanceof Tree.LazySpecifierExpression;
        Term term = Decl.unwrapExpressionsUntilTerm(specifierExpression.getExpression());
        if (!isLazy && term instanceof Tree.FunctionArgument) {
            // this is inlined for member methods, so the term should inherit our boxing specs
            Function specifierModel = ((Tree.FunctionArgument) term).getDeclarationModel();
            if (specifierModel != null) {
                specifierModel.setUnboxed(model.getUnboxed());
            }
        }
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) LazySpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)

Aggregations

Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)5 SpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression)5 LazySpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)3 Function (org.eclipse.ceylon.model.typechecker.model.Function)3 FunctionArgument (org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument)2 MethodDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)2 Term (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term)2 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)2 JCPrimitiveTypeTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree)2 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)2 ArrayList (java.util.ArrayList)1 DeferredSpecification (org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification)1 AnnotationList (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList)1 BaseMemberExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)1 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)1 Primary (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Primary)1 SpecifierOrInitializerExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)1 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)1 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)1 List (org.eclipse.ceylon.langtools.tools.javac.util.List)1