Search in sources :

Example 16 with Term

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

the class SpecificationVisitor method visit.

@Override
public void visit(Tree.SpecifierStatement that) {
    Term lhs = that.getBaseMemberExpression();
    Tree.Term term = lhs;
    boolean parameterized = false;
    while (term instanceof Tree.ParameterizedExpression) {
        Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) term;
        term = pe.getPrimary();
        parameterized = true;
    }
    if (term instanceof Tree.StaticMemberOrTypeExpression) {
        Tree.StaticMemberOrTypeExpression bme = (Tree.StaticMemberOrTypeExpression) term;
        Declaration member = bme.getDeclaration();
        if (member == declaration) {
            if (!isForwardReferenceable() && !lhs.hasErrors()) {
                if (declaration.isFormal()) {
                    bme.addError("member is formal and may not be specified: " + name() + " is declared 'formal'");
                } else if (declaration.isDefault()) {
                    bme.addError("member is default and may not be specified except in its declaration: " + name() + " is declared 'default'");
                }
            }
            if (that.getRefinement()) {
                declare();
            }
            Tree.SpecifierExpression se = that.getSpecifierExpression();
            boolean lazy = se instanceof Tree.LazySpecifierExpression;
            checkSpecifiedValue(se);
            if (!lazy || !parameterized) {
                se.visit(this);
            }
            if (that.getRefinement()) {
                specify();
                term.visit(this);
            } else {
                specification(that, bme);
            }
            if (lazy && parameterized) {
                se.visit(this);
            }
            checkDeclarationSection(that);
        } else {
            super.visit(that);
        }
    } else {
        super.visit(that);
    }
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 17 with Term

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

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);
    JCVariableDecl decl2 = null;
    Substitution prevSubst2 = null;
    if (matchCase.getVariable() != null) {
        // Use the type of the variable, which is more precise than the type we test for.
        Type varType = matchCase.getVariable().getDeclarationModel().getType();
        String name = matchCase.getVariable().getIdentifier().getText();
        TypedDeclaration varDecl = matchCase.getVariable().getDeclarationModel();
        Naming.SyntheticName tmpVarName = selectorAlias;
        Name substVarName = naming.aliasName(name);
        // Want raw type for instanceof since it can't be used with generic types
        JCExpression rawToTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES | JT_RAW);
        // Substitute variable with the correct type to use in the rest of the code block
        JCExpression tmpVarExpr = at(matchCase).TypeCast(rawToTypeExpr, tmpVarName.makeIdent());
        JCExpression toTypeExpr;
        if (isCeylonBasicType(varType) && varDecl.getUnboxed() == true) {
            toTypeExpr = makeJavaType(varType);
            tmpVarExpr = unboxType(tmpVarExpr, varType);
        } else {
            toTypeExpr = makeJavaType(varType, JT_NO_PRIMITIVES);
        }
        // The variable holding the result for the code inside the code block
        decl2 = at(matchCase).VarDef(make().Modifiers(FINAL), substVarName, toTypeExpr, tmpVarExpr);
        // Prepare for variable substitution in the following code block
        prevSubst2 = naming.addVariableSubst(varDecl, substVarName.toString());
    }
    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));
        Type type = term.getTypeModel();
        JCExpression transformedExpression = expressionGen().transformExpression(term, unboxedEquality ? BoxingStrategy.UNBOXED : BoxingStrategy.BOXED, type);
        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(), type), "equals"), List.<JCExpression>of(transformedExpression));
                } else {
                    test = make().Binary(JCTree.Tag.EQ, primitiveSelector ? selectorAlias.makeIdent() : unboxType(selectorAlias.makeIdent(), type), transformedExpression);
                }
            } else {
                test = make().Apply(null, makeSelect(selectorAlias.makeIdent(), "equals"), List.<JCExpression>of(transformedExpression));
            }
            if (isOptional(switchType)) {
                test = make().Binary(JCTree.Tag.AND, make().Binary(JCTree.Tag.NE, selectorAlias.makeIdent(), makeNull()), test);
            }
        } else {
            JCExpression selectorExpr;
            if (!primitiveSelector && isCeylonBasicType(typeFact().getDefiniteType(switchType))) {
                selectorExpr = unboxType(selectorAlias.makeIdent(), type);
            } else {
                selectorExpr = selectorAlias.makeIdent();
            }
            if (term instanceof Tree.Tuple) {
                if (type.isEmpty()) {
                    test = make().TypeTest(selectorAlias.makeIdent(), makeJavaType(typeFact().getEmptyType(), JT_RAW));
                } else {
                    test = make().Apply(null, makeSelect(selectorExpr, "equals"), List.<JCExpression>of(transformedExpression));
                    test = make().Binary(Tag.AND, make().TypeTest(selectorAlias.makeIdent(), make().QualIdent(syms().ceylonTupleType.tsym)), test);
                }
            } else if (type.isString()) {
                test = make().Apply(null, makeSelect(selectorExpr, "equals"), List.<JCExpression>of(transformedExpression));
            } else {
                test = make().Binary(JCTree.Tag.EQ, selectorExpr, transformedExpression);
            }
        }
        if (tests == null) {
            tests = test;
        } else if (isNull(type)) {
            // ensure we do any null check as the first operation in the ||-ed expression
            tests = make().Binary(JCTree.Tag.OR, test, tests);
        } else {
            tests = make().Binary(JCTree.Tag.OR, tests, test);
        }
    }
    java.util.List<Tree.Type> types = matchCase.getExpressionList().getTypes();
    for (Tree.Type caseType : types) {
        // note: There's no point using makeOptimizedTypeTest() because cases are disjoint
        // anyway and the cheap cases get evaluated first.
        Type type = caseType.getTypeModel();
        JCExpression cond = makeTypeTest(null, selectorAlias, type, type);
        if (tests == null) {
            tests = cond;
        } else if (isNull(type)) {
            // ensure we do any null check as the first operation in the ||-ed expression
            tests = make().Binary(JCTree.Tag.OR, cond, tests);
        } else {
            tests = make().Binary(JCTree.Tag.OR, tests, cond);
        }
    }
    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;
    if (decl2 != null) {
        List<JCStatement> stats = List.<JCStatement>of(decl2);
        stats = stats.appendList(transformCaseClause(caseClause, tmpVar, outerExpression, expectedType));
        block = at(matchCase).Block(0, stats);
    } else {
        block = transformCaseClauseBlock(caseClause, tmpVar, outerExpression, expectedType);
    }
    if (prevSubst2 != null) {
        // Deactivate the above variable substitution
        prevSubst2.close();
    }
    if (prevSubst != null) {
        // Deactivate the above variable substitution
        prevSubst.close();
    }
    return at(caseClause).If(tests, block, last);
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) CName(org.eclipse.ceylon.compiler.java.codegen.Naming.CName) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) Substitution(org.eclipse.ceylon.compiler.java.codegen.Naming.Substitution) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) JCBlock(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCBlock) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

