Search in sources :

Example 36 with Declaration

use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.Assertion that) {
    Tree.ConditionList cl = that.getConditionList();
    if (cl != null) {
        for (Tree.Condition c : cl.getConditions()) {
            c.setAssertion(true);
        }
    }
    Declaration d = beginDeclaration(null);
    super.visit(that);
    endDeclaration(d);
}
Also used : CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 37 with Declaration

use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.FunctionArgument that) {
    Tree.Type type = that.getType();
    final Function f = new Function();
    f.setName("anonymous#" + fid++);
    f.setAnonymous(true);
    if (type.getToken() != null) {
        f.setDeclaredVoid(type instanceof Tree.VoidModifier);
    } else {
        Tree.Block block = that.getBlock();
        if (block != null) {
            f.setDeclaredVoid(true);
            new Visitor() {

                @Override
                public void visit(Tree.Declaration that) {
                }

                @Override
                public void visit(Tree.TypedArgument that) {
                }

                @Override
                public void visit(Tree.ObjectExpression that) {
                }

                @Override
                public void visit(Tree.FunctionArgument that) {
                }

                @Override
                public void visit(Tree.Return that) {
                    if (that.getExpression() != null) {
                        f.setDeclaredVoid(false);
                    }
                    super.visit(that);
                }
            }.visit(block);
        }
    }
    that.setDeclarationModel(f);
    visitArgument(that, f);
    Scope o = enterScope(f);
    Declaration d = beginDeclaration(f);
    super.visit(that);
    endDeclaration(d);
    exitScope(o);
    setParameterLists(f, that.getParameterLists(), that);
}
Also used : Visitor(org.eclipse.ceylon.compiler.typechecker.tree.Visitor) Function(org.eclipse.ceylon.model.typechecker.model.Function) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ConditionScope(org.eclipse.ceylon.model.typechecker.model.ConditionScope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 38 with Declaration

use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.

the class ClassTransformer method transformSpecifiedMethodBody.

List<JCStatement> transformSpecifiedMethodBody(Tree.MethodDeclaration def, SpecifierExpression specifierExpression) {
    final Function model = def.getDeclarationModel();
    Tree.MethodDeclaration methodDecl = def;
    boolean isLazy = specifierExpression instanceof Tree.LazySpecifierExpression;
    boolean returnNull = false;
    JCExpression bodyExpr;
    Tree.Term term = null;
    if (specifierExpression != null && specifierExpression.getExpression() != null) {
        term = Decl.unwrapExpressionsUntilTerm(specifierExpression.getExpression());
        HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(term);
        if (error != null) {
            return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
        }
    }
    if (!isLazy && term instanceof Tree.FunctionArgument) {
        // Function specified with lambda: Don't bother generating a
        // Callable, just transform the expr to use as the method body.
        Tree.FunctionArgument fa = (Tree.FunctionArgument) term;
        Type resultType = model.getType();
        returnNull = Decl.isUnboxedVoid(model);
        final java.util.List<Tree.Parameter> lambdaParams = fa.getParameterLists().get(0).getParameters();
        final java.util.List<Tree.Parameter> defParams = def.getParameterLists().get(0).getParameters();
        List<Substitution> substitutions = List.nil();
        for (int ii = 0; ii < lambdaParams.size(); ii++) {
            substitutions = substitutions.append(naming.addVariableSubst((TypedDeclaration) lambdaParams.get(ii).getParameterModel().getModel(), defParams.get(ii).getParameterModel().getName()));
        }
        List<JCStatement> body = null;
        if (fa.getExpression() != null)
            bodyExpr = gen().expressionGen().transformExpression(fa.getExpression(), returnNull ? BoxingStrategy.INDIFFERENT : CodegenUtil.getBoxingStrategy(model), resultType);
        else {
            body = gen().statementGen().transformBlock(fa.getBlock());
            // useless but satisfies branch checking
            bodyExpr = null;
        }
        for (Substitution subs : substitutions) {
            subs.close();
        }
        // if we have a whole body we're done
        if (body != null)
            return body;
    } else if (!isLazy && typeFact().isCallableType(term.getTypeModel())) {
        returnNull = isAnything(term.getTypeModel()) && term.getUnboxed();
        Function method = methodDecl.getDeclarationModel();
        boolean lazy = specifierExpression instanceof Tree.LazySpecifierExpression;
        boolean inlined = CodegenUtil.canOptimiseMethodSpecifier(term, method);
        Invocation invocation;
        if ((lazy || inlined) && term instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) term).getDeclaration() instanceof Functional) {
            Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) term).getDeclaration();
            Reference producedReference = ((Tree.MemberOrTypeExpression) term).getTarget();
            invocation = new MethodReferenceSpecifierInvocation(this, (Tree.MemberOrTypeExpression) term, primaryDeclaration, producedReference, method, specifierExpression);
        } else if (!lazy && !inlined) {
            // must be a callable we stored
            String name = naming.getMethodSpecifierAttributeName(method);
            invocation = new CallableSpecifierInvocation(this, method, naming.makeUnquotedIdent(name), term, term);
        } else if (isCeylonCallableSubtype(term.getTypeModel())) {
            invocation = new CallableSpecifierInvocation(this, method, expressionGen().transformExpression(term), term, term);
        } else {
            throw new BugException(term, "unhandled primary: " + term == null ? "null" : term.getNodeType());
        }
        invocation.handleBoxing(true);
        invocation.setErased(CodegenUtil.hasTypeErased(term) || getReturnTypeOfCallable(term.getTypeModel()).isNothing());
        bodyExpr = expressionGen().transformInvocation(invocation);
    } else {
        Substitution substitution = null;
        JCStatement varDef = null;
        // Handle implementations of Java variadic methods
        Parameter lastParameter = Decl.getLastParameterFromFirstParameterList(model);
        if (lastParameter != null && Decl.isJavaVariadicIncludingInheritance(lastParameter)) {
            SyntheticName alias = naming.alias(lastParameter.getName());
            substitution = naming.addVariableSubst(lastParameter.getModel(), alias.getName());
            varDef = substituteSequentialForJavaVariadic(alias, lastParameter);
        }
        bodyExpr = expressionGen().transformExpression(model, term);
        if (varDef != null) {
            // Turn into Let for java variadic methods
            bodyExpr = make().LetExpr(List.of(varDef), bodyExpr);
            substitution.close();
        }
        // The innermost of an MPL method declared void needs to return null
        returnNull = Decl.isUnboxedVoid(model) && Decl.isMpl(model);
    }
    if (CodegenUtil.downcastForSmall(term, model)) {
        bodyExpr = expressionGen().applyErasureAndBoxing(bodyExpr, term.getTypeModel(), false, !CodegenUtil.isUnBoxed(term), CodegenUtil.getBoxingStrategy(model), model.getType(), ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK);
    }
    List<JCStatement> body;
    if (!Decl.isUnboxedVoid(model) || Decl.isMpl(model) || Strategy.useBoxedVoid(model)) {
        if (returnNull) {
            body = List.<JCStatement>of(make().Exec(bodyExpr), make().Return(makeNull()));
        } else {
            body = List.<JCStatement>of(make().Return(bodyExpr));
        }
    } else {
        body = List.<JCStatement>of(make().Exec(bodyExpr));
    }
    return body;
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Function(org.eclipse.ceylon.model.typechecker.model.Function) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) Substitution(org.eclipse.ceylon.compiler.java.codegen.Naming.Substitution) 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) 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) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) 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) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter)

