Skip to content

Commit

Permalink
Fix a NPE in the CastResolver from rewriting QualifiedName nodes to F…
Browse files Browse the repository at this point in the history
…ieldAccess nodes.

	Change on 2015/06/19 by kstanger <kstanger@google.com>
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=96423936
  • Loading branch information
kstanger committed Jun 22, 2015
1 parent 8672192 commit 51027f4
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 2 deletions.
Expand Up @@ -335,6 +335,9 @@ public static void insertBefore(Statement node, Statement toInsert) {
* Replaces (in place) a QualifiedName node with an equivalent FieldAccess * Replaces (in place) a QualifiedName node with an equivalent FieldAccess
* node. This is helpful when a mutation needs to replace the qualifier with * node. This is helpful when a mutation needs to replace the qualifier with
* a node that has Expression type but not Name type. * 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) { public static FieldAccess convertToFieldAccess(QualifiedName node) {
TreeNode parent = node.getParent(); TreeNode parent = node.getParent();
Expand Down
Expand Up @@ -304,10 +304,15 @@ public void endVisit(MethodInvocation node) {
} }


@Override @Override
public void endVisit(QualifiedName node) { public boolean visit(QualifiedName node) {
if (needsCast(node.getQualifier(), true)) { if (needsCast(node.getQualifier(), true)) {
maybeAddCast(TreeUtil.convertToFieldAccess(node).getExpression(), 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 @Override
Expand Down
Expand Up @@ -122,4 +122,21 @@ public void testCapturedType() throws IOException {
assertTranslation(translation, assertTranslation(translation,
"[((id<Test_Bar>) nil_chk([((Test_Foo *) nil_chk(foo)) get])) bar];"); "[((id<Test_Bar>) nil_chk([((Test_Foo *) nil_chk(foo)) get])) bar];");
} }

public void testChainedFieldLookup() throws IOException {
String translation = translateSourceFile(
"class Test {"
+ " static class Foo { Bar bar; }"
+ " static class Bar { int baz; }"
+ " static class GenericImpl<T> { T foo; }"
+ " static class Impl extends GenericImpl<Foo> {"
+ " int test() {"
// Need to call "foo.bar.baz" twice so that the second expression is
// free of nil_chk's.
+ " int i = foo.bar.baz;"
+ " return foo.bar.baz; } } }", "Test", "Test.m");
// This is actually a regression for a NPE in the translator, but we may as
// well check the output.
assertTranslation(translation, "return ((Test_Foo *) foo_)->bar_->baz_;");
}
} }

0 comments on commit 51027f4

Please sign in to comment.