use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement in project ceylon by eclipse.
the class ExpressionTransformer method transformSuperInvocation.
//
// Invocations
public void transformSuperInvocation(Tree.ExtendedType extendedType, ClassDefinitionBuilder classBuilder) {
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(extendedType);
if (error != null) {
classBuilder.getInitBuilder().delegateCall(this.makeThrowUnresolvedCompilationError(error));
return;
}
if (extendedType.getInvocationExpression() != null && extendedType.getInvocationExpression().getPositionalArgumentList() != null) {
Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) extendedType.getInvocationExpression().getPrimary()).getDeclaration();
java.util.List<ParameterList> paramLists = ((Functional) primaryDeclaration).getParameterLists();
if (paramLists.isEmpty()) {
classBuilder.getInitBuilder().delegateCall(at(extendedType).Exec(makeErroneous(extendedType, "compiler bug: missing parameter list in extends clause: " + primaryDeclaration.getName() + " must be invoked")));
} else {
boolean prevFnCall = withinInvocation(true);
try {
JCStatement superExpr = transformConstructorDelegation(extendedType, new CtorDelegation(null, primaryDeclaration), extendedType.getInvocationExpression(), classBuilder, false);
classBuilder.getInitBuilder().delegateCall(superExpr);
} finally {
withinInvocation(prevFnCall);
}
}
}
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement 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.JCStatement 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.JCStatement in project ceylon by eclipse.
the class ExpressionTransformer method transform.
public JCStatement transform(Tree.SpecifierStatement op) {
// SpecifierStatement do not return any value, therefore we don't care about the type of the expressions.
inStatement = true;
JCStatement result;
HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(op.getBaseMemberExpression());
if (error != null) {
result = this.makeThrowUnresolvedCompilationError(error);
} else if ((error = errors().getFirstExpressionErrorAndMarkBrokenness(op.getSpecifierExpression().getExpression())) != null) {
result = this.makeThrowUnresolvedCompilationError(error);
} else {
result = at(op).Exec(transformAssignment(op, op.getBaseMemberExpression(), op.getSpecifierExpression().getExpression()));
}
inStatement = false;
return result;
}
use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement in project ceylon by eclipse.
the class StatementTransformer method openOuterSubstitutionIfNeeded.
JCStatement openOuterSubstitutionIfNeeded(Value value, Type t, int modifiers) {
JCStatement result = null;
if (value.isSpecifiedInForElse()) {
DeferredSpecification d = new DeferredSpecification(value, modifiers, t);
deferredSpecifications.put(value, d);
result = d.openOuterSubstitution();
}
return result;
}
Aggregations