Search in sources :

Example 1 with HasErrorException

use of com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformSuperInvocation.

// 
// Invocations
public void transformSuperInvocation(Tree.ExtendedType extendedType, ClassDefinitionBuilder classBuilder) {
    HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(extendedType);
    if (error != null) {
        classBuilder.getInitBuilder().delegateCall(this.makeThrowUnresolvedCompilationError(error));
        return;
    }
    if (extendedType.getInvocationExpression() != null && extendedType.getInvocationExpression().getPositionalArgumentList() != null) {
        Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) extendedType.getInvocationExpression().getPrimary()).getDeclaration();
        java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
        if (paramLists.isEmpty()) {
            classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: missing parameter list in extends clause: " + primaryDeclaration.getName() + " must be invoked")));
        } else {
            boolean prevFnCall = withinInvocation(true);
            try {
                JCStatement superExpr = transformConstructorDelegation(extendedType, new CtorDelegation(null, primaryDeclaration), extendedType.getInvocationExpression(), classBuilder, false);
                classBuilder.getInitBuilder().delegateCall(superExpr);
            } finally {
                withinInvocation(prevFnCall);
            }
        }
    }
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 2 with HasErrorException

use of com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transform.

// Statement expressions
public JCStatement transform(Tree.ExpressionStatement tree) {
    // ExpressionStatements do not return any value, therefore we don't care about the type of the expressions.
    inStatement = true;
    JCStatement result;
    HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(tree.getExpression());
    if (error != null) {
        result = this.makeThrowUnresolvedCompilationError(error);
    } else {
        result = at(tree).Exec(transformExpression(tree.getExpression(), BoxingStrategy.INDIFFERENT, null));
    }
    inStatement = false;
    return result;
}
Also used : HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 3 with HasErrorException

use of com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException in project ceylon-compiler by ceylon.

the class StatementTransformer method transformBlock.

