use of com.google.devtools.j2objc.ast.InfixExpression in project j2objc by google.
the class TreeConverter method convertBinary.
private TreeNode convertBinary(JCTree.JCBinary node) {
InfixExpression newNode = new InfixExpression();
newNode.setTypeMirror(node.type).setOperator(InfixExpression.Operator.parse(node.operator.name.toString()));
// Flatten this tree to avoid stack overflow with very deep trees. This
// code traverses the subtree non-recursively and merges all children
// that have the same operator into this node.
List<StackState> stack = Lists.newArrayList();
stack.add(new StackState(node));
while (!stack.isEmpty()) {
StackState currentState = stack.get(stack.size() - 1);
JCTree.JCExpression child = currentState.nextChild();
if (child == null) {
stack.remove(stack.size() - 1);
continue;
}
if (child instanceof JCTree.JCBinary) {
JCTree.JCBinary infixChild = (JCTree.JCBinary) child;
if (infixChild.getKind() == node.getKind()) {
stack.add(new StackState(infixChild));
continue;
}
}
newNode.addOperand((Expression) convert(child));
}
return newNode;
}
use of com.google.devtools.j2objc.ast.InfixExpression in project j2objc by google.
the class OuterReferenceResolverTest method testCapturedLocalVariable.
public void testCapturedLocalVariable() {
resolveSource("Test", "class Test { void test(final int i) { Runnable r = new Runnable() { " + "public void run() { int i2 = i + 1; } }; } }");
TypeDeclaration runnableNode = (TypeDeclaration) nodesByType.get(Kind.TYPE_DECLARATION).get(1);
assertTrue(ElementUtil.isAnonymous(runnableNode.getTypeElement()));
assertFalse(captureInfo.needsOuterReference(runnableNode.getTypeElement()));
List<VariableElement> innerFields = Lists.newArrayList(captureInfo.getCaptureFields(runnableNode.getTypeElement()));
assertEquals(1, innerFields.size());
assertEquals("val$i", ElementUtil.getName(innerFields.get(0)));
ClassInstanceCreation creationNode = (ClassInstanceCreation) nodesByType.get(Kind.CLASS_INSTANCE_CREATION).get(0);
List<Expression> captureArgs = creationNode.getCaptureArgs();
assertEquals(1, captureArgs.size());
Expression captureArg = captureArgs.get(0);
assertTrue(captureArg instanceof SimpleName);
VariableElement captureVar = TreeUtil.getVariableElement(captureArg);
assertNotNull(captureVar);
assertEquals("i", ElementUtil.getName(captureVar));
InfixExpression addition = (InfixExpression) nodesByType.get(Kind.INFIX_EXPRESSION).get(0);
Expression iNode = addition.getOperands().get(0);
assertTrue(iNode instanceof SimpleName);
VariableElement iVar = TreeUtil.getVariableElement(iNode);
assertNotNull(iVar);
assertEquals("val$i", ElementUtil.getName(iVar));
}
use of com.google.devtools.j2objc.ast.InfixExpression in project j2objc by google.
the class ConstantBranchPruner method endVisit.
@Override
public void endVisit(InfixExpression node) {
InfixExpression.Operator operator = node.getOperator();
if (operator != CONDITIONAL_AND && operator != CONDITIONAL_OR) {
return;
}
List<Expression> operands = node.getOperands();
int lastSideEffect = -1;
for (int i = 0; i < operands.size(); i++) {
Expression expr = operands.get(i);
if (TranslationUtil.hasSideEffect(expr)) {
lastSideEffect = i;
}
Boolean knownVal = getKnownValue(expr);
if (knownVal == null) {
continue;
}
if (knownVal == (operator == CONDITIONAL_OR)) {
// Whole expression evaluates to 'knownVal'.
operands.subList(lastSideEffect + 1, operands.size()).clear();
if (lastSideEffect < i) {
operands.add(new BooleanLiteral(knownVal, typeUtil));
}
break;
} else if (lastSideEffect < i) {
// Else remove unnecessary constant value.
operands.remove(i--);
}
}
if (operands.size() == 0) {
if (operator == CONDITIONAL_OR) {
// All constants must have been false, because a true value would have
// caused us to return in the loop above.
node.replaceWith(new BooleanLiteral(false, typeUtil));
} else {
// Likewise, all constants must have been true.
node.replaceWith(new BooleanLiteral(true, typeUtil));
}
} else if (operands.size() == 1) {
node.replaceWith(operands.remove(0));
}
}
use of com.google.devtools.j2objc.ast.InfixExpression in project j2objc by google.
the class NilCheckResolver method handleConditionalOperator.
private boolean handleConditionalOperator(InfixExpression node, boolean logicalAnd) {
Set<VariableElement> newSafeVars = new HashSet<>();
int pushCount = 0;
for (Iterator<Expression> it = node.getOperands().iterator(); it.hasNext(); ) {
Expression operand = it.next();
operand.accept(this);
Set<VariableElement> safeVarsForBranch = logicalAnd ? getSafeVarsTrue(operand) : getSafeVarsFalse(operand);
Set<VariableElement> safeVarsForMerge = logicalAnd ? getSafeVarsFalse(operand) : getSafeVarsTrue(operand);
newSafeVars.addAll(safeVarsForBranch);
if (it.hasNext()) {
pushScope();
addSafeVars(safeVarsForBranch);
scope.next.mergeVars(safeVarsForMerge);
pushCount++;
}
}
while (pushCount-- > 0) {
popAndMerge();
}
setConditionalSafeVars(node, logicalAnd ? newSafeVars : EMPTY_VARS, logicalAnd ? EMPTY_VARS : newSafeVars);
return false;
}
use of com.google.devtools.j2objc.ast.InfixExpression 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));
StringBuffer sb = new StringBuffer("id names[] = {\n ");
for (EnumConstantDeclaration constant : node.getEnumConstants()) {
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("(" + enumClassName + "_values_[i] = e = objc_constructInstance(self, (void *)ptr), ptr += objSize);"));
loopBody.addStatement(new NativeStatement(enumClassName + "_initWithNSString_withInt_(e, names[i], i);"));
}
Aggregations