Skip to content

Commit

Permalink
Improved fix for elements having the wrong enclosing element
Browse files Browse the repository at this point in the history
Follow-up to []

	Change on 2017/02/27 by cushon <cushon@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=148670165
  • Loading branch information
cushon authored and tomball committed Mar 13, 2017
1 parent baa0ce7 commit cd11f4e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 56 deletions.
Expand Up @@ -139,7 +139,6 @@
import javax.lang.model.element.ElementKind; import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement; import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType; import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ExecutableType; import javax.lang.model.type.ExecutableType;
Expand All @@ -154,7 +153,6 @@ public class TreeConverter {
private final JCTree.JCCompilationUnit unit; private final JCTree.JCCompilationUnit unit;
private final JavacEnvironment env; private final JavacEnvironment env;
private CompilationUnit newUnit; private CompilationUnit newUnit;
private final boolean hasWildcardStaticImport;


public static CompilationUnit convertCompilationUnit( public static CompilationUnit convertCompilationUnit(
Options options, JavacEnvironment env, JCTree.JCCompilationUnit javacUnit) { Options options, JavacEnvironment env, JCTree.JCCompilationUnit javacUnit) {
Expand Down Expand Up @@ -191,7 +189,6 @@ public static CompilationUnit convertCompilationUnit(
private TreeConverter(JCTree.JCCompilationUnit javacUnit, JavacEnvironment javacEnv) { private TreeConverter(JCTree.JCCompilationUnit javacUnit, JavacEnvironment javacEnv) {
unit = javacUnit; unit = javacUnit;
env = javacEnv; env = javacEnv;
hasWildcardStaticImport = findWildcardStaticImport(javacUnit);
} }


private TreeNode convert(Object obj) { private TreeNode convert(Object obj) {
Expand Down Expand Up @@ -805,7 +802,7 @@ private TreeNode convertIdent(JCTree.JCIdent node) {
if (text.equals("this")) { if (text.equals("this")) {
return new ThisExpression().setTypeMirror(node.type); 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) { private TreeNode convertIf(JCTree.JCIf node) {
Expand Down Expand Up @@ -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()) { 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; case MEMBER_SELECT: return ((JCTree.JCFieldAccess) node).sym;
default: throw new AssertionError("Unexpected tree kind: " + node.getKind()); default: throw new AssertionError("Unexpected tree kind: " + node.getKind());
} }
Expand All @@ -926,13 +923,13 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) {
JCTree.JCExpression method = node.getMethodSelect(); JCTree.JCExpression method = node.getMethodSelect();
String methodName = getMemberName(method); String methodName = getMemberName(method);
ExecutableType type = (ExecutableType) method.type; 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.JCExpression target = method.getKind() == Kind.MEMBER_SELECT
? ((JCTree.JCFieldAccess) method).selected : null; ? ((JCTree.JCFieldAccess) method).selected : null;


if ("this".equals(methodName)) { if ("this".equals(methodName)) {
ConstructorInvocation newNode = new ConstructorInvocation() ConstructorInvocation newNode = new ConstructorInvocation()
.setExecutablePair(new ExecutablePair(elem)) .setExecutablePair(new ExecutablePair(sym))
.setVarargsType(node.varargsElement); .setVarargsType(node.varargsElement);
for (JCTree.JCExpression arg : node.getArguments()) { for (JCTree.JCExpression arg : node.getArguments()) {
newNode.addArgument((Expression) convert(arg)); newNode.addArgument((Expression) convert(arg));
Expand All @@ -942,7 +939,7 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) {


if ("super".equals(methodName)) { if ("super".equals(methodName)) {
SuperConstructorInvocation newNode = new SuperConstructorInvocation() SuperConstructorInvocation newNode = new SuperConstructorInvocation()
.setExecutablePair(new ExecutablePair(elem)) .setExecutablePair(new ExecutablePair(sym))
.setVarargsType(node.varargsElement); .setVarargsType(node.varargsElement);
if (target != null) { if (target != null) {
newNode.setExpression((Expression) convert(target)); newNode.setExpression((Expression) convert(target));
Expand All @@ -955,9 +952,9 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) {


if (target != null && "super".equals(getMemberName(target))) { if (target != null && "super".equals(getMemberName(target))) {
SuperMethodInvocation newNode = new SuperMethodInvocation() SuperMethodInvocation newNode = new SuperMethodInvocation()
.setExecutablePair(new ExecutablePair(elem, type)) .setExecutablePair(new ExecutablePair(sym, type))
.setVarargsType(node.varargsElement) .setVarargsType(node.varargsElement)
.setName(convertSimpleName(elem, type, getPosition(node))); .setName(convertSimpleName(sym, type, getPosition(node)));
if (target.getKind() == Kind.MEMBER_SELECT) { if (target.getKind() == Kind.MEMBER_SELECT) {
// foo.bar.MyClass.super.print(...): // foo.bar.MyClass.super.print(...):
// target: foo.bar.MyClass.super // target: foo.bar.MyClass.super
Expand All @@ -971,7 +968,7 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) {
} }


MethodInvocation newNode = new MethodInvocation(); MethodInvocation newNode = new MethodInvocation();
newNode.setName(convertSimpleName(elem, type, getPosition(method))); newNode.setName(convertSimpleName(sym, type, getPosition(method)));
if (target != null) { if (target != null) {
newNode.setExpression((Expression) convert(target)); newNode.setExpression((Expression) convert(target));
} }
Expand All @@ -980,7 +977,7 @@ private TreeNode convertMethodInvocation(JCTree.JCMethodInvocation node) {
} }
return newNode return newNode
.setTypeMirror(node.type) .setTypeMirror(node.type)
.setExecutablePair(new ExecutablePair(elem, type)) .setExecutablePair(new ExecutablePair(sym, type))
.setVarargsType(node.varargsElement); .setVarargsType(node.varargsElement);
} }


Expand Down Expand Up @@ -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;
}
} }
Expand Up @@ -46,9 +46,11 @@ public void testConstantFromMethodInvocation() throws IOException {
"return (JavaLangInteger_valueOfWithInt_(42), JavaLangInteger_SIZE);"); "return (JavaLangInteger_valueOfWithInt_(42), JavaLangInteger_SIZE);");
} }


// Javac bug with using a '*' wildcard in an import static statement then using elements from // javac qualifies members imported via non-canonical static imports by the
// classes further up the type hierarchy. // the type of the import, not the type the member is declared in.
public void testIncorrectEnclosingElementBug() throws IOException { // 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( addSourceFile(
"package foo; public class A { " "package foo; public class A { "
+ "public static final int FOO = 1; public static void bar() {} }", "foo/A.java"); + "public static final int FOO = 1; public static void bar() {} }", "foo/A.java");
Expand All @@ -60,4 +62,19 @@ public void testIncorrectEnclosingElementBug() throws IOException {
"jint i = FooA_FOO;", "jint i = FooA_FOO;",
"FooA_bar();"); "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();");
}
} }

0 comments on commit cd11f4e

Please sign in to comment.