Skip to content

Commit 6138923

Browse files
committed
Update Attribute on CF
1 parent 5fb5ea6 commit 6138923

File tree

13 files changed

+86
-56
lines changed

13 files changed

+86
-56
lines changed

src/java.base/share/classes/java/lang/Class.java

+29-11
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@
2626
package java.lang;
2727

2828
import java.lang.annotation.Annotation;
29-
import java.lang.classfile.Attributes;
30-
import java.lang.classfile.ClassFile;
31-
import java.lang.classfile.ClassModel;
32-
import java.lang.classfile.MethodModel;
29+
import java.lang.classfile.*;
3330
import java.lang.classfile.attribute.*;
3431
import java.lang.constant.ClassDesc;
3532
import java.lang.constant.ConstantDescs;
@@ -2311,7 +2308,10 @@ private Method[] filterOutDeconstructorsFromMethods(Method[] in) {
23112308
throw new RuntimeException(e);
23122309
}
23132310
for (MethodModel mm : cm.methods()) {
2314-
PatternAttribute pa = mm.findAttribute(Attributes.PATTERN).orElse(null);
2311+
PatternAttribute pa = null;
2312+
for (Attribute<?> attribute : mm.attributes()) {
2313+
if (attribute instanceof PatternAttribute pap) pa = pap;
2314+
}
23152315
isNotPattern.put(mm.methodName().stringValue(), pa == null);
23162316
}
23172317
Method[] ret = Arrays.stream(in).filter(m -> isNotPattern.getOrDefault(m.getName(), true)).toArray(Method[]::new);
@@ -2413,12 +2413,18 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24132413
byte[] bytes = is.readAllBytes();
24142414
ClassModel cm = ClassFile.of().parse(bytes);
24152415
for (MethodModel mm : cm.methods()) {
2416-
PatternAttribute pa = mm.findAttribute(Attributes.PATTERN).orElse(null);
2416+
PatternAttribute pa = null;
2417+
for (Attribute<?> attribute : mm.attributes()) {
2418+
if (attribute instanceof PatternAttribute pa_) pa = pa_;
2419+
}
24172420
if (pa != null) {
24182421
String descriptorFilter = null;
24192422

24202423
// generic signature detection
2421-
SignatureAttribute sa = pa.findAttribute(Attributes.SIGNATURE).orElse(null);
2424+
SignatureAttribute sa = null;
2425+
for (Attribute<?> attribute : pa.attributes()) {
2426+
if (attribute instanceof SignatureAttribute sa_) sa = sa_;
2427+
}
24222428
List<String> signatures = List.of();
24232429
if (sa != null) {
24242430
signatures = sa.asMethodSignature().arguments().stream().map(a -> a.signatureString()).toList();
@@ -2435,7 +2441,10 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24352441
if ((params.length == 0 || (params.length != 0 && pa.patternTypeSymbol().descriptorString().equals(descriptorFilter))) &&
24362442
(which == Member.DECLARED || mm.flags().has(AccessFlag.PUBLIC))) {
24372443
// binding annotations
2438-
RuntimeVisibleAnnotationsAttribute rva = mm.findAttribute(Attributes.RUNTIME_VISIBLE_ANNOTATIONS).orElse(null);
2444+
RuntimeVisibleAnnotationsAttribute rva = null;
2445+
for (Attribute<?> attribute : mm.attributes()) {
2446+
if (attribute instanceof RuntimeVisibleAnnotationsAttribute rva_) rva = rva_;
2447+
}
24392448
ByteBuffer assembled_rva = null;
24402449
if (rva != null) {
24412450
byte rvaBytes[] = ((BoundAttribute) rva).contents(); // returns the full attribute
@@ -2456,11 +2465,17 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24562465

24572466
// parameter names
24582467
var parameterList = pa.patternTypeSymbol().parameterList();
2459-
MethodParametersAttribute mp = pa.findAttribute(Attributes.METHOD_PARAMETERS).orElse(null);
2468+
MethodParametersAttribute mp = null;
2469+
for (Attribute<?> attribute : pa.attributes()) {
2470+
if (attribute instanceof MethodParametersAttribute mp_) mp = mp_;
2471+
}
24602472
List<String> parameterNameList = mp.parameters().stream().map(p -> p.name().get().stringValue()).toList();
24612473

24622474
// binding annotations
2463-
RuntimeVisibleParameterAnnotationsAttribute rvpa = pa.findAttribute(Attributes.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS).orElse(null);
2475+
RuntimeVisibleParameterAnnotationsAttribute rvpa = null;
2476+
for (Attribute<?> attribute : pa.attributes()) {
2477+
if (attribute instanceof RuntimeVisibleParameterAnnotationsAttribute rvpa_) rvpa = rvpa_;
2478+
}
24642479
ByteBuffer assembled_rvpa = null;
24652480
if (rvpa != null) {
24662481
byte rvpaBytes[] = ((BoundAttribute) rvpa).contents();
@@ -2470,7 +2485,10 @@ private Deconstructor<?>[] getDeclaredDeconstructors0(Class<?>[] params, int whi
24702485
}
24712486

24722487
// binding type annotations
2473-
RuntimeVisibleTypeAnnotationsAttribute rvta = pa.findAttribute(Attributes.RUNTIME_VISIBLE_TYPE_ANNOTATIONS).orElse(null);
2488+
RuntimeVisibleTypeAnnotationsAttribute rvta = null;
2489+
for (Attribute<?> attribute : pa.attributes()) {
2490+
if (attribute instanceof RuntimeVisibleTypeAnnotationsAttribute rvta_) rvta = rvta_;
2491+
}
24742492
ByteBuffer assembled_rvta = null;
24752493
if (rvpa != null) {
24762494
byte rvtaBytes[] = ((BoundAttribute) rvpa).contents();

src/java.base/share/classes/java/lang/classfile/Attributes.java

+8
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* <li>{@link #moduleResolution()}
4242
* <li>{@link #sourceDebugExtension()}
4343
* <li>{@link #synthetic()}
44+
* <li>{@link #pattern()}
4445
* </ul>
4546
*
4647
* The mappers with {@link AttributeStability#CP_REFS CP_REFS} stability are:
@@ -500,4 +501,11 @@ public static AttributeMapper<StackMapTableAttribute> stackMapTable() {
500501
public static AttributeMapper<SyntheticAttribute> synthetic() {
501502
return SyntheticMapper.INSTANCE;
502503
}
504+
505+
/**
506+
* {@return Attribute mapper for the {@code Pattern} attribute}
507+
* The mapper permits multiple instances in a given location.
508+
* @since 23
509+
*/
510+
public static AttributeMapper<PatternAttribute> pattern() { return PatternMapper.INSTANCE; }
503511
}

src/java.base/share/classes/jdk/internal/classfile/impl/AbstractAttributeMapper.java

+21
Original file line numberDiff line numberDiff line change
@@ -821,4 +821,25 @@ protected void writeBody(BufWriter buf, SyntheticAttribute attr) {
821821
// empty
822822
}
823823
}
824+
825+
public static final class PatternMapper extends AbstractAttributeMapper<PatternAttribute> {
826+
public static final PatternMapper INSTANCE = new PatternMapper();
827+
828+
private PatternMapper() {
829+
super(NAME_PATTERN, AttributeStability.STATELESS, true);
830+
}
831+
832+
@Override
833+
public PatternAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
834+
return new BoundAttribute.BoundPatternAttribute(cf, this, p);
835+
}
836+
837+
@Override
838+
protected void writeBody(BufWriter buf, PatternAttribute attr) {
839+
buf.writeIndex(attr.patternName());
840+
buf.writeU2(attr.patternFlagsMask());
841+
buf.writeIndex(attr.patternMethodType());
842+
buf.writeList(attr.attributes());
843+
}
844+
}
824845
}

src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java

+2
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,8 @@ public static AttributeMapper<?> standardAttribute(Utf8Entry name) {
11021102
name.equalsString(NAME_STACK_MAP_TABLE) ? stackMapTable() : null;
11031103
case 0x3dc79b7a ->
11041104
name.equalsString(NAME_SYNTHETIC) ? synthetic() : null;
1105+
case 0x7B286F27 ->
1106+
name.equalsString(NAME_PATTERN) ? pattern() : null;
11051107
default -> null;
11061108
};
11071109
}

src/java.base/share/classes/jdk/internal/classfile/impl/UnboundAttribute.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ public static final class UnboundPatternAttribute
320320
private final List<Attribute<?>> attributes;
321321

322322
public UnboundPatternAttribute(Utf8Entry matcherName, int matcherFlags, Utf8Entry matcherMethodType, List<Attribute<?>> attributes) {
323-
super(Attributes.PATTERN);
323+
super(Attributes.pattern());
324324
this.patternName = matcherName;
325325
this.patternFlags = matcherFlags;
326326
this.patternMethodType = matcherMethodType;

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

+11-10
Original file line numberDiff line numberDiff line change
@@ -4314,7 +4314,17 @@ public void visitRecordPattern(JCRecordPattern tree) {
43144314

43154315
List<Type> expectedRecordTypes = null;
43164316

4317-
if (site.tsym.kind == Kind.TYP) {
4317+
// todo: type check cases where a record class has deconstructors as well
4318+
if (((ClassSymbol) site.tsym).isRecord()) {
4319+
ClassSymbol record = (ClassSymbol) site.tsym;
4320+
expectedRecordTypes = record.getRecordComponents()
4321+
.stream()
4322+
.map(rc -> types.memberType(site, rc))
4323+
.map(t -> types.upward(t, types.captures(t)).baseType())
4324+
.collect(List.collector());
4325+
tree.record = record;
4326+
}
4327+
else if (site.tsym.kind == Kind.TYP) {
43184328
int nestedPatternCount = tree.nested.size();
43194329

43204330
// precalculate types of pattern components (as in method invocation)
@@ -4336,15 +4346,6 @@ public void visitRecordPattern(JCRecordPattern tree) {
43364346
expectedRecordTypes = types.memberType(site, patternDeclaration).getBindingTypes();
43374347
tree.patternDeclaration = patternDeclaration;
43384348
}
4339-
4340-
} else if (((ClassSymbol) site.tsym).isRecord()) {
4341-
ClassSymbol record = (ClassSymbol) site.tsym;
4342-
expectedRecordTypes = record.getRecordComponents()
4343-
.stream()
4344-
.map(rc -> types.memberType(site, rc))
4345-
.map(t -> types.upward(t, types.captures(t)).baseType())
4346-
.collect(List.collector());
4347-
tree.record = record;
43484349
}
43494350
}
43504351

test/langtools/tools/javac/diags/examples/NoCompatibleMatcherFound.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private static int test(D o) {
3636
return -1;
3737
}
3838

39-
public record D() {
39+
public static class D {
4040
public pattern D(Object v1, Float out) {
4141
out = 10.0f;
4242
}

test/langtools/tools/javac/diags/examples/PatternDeclarationOverloadingAmbiguity.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private static int test(D o) {
3434
return -1;
3535
}
3636

37-
public record D() {
37+
public static class D {
3838
public pattern D(Object v, Integer out) {
3939
match D(1, 1);
4040
}

test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ DeconstructionPatternErrors.java:26:29: compiler.err.instanceof.reifiable.not.sa
1818
DeconstructionPatternErrors.java:27:44: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
1919
DeconstructionPatternErrors.java:27:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
2020
DeconstructionPatternErrors.java:28:40: compiler.err.match.binding.exists
21-
DeconstructionPatternErrors.java:29:56: compiler.err.match.binding.exists
22-
DeconstructionPatternErrors.java:29:64: compiler.err.match.binding.exists
21+
DeconstructionPatternErrors.java:29:56: compiler.err.already.defined: kindname.variable, v1, kindname.method, meth()
22+
DeconstructionPatternErrors.java:29:64: compiler.err.already.defined: kindname.variable, v2, kindname.method, meth()
2323
22 errors

test/langtools/tools/javac/patterns/declarations/MultiplePatternDeclarations.java

+6-26
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ public class MultiplePatternDeclarations {
3333
public static void main(String... args) {
3434
assertEquals("A:B", test1A(new Person1("A", "B")));
3535
assertEquals("A", test1B(new Person1("A", "B")));
36-
assertEquals("A:B", test2A(new Person2("A", "B")));
37-
assertEquals("A", test2B(new Person2("A", "B")));
3836
}
3937

4038
private static String test1A(Object o) {
@@ -51,21 +49,14 @@ private static String test1B(Object o) {
5149
return null;
5250
}
5351

54-
private static String test2A(Object o) {
55-
if (o instanceof Person2(String name, String username)) {
56-
return name + ":" + username;
57-
}
58-
return null;
59-
}
52+
public static class Person1 {
53+
private final String name;
54+
private final String username;
6055

61-
private static String test2B(Object o) {
62-
if (o instanceof Person2(String name)) {
63-
return name;
56+
public Person1(String name, String username) {
57+
this.name = name;
58+
this.username = username;
6459
}
65-
return null;
66-
}
67-
68-
public record Person1(String name, String username) {
6960

7061
public Person1(String name) {
7162
this(name, name);
@@ -80,17 +71,6 @@ public pattern Person1(String name) {
8071
}
8172
}
8273

83-
public record Person2(String name, String username) {
84-
85-
public Person2(String name) {
86-
this(name, name);
87-
}
88-
89-
public pattern Person2(String name) {
90-
match Person2(this.name);
91-
}
92-
}
93-
9474
private static <T> void assertEquals(T expected, T actual) {
9575
if (!Objects.equals(expected, actual)) {
9676
throw new AssertionError("Expected: " + expected + ", but got: " + actual);

test/langtools/tools/javac/patterns/declarations/OverloadedPatternDeclarationErrors.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ private static int test2(D2 o) {
1919
return -1;
2020
}
2121

22-
public record D() {
22+
public static class D {
2323
public pattern D(Object v1, Float out) {
2424
match D(10.0f, 10.0f);
2525
}
@@ -29,7 +29,7 @@ public pattern D(Float out, Integer v1) {
2929
}
3030
}
3131

32-
public record D2() {
32+
public static class D2 {
3333
public pattern D2(Object v, Integer out) {
3434
match D2("", 1);
3535
}

test/langtools/tools/javac/patterns/declarations/OverloadedPatternDeclarations.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private static Integer test5(D o) {
7676
static class A {}
7777
static class B extends A {}
7878

79-
public record D() {
79+
public static class D {
8080
public pattern D(Object out, Integer outI) {
8181
match D(42, 1);
8282
}

test/langtools/tools/javac/patterns/declarations/OverloadedPrimitivePatternDeclarations.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ private static int testBoxing(D o) {
4242
return -1;
4343
}
4444

45-
public record D() {
45+
public static class D {
4646
public pattern D(String out, int outI) {
4747
match D("42", 1);
4848
}

0 commit comments

Comments
 (0)