Search in sources :

Example 6 with Expression

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.

the class StatementTransformer method transformCaseMatch.

private JCStatement transformCaseMatch(Naming.SyntheticName selectorAlias, Tree.SwitchClause switchClause, Tree.CaseClause caseClause, String tmpVar, Tree.Term outerExpression, Type expectedType, Tree.MatchCase matchCase, JCStatement last, Type switchType, boolean primitiveSelector) {
    at(matchCase);
    JCExpression tests = null;
    java.util.List<Tree.Expression> expressions = matchCase.getExpressionList().getExpressions();
    for (Tree.Expression expr : expressions) {
        Tree.Term term = ExpressionTransformer.eliminateParens(expr.getTerm());
        boolean unboxedEquality = primitiveSelector || isCeylonBasicType(typeFact().getDefiniteType(switchType));
        JCExpression transformedExpression = expressionGen().transformExpression(term, unboxedEquality ? BoxingStrategy.UNBOXED : BoxingStrategy.BOXED, term.getTypeModel());
        JCExpression test;
        if (term instanceof Tree.Literal || term instanceof Tree.NegativeOp) {
            if (unboxedEquality) {
                if (term instanceof Tree.StringLiteral) {
                    test = make().Apply(null, makeSelect(unboxType(selectorAlias.makeIdent(), term.getTypeModel()), "equals"), List.<JCExpression>of(transformedExpression));
                } else {
                    test = make().Binary(JCTree.EQ, primitiveSelector ? selectorAlias.makeIdent() : unboxType(selectorAlias.makeIdent(), term.getTypeModel()), transformedExpression);
                }
            } else {
                test = make().Apply(null, makeSelect(selectorAlias.makeIdent(), "equals"), List.<JCExpression>of(transformedExpression));
            }
            if (isOptional(switchType)) {
                test = make().Binary(JCTree.AND, make().Binary(JCTree.NE, selectorAlias.makeIdent(), makeNull()), test);
            }
        } else {
            JCExpression selectorExpr;
            if (!primitiveSelector && isCeylonBasicType(typeFact().getDefiniteType(switchType))) {
                selectorExpr = unboxType(selectorAlias.makeIdent(), term.getTypeModel());
            } else {
                selectorExpr = selectorAlias.makeIdent();
            }
            test = make().Binary(JCTree.EQ, selectorExpr, transformedExpression);
        }
        if (tests == null)
            tests = test;
        else if (isNull(term.getTypeModel())) {
            // ensure we do any null check as the first operation in the ||-ed expression
            tests = make().Binary(JCTree.OR, test, tests);
        } else {
            tests = make().Binary(JCTree.OR, tests, test);
        }
    }
    Substitution prevSubst = null;
    if (switchClause.getSwitched().getVariable() != null) {
        // Prepare for variable substitution in the following code block
        prevSubst = naming.addVariableSubst(switchClause.getSwitched().getVariable().getDeclarationModel(), selectorAlias.toString());
    }
    JCBlock block = transformCaseClauseBlock(caseClause, tmpVar, outerExpression, expectedType);
    if (prevSubst != null) {
        // Deactivate the above variable substitution
        prevSubst.close();
    }
    return at(caseClause).If(tests, block, last);
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Substitution(com.redhat.ceylon.compiler.java.codegen.Naming.Substitution) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SpecifierOrInitializerExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

Example 7 with Expression

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.

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 : LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) SpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) SpecifierOrInitializerExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Primary(com.redhat.ceylon.compiler.typechecker.tree.Tree.Primary) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)

Example 8 with Expression

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.

the class CeylonDocTool method warningMissingThrows.

