79
79
import org .eclipse .jdt .internal .compiler .ast .SingleMemberAnnotation ;
80
80
import org .eclipse .jdt .internal .compiler .ast .SingleNameReference ;
81
81
import org .eclipse .jdt .internal .compiler .ast .StringLiteral ;
82
+ import org .eclipse .jdt .internal .compiler .ast .StringTemplate ;
82
83
import org .eclipse .jdt .internal .compiler .ast .SwitchStatement ;
83
84
import org .eclipse .jdt .internal .compiler .ast .TypeDeclaration ;
84
85
import org .eclipse .jdt .internal .compiler .ast .TypeParameter ;
@@ -201,9 +202,10 @@ public class ClassFile implements TypeConstants, TypeIds {
201
202
public static final String ENUMDESC_OF = "EnumDesc.of" ; //$NON-NLS-1$
202
203
public static final String CLASSDESC = "ClassDesc" ; //$NON-NLS-1$
203
204
public static final String CLASSDESC_OF = "ClassDesc.of" ; //$NON-NLS-1$
205
+ public static final String PROCESS_STRING = "process" ; //$NON-NLS-1$
206
+ public static final String NEW_STRING_TEMPLATE = "newStringTemplate" ; //$NON-NLS-1$
204
207
public static final String [] BOOTSTRAP_METHODS = { ALTMETAFACTORY_STRING , METAFACTORY_STRING , BOOTSTRAP_STRING ,
205
- TYPESWITCH_STRING , ENUMSWITCH_STRING , CONCAT_CONSTANTS , INVOKE_STRING , ENUMDESC_OF , CLASSDESC , CLASSDESC_OF };
206
-
208
+ TYPESWITCH_STRING , ENUMSWITCH_STRING , CONCAT_CONSTANTS , INVOKE_STRING , ENUMDESC_OF , CLASSDESC , CLASSDESC_OF , PROCESS_STRING , NEW_STRING_TEMPLATE };
207
209
/**
208
210
* INTERNAL USE-ONLY
209
211
* Request the creation of a ClassFile compatible representation of a problematic type
@@ -619,7 +621,7 @@ private int addFieldAttributes(FieldBinding fieldBinding, int fieldAttributeOffs
619
621
int size = allTypeAnnotationContexts .size ();
620
622
attributesNumber = completeRuntimeTypeAnnotations (attributesNumber ,
621
623
null ,
622
- ( node ) -> size > 0 ,
624
+ node -> size > 0 ,
623
625
() -> allTypeAnnotationContexts );
624
626
}
625
627
} finally {
@@ -672,7 +674,7 @@ private int addComponentAttributes(RecordComponentBinding recordComponentBinding
672
674
int size = allTypeAnnotationContexts .size ();
673
675
attributesNumber = completeRuntimeTypeAnnotations (attributesNumber ,
674
676
null ,
675
- ( node ) -> size > 0 ,
677
+ node -> size > 0 ,
676
678
() -> allTypeAnnotationContexts );
677
679
678
680
}
@@ -1761,7 +1763,7 @@ public int generateTypeAnnotationsOnCodeAttribute() {
1761
1763
int size = allTypeAnnotationContexts .size ();
1762
1764
attributesNumber = completeRuntimeTypeAnnotations (attributesNumber ,
1763
1765
null ,
1764
- ( node ) -> size > 0 ,
1766
+ node -> size > 0 ,
1765
1767
() -> allTypeAnnotationContexts );
1766
1768
return attributesNumber ;
1767
1769
}
@@ -2473,7 +2475,7 @@ public void completeMethodInfo(
2473
2475
int size = allTypeAnnotationContexts .size ();
2474
2476
attributesNumber = completeRuntimeTypeAnnotations (attributesNumber ,
2475
2477
null ,
2476
- ( node ) -> size > 0 ,
2478
+ node -> size > 0 ,
2477
2479
() -> allTypeAnnotationContexts );
2478
2480
}
2479
2481
if ((this .produceAttributes & ClassFileConstants .ATTR_METHOD_PARAMETERS ) != 0 ||
@@ -3667,6 +3669,8 @@ private int generateBootstrapMethods(List<Object> bootStrapMethodsList) {
3667
3669
localContentsOffset = addBootStrapTypeCaseConstantEntry (localContentsOffset , (ResolvedCase ) o , fPtr );
3668
3670
} else if (o instanceof TypeBinding ) {
3669
3671
localContentsOffset = addClassDescBootstrap (localContentsOffset , (TypeBinding ) o , fPtr );
3672
+ } else if (o instanceof StringTemplate template ) {
3673
+ localContentsOffset = addBootStrapTemplateRuntimeEntry (localContentsOffset , template , fPtr );
3670
3674
}
3671
3675
}
3672
3676
@@ -3836,7 +3840,7 @@ private int addBootStrapRecordEntry(int localContentsOffset, TypeDeclaration typ
3836
3840
String names =
3837
3841
Arrays .stream (recordComponents )
3838
3842
.map (f -> new String (f .name ))
3839
- .reduce ((s1 , s2 ) -> { return s1 + ";" + s2 ;} ) //$NON-NLS-1$
3843
+ .reduce ((s1 , s2 ) -> ( s1 + ";" + s2 ) ) //$NON-NLS-1$
3840
3844
.orElse (Util .EMPTY_STRING );
3841
3845
int namesIndex = this .constantPool .literalIndex (names );
3842
3846
this .contents [localContentsOffset ++] = (byte ) (namesIndex >> 8 );
@@ -4021,6 +4025,7 @@ private int addBootStrapEnumSwitchEntry(int localContentsOffset, SwitchStatement
4021
4025
int numArgsLocation = localContentsOffset ;
4022
4026
CaseStatement .ResolvedCase [] constants = switchStatement .otherConstants ;
4023
4027
int numArgs = constants .length ;
4028
+ if (switchStatement .containsNull ) --numArgs ;
4024
4029
this .contents [numArgsLocation ++] = (byte ) (numArgs >> 8 );
4025
4030
this .contents [numArgsLocation ] = (byte ) numArgs ;
4026
4031
localContentsOffset += 2 ;
@@ -4032,8 +4037,11 @@ private int addBootStrapEnumSwitchEntry(int localContentsOffset, SwitchStatement
4032
4037
this .contents [localContentsOffset ++] = (byte ) (typeIndex >> 8 );
4033
4038
this .contents [localContentsOffset ++] = (byte ) typeIndex ;
4034
4039
} else {
4040
+ if (c .e instanceof NullLiteral ) continue ;
4041
+ String s = c .e instanceof QualifiedNameReference qnr ? // handle superfluously qualified enumerator.
4042
+ new String (qnr .tokens [qnr .tokens .length -1 ]) : c .e .toString ();
4035
4043
int intValIdx =
4036
- this .constantPool .literalIndex (c . e . toString () );
4044
+ this .constantPool .literalIndex (s );
4037
4045
this .contents [localContentsOffset ++] = (byte ) (intValIdx >> 8 );
4038
4046
this .contents [localContentsOffset ++] = (byte ) intValIdx ;
4039
4047
}
@@ -4067,6 +4075,40 @@ private int addBootStrapStringConcatEntry(int localContentsOffset, String recipe
4067
4075
4068
4076
return localContentsOffset ;
4069
4077
}
4078
+ private int addBootStrapTemplateRuntimeEntry (int localContentsOffset , StringTemplate template , Map <String , Integer > fPtr ) {
4079
+ final int contentsEntries = 10 ;
4080
+ int indexForProcess = fPtr .get (NEW_STRING_TEMPLATE );
4081
+ if (contentsEntries + localContentsOffset >= this .contents .length ) {
4082
+ resizeContents (contentsEntries );
4083
+ }
4084
+ if (indexForProcess == 0 ) {
4085
+ ReferenceBinding javaLangRuntimeTemplateBootstraps = this .referenceBinding .scope .getJavaLangRuntimeTemplateRuntimeBootstraps ();
4086
+ indexForProcess = this .constantPool .literalIndexForMethodHandle (ClassFileConstants .MethodHandleRefKindInvokeStatic , javaLangRuntimeTemplateBootstraps ,
4087
+ NEW_STRING_TEMPLATE .toCharArray (), ConstantPool .JAVA_LANG_RUNTIME_STRING_TEMPLATE_SIGNATURE , false );
4088
+ fPtr .put (NEW_STRING_TEMPLATE , indexForProcess );
4089
+ }
4090
+ this .contents [localContentsOffset ++] = (byte ) (indexForProcess >> 8 );
4091
+ this .contents [localContentsOffset ++] = (byte ) indexForProcess ;
4092
+
4093
+ // u2 num_bootstrap_arguments
4094
+ int numArgsLocation = localContentsOffset ;
4095
+ StringLiteral [] fragments = template .fragments ();
4096
+ int numArgs = fragments .length ;
4097
+ this .contents [numArgsLocation ++] = (byte ) (numArgs >> 8 );
4098
+ this .contents [numArgsLocation ] = (byte ) numArgs ;
4099
+ localContentsOffset += 2 ;
4100
+
4101
+ if ((numArgs * 2 ) + localContentsOffset >= this .contents .length ) {
4102
+ resizeContents (numArgs * 2 );
4103
+ }
4104
+ for (StringLiteral frag : fragments ) {
4105
+ int intValIdx =
4106
+ this .constantPool .literalIndex (frag .constant .stringValue ());
4107
+ this .contents [localContentsOffset ++] = (byte ) (intValIdx >> 8 );
4108
+ this .contents [localContentsOffset ++] = (byte ) intValIdx ;
4109
+ }
4110
+ return localContentsOffset ;
4111
+ }
4070
4112
private int generateLineNumberAttribute () {
4071
4113
int localContentsOffset = this .contentsOffset ;
4072
4114
int attributesNumber = 0 ;
@@ -4399,7 +4441,7 @@ public int generateMethodInfoAttributes(MethodBinding methodBinding) {
4399
4441
int size = allTypeAnnotationContexts .size ();
4400
4442
attributesNumber = completeRuntimeTypeAnnotations (attributesNumber ,
4401
4443
null ,
4402
- ( node ) -> size > 0 ,
4444
+ node -> size > 0 ,
4403
4445
() -> allTypeAnnotationContexts );
4404
4446
}
4405
4447
}
@@ -4585,7 +4627,7 @@ public void addSyntheticDeserializeLambda(SyntheticMethodBinding methodBinding,
4585
4627
* That method generates the method info header of a clinit:
4586
4628
* The header consists in:
4587
4629
* - the access flags (always default access + static)
4588
- * - the name index of the method name (always <clinit>) inside the constant pool
4630
+ * - the name index of the method name (always {@code <clinit>} ) inside the constant pool
4589
4631
* - the descriptor index of the signature (always ()V) of the method inside the constant pool.
4590
4632
*/
4591
4633
public void generateMethodInfoHeaderForClinit () {
@@ -5137,7 +5179,10 @@ private int generateMethodParameters(final MethodBinding binding) {
5137
5179
for (int i = 0 , max = targetParameters .length , argumentsLength = arguments != null ? arguments .length : 0 ; i < max ; i ++) {
5138
5180
if (argumentsLength > i && arguments [i ] != null ) {
5139
5181
Argument argument = arguments [i ];
5140
- length = writeArgumentName (argument .name , argument .binding .modifiers , length );
5182
+ int modifiers = argument .binding .modifiers ;
5183
+ if (binding .isCompactConstructor ())
5184
+ modifiers |= ClassFileConstants .AccMandated ;
5185
+ length = writeArgumentName (argument .name , modifiers , length );
5141
5186
} else {
5142
5187
length = writeArgumentName (null , ClassFileConstants .AccSynthetic , length );
5143
5188
}
@@ -5850,7 +5895,7 @@ private int generateTypeAnnotationAttributeForTypeDeclaration() {
5850
5895
int size = allTypeAnnotationContexts .size ();
5851
5896
attributesNumber = completeRuntimeTypeAnnotations (attributesNumber ,
5852
5897
null ,
5853
- ( node ) -> size > 0 ,
5898
+ node -> size > 0 ,
5854
5899
() -> allTypeAnnotationContexts );
5855
5900
return attributesNumber ;
5856
5901
}
@@ -6394,6 +6439,13 @@ public int recordBootstrapMethod(String expression) {
6394
6439
this .bootstrapMethods .add (expression );
6395
6440
return this .bootstrapMethods .size () - 1 ;
6396
6441
}
6442
+ public int recordBootstrapMethod (StringTemplate template ) {
6443
+ if (this .bootstrapMethods == null ) {
6444
+ this .bootstrapMethods = new ArrayList <>();
6445
+ }
6446
+ this .bootstrapMethods .add (template );
6447
+ return this .bootstrapMethods .size () - 1 ;
6448
+ }
6397
6449
public void reset (/*@Nullable*/ SourceTypeBinding typeBinding , CompilerOptions options ) {
6398
6450
// the code stream is reinitialized for each method
6399
6451
if (typeBinding != null ) {
@@ -6530,7 +6582,7 @@ public int compare(StackMapFrame frame, StackMapFrame frame2) {
6530
6582
}
6531
6583
6532
6584
private TypeBinding getTypeBinding (char [] typeConstantPoolName , Scope scope , boolean checkcast ) {
6533
- if (typeConstantPoolName .length == 1 ) {
6585
+ if (typeConstantPoolName .length == 1 && ! checkcast ) {
6534
6586
// base type
6535
6587
switch (typeConstantPoolName [0 ]) {
6536
6588
case 'Z' :
@@ -6828,6 +6880,7 @@ public List<StackMapFrame> traverse(
6828
6880
}
6829
6881
}
6830
6882
byte opcode = (byte ) u1At (bytecodes , 0 , pc );
6883
+ inspectFrame (currentPC , frame );
6831
6884
switch (opcode ) {
6832
6885
case Opcodes .OPC_nop :
6833
6886
pc ++;
@@ -7811,6 +7864,10 @@ public List<StackMapFrame> traverse(
7811
7864
return filterFakeFrames (realJumpTarget , frames , codeLength );
7812
7865
}
7813
7866
7867
+ private void inspectFrame (int currentPC , StackMapFrame frame ) {
7868
+ // Plant a breakpoint at the call site to conveniently hover.
7869
+ }
7870
+
7814
7871
private StackMapFrame createNewFrame (int currentPC , StackMapFrame frame , boolean isClinit , MethodBinding methodBinding ) {
7815
7872
StackMapFrame newFrame = frame .duplicate ();
7816
7873
newFrame .pc = currentPC ;
0 commit comments