changeset 3169:ef2011e4555a

8143133: Wrong MethodParameters on capturing local class with multiple constructors Summary: MethodParameters attribute not always generated for local classes constructors Reviewed-by: jlahoda
author mcimadamore
date Mon, 14 Dec 2015 13:55:35 +0000
parents c5237b05fff9
children dc017a37aac5
files src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java test/tools/javac/MethodParameters/ClassFileVisitor.java test/tools/javac/MethodParameters/LocalClassTest.java test/tools/javac/MethodParameters/LocalClassTest.out test/tools/javac/MethodParameters/ReflectionVisitor.java
diffstat 5 files changed, 52 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Dec 11 11:20:10 2015 -0800
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Mon Dec 14 13:55:35 2015 +0000
@@ -2707,11 +2707,11 @@
             if (fvs.nonEmpty()) {
                 List<Type> addedargtypes = List.nil();
                 for (List<VarSymbol> l = fvs; l.nonEmpty(); l = l.tail) {
+                    final Name pName = proxyName(l.head.name);
+                    m.capturedLocals =
+                        m.capturedLocals.prepend((VarSymbol)
+                                                (proxies.findFirst(pName)));
                     if (TreeInfo.isInitialConstructor(tree)) {
-                        final Name pName = proxyName(l.head.name);
-                        m.capturedLocals =
-                            m.capturedLocals.append((VarSymbol)
-                                                    (proxies.findFirst(pName)));
                         added = added.prepend(
                           initField(tree.body.pos, pName));
                     }
--- a/test/tools/javac/MethodParameters/ClassFileVisitor.java	Fri Dec 11 11:20:10 2015 -0800
+++ b/test/tools/javac/MethodParameters/ClassFileVisitor.java	Mon Dec 14 13:55:35 2015 +0000
@@ -279,7 +279,7 @@
                     userParam = param;
                 }
                 }
-                if (expect != null && !param.equals(expect)) {
+                if (check > 0 && expect != null && !param.equals(expect)) {
                     error(prefix + "param[" + x + "]='"
                           + param + "' expected '" + expect + "'");
                     return null;
@@ -346,6 +346,17 @@
                         }
                     }
                 }
+
+                if (synthetic && !mandated && !allowSynthetic) {
+                    //patch treatment for local captures
+                    if (isAnon || (isInner & !isStatic)) {
+                        expect = "val\\$.*";
+                        allowSynthetic = true;
+                        if (isFinal) {
+                            expect = "final val\\$.*";
+                        }
+                    }
+                }
             } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
                 expect = "name";
                 allowMandated = true;
@@ -411,7 +422,6 @@
             if (mSynthetic) {
                 return 0;
             }
-
             // Otherwise, do check test parameter naming convention.
             return 1;
         }
--- a/test/tools/javac/MethodParameters/LocalClassTest.java	Fri Dec 11 11:20:10 2015 -0800
+++ b/test/tools/javac/MethodParameters/LocalClassTest.java	Mon Dec 14 13:55:35 2015 +0000
@@ -45,6 +45,16 @@
         }
         new LocalClassTest().foo();
     }
+
+    void test(final int i) {
+        class CapturingLocal {
+            CapturingLocal(final int j) {
+               this(new Object() { void test() { int x = i; } });
+            }
+            CapturingLocal(Object o) { }
+        }
+        new CapturingLocal(i) { };
+    }
 }
 
 
--- a/test/tools/javac/MethodParameters/LocalClassTest.out	Fri Dec 11 11:20:10 2015 -0800
+++ b/test/tools/javac/MethodParameters/LocalClassTest.out	Mon Dec 14 13:55:35 2015 +0000
@@ -1,12 +1,21 @@
-class LocalClassTest$1Local_has_constructor -- inner
-LocalClassTest$1Local_has_constructor.<init>(final this$0/*implicit*/, a, ba)
-LocalClassTest$1Local_has_constructor.<init>(final this$0/*implicit*/)
-LocalClassTest$1Local_has_constructor.foo(m, nm)
-LocalClassTest$1Local_has_constructor.foo()
+class LocalClassTest$1 -- anon
+LocalClassTest$1.<init>(final this$0/*implicit*/, final j, final val$i/*synthetic*/)
+class LocalClassTest$1CapturingLocal$1 -- anon
+LocalClassTest$1CapturingLocal$1.<init>(final val$this$0/*synthetic*/, final val$val$i/*synthetic*/)
+LocalClassTest$1CapturingLocal$1.test()
+class LocalClassTest$1CapturingLocal -- inner
+LocalClassTest$1CapturingLocal.<init>(final this$0/*implicit*/, final j, final val$i/*synthetic*/)
+LocalClassTest$1CapturingLocal.<init>(final this$0/*implicit*/, o, final val$i/*synthetic*/)
 class LocalClassTest$1Local_default_constructor -- inner
 LocalClassTest$1Local_default_constructor.<init>(final this$0/*implicit*/)
 LocalClassTest$1Local_default_constructor.foo()
 LocalClassTest$1Local_default_constructor.foo(m, nm)
+class LocalClassTest$1Local_has_constructor -- inner
+LocalClassTest$1Local_has_constructor.<init>(final this$0/*implicit*/)
+LocalClassTest$1Local_has_constructor.<init>(final this$0/*implicit*/, a, ba)
+LocalClassTest$1Local_has_constructor.foo()
+LocalClassTest$1Local_has_constructor.foo(m, nm)
 class LocalClassTest -- 
 LocalClassTest.<init>()
-LocalClassTest.foo()
\ No newline at end of file
+LocalClassTest.foo()
+LocalClassTest.test(final i)
--- a/test/tools/javac/MethodParameters/ReflectionVisitor.java	Fri Dec 11 11:20:10 2015 -0800
+++ b/test/tools/javac/MethodParameters/ReflectionVisitor.java	Mon Dec 14 13:55:35 2015 +0000
@@ -164,6 +164,17 @@
                 }
             }
 
+            if (p.isSynthetic() && !p.isImplicit() && !allowSynthetic) {
+                //patch treatment for local captures
+                if (isAnon || ((isLocal || isAnon) & !isStatic)) {
+                    expect = "val\\$.*";
+                    allowSynthetic = true;
+                    if (isFinal) {
+                        expect = "final val\\$.*";
+                    }
+                }
+            }
+
             // Check expected flags
             if (p.isSynthetic() && p.isImplicit()) {
                 error(prefix + "param[" + i + "]='" + pname +