提交 865543ba 编写于 作者: J jlahoda

8037546: javac -parameters does not emit parameter names for lambda expressions

Summary: MethodParameters attribute is missing for synthetic methods encoding lambda expressions.
Reviewed-by: rfield, mcimadamore
Contributed-by: srikanth.adayapalam@oracle.com
上级 6cfa552a
...@@ -265,7 +265,7 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -265,7 +265,7 @@ public class LambdaToMethod extends TreeTranslator {
@Override @Override
public void visitLambda(JCLambda tree) { public void visitLambda(JCLambda tree) {
LambdaTranslationContext localContext = (LambdaTranslationContext)context; LambdaTranslationContext localContext = (LambdaTranslationContext)context;
MethodSymbol sym = (MethodSymbol)localContext.translatedSym; MethodSymbol sym = localContext.translatedSym;
MethodType lambdaType = (MethodType) sym.type; MethodType lambdaType = (MethodType) sym.type;
{ {
...@@ -1755,7 +1755,7 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1755,7 +1755,7 @@ public class LambdaToMethod extends TreeTranslator {
Map<LambdaSymbolKind, Map<Symbol, Symbol>> translatedSymbols; Map<LambdaSymbolKind, Map<Symbol, Symbol>> translatedSymbols;
/** the synthetic symbol for the method hoisting the translated lambda */ /** the synthetic symbol for the method hoisting the translated lambda */
Symbol translatedSym; MethodSymbol translatedSym;
List<JCVariableDecl> syntheticParams; List<JCVariableDecl> syntheticParams;
...@@ -1997,6 +1997,7 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -1997,6 +1997,7 @@ public class LambdaToMethod extends TreeTranslator {
//compute synthetic params //compute synthetic params
ListBuffer<JCVariableDecl> params = new ListBuffer<>(); ListBuffer<JCVariableDecl> params = new ListBuffer<>();
ListBuffer<VarSymbol> parameterSymbols = new ListBuffer<>();
// The signature of the method is augmented with the following // The signature of the method is augmented with the following
// synthetic parameters: // synthetic parameters:
...@@ -2005,19 +2006,16 @@ public class LambdaToMethod extends TreeTranslator { ...@@ -2005,19 +2006,16 @@ public class LambdaToMethod extends TreeTranslator {
// 2) enclosing locals captured by the lambda expression // 2) enclosing locals captured by the lambda expression
for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) { for (Symbol thisSym : getSymbolMap(CAPTURED_VAR).values()) {
params.append(make.VarDef((VarSymbol) thisSym, null)); params.append(make.VarDef((VarSymbol) thisSym, null));
} parameterSymbols.append((VarSymbol) thisSym);
if (methodReferenceReceiver != null) {
params.append(make.VarDef(
make.Modifiers(PARAMETER|FINAL),
names.fromString("$rcvr$"),
make.Type(methodReferenceReceiver.type),
null));
} }
for (Symbol thisSym : getSymbolMap(PARAM).values()) { for (Symbol thisSym : getSymbolMap(PARAM).values()) {
params.append(make.VarDef((VarSymbol) thisSym, null)); params.append(make.VarDef((VarSymbol) thisSym, null));
parameterSymbols.append((VarSymbol) thisSym);
} }
syntheticParams = params.toList(); syntheticParams = params.toList();
translatedSym.params = parameterSymbols.toList();
// Compute and set the lambda name // Compute and set the lambda name
translatedSym.name = isSerializable() translatedSym.name = isSerializable()
? serializedLambdaName() ? serializedLambdaName()
......
...@@ -147,6 +147,7 @@ class ClassFileVisitor extends Tester.Visitor { ...@@ -147,6 +147,7 @@ class ClassFileVisitor extends Tester.Visitor {
public int mAttrs; public int mAttrs;
public int mNumParams; public int mNumParams;
public boolean mSynthetic; public boolean mSynthetic;
public boolean mIsLambda;
public boolean mIsConstructor; public boolean mIsConstructor;
public boolean mIsClinit; public boolean mIsClinit;
public boolean mIsBridge; public boolean mIsBridge;
...@@ -165,6 +166,7 @@ class ClassFileVisitor extends Tester.Visitor { ...@@ -165,6 +166,7 @@ class ClassFileVisitor extends Tester.Visitor {
mIsClinit = mName.equals("<clinit>"); mIsClinit = mName.equals("<clinit>");
prefix = cname + "." + mName + "() - "; prefix = cname + "." + mName + "() - ";
mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE); mIsBridge = method.access_flags.is(AccessFlags.ACC_BRIDGE);
mIsLambda = mSynthetic && mName.startsWith("lambda$");
if (mIsClinit) { if (mIsClinit) {
sb = new StringBuilder(); // Discard output sb = new StringBuilder(); // Discard output
...@@ -225,7 +227,7 @@ class ClassFileVisitor extends Tester.Visitor { ...@@ -225,7 +227,7 @@ class ClassFileVisitor extends Tester.Visitor {
// IMPL: Whether MethodParameters attributes will be generated // IMPL: Whether MethodParameters attributes will be generated
// for some synthetics is unresolved. For now, assume no. // for some synthetics is unresolved. For now, assume no.
if (mSynthetic) { if (mSynthetic && !mIsLambda) {
warn(prefix + "synthetic has MethodParameter attribute"); warn(prefix + "synthetic has MethodParameter attribute");
} }
...@@ -349,10 +351,12 @@ class ClassFileVisitor extends Tester.Visitor { ...@@ -349,10 +351,12 @@ class ClassFileVisitor extends Tester.Visitor {
} else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) { } else if (isEnum && mNumParams == 1 && index == 0 && mName.equals("valueOf")) {
expect = "name"; expect = "name";
allowMandated = true; allowMandated = true;
} else if (mIsBridge) { } else if (mIsBridge || mIsLambda) {
allowSynthetic = true; allowSynthetic = true;
/* you can't expect an special name for bridges' parameters. /* you can't expect an special name for bridges' parameters.
* The name of the original parameters are now copied. * The name of the original parameters are now copied. Likewise
* for a method encoding the lambda expression, names are derived
* from source lambda's parameters and captured enclosing locals.
*/ */
expect = null; expect = null;
} }
......
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
/* /*
* @test * @test
* @bug 8006582 * @bug 8006582 8037546
* @summary javac should generate method parameters correctly. * @summary javac should generate method parameters correctly.
* @build Tester * @build Tester
* @compile -parameters LambdaTest.java * @compile -parameters LambdaTest.java
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
*/ */
/** /**
* Parameter names are not recorded for lambdas. This test verifies * Post https://bugs.openjdk.java.net/browse/JDK-8037546, this test verifies
* that there are no MethodParameters attribute for lambdas. * that MethodParameters attribute for lambdas are emitted properly.
*/ */
class LambdaTest { class LambdaTest {
......
class LambdaTest -- class LambdaTest --
LambdaTest.<init>() LambdaTest.<init>()
LambdaTest.foo(i) LambdaTest.foo(i)
LambdaTest.lambda$static$1(arg0)/*synthetic*/ LambdaTest.lambda$static$1(x1/*synthetic*/)/*synthetic*/
LambdaTest.lambda$null$0(arg0, arg1)/*synthetic*/ LambdaTest.lambda$null$0(final cap$0/*synthetic*/, x2/*synthetic*/)/*synthetic*/
static interface LambdaTest$I -- inner static interface LambdaTest$I -- inner
LambdaTest$I.m(x) LambdaTest$I.m(x)
...@@ -277,7 +277,7 @@ public class ReflectionVisitor extends Tester.Visitor { ...@@ -277,7 +277,7 @@ public class ReflectionVisitor extends Tester.Visitor {
param = "final " + param; param = "final " + param;
} }
sb.append(sep).append(param); sb.append(sep).append(param);
if (!m.isBridge() && !expect.equals(param)) { if (!m.isBridge() && !m.getName().startsWith("lambda$") && !expect.equals(param)) {
error(prefix + "param[" + i + "]='" error(prefix + "param[" + i + "]='"
+ param + "' expected '" + expect + "'"); + param + "' expected '" + expect + "'");
break; break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册