Example 18 with Term

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

the class StatementTransformer method definitelySatisfiedOrNot.

private boolean definitelySatisfiedOrNot(java.util.List<Tree.Condition> conditions, boolean satisfied) {
    if (conditions.size() != 1) {
        return false;
    }
    Tree.Condition condition = conditions.get(0);
    if (!(condition instanceof Tree.BooleanCondition)) {
        return false;
    }
    Tree.Term term = ((Tree.BooleanCondition) condition).getExpression().getTerm();
    if (!(term instanceof Tree.BaseMemberExpression)) {
        return false;
    }
    Declaration declaration = ((Tree.BaseMemberExpression) term).getDeclaration();
    return declaration instanceof Value && satisfied ? isBooleanTrue(declaration) : isBooleanFalse(declaration);
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) Condition(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Condition) Value(org.eclipse.ceylon.model.typechecker.model.Value) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 19 with Term

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

the class Strategy method useConstantIterable.

/**
 * Return true if all the ListedArguments in the given list are compile time constants
 * (or at least literals): In this case we will use a ConstantIterable instead
 * of an anonymous subclass of LazyIterable.
 */
public static boolean useConstantIterable(SequencedArgument sequencedArgument) {
    Unit unit = sequencedArgument.getUnit();
    boolean allCtc = true;
    for (Tree.PositionalArgument pa : sequencedArgument.getPositionalArguments()) {
        if (pa instanceof Tree.ListedArgument) {
            Term term = ((Tree.ListedArgument) pa).getExpression().getTerm();
            if (term instanceof Tree.StringLiteral || term instanceof Tree.NaturalLiteral || term instanceof Tree.FloatLiteral || term instanceof Tree.CharLiteral || (term instanceof Tree.NegativeOp && (((Tree.NegativeOp) term).getTerm() instanceof Tree.NaturalLiteral || ((Tree.NegativeOp) term).getTerm() instanceof Tree.FloatLiteral)) || (term instanceof Tree.BaseMemberExpression && (((Tree.BaseMemberExpression) term).getDeclaration().equals(unit.getTrueValueDeclaration()) || ((Tree.BaseMemberExpression) term).getDeclaration().equals(unit.getFalseValueDeclaration())))) {
            } else {
                allCtc = false;
                break;
            }
        }
    }
    return allCtc;
}
Also used : Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) PositionalArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.PositionalArgument)

Example 20 with Term

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

the class SmallVisitor method visit.

@Override
public void visit(Tree.ValueIterator that) {
    Declaration preva = assigning;
    assigning = that.getVariable().getDeclarationModel();
    Term term = TreeUtil.unwrapExpressionUntilTerm(that.getSpecifierExpression().getExpression());
    if (term instanceof Tree.SegmentOp || term instanceof Tree.RangeOp) {
        ((FunctionOrValue) assigning).setSmall(true);
    }
    super.visit(that);
    if (term instanceof Tree.SegmentOp || term instanceof Tree.RangeOp) {
        boolean small = ((Tree.BinaryOperatorExpression) term).getLeftTerm().getSmall() && ((Tree.BinaryOperatorExpression) term).getRightTerm().getSmall();
        ((FunctionOrValue) assigning).setSmall(small);
        if (small) {
            that.getVariable().getDeclarationModel().setType(SmallDeclarationVisitor.smallUnderlyingType(that.getVariable().getDeclarationModel().getType()));
        }
    }
    checkSmallAssignment(that.getSpecifierExpression().getExpression());
    assigning = preva;
}
Also used : Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) Term(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

Term (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Term)29 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)27 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)14 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)11 Type (org.eclipse.ceylon.model.typechecker.model.Type)11 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)11 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)10 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)10 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)6 Function (org.eclipse.ceylon.model.typechecker.model.Function)6 UnionType (org.eclipse.ceylon.model.typechecker.model.UnionType)6 AttributeDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration)5 TreeUtil.unwrapExpressionUntilTerm (org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.unwrapExpressionUntilTerm)5 BaseMemberExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)4 ExtendedType (org.eclipse.ceylon.compiler.typechecker.tree.Tree.ExtendedType)4 LazySpecifierExpression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression)4 IntersectionType (org.eclipse.ceylon.model.typechecker.model.IntersectionType)4 SyntheticName (org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)3 AssignmentOperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.AssignmentOperatorTranslation)3 OperatorTranslation (org.eclipse.ceylon.compiler.java.codegen.Operators.OperatorTranslation)3