Also: support preview levels in ClsFileImpl Also fixes: IDEA-247551 Exception on first opening of record .class file GitOrigin-RevId: 4362d669d1c16b8230d6d8ab803465b6a7476803master
parent
0749965bc9
commit
1651445c90
@ -0,0 +1,47 @@ |
|||||||
|
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||||
|
package org.jetbrains.java.decompiler.struct; |
||||||
|
|
||||||
|
import org.jetbrains.java.decompiler.struct.consts.ConstantPool; |
||||||
|
import org.jetbrains.java.decompiler.struct.consts.PrimitiveConstant; |
||||||
|
import org.jetbrains.java.decompiler.util.DataInputFullStream; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/* |
||||||
|
record_component_info { |
||||||
|
u2 name_index; |
||||||
|
u2 descriptor_index; |
||||||
|
u2 attributes_count; |
||||||
|
attribute_info attributes[attributes_count]; |
||||||
|
} |
||||||
|
*/ |
||||||
|
public class StructRecordComponent extends StructMember { |
||||||
|
|
||||||
|
private final String name; |
||||||
|
private final String descriptor; |
||||||
|
|
||||||
|
|
||||||
|
public StructRecordComponent(DataInputFullStream in, ConstantPool pool) throws IOException { |
||||||
|
accessFlags = 0; |
||||||
|
int nameIndex = in.readUnsignedShort(); |
||||||
|
int descriptorIndex = in.readUnsignedShort(); |
||||||
|
|
||||||
|
name = ((PrimitiveConstant)pool.getConstant(nameIndex)).getString(); |
||||||
|
descriptor = ((PrimitiveConstant)pool.getConstant(descriptorIndex)).getString(); |
||||||
|
|
||||||
|
attributes = readAttributes(in, pool); |
||||||
|
} |
||||||
|
|
||||||
|
public String getName() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
|
||||||
|
public String getDescriptor() { |
||||||
|
return descriptor; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() { |
||||||
|
return name; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||||
|
package org.jetbrains.java.decompiler.struct.attr; |
||||||
|
|
||||||
|
import org.jetbrains.java.decompiler.struct.StructRecordComponent; |
||||||
|
import org.jetbrains.java.decompiler.struct.consts.ConstantPool; |
||||||
|
import org.jetbrains.java.decompiler.util.DataInputFullStream; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/* |
||||||
|
Record_attribute { |
||||||
|
u2 attribute_name_index; |
||||||
|
u4 attribute_length; |
||||||
|
u2 components_count; |
||||||
|
record_component_info components[components_count]; |
||||||
|
} |
||||||
|
*/ |
||||||
|
public class StructRecordAttribute extends StructGeneralAttribute { |
||||||
|
List<StructRecordComponent> components; |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initContent(DataInputFullStream data, |
||||||
|
ConstantPool pool) throws IOException { |
||||||
|
int componentCount = data.readUnsignedShort(); |
||||||
|
StructRecordComponent[] components = new StructRecordComponent[componentCount]; |
||||||
|
for (int i = 0; i < componentCount; i++) { |
||||||
|
components[i] = new StructRecordComponent(data, pool); |
||||||
|
} |
||||||
|
this.components = Arrays.asList(components); |
||||||
|
} |
||||||
|
|
||||||
|
public List<StructRecordComponent> getComponents() { |
||||||
|
return Collections.unmodifiableList(components); |
||||||
|
} |
||||||
|
} |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,66 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordAnno(@RC @TA int x, int y) { |
||||||
|
public TestRecordAnno(@TA int x, @P int y) { |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
} |
||||||
|
|
||||||
|
public final String toString() { |
||||||
|
return this.toString<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final int hashCode() { |
||||||
|
return this.hashCode<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final boolean equals(Object o) { |
||||||
|
return this.equals<invokedynamic>(this, o); |
||||||
|
} |
||||||
|
|
||||||
|
@TA |
||||||
|
public int x() { |
||||||
|
return this.x; |
||||||
|
} |
||||||
|
|
||||||
|
@M |
||||||
|
public int y() { |
||||||
|
return this.y;// 5 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class 'records/TestRecordAnno' { |
||||||
|
method '<init> (II)V' { |
||||||
|
6 4 |
||||||
|
b 5 |
||||||
|
e 6 |
||||||
|
} |
||||||
|
|
||||||
|
method 'toString ()Ljava/lang/String;' { |
||||||
|
1 9 |
||||||
|
6 9 |
||||||
|
} |
||||||
|
|
||||||
|
method 'hashCode ()I' { |
||||||
|
1 13 |
||||||
|
6 13 |
||||||
|
} |
||||||
|
|
||||||
|
method 'equals (Ljava/lang/Object;)Z' { |
||||||
|
2 17 |
||||||
|
7 17 |
||||||
|
} |
||||||
|
|
||||||
|
method 'x ()I' { |
||||||
|
1 22 |
||||||
|
4 22 |
||||||
|
} |
||||||
|
|
||||||
|
method 'y ()I' { |
||||||
|
1 27 |
||||||
|
4 27 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Lines mapping: |
||||||
|
5 <-> 28 |
@ -0,0 +1,35 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordEmpty() { |
||||||
|
public final String toString() { |
||||||
|
return this.toString<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final int hashCode() { |
||||||
|
return this.hashCode<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final boolean equals(Object o) { |
||||||
|
return this.equals<invokedynamic>(this, o);// 3 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class 'records/TestRecordEmpty' { |
||||||
|
method 'toString ()Ljava/lang/String;' { |
||||||
|
1 4 |
||||||
|
6 4 |
||||||
|
} |
||||||
|
|
||||||
|
method 'hashCode ()I' { |
||||||
|
1 8 |
||||||
|
6 8 |
||||||
|
} |
||||||
|
|
||||||
|
method 'equals (Ljava/lang/Object;)Z' { |
||||||
|
2 12 |
||||||
|
7 12 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Lines mapping: |
||||||
|
3 <-> 13 |
@ -0,0 +1,66 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordGenericVararg<T>(T first, T... other) { |
||||||
|
@SafeVarargs |
||||||
|
public TestRecordGenericVararg(T first, T... other) { |
||||||
|
this.first = first;// 5 |
||||||
|
this.other = other; |
||||||
|
} |
||||||
|
|
||||||
|
public final String toString() { |
||||||
|
return this.toString<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final int hashCode() { |
||||||
|
return this.hashCode<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final boolean equals(Object o) { |
||||||
|
return this.equals<invokedynamic>(this, o); |
||||||
|
} |
||||||
|
|
||||||
|
public T first() { |
||||||
|
return this.first; |
||||||
|
} |
||||||
|
|
||||||
|
public T[] other() { |
||||||
|
return this.other;// 3 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class 'records/TestRecordGenericVararg' { |
||||||
|
method '<init> (Ljava/lang/Object;[Ljava/lang/Object;)V' { |
||||||
|
6 5 |
||||||
|
b 6 |
||||||
|
e 7 |
||||||
|
} |
||||||
|
|
||||||
|
method 'toString ()Ljava/lang/String;' { |
||||||
|
1 10 |
||||||
|
6 10 |
||||||
|
} |
||||||
|
|
||||||
|
method 'hashCode ()I' { |
||||||
|
1 14 |
||||||
|
6 14 |
||||||
|
} |
||||||
|
|
||||||
|
method 'equals (Ljava/lang/Object;)Z' { |
||||||
|
2 18 |
||||||
|
7 18 |
||||||
|
} |
||||||
|
|
||||||
|
method 'first ()Ljava/lang/Object;' { |
||||||
|
1 22 |
||||||
|
4 22 |
||||||
|
} |
||||||
|
|
||||||
|
method 'other ()[Ljava/lang/Object;' { |
||||||
|
1 26 |
||||||
|
4 26 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Lines mapping: |
||||||
|
3 <-> 27 |
||||||
|
5 <-> 6 |
@ -0,0 +1,64 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordSimple(int x, int y) { |
||||||
|
public TestRecordSimple(int x, int y) { |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
} |
||||||
|
|
||||||
|
public final String toString() { |
||||||
|
return this.toString<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final int hashCode() { |
||||||
|
return this.hashCode<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final boolean equals(Object o) { |
||||||
|
return this.equals<invokedynamic>(this, o); |
||||||
|
} |
||||||
|
|
||||||
|
public int x() { |
||||||
|
return this.x; |
||||||
|
} |
||||||
|
|
||||||
|
public int y() { |
||||||
|
return this.y;// 3 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class 'records/TestRecordSimple' { |
||||||
|
method '<init> (II)V' { |
||||||
|
6 4 |
||||||
|
b 5 |
||||||
|
e 6 |
||||||
|
} |
||||||
|
|
||||||
|
method 'toString ()Ljava/lang/String;' { |
||||||
|
1 9 |
||||||
|
6 9 |
||||||
|
} |
||||||
|
|
||||||
|
method 'hashCode ()I' { |
||||||
|
1 13 |
||||||
|
6 13 |
||||||
|
} |
||||||
|
|
||||||
|
method 'equals (Ljava/lang/Object;)Z' { |
||||||
|
2 17 |
||||||
|
7 17 |
||||||
|
} |
||||||
|
|
||||||
|
method 'x ()I' { |
||||||
|
1 21 |
||||||
|
4 21 |
||||||
|
} |
||||||
|
|
||||||
|
method 'y ()I' { |
||||||
|
1 25 |
||||||
|
4 25 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Lines mapping: |
||||||
|
3 <-> 26 |
@ -0,0 +1,64 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordVararg(int x, int[]... y) { |
||||||
|
public TestRecordVararg(int x, int[]... y) { |
||||||
|
this.x = x; |
||||||
|
this.y = y; |
||||||
|
} |
||||||
|
|
||||||
|
public final String toString() { |
||||||
|
return this.toString<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final int hashCode() { |
||||||
|
return this.hashCode<invokedynamic>(this); |
||||||
|
} |
||||||
|
|
||||||
|
public final boolean equals(Object o) { |
||||||
|
return this.equals<invokedynamic>(this, o); |
||||||
|
} |
||||||
|
|
||||||
|
public int x() { |
||||||
|
return this.x; |
||||||
|
} |
||||||
|
|
||||||
|
public int[][] y() { |
||||||
|
return this.y;// 3 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class 'records/TestRecordVararg' { |
||||||
|
method '<init> (I[[I)V' { |
||||||
|
6 4 |
||||||
|
b 5 |
||||||
|
e 6 |
||||||
|
} |
||||||
|
|
||||||
|
method 'toString ()Ljava/lang/String;' { |
||||||
|
1 9 |
||||||
|
6 9 |
||||||
|
} |
||||||
|
|
||||||
|
method 'hashCode ()I' { |
||||||
|
1 13 |
||||||
|
6 13 |
||||||
|
} |
||||||
|
|
||||||
|
method 'equals (Ljava/lang/Object;)Z' { |
||||||
|
2 17 |
||||||
|
7 17 |
||||||
|
} |
||||||
|
|
||||||
|
method 'x ()I' { |
||||||
|
1 21 |
||||||
|
4 21 |
||||||
|
} |
||||||
|
|
||||||
|
method 'y ()[[I' { |
||||||
|
1 25 |
||||||
|
4 25 |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Lines mapping: |
||||||
|
3 <-> 26 |
@ -0,0 +1,17 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
import java.lang.annotation.*; |
||||||
|
|
||||||
|
public record TestRecordAnno(@TA @RC int x, @M @P int y) {} |
||||||
|
|
||||||
|
@Target(ElementType.TYPE_USE) |
||||||
|
@interface TA {} |
||||||
|
|
||||||
|
@Target(ElementType.RECORD_COMPONENT) |
||||||
|
@interface RC {} |
||||||
|
|
||||||
|
@Target(ElementType.METHOD) |
||||||
|
@interface M {} |
||||||
|
|
||||||
|
@Target(ElementType.PARAMETER) |
||||||
|
@interface P {} |
@ -0,0 +1,3 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordEmpty() {} |
@ -0,0 +1,6 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordGenericVararg<T>(T first, T... other) { |
||||||
|
@SafeVarargs |
||||||
|
public TestRecordGenericVararg {} |
||||||
|
} |
@ -0,0 +1,3 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordSimple(int x, int y) {} |
@ -0,0 +1,3 @@ |
|||||||
|
package records; |
||||||
|
|
||||||
|
public record TestRecordVararg(int x, int[]... y) {} |
Loading…
Reference in new issue