use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCExpression transform(Tree.ScaleOp op) {
OperatorTranslation operator = Operators.getOperator(Tree.ScaleOp.class);
Tree.Term scalableTerm = op.getRightTerm();
Type scalableTermType = getSupertype(scalableTerm, typeFact().getScalableDeclaration());
SyntheticName scaleableName = naming.alias("scalable");
JCVariableDecl scaleable = makeVar(scaleableName, makeJavaType(scalableTermType, JT_NO_PRIMITIVES), transformExpression(scalableTerm, BoxingStrategy.BOXED, scalableTermType));
Tree.Term scaleTerm = op.getLeftTerm();
SyntheticName scaleName = naming.alias("scale");
Type scaleType = getTypeArgument(scalableTermType, 0);
JCExpression scaleValue;
if (isCeylonInteger(scaleTerm.getTypeModel()) && isCeylonFloat(scaleType)) {
// Disgusting coercion
scaleValue = transformExpression(scaleTerm, BoxingStrategy.UNBOXED, scalableTerm.getTypeModel());
scaleValue = boxType(scaleValue, typeFact().getFloatType());
} else {
scaleValue = transformExpression(scaleTerm, BoxingStrategy.BOXED, scaleType);
}
JCVariableDecl scale = makeVar(scaleName, makeJavaType(scaleType, JT_NO_PRIMITIVES), scaleValue);
at(op);
return make().LetExpr(List.<JCStatement>of(scale, scaleable), transformOverridableBinaryOperator(op, operator, OptimisationStrategy.NONE, scaleableName.makeIdent(), scaleName.makeIdent(), null, null, op.getTypeModel()).build());
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.
the class ExpressionTransformer method transform.
// Postfix operator
public JCExpression transform(Tree.PostfixOperatorExpression expr) {
OperatorTranslation operator = Operators.getOperator(expr.getClass());
if (operator == null) {
return makeErroneous(expr, "compiler bug " + expr.getNodeType() + " is not yet supported");
}
OptimisationStrategy optimisationStrategy = operator.getUnOpOptimisationStrategy(expr, expr.getTerm(), this);
boolean canOptimise = optimisationStrategy.useJavaOperator();
// only fully optimise if we don't have to access the getter/setter
if (canOptimise && CodegenUtil.isDirectAccessVariable(expr.getTerm())) {
JCExpression term = transformExpression(expr.getTerm(), BoxingStrategy.UNBOXED, expr.getTypeModel(), EXPR_WIDEN_PRIM);
return at(expr).Unary(operator.javacOperator, term);
}
Tree.Term term = unwrapExpressionUntilTerm(expr.getTerm());
Type returnType = term.getTypeModel();
List<JCVariableDecl> decls = List.nil();
List<JCStatement> stats = List.nil();
JCExpression result = null;
// we can optimise that case a bit sometimes
boolean boxResult = !canOptimise;
// (let $tmp = attr; attr = $tmp.getSuccessor(); $tmp;)
if (term instanceof Tree.BaseMemberExpression || // special case for java statics Foo.attr where Foo does not need to be evaluated
(term instanceof Tree.QualifiedMemberExpression && ((Tree.QualifiedMemberExpression) term).getStaticMethodReference())) {
JCExpression getter;
if (term instanceof Tree.BaseMemberExpression)
getter = transform((Tree.BaseMemberExpression) term, null);
else
getter = transformMemberExpression((Tree.QualifiedMemberExpression) term, null, null);
at(expr);
// Type $tmp = attr
JCExpression exprType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
Name varName = naming.tempName("op");
// make sure we box the results if necessary
getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, returnType);
JCVariableDecl tmpVar = make().VarDef(make().Modifiers(0), varName, exprType, getter);
decls = decls.prepend(tmpVar);
// attr = $tmp.getSuccessor()
JCExpression successor;
if (canOptimise) {
// use +1/-1 if we can optimise a bit
successor = make().Binary(operator == OperatorTranslation.UNARY_POSTFIX_INCREMENT ? JCTree.Tag.PLUS : JCTree.Tag.MINUS, make().Ident(varName), makeInteger(1));
successor = unAutoPromote(successor, returnType, expr.getSmall());
} else {
successor = make().Apply(null, makeSelect(make().Ident(varName), operator.getCeylonMethodName()), List.<JCExpression>nil());
// make sure the result is boxed if necessary, the result of successor/predecessor is always boxed
successor = boxUnboxIfNecessary(successor, true, term.getTypeModel(), CodegenUtil.getBoxingStrategy(term));
}
JCExpression assignment = makeAssignment(expr, term, transformAssignmentLhs(expr, term), successor);
stats = stats.prepend(at(expr).Exec(assignment));
// $tmp
result = make().Ident(varName);
} else if (term instanceof Tree.QualifiedMemberExpression) {
// e.attr++
// (let $tmpE = e, $tmpV = $tmpE.attr; $tmpE.attr = $tmpV.getSuccessor(); $tmpV;)
Tree.QualifiedMemberExpression qualified = (Tree.QualifiedMemberExpression) term;
boolean isSuper = isSuperOrSuperOf(qualified.getPrimary());
boolean isPackage = isPackageQualified(qualified);
// transform the primary, this will get us a boxed primary
JCExpression e = transformQualifiedMemberPrimary(qualified);
at(expr);
// Type $tmpE = e
JCExpression exprType = makeJavaType(qualified.getTarget().getQualifyingType(), JT_NO_PRIMITIVES);
Name varEName = naming.tempName("opE");
JCVariableDecl tmpEVar = make().VarDef(make().Modifiers(0), varEName, exprType, e);
// Type $tmpV = $tmpE.attr
JCExpression attrType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
Name varVName = naming.tempName("opV");
JCExpression getter;
if (isSuper) {
getter = transformMemberExpression(qualified, transformSuper(qualified), null);
} else if (isPackage) {
getter = transformMemberExpression(qualified, null, null);
} else {
getter = transformMemberExpression(qualified, make().Ident(varEName), null);
}
// make sure we box the results if necessary
getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, returnType);
JCVariableDecl tmpVVar = make().VarDef(make().Modifiers(0), varVName, attrType, getter);
decls = decls.prepend(tmpVVar);
if (!isSuper && !isPackage) {
// define all the variables
decls = decls.prepend(tmpEVar);
}
// $tmpE.attr = $tmpV.getSuccessor()
JCExpression successor;
if (canOptimise) {
// use +1/-1 if we can optimise a bit
successor = make().Binary(operator == OperatorTranslation.UNARY_POSTFIX_INCREMENT ? JCTree.Tag.PLUS : JCTree.Tag.MINUS, make().Ident(varVName), makeInteger(1));
successor = unAutoPromote(successor, returnType, expr.getSmall());
} else {
successor = make().Apply(null, makeSelect(make().Ident(varVName), operator.getCeylonMethodName()), List.<JCExpression>nil());
// make sure the result is boxed if necessary, the result of successor/predecessor is always boxed
successor = boxUnboxIfNecessary(successor, true, term.getTypeModel(), CodegenUtil.getBoxingStrategy(term));
}
JCExpression assignment = makeAssignment(expr, term, qualifyLhs(expr, term, isSuper ? transformSuper(qualified) : make().Ident(varEName)), successor);
stats = stats.prepend(at(expr).Exec(assignment));
// $tmpV
result = make().Ident(varVName);
} else {
return makeErroneous(term, "compiler bug: " + term.getNodeType() + " is not supported yet");
}
return make().LetExpr(decls, stats, result);
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.
the class ExpressionTransformer method transformAssignAndReturnOperation.
private JCExpression transformAssignAndReturnOperation(Node operator, Tree.Term term, boolean boxResult, Type valueType, Type returnType, AssignAndReturnOperationFactory factory) {
List<JCVariableDecl> decls = List.nil();
List<JCStatement> stats = List.nil();
JCExpression result = null;
// (let $tmp = OP(attr); attr = $tmp; $tmp)
if (term instanceof Tree.BaseMemberExpression || (term instanceof Tree.IndexExpression) || // special case for java statics Foo.attr where Foo does not need to be evaluated
(term instanceof Tree.QualifiedMemberExpression && ((Tree.QualifiedMemberExpression) term).getStaticMethodReference())) {
JCExpression getter;
if (term instanceof Tree.BaseMemberExpression)
getter = transform((Tree.BaseMemberExpression) term, null);
else if (term instanceof Tree.IndexExpression)
getter = null;
else
getter = transformMemberExpression((Tree.QualifiedMemberExpression) term, null, null);
at(operator);
// Type $tmp = OP(attr);
JCExpression exprType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
Name varName = naming.tempName("op");
// make sure we box the results if necessary
getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, valueType);
JCExpression newValue = factory.getNewValue(getter);
// no need to box/unbox here since newValue and $tmpV share the same boxing type
JCVariableDecl tmpVar = make().VarDef(make().Modifiers(0), varName, exprType, newValue);
decls = decls.prepend(tmpVar);
// attr = $tmp
// make sure the result is unboxed if necessary, $tmp may be boxed
JCExpression value = make().Ident(varName);
BoxingStrategy boxingStrategy = CodegenUtil.getBoxingStrategy(term);
value = applyErasureAndBoxing(value, returnType, boxResult, boxingStrategy, valueType);
JCExpression assignment = makeAssignment(operator, term, transformAssignmentLhs(operator, term), value);
stats = stats.prepend(at(operator).Exec(assignment));
// $tmp
// return, with the box type we asked for
result = make().Ident(varName);
} else if (term instanceof Tree.QualifiedMemberExpression) {
// e.attr
// (let $tmpE = e, $tmpV = OP($tmpE.attr); $tmpE.attr = $tmpV; $tmpV;)
Tree.QualifiedMemberExpression qualified = (Tree.QualifiedMemberExpression) term;
boolean isSuper = isSuperOrSuperOf(qualified.getPrimary());
// transform the primary, this will get us a boxed primary
JCExpression e = transformQualifiedMemberPrimary(qualified);
at(operator);
// Type $tmpE = e
JCExpression exprType = makeJavaType(qualified.getTarget().getQualifyingType(), JT_NO_PRIMITIVES);
Name varEName = naming.tempName("opE");
JCVariableDecl tmpEVar = make().VarDef(make().Modifiers(0), varEName, exprType, e);
// Type $tmpV = OP($tmpE.attr)
JCExpression attrType = makeJavaType(returnType, boxResult ? JT_NO_PRIMITIVES : 0);
Name varVName = naming.tempName("opV");
JCExpression getter = transformMemberExpression(qualified, isSuper ? transformSuper(qualified) : make().Ident(varEName), null);
// make sure we box the results if necessary
getter = applyErasureAndBoxing(getter, term, boxResult ? BoxingStrategy.BOXED : BoxingStrategy.UNBOXED, valueType);
JCExpression newValue = factory.getNewValue(getter);
// no need to box/unbox here since newValue and $tmpV share the same boxing type
JCVariableDecl tmpVVar = make().VarDef(make().Modifiers(0), varVName, attrType, newValue);
// define all the variables
decls = decls.prepend(tmpVVar);
if (!isSuper) {
decls = decls.prepend(tmpEVar);
}
// $tmpE.attr = $tmpV
// make sure $tmpV is unboxed if necessary
JCExpression value = make().Ident(varVName);
BoxingStrategy boxingStrategy = CodegenUtil.getBoxingStrategy(term);
value = applyErasureAndBoxing(value, returnType, boxResult, boxingStrategy, valueType);
JCExpression assignment = makeAssignment(operator, term, qualifyLhs(operator, term, isSuper ? transformSuper(qualified) : make().Ident(varEName)), value);
stats = stats.prepend(at(operator).Exec(assignment));
// $tmpV
// return, with the box type we asked for
result = make().Ident(varVName);
} else {
return makeErroneous(operator, "compiler bug: " + term.getNodeType() + " is not a supported assign and return operator");
}
return make().LetExpr(decls, stats, result);
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.
the class StatementTransformer method transformCatchesPolymorphic.
/**
* Transforms a list of {@code CatchClause}s to a corresponding list
* of {@code JCCatch}.
* @see #transformCatchesIfElseIf(java.util.List)
*/
private List<JCCatch> transformCatchesPolymorphic(java.util.List<Tree.CatchClause> catchClauses) {
final ListBuffer<JCCatch> catches = new ListBuffer<JCCatch>();
for (Tree.CatchClause catchClause : catchClauses) {
at(catchClause);
Tree.Variable variable = catchClause.getCatchVariable().getVariable();
Type exceptionType = variable.getDeclarationModel().getType();
JCExpression type = makeJavaType(exceptionType, JT_CATCH);
JCVariableDecl param = make().VarDef(make().Modifiers(Flags.FINAL), names().fromString(variable.getIdentifier().getText()), type, null);
catches.add(make().Catch(param, transform(catchClause.getBlock())));
}
return catches.toList();
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl in project ceylon by eclipse.
the class StatementTransformer method transform.
/**
* Transforms a Ceylon destructuring assignment to Java code.
* @param stmt The Ceylon destructure
* @return The Java tree
*/
List<JCStatement> transform(Tree.Destructure stmt) {
List<JCStatement> result = List.nil();
// Create temp var to hold result of expression
Tree.Pattern pat = stmt.getPattern();
Naming.SyntheticName tmpVarName = naming.synthetic(pat);
Expression destExpr = stmt.getSpecifierExpression().getExpression();
JCExpression typeExpr = makeJavaType(destExpr.getTypeModel());
JCExpression expr = expressionGen().transformExpression(destExpr);
at(stmt);
JCVariableDecl tmpVar = makeVar(Flags.FINAL, tmpVarName, typeExpr, expr);
result = result.append(tmpVar);
// Now add the destructured variables
List<VarDefBuilder> destructured = transformPattern(pat, tmpVarName.makeIdent());
for (VarDefBuilder vdb : destructured) {
Value v = vdb.var.getDeclarationModel();
at(vdb.var);
if (v.isClassMember() && v.isCaptured()) {
AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, v.getName(), v);
adb.immutable();
classGen().current().attribute(adb);
classGen().current().defs(vdb.buildDefOnly());
result = result.append(make().Exec(make().Assign(vdb.name().makeIdentWithThis(), vdb.expr())));
} else {
result = result.append(vdb.build());
}
}
return result;
}
Aggregations