Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java17
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java359
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java1
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java2
-rw-r--r--org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java2
5 files changed, 188 insertions, 193 deletions
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
index 8aa63ad5af..6de0a9b851 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/RecordsRestrictedClassTest.java
@@ -3922,21 +3922,4 @@ public void testBug565830_01() {
},
"private final int X$1Bar.x");
}
-public void testBug565787_01() {
- runConformTest(
- new String[] {
- "X.java",
- "public record X(String s) {\n"+
- " public X {\n"+
- " s.codePoints()\n"+
- " .forEach(cp -> System.out.println((java.util.function.Predicate<String>) \"\"::equals));\n"+
- " }\n"+
- " public static void main(String[] args) {\n"+
- " X a = new X(\"\");\n"+
- " a.equals(a);\n"+
- " }\n"+
- "}",
- },
- "");
-}
} \ No newline at end of file
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 3f728a020a..974f01248a 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -160,7 +160,8 @@ public class ClassFile implements TypeConstants, TypeIds {
// that collection contains all the remaining bytes of the .class file
public int headerOffset;
public Map<TypeBinding, Boolean> innerClassesBindings;
- public List<ASTNode> bootstrapMethods = null;
+ public List bootstrapMethods = null;
+ public List<TypeBinding> recordBootstrapMethods = null;
public int methodCount;
public int methodCountOffset;
// pool managment
@@ -176,9 +177,6 @@ public class ClassFile implements TypeConstants, TypeIds {
public Set visitedTypes;
- private int indexForMetaFactory = 0;
- private int indexForAltMetaFactory = 0;
- private int indexForObjectMethodBootStrap = 0;
public static final int INITIAL_CONTENTS_SIZE = 400;
public static final int INITIAL_HEADER_SIZE = 1500;
public static final int INNER_CLASSES_SIZE = 5;
@@ -425,8 +423,9 @@ public class ClassFile implements TypeConstants, TypeIds {
attributesNumber += generateHierarchyInconsistentAttribute();
}
// Functional expression, lambda bootstrap methods and record bootstrap methods
- if (this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) {
- attributesNumber += generateBootstrapMethods(this.bootstrapMethods);
+ if ((this.bootstrapMethods != null && !this.bootstrapMethods.isEmpty()) ||
+ (this.recordBootstrapMethods != null && !this.recordBootstrapMethods.isEmpty())) {
+ attributesNumber += generateBootstrapMethods(this.bootstrapMethods, this.recordBootstrapMethods);
}
// Inner class attribute
int numberOfInnerClasses = this.innerClassesBindings == null ? 0 : this.innerClassesBindings.size();
@@ -1079,7 +1078,7 @@ public class ClassFile implements TypeConstants, TypeIds {
* - default abstract methods
* - lambda methods.
*/
- public void addSpecialMethods(TypeDeclaration typeDecl) {
+ public void addSpecialMethods() {
// add all methods (default abstract methods and synthetic)
@@ -1166,7 +1165,7 @@ public class ClassFile implements TypeConstants, TypeIds {
case SyntheticMethodBinding.RecordOverrideEquals:
case SyntheticMethodBinding.RecordOverrideHashCode:
case SyntheticMethodBinding.RecordOverrideToString:
- addSyntheticRecordOverrideMethods(typeDecl, syntheticMethod, syntheticMethod.purpose);
+ addSyntheticRecordOverrideMethods(syntheticMethod, syntheticMethod.purpose);
break;
}
}
@@ -1198,12 +1197,13 @@ public class ClassFile implements TypeConstants, TypeIds {
}
}
- private void addSyntheticRecordOverrideMethods(TypeDeclaration typeDecl, SyntheticMethodBinding methodBinding, int purpose) {
- if (this.bootstrapMethods == null)
- this.bootstrapMethods = new ArrayList<>(3);
- if (!this.bootstrapMethods.contains(typeDecl))
- this.bootstrapMethods.add(typeDecl);
- int index = this.bootstrapMethods.indexOf(typeDecl);
+ private void addSyntheticRecordOverrideMethods(SyntheticMethodBinding methodBinding, int purpose) {
+ if (this.recordBootstrapMethods == null)
+ this.recordBootstrapMethods = new ArrayList<>(3);
+ if (!this.recordBootstrapMethods.contains(methodBinding.declaringClass))
+ this.recordBootstrapMethods.add(methodBinding.declaringClass);
+ int index = this.bootstrapMethods != null ? this.bootstrapMethods.size() +
+ this.recordBootstrapMethods.size() - 1 : 0;
generateMethodInfoHeader(methodBinding);
int methodAttributeOffset = this.contentsOffset;
// this will add exception attribute, synthetic attribute, deprecated attribute,...
@@ -3576,7 +3576,7 @@ public class ClassFile implements TypeConstants, TypeIds {
return 1;
}
- private int generateBootstrapMethods(List<ASTNode> bootStrapMethodsList) {
+ private int generateBootstrapMethods(List functionalExpressionList, List<TypeBinding> recordBootstrapMethods2) {
/* See JVM spec 4.7.21
The BootstrapMethods attribute has the following format:
BootstrapMethods_attribute {
@@ -3594,7 +3594,9 @@ public class ClassFile implements TypeConstants, TypeIds {
if (methodHandlesLookup == null) return 0; // skip bootstrap section, class path problem already reported, just avoid NPE.
recordInnerClasses(methodHandlesLookup); // Should be done, it's what javac does also
- int numberOfBootstraps = bootStrapMethodsList != null ? bootStrapMethodsList.size() : 0;
+ int nfunctionalExpressions = functionalExpressionList != null ? functionalExpressionList.size() : 0;
+ int nRecordBootStraps = recordBootstrapMethods2 != null ? recordBootstrapMethods2.size() : 0;
+ int numberOfBootstraps = nfunctionalExpressions + nRecordBootStraps;
int localContentsOffset = this.contentsOffset;
// Generate the boot strap attribute - since we are only making lambdas and
// functional expressions, we know the size ahead of time - this less general
@@ -3617,14 +3619,12 @@ public class ClassFile implements TypeConstants, TypeIds {
this.contents[localContentsOffset++] = (byte) (numberOfBootstraps >> 8);
this.contents[localContentsOffset++] = (byte) numberOfBootstraps;
- for (int i = 0; i < numberOfBootstraps; i++) {
- Object o = this.bootstrapMethods.get(i);
- if (o instanceof FunctionalExpression) {
- localContentsOffset = addBootStrapLambdaEntry(localContentsOffset, (FunctionalExpression) o);
- } else if (o instanceof TypeDeclaration) {
- localContentsOffset = addBootStrapRecordEntry(localContentsOffset, (TypeDeclaration) o);
- }
- }
+ if (nfunctionalExpressions > 0)
+ localContentsOffset = generateLambdaMetaFactoryBootStrapMethods(functionalExpressionList,
+ localContentsOffset, contentsEntries);
+ if (nRecordBootStraps > 0)
+ localContentsOffset = generateObjectMethodsBootStrapMethods(recordBootstrapMethods2, localContentsOffset,
+ contentsEntries);
int attributeLength = localContentsOffset - attributeLengthPosition - 4;
this.contents[attributeLengthPosition++] = (byte) (attributeLength >> 24);
@@ -3635,173 +3635,184 @@ public class ClassFile implements TypeConstants, TypeIds {
return 1;
}
- private int addBootStrapLambdaEntry(int localContentsOffset, FunctionalExpression functional) {
- MethodBinding [] bridges = functional.getRequiredBridges();
- TypeBinding[] markerInterfaces = null;
- final int contentsEntries = 10;
- if ((functional instanceof LambdaExpression
- && (((markerInterfaces = ((LambdaExpression) functional).getMarkerInterfaces()) != null))
- || bridges != null) || functional.isSerializable) {
- // may need even more space
- int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry
- if (markerInterfaces != null) {
- // 2 for the marker interface list size then 2 per marker interface index
- extraSpace += (2 + 2 * markerInterfaces.length);
- }
- if (bridges != null) {
- // 2 for bridge count then 2 per bridge method type.
- extraSpace += (2 + 2 * bridges.length);
- }
- if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(extraSpace + contentsEntries);
- }
+ private int generateLambdaMetaFactoryBootStrapMethods(List functionalExpressionList,
+ int localContentsOffset, final int contentsEntries) {
+ ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
+ int numberOfBootstraps = functionalExpressionList.size();
- if (this.indexForAltMetaFactory == 0) {
- ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
- this.indexForAltMetaFactory =
- this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
- ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false);
- }
- this.contents[localContentsOffset++] = (byte) (this.indexForAltMetaFactory >> 8);
- this.contents[localContentsOffset++] = (byte) this.indexForAltMetaFactory;
+ // Depending on the complexity of the expression it may be necessary to use the altMetafactory() rather than the metafactory()
+ int indexForMetaFactory = 0;
+ int indexForAltMetaFactory = 0;
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) +
- (bridges == null ? 0 : 1 + bridges.length));
+ for (int i = 0; i < numberOfBootstraps; i++) {
+ FunctionalExpression functional = (FunctionalExpression) functionalExpressionList.get(i);
+ MethodBinding [] bridges = functional.getRequiredBridges();
+ TypeBinding[] markerInterfaces = null;
+ if ((functional instanceof LambdaExpression
+ && (((markerInterfaces = ((LambdaExpression) functional).getMarkerInterfaces()) != null))
+ || bridges != null) || functional.isSerializable) {
+ // may need even more space
+ int extraSpace = 2; // at least 2 more than when the normal metafactory is used, for the bitflags entry
+ if (markerInterfaces != null) {
+ // 2 for the marker interface list size then 2 per marker interface index
+ extraSpace += (2 + 2 * markerInterfaces.length);
+ }
+ if (bridges != null) {
+ // 2 for bridge count then 2 per bridge method type.
+ extraSpace += (2 + 2 * bridges.length);
+ }
+ if (extraSpace + contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(extraSpace + contentsEntries);
+ }
- int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
- this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
+ if (indexForAltMetaFactory == 0) {
+ indexForAltMetaFactory =
+ this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
+ ConstantPool.ALTMETAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_ALTMETAFACTORY_SIGNATURE, false);
+ }
+ this.contents[localContentsOffset++] = (byte) (indexForAltMetaFactory >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForAltMetaFactory;
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ // u2 num_bootstrap_arguments
+ this.contents[localContentsOffset++] = 0;
+ this.contents[localContentsOffset++] = (byte) (4 + (markerInterfaces==null?0:1+markerInterfaces.length) +
+ (bridges == null ? 0 : 1 + bridges.length));
- char [] instantiatedSignature = functional.descriptor.signature();
- int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
- this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+ int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
+ this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
- int bitflags = 0;
- if (functional.isSerializable) {
- bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
- }
- if (markerInterfaces!=null) {
- bitflags |= ClassFileConstants.FLAG_MARKERS;
- }
- if (bridges != null) {
- bitflags |= ClassFileConstants.FLAG_BRIDGES;
- }
- int indexForBitflags = this.constantPool.literalIndex(bitflags);
+ int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
+ this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodHandleIndex;
- this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
- this.contents[localContentsOffset++] = (byte)(indexForBitflags);
+ char [] instantiatedSignature = functional.descriptor.signature();
+ int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
+ this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodTypeIndex;
- if (markerInterfaces != null) {
- int markerInterfaceCountIndex = this.constantPool.literalIndex(markerInterfaces.length);
- this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8);
- this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex);
- for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) {
- int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]);
- this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8);
- this.contents[localContentsOffset++] = (byte)(classTypeIndex);
+ int bitflags = 0;
+ if (functional.isSerializable) {
+ bitflags |= ClassFileConstants.FLAG_SERIALIZABLE;
}
- }
- if (bridges != null) {
- int bridgeCountIndex = this.constantPool.literalIndex(bridges.length);
- this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8);
- this.contents[localContentsOffset++] = (byte) (bridgeCountIndex);
- for (int m = 0, maxm = bridges.length; m < maxm; m++) {
- char [] bridgeSignature = bridges[m].signature();
- int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature);
- this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex;
+ if (markerInterfaces!=null) {
+ bitflags |= ClassFileConstants.FLAG_MARKERS;
}
- }
- } else {
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (this.indexForMetaFactory == 0) {
- ReferenceBinding javaLangInvokeLambdaMetafactory = this.referenceBinding.scope.getJavaLangInvokeLambdaMetafactory();
- this.indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
- ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
- }
- this.contents[localContentsOffset++] = (byte) (this.indexForMetaFactory >> 8);
- this.contents[localContentsOffset++] = (byte) this.indexForMetaFactory;
+ if (bridges != null) {
+ bitflags |= ClassFileConstants.FLAG_BRIDGES;
+ }
+ int indexForBitflags = this.constantPool.literalIndex(bitflags);
+
+ this.contents[localContentsOffset++] = (byte)(indexForBitflags>>8);
+ this.contents[localContentsOffset++] = (byte)(indexForBitflags);
+
+ if (markerInterfaces != null) {
+ int markerInterfaceCountIndex = this.constantPool.literalIndex(markerInterfaces.length);
+ this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex>>8);
+ this.contents[localContentsOffset++] = (byte)(markerInterfaceCountIndex);
+ for (int m = 0, maxm = markerInterfaces.length; m < maxm; m++) {
+ int classTypeIndex = this.constantPool.literalIndexForType(markerInterfaces[m]);
+ this.contents[localContentsOffset++] = (byte)(classTypeIndex>>8);
+ this.contents[localContentsOffset++] = (byte)(classTypeIndex);
+ }
+ }
+ if (bridges != null) {
+ int bridgeCountIndex = this.constantPool.literalIndex(bridges.length);
+ this.contents[localContentsOffset++] = (byte) (bridgeCountIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) (bridgeCountIndex);
+ for (int m = 0, maxm = bridges.length; m < maxm; m++) {
+ char [] bridgeSignature = bridges[m].signature();
+ int bridgeMethodTypeIndex = this.constantPool.literalIndexForMethodType(bridgeSignature);
+ this.contents[localContentsOffset++] = (byte) (bridgeMethodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) bridgeMethodTypeIndex;
+ }
+ }
+ } else {
+ if (contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(contentsEntries);
+ }
+ if (indexForMetaFactory == 0) {
+ indexForMetaFactory = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangInvokeLambdaMetafactory,
+ ConstantPool.METAFACTORY, ConstantPool.JAVA_LANG_INVOKE_LAMBDAMETAFACTORY_METAFACTORY_SIGNATURE, false);
+ }
+ this.contents[localContentsOffset++] = (byte) (indexForMetaFactory >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForMetaFactory;
- // u2 num_bootstrap_arguments
- this.contents[localContentsOffset++] = 0;
- this.contents[localContentsOffset++] = (byte) 3;
+ // u2 num_bootstrap_arguments
+ this.contents[localContentsOffset++] = 0;
+ this.contents[localContentsOffset++] = (byte) 3;
- int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
- this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
- this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
+ int functionalDescriptorIndex = this.constantPool.literalIndexForMethodType(functional.descriptor.original().signature());
+ this.contents[localContentsOffset++] = (byte) (functionalDescriptorIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) functionalDescriptorIndex;
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding instanceof PolymorphicMethodBinding ? functional.binding : functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ int methodHandleIndex = this.constantPool.literalIndexForMethodHandle(functional.binding instanceof PolymorphicMethodBinding ? functional.binding : functional.binding.original()); // Speak of " implementation" (erased) version here, adaptations described below.
+ this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodHandleIndex;
- char [] instantiatedSignature = functional.descriptor.signature();
- int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
- this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+ char [] instantiatedSignature = functional.descriptor.signature();
+ int methodTypeIndex = this.constantPool.literalIndexForMethodType(instantiatedSignature);
+ this.contents[localContentsOffset++] = (byte) (methodTypeIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodTypeIndex;
+ }
}
return localContentsOffset;
}
+ private int generateObjectMethodsBootStrapMethods(List<TypeBinding> recordList,
+ int localContentsOffset, final int contentsEntries) {
+ ReferenceBinding javaLangRuntimeObjectMethods = this.referenceBinding.scope.getJavaLangRuntimeObjectMethods();
+ int numberOfBootstraps = recordList.size();
+ int indexForObjectMethodBootStrap = 0;
+ for (int i = 0; i < numberOfBootstraps; i++) {
+ if (contentsEntries + localContentsOffset >= this.contents.length) {
+ resizeContents(contentsEntries);
+ }
+ if (indexForObjectMethodBootStrap == 0) {
+ indexForObjectMethodBootStrap = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeObjectMethods,
+ ConstantPool.BOOTSTRAP, ConstantPool.JAVA_LANG_RUNTIME_OBJECTMETHOD_BOOTSTRAP_SIGNATURE, false);
+ }
+ this.contents[localContentsOffset++] = (byte) (indexForObjectMethodBootStrap >> 8);
+ this.contents[localContentsOffset++] = (byte) indexForObjectMethodBootStrap;
- private int addBootStrapRecordEntry(int localContentsOffset, TypeDeclaration typeDecl) {
- TypeBinding type = typeDecl.binding;
- assert type.isRecord(); // sanity check
- final int contentsEntries = 10;
- if (contentsEntries + localContentsOffset >= this.contents.length) {
- resizeContents(contentsEntries);
- }
- if (this.indexForObjectMethodBootStrap == 0) {
- ReferenceBinding javaLangRuntimeObjectMethods = this.referenceBinding.scope.getJavaLangRuntimeObjectMethods();
- this.indexForObjectMethodBootStrap = this.constantPool.literalIndexForMethodHandle(ClassFileConstants.MethodHandleRefKindInvokeStatic, javaLangRuntimeObjectMethods,
- ConstantPool.BOOTSTRAP, ConstantPool.JAVA_LANG_RUNTIME_OBJECTMETHOD_BOOTSTRAP_SIGNATURE, false);
- }
- this.contents[localContentsOffset++] = (byte) (this.indexForObjectMethodBootStrap >> 8);
- this.contents[localContentsOffset++] = (byte) this.indexForObjectMethodBootStrap;
-
- // u2 num_bootstrap_arguments
- int numArgsLocation = localContentsOffset;
- localContentsOffset += 2;
+ // u2 num_bootstrap_arguments
+ int numArgsLocation = localContentsOffset;
+ localContentsOffset += 2;
- char[] recordName = type.constantPoolName();
- int recordIndex = this.constantPool.literalIndexForType(recordName);
- this.contents[localContentsOffset++] = (byte) (recordIndex >> 8);
- this.contents[localContentsOffset++] = (byte) recordIndex;
+ TypeBinding type = recordList.get(i);
+ assert type.isRecord(); // sanity check
+ char[] recordName = type.constantPoolName();
+ int recordIndex = this.constantPool.literalIndexForType(recordName);
+ this.contents[localContentsOffset++] = (byte) (recordIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) recordIndex;
- assert type instanceof SourceTypeBinding;
- SourceTypeBinding sourceType = (SourceTypeBinding) type;
- FieldBinding[] recordComponents = sourceType.getImplicitComponentFields();
+ assert type instanceof SourceTypeBinding;
+ SourceTypeBinding sourceType = (SourceTypeBinding) type;
+ FieldBinding[] recordComponents = sourceType.getImplicitComponentFields();
- int numArgs = 2 + recordComponents.length;
- this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
- this.contents[numArgsLocation] = (byte) numArgs;
+ int numArgs = 2 + recordComponents.length;
+ this.contents[numArgsLocation++] = (byte) (numArgs >> 8);
+ this.contents[numArgsLocation] = (byte) numArgs;
- String names =
- Arrays.stream(recordComponents)
- .map(f -> new String(f.name))
- .reduce((s1, s2) -> { return s1 + ";" + s2;}) //$NON-NLS-1$
- .orElse(Util.EMPTY_STRING);
- int namesIndex = this.constantPool.literalIndex(names);
- this.contents[localContentsOffset++] = (byte) (namesIndex >> 8);
- this.contents[localContentsOffset++] = (byte) namesIndex;
+ String names =
+ Arrays.stream(recordComponents)
+ .map(f -> new String(f.name))
+ .reduce((s1, s2) -> { return s1 + ";" + s2;}) //$NON-NLS-1$
+ .orElse(Util.EMPTY_STRING);
+ int namesIndex = this.constantPool.literalIndex(names);
+ this.contents[localContentsOffset++] = (byte) (namesIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) namesIndex;
- if (recordComponents.length * 2 + localContentsOffset >= this.contents.length) {
- resizeContents(recordComponents.length * 2);
- }
- for (FieldBinding field : recordComponents) {
- int methodHandleIndex = this.constantPool.literalIndexForMethodHandleFieldRef(
- ClassFileConstants.MethodHandleRefKindGetField,
- recordName, field.name, field.type.signature());
+ if (recordComponents.length * 2 + localContentsOffset >= this.contents.length) {
+ resizeContents(recordComponents.length * 2);
+ }
+ for (FieldBinding field : recordComponents) {
+ int methodHandleIndex = this.constantPool.literalIndexForMethodHandleFieldRef(
+ ClassFileConstants.MethodHandleRefKindGetField,
+ recordName, field.name, field.type.signature());
- this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
- this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ this.contents[localContentsOffset++] = (byte) (methodHandleIndex >> 8);
+ this.contents[localContentsOffset++] = (byte) methodHandleIndex;
+ }
}
return localContentsOffset;
}
@@ -6018,13 +6029,10 @@ public class ClassFile implements TypeConstants, TypeIds {
}
if (expression instanceof ReferenceExpression) {
for (int i = 0; i < this.bootstrapMethods.size(); i++) {
- ASTNode node = this.bootstrapMethods.get(i);
- if (node instanceof FunctionalExpression) {
- FunctionalExpression fexp = (FunctionalExpression) node;
- if (fexp.binding == expression.binding
- && TypeBinding.equalsEquals(fexp.expectedType(), expression.expectedType()))
- return expression.bootstrapMethodNumber = i;
- }
+ FunctionalExpression fexp = (FunctionalExpression) this.bootstrapMethods.get(i);
+ if (fexp.binding == expression.binding
+ && TypeBinding.equalsEquals(fexp.expectedType(), expression.expectedType()))
+ return expression.bootstrapMethodNumber = i;
}
}
this.bootstrapMethods.add(expression);
@@ -6073,6 +6081,9 @@ public class ClassFile implements TypeConstants, TypeIds {
if (this.bootstrapMethods != null) {
this.bootstrapMethods.clear();
}
+ if (this.recordBootstrapMethods != null) {
+ this.recordBootstrapMethods.clear();
+ }
this.missingTypes = null;
this.visitedTypes = null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
index 8beee5a001..bfc5cb05fe 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CompilationUnitDeclaration.java
@@ -174,6 +174,7 @@ public void cleanUp() {
classFile.referenceBinding = null;
classFile.innerClassesBindings = null;
classFile.bootstrapMethods = null;
+ classFile.recordBootstrapMethods = null;
classFile.missingTypes = null;
classFile.visitedTypes = null;
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
index e6e22c8815..ba892531da 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java
@@ -748,7 +748,7 @@ public void generateCode(ClassFile enclosingClassFile) {
}
}
// generate all synthetic and abstract methods
- classFile.addSpecialMethods(this);
+ classFile.addSpecialMethods();
if (this.ignoreFurtherInvestigation) { // trigger problem type generation for code gen errors
throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);
diff --git a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
index 8510532dac..330d96b226 100644
--- a/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
+++ b/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetTypeDeclaration.java
@@ -76,7 +76,7 @@ public void generateCode(ClassFile enclosingClassFile) {
}
// generate all methods
- classFile.addSpecialMethods(this);
+ classFile.addSpecialMethods();
if (this.ignoreFurtherInvestigation){ // trigger problem type generation for code gen errors
throw new AbortType(this.scope.referenceCompilationUnit().compilationResult, null);

Back to the top