public List<JCStatement> transformBlock(Tree.Block block, boolean revertRet) {
    if (block == null) {
        return List.<JCStatement>nil();
    }
    at(block);
    CeylonVisitor v = gen().visitor;
    final ListBuffer<JCTree> prevDefs = v.defs;
    final boolean prevInInitializer = v.inInitializer;
    final ClassDefinitionBuilder prevClassBuilder = v.classBuilder;
    List<JCStatement> result;
    try {
        v.defs = new ListBuffer<JCTree>();
        v.inInitializer = false;
        v.classBuilder = current();
        java.util.Iterator<Statement> statements = block.getStatements().iterator();
        while (statements.hasNext()) {
            Tree.Statement stmt = statements.next();
            Transformer<JCStatement, Return> returnTransformer;
            if (revertRet && stmt instanceof Tree.Declaration) {
                returnTransformer = returnTransformer(defaultReturnTransformer);
            } else {
                returnTransformer = this.returnTransformer;
            }
            try {
                HasErrorException error = errors().getFirstErrorBlock(stmt);
                if (error == null) {
                    stmt.visit(v);
                } else {
                    v.append(this.makeThrowUnresolvedCompilationError(error));
                    break;
                }
            } finally {
                returnTransformer(returnTransformer);
            }
        }
        result = (List<JCStatement>) v.getResult().toList();
    } finally {
        v.classBuilder = prevClassBuilder;
        v.inInitializer = prevInInitializer;
        v.defs = prevDefs;
        // Close Substitutions which were scoped to this block
        Scope scope = block.getScope();
        while (scope instanceof ConditionScope) {
            scope = scope.getScope();
        }
        naming.closeScopedSubstitutions(scope);
    }
    return result;
}
Also used : Return(com.redhat.ceylon.compiler.typechecker.tree.Tree.Return) ForStatement(com.redhat.ceylon.compiler.typechecker.tree.Tree.ForStatement) Statement(com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) JCTree(com.sun.tools.javac.tree.JCTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Statement(com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement) ConditionScope(com.redhat.ceylon.model.typechecker.model.ConditionScope) Scope(com.redhat.ceylon.model.typechecker.model.Scope) ConditionScope(com.redhat.ceylon.model.typechecker.model.ConditionScope) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

Example 4 with HasErrorException

use of com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException in project ceylon-compiler by ceylon.

the class CeylonTransformer method transformAttribute.

public List<JCTree> transformAttribute(TypedDeclaration declarationModel, String attrName, String attrClassName, final Tree.Declaration annotated, final Tree.Block block, final Tree.SpecifierOrInitializerExpression expression, final Tree.TypedDeclaration decl, final Tree.AttributeSetterDefinition setterDecl) {
    // For everything else generate a getter/setter method
    AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, attrClassName, null, attrName, declarationModel, declarationModel.isToplevel()).is(Flags.PUBLIC, declarationModel.isShared());
    final JCExpression initialValue;
    final HasErrorException expressionError;
    if (expression != null) {
        expressionError = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getExpression());
        if (expressionError != null) {
            initialValue = make().Erroneous();
        } else {
            initialValue = transformValueInit(declarationModel, attrName, expression);
        }
    } else {
        expressionError = null;
        initialValue = transformValueInit(declarationModel, attrName, expression);
    }
    // For captured local variable Values, use a VariableBox
    if (Decl.isBoxedVariable(declarationModel)) {
        if (expressionError != null) {
            return List.<JCTree>of(this.makeThrowUnresolvedCompilationError(expressionError));
        } else {
            return List.<JCTree>of(makeVariableBoxDecl(initialValue, declarationModel));
        }
    }
    // For late-bound getters we only generate a declaration
    if (block == null && expression == null && !Decl.isToplevel(declarationModel)) {
        JCExpression typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
        JCTree.JCVariableDecl var = makeVar(attrClassName, typeExpr, null);
        return List.<JCTree>of(var);
    }
    // Set the local declarations annotation
    if (decl != null) {
        List<JCAnnotation> scopeAnnotations;
        if (Decl.isToplevel(declarationModel) && setterDecl != null) {
            scopeAnnotations = makeAtLocalDeclarations(decl, setterDecl);
        } else {
            scopeAnnotations = makeAtLocalDeclarations(decl);
        }
        builder.classAnnotations(scopeAnnotations);
    } else if (block != null) {
        List<JCAnnotation> scopeAnnotations = makeAtLocalDeclarations(block);
        builder.classAnnotations(scopeAnnotations);
    }
    // Remember the setter class if we generate a getter
    if (Decl.isGetter(declarationModel) && declarationModel.isVariable() && Decl.isLocal(declarationModel)) {
        // we must have a setter class
        Setter setter = ((Value) declarationModel).getSetter();
        if (setter != null) {
            String setterClassName = Naming.getAttrClassName(setter, 0);
            JCExpression setterClassNameExpr = naming.makeUnquotedIdent(setterClassName);
            builder.setterClass(makeSelect(setterClassNameExpr, "class"));
        }
    }
    if (declarationModel instanceof Setter || (declarationModel instanceof FunctionOrValue && ((FunctionOrValue) declarationModel).isParameter())) {
        // For local setters
        JCBlock setterBlock = makeSetterBlock(declarationModel, block, expression);
        builder.setterBlock(setterBlock);
        builder.skipGetter();
        if (Decl.isLocal(decl)) {
            // we need to find back the Setter model for local setters, because
            // in transformAttribute(Tree.TypedDeclaration decl, Tree.AttributeSetterDefinition setterDecl)
            // we turn the declaration model from the Setter to its single parameter
            Setter setter = (Setter) declarationModel.getContainer();
            String getterClassName = Naming.getAttrClassName(setter.getGetter(), 0);
            JCExpression getterClassNameExpr = naming.makeUnquotedIdent(getterClassName);
            builder.isSetter(makeSelect(getterClassNameExpr, "class"));
        }
    } else {
        if (Decl.isValue(declarationModel)) {
            // For local and toplevel value attributes
            if (!declarationModel.isVariable() && !declarationModel.isLate()) {
                builder.immutable();
            }
        } else {
            // For local and toplevel getters
            boolean prevSyntheticClassBody;
            if (Decl.isLocal(declarationModel)) {
                prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(true);
            } else {
                prevSyntheticClassBody = expressionGen().isWithinSyntheticClassBody();
            }
            JCBlock getterBlock = makeGetterBlock(declarationModel, block, expression);
            prevSyntheticClassBody = expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
            builder.getterBlock(getterBlock);
            if (Decl.isLocal(declarationModel)) {
                // For local getters
                builder.immutable();
            } else {
                // For toplevel getters
                if (setterDecl != null) {
                    JCBlock setterBlock = makeSetterBlock(setterDecl.getDeclarationModel(), setterDecl.getBlock(), setterDecl.getSpecifierExpression());
                    builder.setterBlock(setterBlock);
                    // builder.userAnnotationsSetter(expressionGen().transformAnnotations(true, OutputElement.METHOD, setterDecl));
                    builder.userAnnotationsSetter(expressionGen().transformAnnotations(OutputElement.SETTER, setterDecl));
                } else {
                    builder.immutable();
                }
            }
        }
    }
    if (annotated != null) {
        builder.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, annotated));
    }
    if (Decl.isLocal(declarationModel)) {
        if (expressionError != null) {
            return List.<JCTree>of(this.makeThrowUnresolvedCompilationError(expressionError));
        }
        builder.classAnnotations(makeAtLocalDeclaration(declarationModel.getQualifier(), false));
        if (initialValue != null)
            builder.valueConstructor();
        JCExpression typeExpr;
        if (declarationModel instanceof Setter || (declarationModel instanceof FunctionOrValue && ((FunctionOrValue) declarationModel).isParameter())) {
            typeExpr = makeQuotedIdent(attrClassName);
        } else {
            typeExpr = makeJavaType(getGetterInterfaceType(declarationModel));
        }
        return builder.build().append(makeLocalIdentityInstance(typeExpr, attrClassName, attrClassName, declarationModel.isShared(), initialValue));
    } else {
        if (expressionError != null) {
            builder.initialValueError(expressionError);
        } else if (initialValue != null) {
            builder.initialValue(initialValue);
        }
        builder.is(Flags.STATIC, true);
        return builder.build();
    }
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCTree(com.sun.tools.javac.tree.JCTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Setter(com.redhat.ceylon.model.typechecker.model.Setter) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) Value(com.redhat.ceylon.model.typechecker.model.Value) List(com.sun.tools.javac.util.List) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Example 5 with HasErrorException

