Mercurial > hg > openjdk > jdk8u > langtools
changeset 2712:ba758e1ffa69 jdk8u60-b10
8054220: Debugger doesn't show variables *outside* lambda
8058227: Debugger has no access to outer variables inside Lambda
Summary: Put local variables captured by lambda into the lambda method's LocalVariableTable.
Reviewed-by: mcimadamore, rfield
author | jlahoda |
---|---|
date | Thu, 26 Mar 2015 11:34:50 +0100 |
parents | 7974f6da2d76 |
children | c18117bf5a9f |
files | src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java src/share/classes/com/sun/tools/javac/jvm/Code.java test/tools/javac/MethodParameters/LambdaTest.out test/tools/javac/lambda/LocalVariableTable.java |
diffstat | 4 files changed, 18 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Tue Jan 13 10:25:24 2015 +0100 +++ b/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Mar 26 11:34:50 2015 +0100 @@ -1883,7 +1883,7 @@ * Translate a symbol of a given kind into something suitable for the * synthetic lambda body */ - Symbol translate(Name name, final Symbol sym, LambdaSymbolKind skind) { + Symbol translate(final Symbol sym, LambdaSymbolKind skind) { Symbol ret; switch (skind) { case CAPTURED_THIS: @@ -1891,7 +1891,7 @@ break; case TYPE_VAR: // Just erase the type var - ret = new VarSymbol(sym.flags(), name, + ret = new VarSymbol(sym.flags(), sym.name, types.erasure(sym.type), sym.owner); /* this information should also be kept for LVT generation at Gen @@ -1900,7 +1900,7 @@ ((VarSymbol)ret).pos = ((VarSymbol)sym).pos; break; case CAPTURED_VAR: - ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, name, types.erasure(sym.type), translatedSym) { + ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, sym.name, types.erasure(sym.type), translatedSym) { @Override public Symbol baseSymbol() { //keep mapping with original captured symbol @@ -1909,16 +1909,16 @@ }; break; case LOCAL_VAR: - ret = new VarSymbol(sym.flags() & FINAL, name, sym.type, translatedSym); + ret = new VarSymbol(sym.flags() & FINAL, sym.name, sym.type, translatedSym); ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; break; case PARAM: - ret = new VarSymbol((sym.flags() & FINAL) | PARAMETER, name, types.erasure(sym.type), translatedSym); + ret = new VarSymbol((sym.flags() & FINAL) | PARAMETER, sym.name, types.erasure(sym.type), translatedSym); ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; break; default: - ret = makeSyntheticVar(FINAL, name, types.erasure(sym.type), translatedSym); - ((VarSymbol) ret).pos = ((VarSymbol) sym).pos; + Assert.error(skind.name()); + throw new AssertionError(); } if (ret != sym) { ret.setDeclarationAttributes(sym.getRawAttributes()); @@ -1929,27 +1929,8 @@ void addSymbol(Symbol sym, LambdaSymbolKind skind) { Map<Symbol, Symbol> transMap = getSymbolMap(skind); - Name preferredName; - switch (skind) { - case CAPTURED_THIS: - preferredName = names.fromString("encl$" + transMap.size()); - break; - case CAPTURED_VAR: - preferredName = names.fromString("cap$" + transMap.size()); - break; - case LOCAL_VAR: - preferredName = sym.name; - break; - case PARAM: - preferredName = sym.name; - break; - case TYPE_VAR: - preferredName = sym.name; - break; - default: throw new AssertionError(); - } if (!transMap.containsKey(sym)) { - transMap.put(sym, translate(preferredName, sym, skind)); + transMap.put(sym, translate(sym, skind)); } }
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java Tue Jan 13 10:25:24 2015 +0100 +++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java Thu Mar 26 11:34:50 2015 +0100 @@ -2172,7 +2172,11 @@ boolean keepLocalVariables = varDebugInfo || (var.sym.isExceptionParameter() && var.sym.hasTypeAnnotations()); if (!keepLocalVariables) return; - if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return; + //don't keep synthetic vars, unless they are lambda method parameters + boolean ignoredSyntheticVar = (var.sym.flags() & Flags.SYNTHETIC) != 0 && + ((var.sym.owner.flags() & Flags.LAMBDA_METHOD) == 0 || + (var.sym.flags() & Flags.PARAMETER) == 0); + if (ignoredSyntheticVar) return; if (varBuffer == null) varBuffer = new LocalVar[20]; else
--- a/test/tools/javac/MethodParameters/LambdaTest.out Tue Jan 13 10:25:24 2015 +0100 +++ b/test/tools/javac/MethodParameters/LambdaTest.out Thu Mar 26 11:34:50 2015 +0100 @@ -2,6 +2,6 @@ LambdaTest.<init>() LambdaTest.foo(i) LambdaTest.lambda$static$1(x1/*synthetic*/)/*synthetic*/ -LambdaTest.lambda$null$0(final cap$0/*synthetic*/, x2/*synthetic*/)/*synthetic*/ +LambdaTest.lambda$null$0(final x1/*synthetic*/, x2/*synthetic*/)/*synthetic*/ static interface LambdaTest$I -- inner LambdaTest$I.m(x)
--- a/test/tools/javac/lambda/LocalVariableTable.java Tue Jan 13 10:25:24 2015 +0100 +++ b/test/tools/javac/lambda/LocalVariableTable.java Thu Mar 26 11:34:50 2015 +0100 @@ -23,7 +23,7 @@ /* * @test - * @bug 8025998 8026749 + * @bug 8025998 8026749 8054220 8058227 * @summary Missing LV table in lambda bodies * @compile -g LocalVariableTable.java * @run main LocalVariableTable @@ -183,7 +183,7 @@ Run1 r = (a) -> { int x = a; }; } - @Expect({ "a", "x" }) + @Expect({ "a", "x", "v" }) static class Lambda_Args1_Local1_Captured1 { void m() { int v = 0; @@ -191,7 +191,7 @@ } } - @Expect({ "a1", "a2", "x1", "x2", "this" }) + @Expect({ "a1", "a2", "x1", "x2", "this", "v1", "v2" }) static class Lambda_Args2_Local2_Captured2_this { int v; void m() { @@ -204,7 +204,7 @@ } } - @Expect({ "e" }) + @Expect({ "e", "c" }) static class Lambda_Try_Catch { private static Runnable asUncheckedRunnable(Closeable c) { return () -> {