use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.
the class StatementTransformer method transformVariableOrDestructure.
public List<JCVariableDecl> transformVariableOrDestructure(Tree.Statement varOrDes) {
List<JCVariableDecl> vars = List.<JCVariableDecl>nil();
if (varOrDes instanceof Tree.Variable) {
Tree.Variable var = (Tree.Variable) varOrDes;
Expression expr = var.getSpecifierExpression().getExpression();
BoxingStrategy boxingStrategy = CodegenUtil.getBoxingStrategy(var.getDeclarationModel());
JCExpression init = expressionGen().transformExpression(expr, boxingStrategy, var.getType().getTypeModel());
vars = vars.append(transformVariable(var, init, expr.getTypeModel(), boxingStrategy == BoxingStrategy.BOXED).build());
} else if (varOrDes instanceof Tree.Destructure) {
Tree.Destructure des = (Tree.Destructure) varOrDes;
vars = vars.appendList(transform(des));
} else {
throw BugException.unhandledCase(varOrDes);
}
return vars;
}
use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.
the class NamedArgumentInvocation method bindMethodArgument.
private void bindMethodArgument(Tree.MethodArgument methodArg, Parameter declaredParam, Naming.SyntheticName argName) {
ListBuffer<JCStatement> statements;
Function model = methodArg.getDeclarationModel();
List<JCStatement> body;
boolean prevNoExpressionlessReturn = gen.statementGen().noExpressionlessReturn;
boolean prevSyntheticClassBody = gen.expressionGen().withinSyntheticClassBody(Decl.isMpl(model) || gen.expressionGen().isWithinSyntheticClassBody());
try {
gen.statementGen().noExpressionlessReturn = gen.isAnything(model.getType());
if (methodArg.getBlock() != null) {
body = gen.statementGen().transformBlock(methodArg.getBlock());
if (!methodArg.getBlock().getDefinitelyReturns()) {
if (gen.isAnything(model.getType())) {
body = body.append(gen.make().Return(gen.makeNull()));
} else {
body = body.append(gen.make().Return(gen.makeErroneous(methodArg.getBlock(), "compiler bug: non-void method does not definitely return")));
}
}
} else {
Expression expr = methodArg.getSpecifierExpression().getExpression();
BoxingStrategy boxing = CodegenUtil.getBoxingStrategy(model);
Type type = model.getType();
JCExpression transExpr = gen.expressionGen().transformExpression(expr, boxing, type);
JCReturn returnStat = gen.make().Return(transExpr);
body = List.<JCStatement>of(returnStat);
}
} finally {
gen.expressionGen().withinSyntheticClassBody(prevSyntheticClassBody);
gen.statementGen().noExpressionlessReturn = prevNoExpressionlessReturn;
}
Type callableType = model.appliedReference(null, Collections.<Type>emptyList()).getFullType();
CallableBuilder callableBuilder = CallableBuilder.methodArgument(gen.gen(), methodArg, model, callableType, Collections.singletonList(methodArg.getParameterLists().get(0)), gen.classGen().transformMplBody(methodArg.getParameterLists(), model, body));
JCExpression callable = callableBuilder.build();
JCExpression typeExpr = gen.makeJavaType(callableType, JT_RAW);
JCVariableDecl varDecl = gen.makeVar(argName, typeExpr, callable);
statements = ListBuffer.<JCStatement>of(varDecl);
bind(declaredParam, argName, gen.makeJavaType(callableType), statements.toList());
}
use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.
the class BoxingVisitor method visit.
@Override
public void visit(Tree.SwitchExpression that) {
super.visit(that);
SwitchCaseList caseList = that.getSwitchCaseList();
if (caseList == null || caseList.getCaseClauses() == null)
return;
boolean unboxed = true;
for (Tree.CaseClause caseClause : caseList.getCaseClauses()) {
Expression expr = caseClause.getExpression();
if (expr == null)
return;
// a single boxed one makes the whole switch boxed
if (!CodegenUtil.isUnBoxed(expr))
unboxed = false;
// A Switch expression can never be raw, type erased or untrusted because
// it uses a Let with a new variable declaration, so the rawness,
// erasedness and untrustedness of its branches cannot propagate further
// up the tree.
}
if (caseList.getElseClause() != null) {
Expression expr = caseList.getElseClause().getExpression();
if (expr == null)
return;
// a single boxed one makes the whole switch boxed
if (!CodegenUtil.isUnBoxed(expr))
unboxed = false;
// see comment about about why we don't propagate rawness etc here.
}
if (unboxed && !willEraseToObject(that.getUnit().denotableType(that.getTypeModel())))
CodegenUtil.markUnBoxed(that);
if (that.getTypeModel().isExactly(that.getUnit().getNullValueDeclaration().getType())) {
CodegenUtil.markTypeErased(that);
}
}
use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.
the class BoxingVisitor method visit.
@Override
public void visit(Tree.IfExpression that) {
super.visit(that);
if (that.getIfClause() == null || that.getElseClause() == null)
return;
Tree.Expression ifExpr = that.getIfClause().getExpression();
Tree.Expression elseExpr = that.getElseClause().getExpression();
if (ifExpr == null || elseExpr == null)
return;
if (CodegenUtil.isUnBoxed(ifExpr) && CodegenUtil.isUnBoxed(elseExpr) && !willEraseToObject(that.getUnit().denotableType(that.getTypeModel())))
CodegenUtil.markUnBoxed(that);
if (that.getTypeModel().isExactly(that.getUnit().getNullValueDeclaration().getType())) {
CodegenUtil.markTypeErased(that);
}
// An If expression can never be raw, type erased or untrusted because
// it uses a Let with a new variable declaration, so the rawness,
// erasedness and untrustedness of its branches cannot propagate further
// up the tree.
}
use of com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression in project ceylon-compiler by ceylon.
the class ExpressionTransformer method transformStringExpression.
public JCExpression transformStringExpression(Tree.StringTemplate expr) {
at(expr);
JCExpression builder;
builder = make().NewClass(null, null, naming.makeFQIdent("java", "lang", "StringBuilder"), List.<JCExpression>nil(), null);
java.util.List<Tree.StringLiteral> literals = expr.getStringLiterals();
java.util.List<Tree.Expression> expressions = expr.getExpressions();
for (int ii = 0; ii < literals.size(); ii += 1) {
Tree.StringLiteral literal = literals.get(ii);
if (!literal.getText().isEmpty()) {
// ignore empty string literals
at(literal);
builder = make().Apply(null, makeSelect(builder, "append"), List.<JCExpression>of(transform(literal)));
}
if (ii == expressions.size()) {
// after that because we've already exhausted all the expressions
break;
}
Tree.Expression expression = expressions.get(ii);
at(expression);
// Here in both cases we don't need a type cast for erasure
if (isCeylonBasicType(expression.getTypeModel()) && expression.getUnboxed()) {
// TODO: Test should be erases to String, long, int, boolean, char, byte, float, double
// If erases to a Java primitive just call append, don't box it just to call format.
String method = isCeylonCharacter(expression.getTypeModel()) ? "appendCodePoint" : "append";
builder = make().Apply(null, makeSelect(builder, method), List.<JCExpression>of(transformExpression(expression, BoxingStrategy.UNBOXED, null)));
} else {
JCMethodInvocation formatted = make().Apply(null, makeSelect(transformExpression(expression), "toString"), List.<JCExpression>nil());
builder = make().Apply(null, makeSelect(builder, "append"), List.<JCExpression>of(formatted));
}
}
return make().Apply(null, makeSelect(builder, "toString"), List.<JCExpression>nil());
}
Aggregations