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