protected void warningMissingThrows(Declaration d) {
    if (ignoreMissingThrows) {
        return;
    }
    final Scope scope = d.getScope();
    final PhasedUnit unit = getUnit(d);
    final Node node = getNode(d);
    if (scope == null || unit == null || unit.getUnit() == null || node == null || !(d instanceof FunctionOrValue)) {
        return;
    }
    List<Type> documentedExceptions = new ArrayList<Type>();
    for (Annotation annotation : d.getAnnotations()) {
        if (annotation.getName().equals("throws")) {
            String exceptionName = annotation.getPositionalArguments().get(0);
            Declaration exceptionDecl = scope.getMemberOrParameter(unit.getUnit(), exceptionName, null, false);
            if (exceptionDecl instanceof TypeDeclaration) {
                documentedExceptions.add(((TypeDeclaration) exceptionDecl).getType());
            }
        }
    }
    final List<Type> thrownExceptions = new ArrayList<Type>();
    node.visitChildren(new Visitor() {

        @Override
        public void visit(Tree.Throw that) {
            Expression expression = that.getExpression();
            if (expression != null) {
                thrownExceptions.add(expression.getTypeModel());
            } else {
                thrownExceptions.add(unit.getUnit().getExceptionType());
            }
        }

        @Override
        public void visit(Tree.Declaration that) {
        // the end of searching
        }
    });
    for (Type thrownException : thrownExceptions) {
        boolean isDocumented = false;
        for (Type documentedException : documentedExceptions) {
            if (thrownException.isSubtypeOf(documentedException)) {
                isDocumented = true;
                break;
            }
        }
        if (!isDocumented) {
            log.warning(CeylondMessages.msg("warn.missingThrows", thrownException.asString(), getWhere(d), getPosition(getNode(d))));
        }
    }
}
Also used : Visitor(com.redhat.ceylon.compiler.typechecker.tree.Visitor) SourceDeclarationVisitor(com.redhat.ceylon.compiler.java.loader.SourceDeclarationVisitor) Node(com.redhat.ceylon.compiler.typechecker.tree.Node) ArrayList(java.util.ArrayList) Annotation(com.redhat.ceylon.model.typechecker.model.Annotation) PhasedUnit(com.redhat.ceylon.compiler.typechecker.context.PhasedUnit) NothingType(com.redhat.ceylon.model.typechecker.model.NothingType) Type(com.redhat.ceylon.model.typechecker.model.Type) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue)

Example 9 with Expression

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.

the class StatementTransformer method transform.

JCStatement transform(Node node, Tree.SwitchClause switchClause, Tree.SwitchCaseList caseList, String tmpVar, Tree.Term outerExpression, Type expectedType) {
    at(switchClause);
    block();
    SwitchTransformation transformation = null;
    Type exprType = switchExpressionType(switchClause);
    Boolean switchUnboxed = switchExpressionUnboxed(switchClause);
    // Are we switching with just String literal or Character literal match cases? 
    if (isJavaSwitchableType(exprType, switchUnboxed)) {
        boolean canUseSwitch = true;
        caseStmts: for (Tree.CaseClause clause : caseList.getCaseClauses()) {
            if (clause.getCaseItem() instanceof Tree.MatchCase) {
                java.util.List<Expression> caseExprs = ((Tree.MatchCase) clause.getCaseItem()).getExpressionList().getExpressions();
                caseExpr: for (Tree.Expression expr : caseExprs) {
                    Tree.Term e = ExpressionTransformer.eliminateParens(expr);
                    if (e instanceof Tree.StringLiteral || e instanceof Tree.CharLiteral) {
                        continue caseExpr;
                    } else if (e instanceof Tree.BaseMemberExpression && ((Tree.BaseMemberExpression) e).getDeclaration() instanceof Value && ((Value) ((Tree.BaseMemberExpression) e).getDeclaration()).isEnumValue()) {
                        continue caseExpr;
                    } else {
                        canUseSwitch = false;
                        break caseStmts;
                    }
                }
            } else {
                canUseSwitch = false;
                break caseStmts;
            }
        }
        if (canUseSwitch) {
            // yes, so use a Java Switch
            transformation = new Switch();
        }
    }
    if (transformation == null && isOptional(exprType)) {
        // Are we switching with just String literal or Character literal plus null 
        // match cases?
        Type definiteType = typeFact().getDefiniteType(exprType);
        if (isJavaSwitchableType(definiteType, switchUnboxed)) {
            boolean canUseIfElseSwitch = true;
            boolean hasSingletonNullCase = false;
            caseStmts: for (Tree.CaseClause clause : caseList.getCaseClauses()) {
                if (clause.getCaseItem() instanceof Tree.MatchCase) {
                    if (getSingletonNullCase(clause) != null) {
                        hasSingletonNullCase = true;
                    }
                    java.util.List<Expression> caseExprs = ((Tree.MatchCase) clause.getCaseItem()).getExpressionList().getExpressions();
                    caseExpr: for (Tree.Expression expr : caseExprs) {
                        Tree.Term e = ExpressionTransformer.eliminateParens(expr);
                        if (e instanceof Tree.StringLiteral || e instanceof Tree.CharLiteral) {
                            continue caseExpr;
                        } else if (e instanceof Tree.BaseMemberExpression && isNullValue(((Tree.BaseMemberExpression) e).getDeclaration()) && caseExprs.size() == 1) {
                            continue caseExpr;
                        } else if (e instanceof Tree.BaseMemberExpression && ((Tree.BaseMemberExpression) e).getDeclaration() instanceof Value && ((Value) ((Tree.BaseMemberExpression) e).getDeclaration()).isEnumValue()) {
                            continue caseExpr;
                        } else {
                            canUseIfElseSwitch = false;
                            break caseStmts;
                        }
                    }
                } else {
                    canUseIfElseSwitch = false;
                    break caseStmts;
                }
            }
            canUseIfElseSwitch &= hasSingletonNullCase;
            if (canUseIfElseSwitch) {
                // yes, so use a If
                transformation = new IfNullElseSwitch();
            }
        }
    }
    // The default transformation
    if (transformation == null) {
        transformation = new IfElseChain();
    }
    JCStatement result = transformation.transformSwitch(node, switchClause, caseList, tmpVar, outerExpression, expectedType);
    unblock();
    return result;
}
Also used : Term(com.redhat.ceylon.compiler.typechecker.tree.Tree.Term) CaseClause(com.redhat.ceylon.compiler.typechecker.tree.Tree.CaseClause) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Type(com.redhat.ceylon.model.typechecker.model.Type) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) Value(com.redhat.ceylon.model.typechecker.model.Value) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) ConditionList(com.redhat.ceylon.compiler.typechecker.tree.Tree.ConditionList) List(com.sun.tools.javac.util.List) ArrayList(java.util.ArrayList)

