Search in sources :

Example 1 with MatchCase

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

the class ConditionGenerator method caseClause.

/**
 * Generates code for a case clause, as part of a switch statement. Each case
 * is rendered as an if.
 */
private void caseClause(final Tree.CaseClause cc, String expvar, final Tree.Term switchTerm) {
    gen.out("if(");
    final Tree.CaseItem item = cc.getCaseItem();
    Tree.Variable caseVar = null;
    Value caseDec = null;
    if (item instanceof IsCase) {
        IsCase isCaseItem = (IsCase) item;
        gen.generateIsOfType(item, expvar, isCaseItem.getType().getTypeModel(), null, false, false);
        caseVar = isCaseItem.getVariable();
        if (caseVar != null) {
            caseDec = caseVar.getDeclarationModel();
            directAccess.add(caseDec);
            names.forceName(caseDec, expvar);
        }
    } else if (item instanceof Tree.SatisfiesCase) {
        item.addError("case(satisfies) not yet supported", Backend.JavaScript);
        gen.out("true");
    } else if (item instanceof MatchCase) {
        final boolean isNull = switchTerm.getTypeModel().covers(switchTerm.getUnit().getNullType());
        boolean first = true;
        MatchCase matchCaseItem = (MatchCase) item;
        Tree.MatchList matchList = matchCaseItem.getExpressionList();
        if (!matchList.getTypes().isEmpty()) {
            first = false;
            List<Type> union = new ArrayList<Type>();
            for (Tree.Type type : matchList.getTypes()) {
                ModelUtil.addToUnion(union, type.getTypeModel());
            }
            gen.generateIsOfType(item, expvar, ModelUtil.union(union, matchList.getUnit()), null, false, false);
        }
        for (Expression exp : matchList.getExpressions()) {
            if (!first)
                gen.out(" || ");
            final Tree.Term term = exp.getTerm();
            if (term instanceof Tree.StringLiteral || term instanceof Tree.NaturalLiteral) {
                if (isNull) {
                    gen.out(gen.getClAlias(), "nn$(", expvar, ")&&");
                }
                exp.visit(gen);
                gen.out(".equals(", expvar, ")");
            } else if (ModelUtil.isTypeUnknown(switchTerm.getTypeModel())) {
                gen.out(expvar, "===");
                if (!gen.isNaturalLiteral(term)) {
                    exp.visit(gen);
                }
            } else if (term instanceof Tree.Literal) {
                if (switchTerm.getUnit().isOptionalType(switchTerm.getTypeModel())) {
                    gen.out(expvar, "!==null&&");
                }
                gen.out(expvar, ".equals(");
                exp.visit(gen);
                gen.out(")");
            } else if (term instanceof Tree.Tuple) {
                if (((Tree.Tuple) term).getSequencedArgument() == null) {
                    gen.out(expvar, "===", gen.getClAlias(), "empty()");
                } else {
                    gen.out(gen.getClAlias(), "is$(", expvar, ",{t:", gen.getClAlias(), "Tuple})&&", expvar, ".equals(");
                    exp.visit(gen);
                    gen.out(")");
                }
            } else {
                gen.out(expvar, "===");
                exp.visit(gen);
            }
            first = false;
        }
        caseVar = matchCaseItem.getVariable();
        if (caseVar != null) {
            caseDec = caseVar.getDeclarationModel();
            directAccess.add(caseDec);
            names.forceName(caseDec, expvar);
        }
    } else {
        cc.addUnexpectedError("support for case of type " + cc.getClass().getSimpleName() + " not yet implemented", Backend.JavaScript);
    }
    gen.out(")");
    if (cc.getBlock() == null) {
        gen.out("return ");
        cc.getExpression().visit(gen);
        gen.out(";");
    } else {
        gen.out(" ");
        Set<Value> cap = caseDec != null && caseDec.isJsCaptured() ? Collections.singleton(caseDec) : null;
        gen.encloseBlockInFunction(cc.getBlock(), true, cap);
    }
    if (caseDec != null) {
        directAccess.remove(caseDec);
        names.forceName(caseDec, null);
    }
}
Also used : ArrayList(java.util.ArrayList) Type(org.eclipse.ceylon.model.typechecker.model.Type) Expression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression) MatchCase(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MatchCase) Value(org.eclipse.ceylon.model.typechecker.model.Value) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) IsCase(org.eclipse.ceylon.compiler.typechecker.tree.Tree.IsCase)

Aggregations

ArrayList (java.util.ArrayList)1 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)1 Expression (org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression)1 IsCase (org.eclipse.ceylon.compiler.typechecker.tree.Tree.IsCase)1 MatchCase (org.eclipse.ceylon.compiler.typechecker.tree.Tree.MatchCase)1 Type (org.eclipse.ceylon.model.typechecker.model.Type)1 Value (org.eclipse.ceylon.model.typechecker.model.Value)1