Skip to content

Commit 1cfb265

Browse files
committed
8307814: In the case of two methods with Record Patterns, the second one contains a line number from the first method
Reviewed-by: vromero, godin
1 parent eb11508 commit 1cfb265

File tree

4 files changed

+135
-23
lines changed

4 files changed

+135
-23
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ private UnrolledRecordPattern unrollRecordPattern(JCRecordPattern recordPattern)
304304
BindingSymbol tempBind = new BindingSymbol(Flags.SYNTHETIC,
305305
names.fromString(target.syntheticNameChar() + "b" + target.syntheticNameChar() + variableIndex++), recordType,
306306
currentMethodSym);
307-
JCVariableDecl recordBindingVar = make.VarDef(tempBind, null);
307+
JCVariableDecl recordBindingVar = make.at(recordPattern.pos()).VarDef(tempBind, null);
308308

309309
VarSymbol recordBinding = recordBindingVar.sym;
310310
List<? extends RecordComponent> components = recordPattern.record.getRecordComponents();
@@ -341,7 +341,7 @@ private UnrolledRecordPattern unrollRecordPattern(JCRecordPattern recordPattern)
341341
types.boxedTypeOrType(types.erasure(nestedBinding.type)));
342342
}
343343
JCMethodInvocation componentAccessor =
344-
make.App(make.Select(convert(make.Ident(recordBinding), recordBinding.type), //TODO - cast needed????
344+
make.at(recordPattern.pos()).App(make.Select(convert(make.Ident(recordBinding), recordBinding.type),
345345
component.accessor)).setType(types.erasure(component.accessor.getReturnType()));
346346
if (deconstructorCalls == null) {
347347
deconstructorCalls = Collections.newSetFromMap(new IdentityHashMap<>());

test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
3535
import static com.sun.tools.classfile.Attribute.Code;
3636
import static com.sun.tools.classfile.Attribute.LineNumberTable;
3737
import static java.lang.String.format;
38-
import static java.util.stream.Collectors.toList;
38+
import static java.util.stream.Collectors.toSet;
3939

4040
/**
4141
* Base class for line number table attribute tests.
@@ -82,22 +82,25 @@ protected void test(List<TestCase> testCases) throws Exception {
8282
LineNumberTable_attribute tableAttribute =
8383
(LineNumberTable_attribute) code_attribute.attributes.get(LineNumberTable);
8484
checkAttribute(testCase, tableAttribute, code_attribute.code_length);
85-
coveredLines.addAll(
85+
Set<Integer> methodCoveredLines =
8686
Stream.of(tableAttribute.line_number_table)
8787
.map(e -> e.line_number)
88-
.collect(toList()));
88+
.collect(toSet());
89+
90+
TestCase.MethodData expected = testCase.findData(m.getName(classFile.constant_pool));
91+
92+
if (expected != null) {
93+
verifyCoveredLines(methodCoveredLines, expected);
94+
}
95+
96+
coveredLines.addAll(methodCoveredLines);
8997
}
9098
}
91-
if (testCase.exactLines) {
92-
assertTrue(coveredLines.equals(testCase.expectedLines),
93-
format("Incorrect covered lines.%n" +
94-
"Covered: %s%n" +
95-
"Expected: %s%n", coveredLines, testCase.expectedLines));
96-
} else {
97-
assertTrue(coveredLines.containsAll(testCase.expectedLines),
98-
format("All significant lines are not covered.%n" +
99-
"Covered: %s%n" +
100-
"Expected: %s%n", coveredLines, testCase.expectedLines));
99+
100+
TestCase.MethodData expected = testCase.findData(null);
101+
102+
if (expected != null) {
103+
verifyCoveredLines(coveredLines, expected);
101104
}
102105
} catch (AssertionFailedException | CompilationException ex) {
103106
System.err.printf("# %-20s#%n", testCase.getName());
@@ -117,6 +120,20 @@ protected void test(List<TestCase> testCases) throws Exception {
117120
}
118121
}
119122

123+
private void verifyCoveredLines(Set<Integer> actualCoveredLines, TestCase.MethodData expected) {
124+
if (expected.exactLines()) {
125+
assertTrue(actualCoveredLines.equals(expected.expectedLines()),
126+
format("Incorrect covered lines.%n" +
127+
"Covered: %s%n" +
128+
"Expected: %s%n", actualCoveredLines, expected.expectedLines()));
129+
} else {
130+
assertTrue(actualCoveredLines.containsAll(expected.expectedLines()),
131+
format("All significant lines are not covered.%n" +
132+
"Covered: %s%n" +
133+
"Expected: %s%n", actualCoveredLines, expected.expectedLines()));
134+
}
135+
}
136+
120137
private int countAttributes(String name, Attribute[] attrs, ConstantPool constant_pool) throws ConstantPoolException {
121138
int i = 0;
122139
for (Attribute attribute : attrs) {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8307814
27+
* @summary Verify correct LineNumberTable is generated for unrolled record patterns.
28+
* @library /tools/lib /tools/javac/lib ../lib
29+
* @modules jdk.compiler/com.sun.tools.javac.api
30+
* jdk.compiler/com.sun.tools.javac.main
31+
* jdk.compiler/com.sun.tools.javac.util
32+
* jdk.jdeps/com.sun.tools.classfile
33+
* @build toolbox.ToolBox InMemoryFileManager TestBase
34+
* @build LineNumberTestBase TestCase
35+
* @run main MultipleRecordPatterns
36+
*/
37+
38+
import java.util.List;
39+
40+
public class MultipleRecordPatterns extends LineNumberTestBase {
41+
public static void main(String[] args) throws Exception {
42+
new MultipleRecordPatterns().test();
43+
}
44+
45+
public void test() throws Exception {
46+
test(List.of(TEST_CASE));
47+
}
48+
49+
private static final TestCase[] TEST_CASE = new TestCase[] {
50+
new TestCase("""
51+
public class Patterns { // 1
52+
private void test1(Object o) { // 2
53+
if (o instanceof R(var v)) { // 3
54+
System.err.println(v); // 4
55+
} // 5
56+
} // 6
57+
private void test2(Object o) { // 7
58+
if (o instanceof R(var v)) { // 8
59+
System.err.println(v); // 9
60+
} //10
61+
} //11
62+
record R(int i) {} //12
63+
} //13
64+
""",
65+
"Patterns",
66+
new TestCase.MethodData("test1", List.of(3, 4, 6), true),
67+
new TestCase.MethodData("test2", List.of(8, 9, 11), true))
68+
};
69+
70+
}

test/langtools/tools/javac/classfiles/attributes/LineNumberTable/TestCase.java

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,36 +24,61 @@
2424
import java.util.Collection;
2525
import java.util.HashSet;
2626
import java.util.List;
27-
import java.util.Set;
27+
import java.util.Objects;
2828

2929
/**
3030
* TestCase contains source code to be compiled
3131
* and expected lines to be covered by a line number table attribute.
3232
*/
3333
public class TestCase {
3434
public final String src;
35-
public final Set<Integer> expectedLines;
36-
public final boolean exactLines;
3735
public final List<String> extraCompilerOptions;
3836

3937

4038
private final String name;
39+
private final MethodData[] methodData;
4140

4241
public String getName() {
4342
return name;
4443
}
4544

4645
public TestCase(String src, Collection<Integer> expectedLines, String name) {
47-
this(src, expectedLines, false, List.of(), name);
46+
this(src, name, new MethodData(null, expectedLines, false));
47+
}
48+
49+
public TestCase(String src, String name, MethodData... methodData) {
50+
this(src, List.of(), name, methodData);
4851
}
4952

5053
public TestCase(String src, Collection<Integer> expectedLines,
5154
boolean exactLines, List<String> extraCompilerOptions,
5255
String name) {
56+
this(src, extraCompilerOptions, name, new MethodData(null, expectedLines, exactLines));
57+
}
58+
59+
public TestCase(String src, List<String> extraCompilerOptions,
60+
String name, MethodData... methodData) {
5361
this.src = src;
54-
this.expectedLines = new HashSet<>(expectedLines);
55-
this.exactLines = exactLines;
5662
this.extraCompilerOptions = extraCompilerOptions;
5763
this.name = name;
64+
this.methodData = methodData;
65+
}
66+
67+
public MethodData findData(String methodName) {
68+
for (MethodData md : methodData) {
69+
if (Objects.equals(md.methodName(), methodName)) {
70+
return md;
71+
}
72+
}
73+
74+
return null;
75+
}
76+
77+
record MethodData(String methodName, Collection<Integer> expectedLines, boolean exactLines) {
78+
79+
public MethodData {
80+
expectedLines = new HashSet<>(expectedLines);
81+
}
82+
5883
}
5984
}

0 commit comments

Comments
 (0)