Example 39 with Declaration

use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.

the class ClassTransformer method addMissingUnrefinedMembers.

/**
 * Recover from members not being refined in the class hierarchy
 * by generating a stub method that throws.
 */
private void addMissingUnrefinedMembers(Node def, Class classModel, ClassDefinitionBuilder classBuilder) {
    for (Reference unrefined : classModel.getUnimplementedFormals()) {
        // classModel.getMember(memberName, null, false);
        Declaration formalMember = unrefined.getDeclaration();
        String errorMessage = "formal member '" + formalMember.getName() + "' of '" + ((TypeDeclaration) formalMember.getContainer()).getName() + "' not implemented in class hierarchy";
        java.util.List<Type> params = new java.util.ArrayList<Type>();
        for (TypeParameter tp : formalMember.getTypeParameters()) {
            params.add(tp.getType());
        }
        if (formalMember instanceof Value) {
            addRefinedThrowerAttribute(classBuilder, errorMessage, def, classModel, (Value) formalMember);
        } else if (formalMember instanceof Function) {
            addRefinedThrowerMethod(classBuilder, errorMessage, classModel, (Function) formalMember);
        } else if (formalMember instanceof Class && formalMember.isClassMember()) {
            addRefinedThrowerInstantiatorMethod(classBuilder, errorMessage, classModel, (Class) formalMember, unrefined);
        }
    // formal member class of interface handled in
    // makeDelegateToCompanion()
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) ArrayList(java.util.ArrayList) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) 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) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 40 with Declaration

use of org.eclipse.ceylon.model.typechecker.model.Declaration in project ceylon by eclipse.

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(new TransformedType(make().Type(syms().ceylonReachableReferenceType), null, makeAtNonNull()));
    mdb.parameter(pdb);
    mdb.resultType(new TransformedType(make().Type(syms().objectType), null, makeAtNonNull()));
    /*
         * public void $get$(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 = new ListBuffer<JCCase>();
    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 = new ListBuffer<JCStatement>();
            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 = AttributeDefinitionBuilder.field(this, null, member.getName(), (Value) member, false).buildUninitTest();
                if (test != null) {
                    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 = new ListBuffer<JCStatement>();
    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 = new ListBuffer<JCStatement>();
    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 : ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Function(org.eclipse.ceylon.model.typechecker.model.Function) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCSwitch(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCSwitch) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) 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) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCCase(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCCase)

Aggregations

Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)370 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)309 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)264 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)129 Type (org.eclipse.ceylon.model.typechecker.model.Type)100 Class (org.eclipse.ceylon.model.typechecker.model.Class)78 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)74 Value (org.eclipse.ceylon.model.typechecker.model.Value)73 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)72 Function (org.eclipse.ceylon.model.typechecker.model.Function)71 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)71 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)63 ArrayList (java.util.ArrayList)61 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)60 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)60 ModelUtil.getNativeDeclaration (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration)57 AnalyzerUtil.getPackageTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration)51 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)50 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)48 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)45