8143133: Wrong MethodParameters on capturing local class with multiple constructors

MethodParameters attribute not always generated for local classes constructors

Reviewed-by: jlahoda
This commit is contained in:
Maurizio Cimadamore 2015-12-14 13:55:35 +00:00
parent ec26043caf
commit de127a784a
5 changed files with 52 additions and 12 deletions

View File

@ -2707,11 +2707,11 @@ public class Lower extends TreeTranslator {
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));
}

View File

@ -279,7 +279,7 @@ class ClassFileVisitor extends Tester.Visitor {
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 @@ class ClassFileVisitor extends Tester.Visitor {
}
}
}
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 @@ class ClassFileVisitor extends Tester.Visitor {
if (mSynthetic) {
return 0;
}
// Otherwise, do check test parameter naming convention.
return 1;
}

View File

@ -45,6 +45,16 @@ class LocalClassTest {
}
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) { };
}
}

View File

@ -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()
LocalClassTest.foo()
LocalClassTest.test(final i)

View File

@ -164,6 +164,17 @@ public class ReflectionVisitor extends Tester.Visitor {
}
}
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 +