use of com.google.devtools.j2objc.ast.Statement in project j2objc by google.
the class LabelRewriter method endVisit.
@Override
public void endVisit(LabeledStatement node) {
Statement loopBody = getLoopBody(node.getBody());
final String labelIdentifier = node.getLabel().getIdentifier();
final boolean[] hasContinue = new boolean[1];
final boolean[] hasBreak = new boolean[1];
node.accept(new TreeVisitor() {
@Override
public void endVisit(ContinueStatement node) {
if (node.getLabel() != null && node.getLabel().getIdentifier().equals(labelIdentifier)) {
hasContinue[0] = true;
node.setLabel(new SimpleName("continue_" + labelIdentifier));
}
}
@Override
public void endVisit(BreakStatement node) {
if (node.getLabel() != null && node.getLabel().getIdentifier().equals(labelIdentifier)) {
hasBreak[0] = true;
node.setLabel(new SimpleName("break_" + labelIdentifier));
}
}
});
if (hasContinue[0]) {
assert loopBody != null : "Continue statements must be inside a loop.";
LabeledStatement newLabelStmt = new LabeledStatement("continue_" + labelIdentifier);
newLabelStmt.setBody(new EmptyStatement());
// Put the loop body into an inner block so the continue label is outside
// the scope of any variable initializations.
Block newBlock = new Block();
loopBody.replaceWith(newBlock);
newBlock.addStatement(loopBody);
newBlock.addStatement(newLabelStmt);
}
if (hasBreak[0]) {
LabeledStatement newLabelStmt = new LabeledStatement("break_" + labelIdentifier);
newLabelStmt.setBody(new EmptyStatement());
TreeUtil.insertAfter(node, newLabelStmt);
}
if (hasContinue[0] || hasBreak[0]) {
// Replace this node with its statement, thus deleting the label.
node.replaceWith(TreeUtil.remove(node.getBody()));
}
}
use of com.google.devtools.j2objc.ast.Statement in project j2objc by google.
the class EnumRewriter method addArcInitialization.
// ARC does not allow using "objc_constructInstance" so ARC code doesn't get
// the shared allocation optimization.
private void addArcInitialization(EnumDeclaration node) {
List<Statement> stmts = node.getClassInitStatements().subList(0, 0);
int i = 0;
for (EnumConstantDeclaration constant : node.getEnumConstants()) {
VariableElement varElement = constant.getVariableElement();
ClassInstanceCreation creation = new ClassInstanceCreation(constant.getExecutablePair());
TreeUtil.copyList(constant.getArguments(), creation.getArguments());
String stringLiteralName = options.stripEnumConstants() ? ENUM_NAME_STRIPPED : ElementUtil.getName(varElement);
creation.addArgument(new StringLiteral(stringLiteralName, typeUtil));
creation.addArgument(new NumberLiteral(i++, typeUtil));
creation.setHasRetainedResult(true);
stmts.add(new ExpressionStatement(new Assignment(new SimpleName(varElement), creation)));
}
}
use of com.google.devtools.j2objc.ast.Statement in project j2objc by google.
the class EnumRewriter method addSimpleNonArcInitialization.
private void addSimpleNonArcInitialization(EnumDeclaration node) {
List<EnumConstantDeclaration> constants = node.getEnumConstants();
List<Statement> stmts = node.getClassInitStatements().subList(0, 0);
stmts.add(new NativeStatement("size_t objSize = class_getInstanceSize(self);"));
stmts.add(new NativeStatement(UnicodeUtils.format("size_t allocSize = %s * objSize;", constants.size())));
stmts.add(new NativeStatement("uintptr_t ptr = (uintptr_t)calloc(allocSize, 1);"));
VariableElement localEnum = GeneratedVariableElement.newLocalVar("e", TypeUtil.ID_TYPE, null);
stmts.add(new VariableDeclarationStatement(localEnum, null));
// Create a local array of enum names only if reflection is stripped but
// enum constants are not. For non-stripped classes, enum names are now
// retrieved from metadata, to avoid duplicates.
boolean useNamesArray = options.stripReflection() && !options.stripEnumConstants();
if (useNamesArray) {
StringBuilder sb = new StringBuilder("id names[] = {\n ");
for (EnumConstantDeclaration constant : constants) {
sb.append("@\"" + ElementUtil.getName(constant.getVariableElement()) + "\", ");
}
sb.append("\n};");
stmts.add(new NativeStatement(sb.toString()));
}
TypeMirror intType = typeUtil.getInt();
GeneratedVariableElement loopCounterElement = GeneratedVariableElement.newLocalVar("i", intType, TreeUtil.getEnclosingElement(node));
VariableDeclarationExpression loopCounter = new VariableDeclarationExpression().setType(Type.newType(loopCounterElement.asType())).addFragment(new VariableDeclarationFragment(loopCounterElement, TreeUtil.newLiteral(0, typeUtil)));
Expression loopTest = new InfixExpression().setOperator(InfixExpression.Operator.LESS).setTypeMirror(intType).addOperand(new SimpleName(loopCounterElement)).addOperand(TreeUtil.newLiteral(constants.size(), typeUtil));
Expression loopUpdater = new PostfixExpression(loopCounterElement, PostfixExpression.Operator.INCREMENT);
Block loopBody = new Block();
stmts.add(new ForStatement().addInitializer(loopCounter).setExpression(loopTest).addUpdater(loopUpdater).setBody(loopBody));
String enumClassName = nameTable.getFullName(node.getTypeElement());
loopBody.addStatement(new NativeStatement("((void)(" + enumClassName + "_values_[i] = e = objc_constructInstance(self, (void *)ptr)), ptr += objSize);"));
if (useNamesArray) {
loopBody.addStatement(new NativeStatement(enumClassName + "_initWithNSString_withInt_(e, names[i], i);"));
} else if (options.stripEnumConstants()) {
String statementText = enumClassName + "_initWithNSString_withInt_(e, " + ENUM_NAME_STRIPPED + ", i);";
loopBody.addStatement(new NativeStatement(statementText));
} else {
loopBody.addStatement(new NativeStatement(enumClassName + "_initWithNSString_withInt_(e, JreEnumConstantName(" + enumClassName + "_class_(), i), i);"));
}
}
use of com.google.devtools.j2objc.ast.Statement in project j2objc by google.
the class UnsequencedExpressionRewriter method extractConditionalExpression.
private void extractConditionalExpression(List<Statement> stmtList, ConditionalExpression conditional, List<VariableAccess> toExtract) {
Expression condition = conditional.getExpression();
Expression thenExpr = conditional.getThenExpression();
Expression elseExpr = conditional.getElseExpression();
List<VariableAccess> conditionAccesses = Lists.newArrayList();
List<VariableAccess> thenAccesses = Lists.newArrayList();
List<VariableAccess> elseAccesses = Lists.newArrayList();
boolean needsExtraction = false;
for (VariableAccess access : toExtract) {
TreeNode node = access.expression;
while (node.getParent() != conditional) {
node = node.getParent();
}
if (node == condition) {
conditionAccesses.add(access);
} else if (node == thenExpr) {
thenAccesses.add(access);
} else if (node == elseExpr) {
elseAccesses.add(access);
} else {
throw new AssertionError();
}
if (node != condition) {
// We need to extract an if-statement if there is an access that
// executes conditionally.
needsExtraction = true;
}
}
extractOrderedAccesses(stmtList, condition, conditionAccesses);
// The recursive call might replace the condition child.
condition = conditional.getExpression();
if (needsExtraction) {
VariableElement resultVar = GeneratedVariableElement.newLocalVar("unseq$" + count++, conditional.getTypeMirror(), currentMethod);
conditional.replaceWith(new SimpleName(resultVar));
stmtList.add(new VariableDeclarationStatement(resultVar, null));
IfStatement newIf = new IfStatement();
newIf.setExpression(condition.copy());
stmtList.add(newIf);
Block thenBlock = new Block();
newIf.setThenStatement(thenBlock);
List<Statement> thenStmts = thenBlock.getStatements();
extractOrderedAccesses(thenStmts, thenExpr, thenAccesses);
// The recursive call might replace the then expression child.
thenExpr = conditional.getThenExpression();
thenStmts.add(new ExpressionStatement(new Assignment(new SimpleName(resultVar), thenExpr.copy())));
Block elseBlock = new Block();
newIf.setElseStatement(elseBlock);
List<Statement> elseStmts = elseBlock.getStatements();
extractOrderedAccesses(elseStmts, elseExpr, elseAccesses);
// The recursive call might replace the else expression child.
elseExpr = conditional.getElseExpression();
elseStmts.add(new ExpressionStatement(new Assignment(new SimpleName(resultVar), elseExpr.copy())));
} else {
extractOrderedAccesses(stmtList, thenExpr, thenAccesses);
extractOrderedAccesses(stmtList, elseExpr, elseAccesses);
}
}
use of com.google.devtools.j2objc.ast.Statement in project j2objc by google.
the class UnsequencedExpressionRewriter method visit.
@Override
public boolean visit(DoStatement node) {
node.getBody().accept(this);
newExpression(node.getExpression());
node.getExpression().accept(this);
List<VariableAccess> toExtract = getUnsequencedAccesses();
if (!toExtract.isEmpty()) {
// Convert "while (cond)" into "while (true) { if (!(cond)) break; ... }".
List<Statement> stmtList = TreeUtil.asStatementList(node.getBody());
extractOrderedAccesses(stmtList, currentTopNode, toExtract);
stmtList.add(createLoopTermination(node.getExpression()));
node.setExpression(new BooleanLiteral(true, typeUtil));
}
return false;
}
Aggregations