8282714: synthetic arguments are being added to the constructors of static local classes
Reviewed-by: jlahoda
This commit is contained in:
parent
e7795851d2
commit
9c86c82091
src/jdk.compiler/share/classes/com/sun/tools/javac
test/langtools/tools/javac/records
@ -491,7 +491,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
|
||||
return kind == TYP && type.getEnclosingType().hasTag(CLASS);
|
||||
}
|
||||
|
||||
/** An inner class has an outer instance if it is not an interface
|
||||
/** An inner class has an outer instance if it is not an interface, enum or record,
|
||||
* it has an enclosing instance class which might be referenced from the class.
|
||||
* Nested classes can see instance members of their enclosing class.
|
||||
* Their constructors carry an additional this$n parameter, inserted
|
||||
@ -501,7 +501,7 @@ public abstract class Symbol extends AnnoConstruct implements PoolConstant, Elem
|
||||
*/
|
||||
public boolean hasOuterInstance() {
|
||||
return
|
||||
type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | NOOUTERTHIS)) == 0;
|
||||
type.getEnclosingType().hasTag(CLASS) && (flags() & (INTERFACE | ENUM | RECORD | NOOUTERTHIS)) == 0;
|
||||
}
|
||||
|
||||
/** The closest enclosing class of this symbol's declaration.
|
||||
|
@ -396,7 +396,7 @@ public class Lower extends TreeTranslator {
|
||||
if (fvs != null) {
|
||||
return fvs;
|
||||
}
|
||||
if (c.owner.kind.matches(KindSelector.VAL_MTH)) {
|
||||
if (c.owner.kind.matches(KindSelector.VAL_MTH) && !c.isStatic()) {
|
||||
FreeVarCollector collector = new FreeVarCollector(c);
|
||||
collector.scan(classDef(c));
|
||||
fvs = collector.fvs;
|
||||
@ -2688,6 +2688,7 @@ public class Lower extends TreeTranslator {
|
||||
|
||||
private void visitMethodDefInternal(JCMethodDecl tree) {
|
||||
if (tree.name == names.init &&
|
||||
!currentClass.isStatic() &&
|
||||
(currentClass.isInner() || currentClass.isDirectlyOrIndirectlyLocal())) {
|
||||
// We are seeing a constructor of an inner class.
|
||||
MethodSymbol m = tree.sym;
|
||||
@ -2823,7 +2824,7 @@ public class Lower extends TreeTranslator {
|
||||
|
||||
// If created class is local, add free variables after
|
||||
// explicit constructor arguments.
|
||||
if (c.isDirectlyOrIndirectlyLocal()) {
|
||||
if (c.isDirectlyOrIndirectlyLocal() && !c.isStatic()) {
|
||||
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
|
||||
}
|
||||
|
||||
@ -3025,7 +3026,7 @@ public class Lower extends TreeTranslator {
|
||||
// If we are calling a constructor of a local class, add
|
||||
// free variables after explicit constructor arguments.
|
||||
ClassSymbol c = (ClassSymbol)constructor.owner;
|
||||
if (c.isDirectlyOrIndirectlyLocal()) {
|
||||
if (c.isDirectlyOrIndirectlyLocal() && !c.isStatic()) {
|
||||
tree.args = tree.args.appendList(loadFreevars(tree.pos(), freevars(c)));
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8282714
|
||||
* @summary synthetic arguments are being added to the constructors of static local classes
|
||||
* @library /lib/combo /tools/lib /tools/javac/lib
|
||||
* @modules jdk.compiler/com.sun.tools.javac.api
|
||||
* jdk.compiler/com.sun.tools.javac.file
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* @run testng/othervm LocalStaticDeclarations2
|
||||
*/
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import tools.javac.combo.CompilationTestCase;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
@Test
|
||||
public class LocalStaticDeclarations2 extends CompilationTestCase {
|
||||
public void testLocalStatic() {
|
||||
assertOK(
|
||||
"""
|
||||
class Test {
|
||||
class Inner {
|
||||
Inner() { enum E { A } }
|
||||
}
|
||||
}
|
||||
""");
|
||||
assertOK(
|
||||
"""
|
||||
class Test {
|
||||
class Inner {
|
||||
Inner() {
|
||||
record R(Object o) {
|
||||
static R create() { return new R("hi"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""");
|
||||
assertOK(
|
||||
"""
|
||||
class Test {
|
||||
class Inner {
|
||||
Inner() {
|
||||
record R(Object o) {
|
||||
static R create(Object obj) { return new R(obj); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
""");
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
* RecordCompilationTests
|
||||
*
|
||||
* @test
|
||||
* @bug 8250629 8252307 8247352 8241151 8246774 8259025 8288130
|
||||
* @bug 8250629 8252307 8247352 8241151 8246774 8259025 8288130 8282714
|
||||
* @summary Negative compilation tests, and positive compilation (smoke) tests for records
|
||||
* @library /lib/combo /tools/lib /tools/javac/lib
|
||||
* @modules
|
||||
@ -1259,23 +1259,52 @@ public class RecordCompilationTests extends CompilationTestCase {
|
||||
}
|
||||
|
||||
public void testOnlyOneFieldRef() throws Exception {
|
||||
int numberOfFieldRefs = 0;
|
||||
File dir = assertOK(true, "record R(int recordComponent) {}");
|
||||
for (final File fileEntry : dir.listFiles()) {
|
||||
if (fileEntry.getName().equals("R.class")) {
|
||||
ClassFile classFile = ClassFile.read(fileEntry);
|
||||
for (CPInfo cpInfo : classFile.constant_pool.entries()) {
|
||||
if (cpInfo instanceof ConstantPool.CONSTANT_Fieldref_info) {
|
||||
numberOfFieldRefs++;
|
||||
ConstantPool.CONSTANT_NameAndType_info nameAndType =
|
||||
(ConstantPool.CONSTANT_NameAndType_info)classFile.constant_pool
|
||||
.get(((ConstantPool.CONSTANT_Fieldref_info)cpInfo).name_and_type_index);
|
||||
Assert.check(nameAndType.getName().equals("recordComponent"));
|
||||
for (String source : List.of(
|
||||
"record R(int recordComponent) {}",
|
||||
"""
|
||||
class Test {
|
||||
class Inner {
|
||||
Inner() {
|
||||
record R(int recordComponent) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
""",
|
||||
"""
|
||||
class Test {
|
||||
class Inner {
|
||||
void m() {
|
||||
record R(int recordComponent) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
""",
|
||||
"""
|
||||
class Test {
|
||||
void m() {
|
||||
record R(int recordComponent) {}
|
||||
}
|
||||
}
|
||||
"""
|
||||
)) {
|
||||
File dir = assertOK(true, source);
|
||||
int numberOfFieldRefs = 0;
|
||||
for (final File fileEntry : dir.listFiles()) {
|
||||
if (fileEntry.getName().endsWith("R.class")) {
|
||||
ClassFile classFile = ClassFile.read(fileEntry);
|
||||
for (CPInfo cpInfo : classFile.constant_pool.entries()) {
|
||||
if (cpInfo instanceof ConstantPool.CONSTANT_Fieldref_info) {
|
||||
numberOfFieldRefs++;
|
||||
ConstantPool.CONSTANT_NameAndType_info nameAndType =
|
||||
(ConstantPool.CONSTANT_NameAndType_info)classFile.constant_pool
|
||||
.get(((ConstantPool.CONSTANT_Fieldref_info)cpInfo).name_and_type_index);
|
||||
Assert.check(nameAndType.getName().equals("recordComponent"));
|
||||
}
|
||||
}
|
||||
Assert.check(numberOfFieldRefs == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
Assert.check(numberOfFieldRefs == 1);
|
||||
}
|
||||
|
||||
// check that fields are initialized in a canonical constructor in the same declaration order as the corresponding
|
||||
|
Loading…
x
Reference in New Issue
Block a user