use of com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException in project ceylon-compiler by ceylon.

the class ClassTransformer method transformSpecifiedMethodBody.

List<JCStatement> transformSpecifiedMethodBody(Tree.MethodDeclaration def, SpecifierExpression specifierExpression) {
    final Function model = def.getDeclarationModel();
    List<JCStatement> body;
    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 = isAnything(resultType) && fa.getExpression().getUnboxed();
        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()));
        }
        bodyExpr = gen().expressionGen().transformExpression(fa.getExpression(), returnNull ? BoxingStrategy.INDIFFERENT : CodegenUtil.getBoxingStrategy(model), resultType);
        for (Substitution subs : substitutions) {
            subs.close();
        }
    } 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 {
        bodyExpr = expressionGen().transformExpression(model, term);
        // The innermost of an MPL method declared void needs to return null
        returnNull = Decl.isUnboxedVoid(model) && Decl.isMpl(model);
    }
    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 : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Function(com.redhat.ceylon.model.typechecker.model.Function) FunctionArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) Substitution(com.redhat.ceylon.compiler.java.codegen.Naming.Substitution) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) FunctionArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Functional(com.redhat.ceylon.model.typechecker.model.Functional) Type(com.redhat.ceylon.model.typechecker.model.Type) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) HasErrorException(com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter)

Aggregations

HasErrorException (com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException)13 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)11 Type (com.redhat.ceylon.model.typechecker.model.Type)6 JCTree (com.sun.tools.javac.tree.JCTree)6 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)5 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)5 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)4 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)3 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)3 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)3 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)3 CustomTree (com.redhat.ceylon.compiler.typechecker.tree.CustomTree)2 SpecifierOrInitializerExpression (com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)2 Statement (com.redhat.ceylon.compiler.typechecker.tree.Tree.Statement)2 Constructor (com.redhat.ceylon.model.typechecker.model.Constructor)2 Function (com.redhat.ceylon.model.typechecker.model.Function)2 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)2 Functional (com.redhat.ceylon.model.typechecker.model.Functional)2 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)2 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)2