Example 10 with Expression

use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.

the class StatementTransformer method getDocAnnotationText.

private String getDocAnnotationText(Tree.Assertion ass) {
    String docText = null;
    Tree.Annotation doc = getAnnotation(ass.getAnnotationList(), "doc");
    if (doc != null) {
        Tree.Expression expression = null;
        if (doc.getPositionalArgumentList() != null) {
            Tree.PositionalArgument arg = doc.getPositionalArgumentList().getPositionalArguments().get(0);
            if (arg instanceof Tree.ListedArgument)
                expression = ((Tree.ListedArgument) arg).getExpression();
            else
                throw new BugException(arg, "argument to doc annotation cannot be a spread argument or comprehension: " + arg);
        } else if (doc.getNamedArgumentList() != null) {
            Tree.SpecifiedArgument arg = (Tree.SpecifiedArgument) doc.getNamedArgumentList().getNamedArguments().get(0);
            expression = arg.getSpecifierExpression().getExpression();
        } else {
            // Impossible on a well-formed tree
            return null;
        }
        Tree.Literal literal = (Tree.Literal) expression.getTerm();
        docText = literal.getText();
    } else if (ass.getAnnotationList() != null && ass.getAnnotationList().getAnonymousAnnotation() != null) {
        docText = ass.getAnnotationList().getAnonymousAnnotation().getStringLiteral().getText();
    }
    return docText;
}
Also used : Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

Aggregations

Expression (com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression)15 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)14 JCTree (com.sun.tools.javac.tree.JCTree)10 CustomTree (com.redhat.ceylon.compiler.typechecker.tree.CustomTree)8 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)8 Type (com.redhat.ceylon.model.typechecker.model.Type)6 SpecifierOrInitializerExpression (com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression)5 Term (com.redhat.ceylon.compiler.typechecker.tree.Tree.Term)5 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)4 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)4 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)3 ArrayList (java.util.ArrayList)3 BoxingStrategy (com.redhat.ceylon.compiler.java.codegen.AbstractTransformer.BoxingStrategy)2 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)2 LetExpression (com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression)2 Variable (com.redhat.ceylon.compiler.typechecker.tree.Tree.Variable)2 CName (com.redhat.ceylon.compiler.java.codegen.Naming.CName)1 Substitution (com.redhat.ceylon.compiler.java.codegen.Naming.Substitution)1 SourceDeclarationVisitor (com.redhat.ceylon.compiler.java.loader.SourceDeclarationVisitor)1 PhasedUnit (com.redhat.ceylon.compiler.typechecker.context.PhasedUnit)1