use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
the class GenerateJsVisitor method visit.
@Override
public void visit(final Tree.StringTemplate that) {
if (errVisitor.hasErrors(that))
return;
List<Tree.StringLiteral> literals = that.getStringLiterals();
List<Expression> exprs = that.getExpressions();
out("(");
for (int i = 0; i < literals.size(); i++) {
Tree.StringLiteral literal = literals.get(i);
boolean skip = (i == 0 || i == literals.size() - 1) && literal.getText().isEmpty();
if (i > 0 && !skip) {
out("+");
}
if (!skip) {
literal.visit(this);
}
// }
if (i < exprs.size()) {
if (!skip) {
out("+");
}
final Expression expr = exprs.get(i);
final Type t = expr.getTypeModel();
expr.visit(this);
if (t == null || t.isUnknown()) {
out(".toString()");
} else if (!t.isString()) {
out(".string");
}
}
}
out(")");
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
the class Operators method indexOp.
static void indexOp(final Tree.IndexExpression that, final GenerateJsVisitor gen) {
that.getPrimary().visit(gen);
Tree.ElementOrRange eor = that.getElementOrRange();
if (eor instanceof Tree.Element) {
final Tree.Expression _elemexpr = ((Tree.Element) eor).getExpression();
final String _end;
if (gen.isInDynamicBlock() && ModelUtil.isTypeUnknown(that.getPrimary().getTypeModel())) {
gen.out("[");
_end = "]";
} else {
gen.out(".$_get(");
_end = ")";
}
if (!gen.isNaturalLiteral(_elemexpr.getTerm())) {
_elemexpr.visit(gen);
}
gen.out(_end);
} else {
// range, or spread?
Tree.ElementRange er = (Tree.ElementRange) eor;
Expression sexpr = er.getLength();
if (sexpr == null) {
if (er.getLowerBound() == null) {
gen.out(".spanTo(");
} else if (er.getUpperBound() == null) {
gen.out(".spanFrom(");
} else {
gen.out(".span(");
}
} else {
gen.out(".measure(");
}
if (er.getLowerBound() != null) {
if (!gen.isNaturalLiteral(er.getLowerBound().getTerm())) {
er.getLowerBound().visit(gen);
}
if (er.getUpperBound() != null || sexpr != null) {
gen.out(",");
}
}
if (er.getUpperBound() != null) {
if (!gen.isNaturalLiteral(er.getUpperBound().getTerm())) {
er.getUpperBound().visit(gen);
}
} else if (sexpr != null) {
sexpr.visit(gen);
}
gen.out(")");
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
the class ConditionGenerator method generateSwitch.
private void generateSwitch(final Tree.SwitchClause clause, final Tree.SwitchCaseList cases, final SwitchGen sgen) {
final String expvar;
final Expression expr;
if (clause.getSwitched().getExpression() == null) {
expvar = names.name(clause.getSwitched().getVariable().getDeclarationModel());
expr = clause.getSwitched().getVariable().getSpecifierExpression().getExpression();
directAccess.add(clause.getSwitched().getVariable().getDeclarationModel());
} else {
// Put the expression in a tmp var
expr = clause.getSwitched().getExpression();
expvar = names.createTempVariable();
}
sgen.gen1(expvar, expr);
// For each case, do an if
boolean first = true;
for (Tree.CaseClause cc : cases.getCaseClauses()) {
if (!first)
gen.out("else ");
caseClause(cc, expvar, expr.getTerm());
first = false;
}
final Tree.ElseClause anoserque = cases.getElseClause();
if (anoserque == null) {
if (gen.isInDynamicBlock() && ModelUtil.isTypeUnknown(expr.getTypeModel())) {
gen.out("else throw ", gen.getClAlias(), "Exception('Ceylon switch over unknown type does not cover all cases')");
} else {
gen.out("else throw ", gen.getClAlias(), "Exception('Supposedly exhaustive switch was not exhaustive')");
}
} else {
final Tree.Variable elsevar = anoserque.getVariable();
if (elsevar != null) {
directAccess.add(elsevar.getDeclarationModel());
names.forceName(elsevar.getDeclarationModel(), expvar);
}
sgen.gen2(anoserque);
if (elsevar != null) {
directAccess.remove(elsevar.getDeclarationModel());
names.forceName(elsevar.getDeclarationModel(), null);
}
}
sgen.gen3(expr);
if (clause.getSwitched().getExpression() == null) {
directAccess.remove(clause.getSwitched().getVariable().getDeclarationModel());
}
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon by eclipse.
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);
}
use of org.eclipse.ceylon.compiler.typechecker.tree.Tree.Expression 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);
}
Aggregations