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);
}
}
Aggregations