From 11f804eb39473d4876a97a9f565028aaa93f0cd9 Mon Sep 17 00:00:00 2001 From: kstanger Date: Mon, 29 Jun 2015 12:17:17 -0700 Subject: [PATCH] Convert certain QualifiedName nodes to FieldAccess at tree conversion time, thus avoiding the conversion during later mutations. Change on 2015/06/29 by kstanger ------------- Created by MOE: http://code.google.com/p/moe-java MOE_MIGRATED_REVID=97153120 --- .../google/devtools/j2objc/ast/TreeUtil.java | 23 ---------------- .../j2objc/translate/CastResolver.java | 13 ---------- .../j2objc/translate/NilCheckResolver.java | 24 ----------------- .../translate/OuterReferenceResolver.java | 19 +++++++++----- .../devtools/j2objc/translate/Rewriter.java | 26 ++++++------------- .../j2objc/translate/StaticVarRewriter.java | 10 +++---- 6 files changed, 23 insertions(+), 92 deletions(-) diff --git a/translator/src/main/java/com/google/devtools/j2objc/ast/TreeUtil.java b/translator/src/main/java/com/google/devtools/j2objc/ast/TreeUtil.java index c2ba739c3f..e72ae9550e 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/ast/TreeUtil.java +++ b/translator/src/main/java/com/google/devtools/j2objc/ast/TreeUtil.java @@ -348,29 +348,6 @@ public static void insertBefore(Statement node, Statement toInsert) { asStatementList(node).add(0, toInsert); } - /** - * Replaces (in place) a QualifiedName node with an equivalent FieldAccess - * node. This is helpful when a mutation needs to replace the qualifier with - * a node that has Expression type but not Name type. - * CAUTION: It is strongly recommended that this method be used within a - * "visit", and not a "endVisit" because it will rewrite all QualifiedNode - * ancestors. - */ - public static FieldAccess convertToFieldAccess(QualifiedName node) { - TreeNode parent = node.getParent(); - if (parent instanceof QualifiedName) { - FieldAccess newParent = convertToFieldAccess((QualifiedName) parent); - Expression expr = newParent.getExpression(); - assert expr instanceof QualifiedName; - node = (QualifiedName) expr; - } - IVariableBinding variableBinding = getVariableBinding(node); - assert variableBinding != null : "node must be a variable"; - FieldAccess newNode = new FieldAccess(variableBinding, remove(node.getQualifier())); - node.replaceWith(newNode); - return newNode; - } - public static Expression newLiteral(Object value, Types typeEnv) { if (value instanceof Boolean) { return new BooleanLiteral((Boolean) value, typeEnv); diff --git a/translator/src/main/java/com/google/devtools/j2objc/translate/CastResolver.java b/translator/src/main/java/com/google/devtools/j2objc/translate/CastResolver.java index 9c9db5d270..123e16d99f 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/translate/CastResolver.java +++ b/translator/src/main/java/com/google/devtools/j2objc/translate/CastResolver.java @@ -24,7 +24,6 @@ import com.google.devtools.j2objc.ast.MethodDeclaration; import com.google.devtools.j2objc.ast.MethodInvocation; import com.google.devtools.j2objc.ast.ParenthesizedExpression; -import com.google.devtools.j2objc.ast.QualifiedName; import com.google.devtools.j2objc.ast.ReturnStatement; import com.google.devtools.j2objc.ast.SimpleName; import com.google.devtools.j2objc.ast.SuperMethodInvocation; @@ -302,18 +301,6 @@ public void endVisit(MethodInvocation node) { } } - @Override - public boolean visit(QualifiedName node) { - if (needsCast(node.getQualifier(), true)) { - // The qualifier child has type Name and can't be replaced with a - // CastExpression, so we must convert to a FieldAccess. - FieldAccess newNode = TreeUtil.convertToFieldAccess(node); - newNode.accept(this); - return false; - } - return true; - } - @Override public void endVisit(ReturnStatement node) { Expression expr = node.getExpression(); diff --git a/translator/src/main/java/com/google/devtools/j2objc/translate/NilCheckResolver.java b/translator/src/main/java/com/google/devtools/j2objc/translate/NilCheckResolver.java index f69d0d2b75..494b11d735 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/translate/NilCheckResolver.java +++ b/translator/src/main/java/com/google/devtools/j2objc/translate/NilCheckResolver.java @@ -38,7 +38,6 @@ import com.google.devtools.j2objc.ast.MethodInvocation; import com.google.devtools.j2objc.ast.NullLiteral; import com.google.devtools.j2objc.ast.ParenthesizedExpression; -import com.google.devtools.j2objc.ast.QualifiedName; import com.google.devtools.j2objc.ast.Statement; import com.google.devtools.j2objc.ast.SwitchCase; import com.google.devtools.j2objc.ast.SwitchStatement; @@ -191,29 +190,6 @@ public void endVisit(FieldAccess node) { } } - @Override - public boolean visit(QualifiedName node) { - if (!needsNilCheck(node.getQualifier())) { - return true; - } - - // Instance references to static fields don't need to be nil-checked. - // This is true in Java (surprisingly), where instance.FIELD returns - // FIELD even when instance is null. - IVariableBinding var = TreeUtil.getVariableBinding(node); - IVariableBinding qualifierVar = TreeUtil.getVariableBinding(node.getQualifier()); - if (var != null && qualifierVar != null && BindingUtil.isStatic(var) - && !BindingUtil.isStatic(qualifierVar)) { - return true; - } - - // We can't substitute the qualifier with a nil_chk because it must have a - // Name type, so we have to convert to a FieldAccess node. - FieldAccess newNode = TreeUtil.convertToFieldAccess(node); - newNode.accept(this); - return false; - } - @Override public void endVisit(MethodInvocation node) { IMethodBinding binding = node.getMethodBinding(); diff --git a/translator/src/main/java/com/google/devtools/j2objc/translate/OuterReferenceResolver.java b/translator/src/main/java/com/google/devtools/j2objc/translate/OuterReferenceResolver.java index ee61d63b60..6e20523e7f 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/translate/OuterReferenceResolver.java +++ b/translator/src/main/java/com/google/devtools/j2objc/translate/OuterReferenceResolver.java @@ -320,14 +320,19 @@ public void endVisit(AnnotationTypeDeclaration node) { } @Override - public boolean visit(SimpleName node) { - TreeNode parent = node.getParent(); - if (parent instanceof FieldAccess - || (parent instanceof QualifiedName && node == ((QualifiedName) parent).getName())) { - // Already a qualified node. - return false; - } + public boolean visit(FieldAccess node) { + node.getExpression().accept(this); + return false; + } + + @Override + public boolean visit(QualifiedName node) { + node.getQualifier().accept(this); + return false; + } + @Override + public boolean visit(SimpleName node) { IVariableBinding var = TreeUtil.getVariableBinding(node); if (var != null) { if (var.isField() && !Modifier.isStatic(var.getModifiers())) { diff --git a/translator/src/main/java/com/google/devtools/j2objc/translate/Rewriter.java b/translator/src/main/java/com/google/devtools/j2objc/translate/Rewriter.java index df5a6e3409..70758aba51 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/translate/Rewriter.java +++ b/translator/src/main/java/com/google/devtools/j2objc/translate/Rewriter.java @@ -39,7 +39,6 @@ import com.google.devtools.j2objc.ast.LabeledStatement; import com.google.devtools.j2objc.ast.LambdaExpression; import com.google.devtools.j2objc.ast.MethodDeclaration; -import com.google.devtools.j2objc.ast.Name; import com.google.devtools.j2objc.ast.ParenthesizedExpression; import com.google.devtools.j2objc.ast.QualifiedName; import com.google.devtools.j2objc.ast.ReturnStatement; @@ -60,7 +59,6 @@ import com.google.j2objc.annotations.AutoreleasePool; import com.google.j2objc.annotations.RetainedLocalRef; -import org.eclipse.jdt.core.dom.IBinding; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.IVariableBinding; @@ -407,22 +405,14 @@ public void endVisit(FieldDeclaration node) { @Override public boolean visit(QualifiedName node) { - // Check for ScopedLocalRefs. - IBinding var = node.getBinding(); - if (var instanceof IVariableBinding) { - IVariableBinding localRef = localRefs.get(node.getQualifier().getBinding()); - if (localRef != null) { - IVariableBinding localRefFieldBinding = typeEnv.getLocalRefType().getDeclaredFields()[0]; - Name newQualifier = node.getQualifier().copy(); - newQualifier.setBinding(localRef); - FieldAccess localRefAccess = new FieldAccess(localRefFieldBinding, newQualifier); - CastExpression newCast = new CastExpression( - node.getQualifier().getTypeBinding(), localRefAccess); - ParenthesizedExpression newParens = ParenthesizedExpression.parenthesize(newCast); - FieldAccess access = new FieldAccess((IVariableBinding) var, newParens); - node.replaceWith(access); - return false; - } + IVariableBinding var = TreeUtil.getVariableBinding(node); + Expression qualifier = node.getQualifier(); + if (var != null && var.isField() && TreeUtil.getVariableBinding(qualifier) != null) { + // FieldAccess nodes are more easily mutated than QualifiedName. + FieldAccess fieldAccess = new FieldAccess(var, TreeUtil.remove(qualifier)); + node.replaceWith(fieldAccess); + fieldAccess.accept(this); + return false; } return true; } diff --git a/translator/src/main/java/com/google/devtools/j2objc/translate/StaticVarRewriter.java b/translator/src/main/java/com/google/devtools/j2objc/translate/StaticVarRewriter.java index cca4455877..ed442a4f71 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/translate/StaticVarRewriter.java +++ b/translator/src/main/java/com/google/devtools/j2objc/translate/StaticVarRewriter.java @@ -105,6 +105,9 @@ private void handleFieldAccess(Expression node, Expression maybeFieldAccess) { expr.accept(this); } else { fieldAccess.replaceWith(TreeUtil.remove(name)); + if (fieldAccess == node) { + name.accept(this); + } } } @@ -127,13 +130,6 @@ public boolean visit(QualifiedName node) { private boolean visitName(Name node) { IVariableBinding var = TreeUtil.getVariableBinding(node); if (var != null && useAccessor(node, var)) { - TreeNode parent = node.getParent(); - if (parent instanceof QualifiedName && node == ((QualifiedName) parent).getQualifier()) { - // QualifiedName nodes can only have qualifier children of type Name, so - // we must convert QualifiedName parents to FieldAccess nodes. - FieldAccess newParent = TreeUtil.convertToFieldAccess((QualifiedName) parent); - node = (Name) newParent.getExpression(); - } node.replaceWith(newGetterInvocation(var, false)); return false; }