From cd11f4e4db90d51f6a45f40f1c8eb97e46486974 Mon Sep 17 00:00:00 2001 From: cushon Date: Mon, 27 Feb 2017 11:11:44 -0800 Subject: [PATCH] Improved fix for elements having the wrong enclosing element Follow-up to [] Change on 2017/02/27 by cushon ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=148670165 --- .../devtools/j2objc/javac/TreeConverter.java | 63 +++---------------- .../j2objc/javac/JavacTreeConverterTest.java | 23 ++++++- 2 files changed, 30 insertions(+), 56 deletions(-) diff --git a/translator/src/main/java/com/google/devtools/j2objc/javac/TreeConverter.java b/translator/src/main/java/com/google/devtools/j2objc/javac/TreeConverter.java index e118904c0e..0219102741 100644 --- a/translator/src/main/java/com/google/devtools/j2objc/javac/TreeConverter.java +++ b/translator/src/main/java/com/google/devtools/j2objc/javac/TreeConverter.java @@ -139,7 +139,6 @@ import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ExecutableType; @@ -154,7 +153,6 @@ public class TreeConverter { private final JCTree.JCCompilationUnit unit; private final JavacEnvironment env; private CompilationUnit newUnit; - private final boolean hasWildcardStaticImport; public static CompilationUnit convertCompilationUnit( Options options, JavacEnvironment env, JCTree.JCCompilationUnit javacUnit) { @@ -191,7 +189,6 @@ public static CompilationUnit convertCompilationUnit( private TreeConverter(JCTree.JCCompilationUnit javacUnit, JavacEnvironment javacEnv) { unit = javacUnit; env = javacEnv; - hasWildcardStaticImport = findWildcardStaticImport(javacUnit); } private TreeNode convert(Object obj) { @@ -805,7 +802,7 @@ private TreeNode convertIdent(JCTree.JCIdent node) { if (text.equals("this")) { return new ThisExpression().setTypeMirror(node.type); } - return new SimpleName(fixEnclosing(node.sym), node.type); + return new SimpleName(node.sym.baseSymbol(), node.type); } private TreeNode convertIf(JCTree.JCIf node) { @@ -914,9 +911,9 @@ private static String getMemberName(JCTree.JCExpression node) { } } - private Element getMemberSymbol(JCTree.JCExpression node) { + private static Symbol getMemberSymbol(JCTree.JCExpression node) { switch (node.getKind()) { - case IDENTIFIER: return fixEnclosing(((JCTree.JCIdent) node).sym); + case IDENTIFIER: return ((JCTree.JCIdent) node).sym.baseSymbol(); case MEMBER_SELECT: return ((JCTree.JCFieldAccess) node).sym; default: throw new AssertionError("Unexpected tree kind: " + node.getKind()); } @@ -926,13 +923,13 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) { JCTree.JCExpression method = node.getMethodSelect(); String methodName = getMemberName(method); ExecutableType type = (ExecutableType) method.type; - ExecutableElement elem = (ExecutableElement) getMemberSymbol(method); + Symbol.MethodSymbol sym = (Symbol.MethodSymbol) getMemberSymbol(method); JCTree.JCExpression target = method.getKind() == Kind.MEMBER_SELECT ? ((JCTree.JCFieldAccess) method).selected : null; if ("this".equals(methodName)) { ConstructorInvocation newNode = new ConstructorInvocation() - .setExecutablePair(new ExecutablePair(elem)) + .setExecutablePair(new ExecutablePair(sym)) .setVarargsType(node.varargsElement); for (JCTree.JCExpression arg : node.getArguments()) { newNode.addArgument((Expression) convert(arg)); @@ -942,7 +939,7 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) { if ("super".equals(methodName)) { SuperConstructorInvocation newNode = new SuperConstructorInvocation() - .setExecutablePair(new ExecutablePair(elem)) + .setExecutablePair(new ExecutablePair(sym)) .setVarargsType(node.varargsElement); if (target != null) { newNode.setExpression((Expression) convert(target)); @@ -955,9 +952,9 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) { if (target != null && "super".equals(getMemberName(target))) { SuperMethodInvocation newNode = new SuperMethodInvocation() - .setExecutablePair(new ExecutablePair(elem, type)) + .setExecutablePair(new ExecutablePair(sym, type)) .setVarargsType(node.varargsElement) - .setName(convertSimpleName(elem, type, getPosition(node))); + .setName(convertSimpleName(sym, type, getPosition(node))); if (target.getKind() == Kind.MEMBER_SELECT) { // foo.bar.MyClass.super.print(...): // target: foo.bar.MyClass.super @@ -971,7 +968,7 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) { } MethodInvocation newNode = new MethodInvocation(); - newNode.setName(convertSimpleName(elem, type, getPosition(method))); + newNode.setName(convertSimpleName(sym, type, getPosition(method))); if (target != null) { newNode.setExpression((Expression) convert(target)); } @@ -980,7 +977,7 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) { } return newNode .setTypeMirror(node.type) - .setExecutablePair(new ExecutablePair(elem, type)) + .setExecutablePair(new ExecutablePair(sym, type)) .setVarargsType(node.varargsElement); } @@ -1400,44 +1397,4 @@ private JCTree.JCExpression nextChild() { } } } - - private static boolean findWildcardStaticImport(JCTree.JCCompilationUnit javacUnit) { - for (JCTree.JCImport imp : javacUnit.getImports()) { - if (imp.isStatic()) { - JCTree ident = imp.getQualifiedIdentifier(); - if (ident.getKind() == Kind.MEMBER_SELECT - && ((JCTree.JCFieldAccess) ident).getIdentifier().toString().equals("*")) { - return true; - } - } - } - return false; - } - - // Fixes a Javac bug where a static element has the wrong enclosing element. - private Element fixEnclosing(Element e) { - if (!hasWildcardStaticImport || !ElementUtil.isStatic(e)) { - // Bug only applies when there are wildcarded static imports. - // Bug only applies to static elements. - return e; - } - Element enclosing = e.getEnclosingElement(); - if (enclosing == null || !(enclosing instanceof TypeElement) - || enclosing.getEnclosedElements().contains(e)) { - return e; - } - // 'e' is does not appear in its enclosing element's list of enclosed elements. This is bad. - // Search the type hierarchy of the enclosing to find an element with the same name as 'e'. - javax.lang.model.element.Name name = e.getSimpleName(); - TypeElement javaObject = newUnit.getEnv().typeUtil().getJavaObject(); - TypeElement superclass = ElementUtil.getSuperclass((TypeElement) enclosing); - while (superclass != null && !javaObject.equals(superclass)) { - for (Element enclosed : superclass.getEnclosedElements()) { - if (name.equals(enclosed.getSimpleName())) { - return enclosed; - } - } - } - return e; - } } diff --git a/translator/src/test/java/com/google/devtools/j2objc/javac/JavacTreeConverterTest.java b/translator/src/test/java/com/google/devtools/j2objc/javac/JavacTreeConverterTest.java index 8f79732d14..a7557825af 100644 --- a/translator/src/test/java/com/google/devtools/j2objc/javac/JavacTreeConverterTest.java +++ b/translator/src/test/java/com/google/devtools/j2objc/javac/JavacTreeConverterTest.java @@ -46,9 +46,11 @@ public void testConstantFromMethodInvocation() throws IOException { "return (JavaLangInteger_valueOfWithInt_(42), JavaLangInteger_SIZE);"); } - // Javac bug with using a '*' wildcard in an import static statement then using elements from - // classes further up the type hierarchy. - public void testIncorrectEnclosingElementBug() throws IOException { + // javac qualifies members imported via non-canonical static imports by the + // the type of the import, not the type the member is declared in. + // In the example below, FOO's enclosing element is B rather than A. + // See: https://bugs.openjdk.java.net/browse/JDK-6225935. + public void testIncorrectEnclosingElementBug_staticOnDemandImport() throws IOException { addSourceFile( "package foo; public class A { " + "public static final int FOO = 1; public static void bar() {} }", "foo/A.java"); @@ -60,4 +62,19 @@ public void testIncorrectEnclosingElementBug() throws IOException { "jint i = FooA_FOO;", "FooA_bar();"); } + + public void testIncorrectEnclosingElementBug_staticNamedImport() throws IOException { + addSourceFile( + "package foo; public class A { " + + "public static final int FOO = 1; public static void bar() {} }", + "foo/A.java"); + addSourceFile("package foo; public class B extends A {}", "foo/B.java"); + String translation = + translateSourceFile( + "import static foo.B.FOO; import static foo.B.bar;" + + "class Test { void test() { int i = FOO; bar(); } }", + "Test", + "Test.m"); + assertTranslatedLines(translation, "jint i = FooA_FOO;", "FooA_bar();"); + } }