use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class StatementTransformer method transform.
JCStatement transform(Node node, Tree.SwitchClause switchClause, Tree.SwitchCaseList caseList, String tmpVar, Tree.Term outerExpression, Type expectedType) {
at(switchClause);
block();
SwitchTransformation transformation = null;
Type exprType = switchExpressionType(switchClause);
Boolean switchUnboxed = switchExpressionUnboxed(switchClause);
// Are we switching with just String literal or Character literal match cases?
if (isJavaSwitchableType(exprType, switchUnboxed)) {
boolean canUseSwitch = true;
caseStmts: for (Tree.CaseClause clause : caseList.getCaseClauses()) {
if (clause.getCaseItem() instanceof Tree.MatchCase) {
java.util.List<Expression> caseExprs = ((Tree.MatchCase) clause.getCaseItem()).getExpressionList().getExpressions();
caseExpr: for (Tree.Expression expr : caseExprs) {
Tree.Term e = ExpressionTransformer.eliminateParens(expr);
if (e instanceof Tree.StringLiteral || e instanceof Tree.CharLiteral) {
continue caseExpr;
} else if (e instanceof Tree.BaseMemberExpression && ((Tree.BaseMemberExpression) e).getDeclaration() instanceof Value && ((Value) ((Tree.BaseMemberExpression) e).getDeclaration()).isEnumValue()) {
continue caseExpr;
} else {
canUseSwitch = false;
break caseStmts;
}
}
} else {
canUseSwitch = false;
break caseStmts;
}
}
if (canUseSwitch) {
// yes, so use a Java Switch
transformation = new Switch();
}
}
if (transformation == null && isOptional(exprType)) {
// Are we switching with just String literal or Character literal plus null
// match cases?
Type definiteType = typeFact().getDefiniteType(exprType);
if (isJavaSwitchableType(definiteType, switchUnboxed)) {
boolean canUseIfElseSwitch = true;
boolean hasSingletonNullCase = false;
caseStmts: for (Tree.CaseClause clause : caseList.getCaseClauses()) {
if (clause.getCaseItem() instanceof Tree.MatchCase) {
if (getSingletonNullCase(clause) != null) {
hasSingletonNullCase = true;
}
java.util.List<Expression> caseExprs = ((Tree.MatchCase) clause.getCaseItem()).getExpressionList().getExpressions();
caseExpr: for (Tree.Expression expr : caseExprs) {
Tree.Term e = ExpressionTransformer.eliminateParens(expr);
if (e instanceof Tree.StringLiteral || e instanceof Tree.CharLiteral) {
continue caseExpr;
} else if (e instanceof Tree.BaseMemberExpression && isNullValue(((Tree.BaseMemberExpression) e).getDeclaration()) && caseExprs.size() == 1) {
continue caseExpr;
} else if (e instanceof Tree.BaseMemberExpression && ((Tree.BaseMemberExpression) e).getDeclaration() instanceof Value && ((Value) ((Tree.BaseMemberExpression) e).getDeclaration()).isEnumValue()) {
continue caseExpr;
} else {
canUseIfElseSwitch = false;
break caseStmts;
}
}
} else {
canUseIfElseSwitch = false;
break caseStmts;
}
}
canUseIfElseSwitch &= hasSingletonNullCase;
if (canUseIfElseSwitch) {
// yes, so use a If
transformation = new IfNullElseSwitch();
}
}
}
// The default transformation
if (transformation == null) {
transformation = new IfElseChain();
}
JCStatement result = transformation.transformSwitch(node, switchClause, caseList, tmpVar, outerExpression, expectedType);
unblock();
return result;
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class StatementTransformer method transformCatchesIfElseIf.
/**
* Transforms a list of {@code CatchClause}s to a single {@code JCCatch}
* containing and if/else if chain for finding the appropriate catch block.
* @see #transformCatchesPolymorphic(java.util.List)
*/
private List<JCCatch> transformCatchesIfElseIf(java.util.List<Tree.CatchClause> catchClauses) {
Type supertype = intersectionOfCatchClauseTypes(catchClauses);
JCExpression exceptionType = makeJavaType(supertype, JT_CATCH | JT_RAW);
SyntheticName exceptionVar = naming.alias("exception");
JCVariableDecl param = make().VarDef(make().Modifiers(Flags.FINAL), exceptionVar.asName(), exceptionType, null);
ArrayList<Tree.CatchClause> reversed = new ArrayList<Tree.CatchClause>(catchClauses);
Collections.reverse(reversed);
JCStatement elsePart = make().Throw(exceptionVar.makeIdent());
for (Tree.CatchClause catchClause : reversed) {
Tree.Variable caughtVar = catchClause.getCatchVariable().getVariable();
Type caughtType = caughtVar.getType().getTypeModel();
List<JCStatement> catchBlock = transformBlock(catchClause.getBlock());
catchBlock = catchBlock.prepend(makeVar(FINAL, caughtVar.getIdentifier().getText(), makeJavaType(caughtType), expressionGen().applyErasureAndBoxing(exceptionVar.makeIdent(), supertype, true, true, BoxingStrategy.BOXED, caughtType, 0)));
elsePart = make().If(makeOptimizedTypeTest(null, exceptionVar, caughtType, supertype), make().Block(0, catchBlock), elsePart);
}
return List.of(make().Catch(param, make().Block(0, List.<JCStatement>of(elsePart))));
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class NamedArgumentInvocation method bindSpecifiedArgument.
private void bindSpecifiedArgument(Tree.SpecifiedArgument specifiedArg, Parameter declaredParam, Naming.SyntheticName argName) {
ListBuffer<JCStatement> statements;
Tree.Expression expr = specifiedArg.getSpecifierExpression().getExpression();
Type type = parameterType(declaredParam, expr.getTypeModel(), gen.TP_TO_BOUND);
final BoxingStrategy boxType = getNamedParameterBoxingStrategy(declaredParam);
int jtFlags = 0;
int exprFlags = 0;
if (boxType == BoxingStrategy.BOXED)
jtFlags |= JT_TYPE_ARGUMENT;
if (!isParameterRaw(declaredParam)) {
exprFlags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_NOT_RAW;
}
if (isParameterWithConstrainedTypeParameters(declaredParam)) {
exprFlags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_CONSTRAINED_TYPE_PARAMETERS;
// we can't just generate types like Foo<?> if the target type param is not raw because the bounds will
// not match, so we go raw
jtFlags |= JT_RAW;
}
if (isParameterWithDependentCovariantTypeParameters(declaredParam)) {
exprFlags |= ExpressionTransformer.EXPR_EXPECTED_TYPE_HAS_DEPENDENT_COVARIANT_TYPE_PARAMETERS;
}
if (erasedArgument(TreeUtil.unwrapExpressionUntilTerm(expr))) {
exprFlags |= ExpressionTransformer.EXPR_DOWN_CAST;
}
JCExpression typeExpr = gen.makeJavaType(type, jtFlags);
JCExpression argExpr = gen.expressionGen().transformExpression(expr, boxType, type, exprFlags);
JCVariableDecl varDecl = gen.makeVar(argName, typeExpr, argExpr);
statements = ListBuffer.<JCStatement>of(varDecl);
bind(declaredParam, argName, gen.makeJavaType(type, jtFlags), statements.toList());
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class NamedArgumentInvocation method bindAttributeArgument.
private void bindAttributeArgument(Tree.AttributeArgument attrArg, Parameter declaredParam, Naming.SyntheticName argName) {
ListBuffer<JCStatement> statements;
final Value model = attrArg.getDeclarationModel();
final String name = model.getName();
String className = Naming.getAttrClassName(model, 0);
final List<JCTree> attrClass = gen.gen().transformAttribute(model, name, className, null, attrArg.getBlock(), attrArg.getSpecifierExpression(), null, null);
TypedReference typedRef = gen.getTypedReference(model);
TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
Type nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
Type type = parameterType(declaredParam, model.getType(), 0);
final BoxingStrategy boxType = getNamedParameterBoxingStrategy(declaredParam);
JCExpression initValue = gen.make().Apply(null, gen.makeSelect(gen.makeUnquotedIdent(className), Naming.getGetterName(model)), List.<JCExpression>nil());
initValue = gen.expressionGen().applyErasureAndBoxing(initValue, nonWideningType, !CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration()), boxType, type);
JCTree.JCVariableDecl var = gen.make().VarDef(gen.make().Modifiers(FINAL, List.<JCAnnotation>nil()), argName.asName(), gen.makeJavaType(type, boxType == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), initValue);
statements = toStmts(attrArg, attrClass).append(var);
bind(declaredParam, argName, gen.makeJavaType(type, boxType == BoxingStrategy.BOXED ? JT_NO_PRIMITIVES : 0), statements.toList());
}
use of com.sun.tools.javac.tree.JCTree.JCStatement in project ceylon-compiler by ceylon.
the class StatementTransformer method transformCaseIs.
/**
* Transform a "case(is ...)"
* @param selectorAlias
* @param caseClause
* @param isCase
* @param last
* @return
*/
private JCStatement transformCaseIs(Naming.SyntheticName selectorAlias, Tree.CaseClause caseClause, String tmpVar, Tree.Term outerExpression, Type expectedType, Tree.IsCase isCase, JCStatement last, Type expressionType) {
at(isCase);
// Use the type of the variable, which is more precise than the type we test for.
Type varType = isCase.getVariable().getDeclarationModel().getType();
Type caseType = isCase.getType().getTypeModel();
// note: There's no point using makeOptimizedTypeTest() because cases are disjoint
// anyway and the cheap cases get evaluated first.
JCExpression cond = makeTypeTest(null, selectorAlias, caseType, expressionType);
String name = isCase.getVariable().getIdentifier().getText();
TypedDeclaration varDecl = isCase.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(isCase).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
JCVariableDecl decl2 = at(isCase).VarDef(make().Modifiers(FINAL), substVarName, toTypeExpr, tmpVarExpr);
// Prepare for variable substitution in the following code block
Substitution prevSubst = naming.addVariableSubst(varDecl, substVarName.toString());
List<JCStatement> stats = List.<JCStatement>of(decl2);
stats = stats.appendList(transformCaseClause(caseClause, tmpVar, outerExpression, expectedType));
JCBlock block = at(isCase).Block(0, stats);
// Deactivate the above variable substitution
prevSubst.close();
last = make().If(cond, block, last);
return last;
}
Aggregations