6363import org .eclipse .jdt .internal .compiler .problem .ProblemReporter ;
6464import org .eclipse .jdt .internal .compiler .problem .ProblemSeverities ;
6565import org .eclipse .jdt .internal .compiler .problem .ShouldNotImplement ;
66+ import org .eclipse .jdt .internal .compiler .tool .EclipseCompiler ;
6667import org .eclipse .jdt .internal .compiler .util .Messages ;
6768import org .eclipse .jdt .internal .compiler .util .Util ;
6869
@@ -549,6 +550,13 @@ private RecordComponent getRecordComponent(ReferenceBinding declaringClass, char
549550 }
550551 return null ;
551552 }
553+ private RecordComponent [] getRecordComponents (ReferenceBinding declaringClass ) {
554+ RecordComponentBinding [] rcbs = declaringClass .components ();
555+ RecordComponent [] recordComponents = new RecordComponent [rcbs .length ];
556+ for (int i = 0 , length = rcbs .length ; i < length ; i ++)
557+ recordComponents [i ] = rcbs [i ].sourceRecordComponent ();
558+ return recordComponents ;
559+ }
552560 private int addComponentAttributes (RecordComponentBinding recordComponentBinding , int componetAttributeOffset ) {
553561 // See JVMS 14 Table 4.7-C - Record Preview for allowed attributes
554562 int attributesNumber = 0 ;
@@ -1115,9 +1123,7 @@ private void addSyntheticRecordCanonicalConstructor(TypeDeclaration typeDecl, Sy
11151123 .referenceCompilationUnit ()
11161124 .compilationResult
11171125 .getLineSeparatorPositions ());
1118- // update the number of attributes
1119- this .contents [methodAttributeOffset ++] = (byte ) (attributeNumber >> 8 );
1120- this .contents [methodAttributeOffset ] = (byte ) attributeNumber ;
1126+ completeMethodInfo (methodBinding , methodAttributeOffset , attributeNumber );
11211127 }
11221128
11231129 private void addSyntheticRecordOverrideMethods (TypeDeclaration typeDecl , SyntheticMethodBinding methodBinding , int purpose ) {
@@ -2313,9 +2319,9 @@ public void completeCodeAttributeForSyntheticMethod(
23132319 ((SourceTypeBinding ) binding .declaringClass ).scope );
23142320 }
23152321
2316- private void completeArgumentAnnotationInfo (Argument [] arguments , List <AnnotationContext > allAnnotationContexts ) {
2322+ private void completeArgumentAnnotationInfo (AbstractVariableDeclaration [] arguments , List <AnnotationContext > allAnnotationContexts ) {
23172323 for (int i = 0 , max = arguments .length ; i < max ; i ++) {
2318- Argument argument = arguments [i ];
2324+ AbstractVariableDeclaration argument = arguments [i ];
23192325 if ((argument .bits & ASTNode .HasTypeAnnotations ) != 0 ) {
23202326 argument .getAllAnnotationContexts (AnnotationTargetTypeConstants .METHOD_FORMAL_PARAMETER , i , allAnnotationContexts );
23212327 }
@@ -2376,6 +2382,9 @@ public void completeMethodInfo(
23762382 }
23772383 }
23782384 }
2385+ } else if (binding instanceof SyntheticMethodBinding syntheticMethod && syntheticMethod .isCanonicalConstructor ()) {
2386+ AbstractVariableDeclaration [] parameters = getRecordComponents (syntheticMethod .declaringClass );
2387+ completeArgumentAnnotationInfo (parameters , allTypeAnnotationContexts );
23792388 } else if (binding .sourceLambda () != null ) { // SyntheticMethodBinding, purpose : LambdaMethod.
23802389 LambdaExpression lambda = binding .sourceLambda ();
23812390 if ((lambda .bits & ASTNode .HasTypeAnnotations ) != 0 ) {
@@ -4173,7 +4182,7 @@ private int generateLocalVariableTableAttribute(int code_length, boolean methodD
41734182 LocalVariableBinding localVariable = this .codeStream .locals [i ];
41744183 int initializationCount = localVariable .initializationCount ;
41754184 if (initializationCount == 0 ) continue ;
4176- if (localVariable .declaration == null ) continue ;
4185+ if (localVariable .declaration == null && !( localVariable . declaringScope != null && localVariable . declaringScope . referenceContext () instanceof ConstructorDeclaration cd && cd . isCompactConstructor ()) ) continue ;
41774186 final TypeBinding localVariableTypeBinding = localVariable .type ;
41784187 boolean isParameterizedType = localVariableTypeBinding .isParameterizedType () || localVariableTypeBinding .isTypeVariable ();
41794188 if (isParameterizedType ) {
@@ -4335,15 +4344,13 @@ public int generateMethodInfoAttributes(MethodBinding methodBinding) {
43354344 attributesNumber += generateSignatureAttribute (genericSignature );
43364345 }
43374346 AbstractMethodDeclaration methodDeclaration = methodBinding .sourceMethod ();
4338- if (methodBinding instanceof SyntheticMethodBinding ) {
4339- SyntheticMethodBinding syntheticMethod = (SyntheticMethodBinding ) methodBinding ;
4347+ if (methodBinding instanceof SyntheticMethodBinding syntheticMethod ) {
43404348 if (syntheticMethod .purpose == SyntheticMethodBinding .BridgeMethod
43414349 || (syntheticMethod .purpose == SyntheticMethodBinding .SuperMethodAccess
43424350 && CharOperation .equals (syntheticMethod .selector , syntheticMethod .targetMethod .selector ))) {
43434351 methodDeclaration = ((SyntheticMethodBinding ) methodBinding ).targetMethod .sourceMethod ();
43444352 }
43454353 if (syntheticMethod .recordComponentBinding != null ) {
4346- assert methodDeclaration == null ;
43474354 long rcMask = TagBits .AnnotationForMethod | TagBits .AnnotationForTypeUse ;
43484355 // record component (field) accessor method
43494356 ReferenceBinding declaringClass = methodBinding .declaringClass ;
@@ -4370,6 +4377,9 @@ public int generateMethodInfoAttributes(MethodBinding methodBinding) {
43704377 () -> allTypeAnnotationContexts );
43714378 }
43724379 }
4380+ } else if (syntheticMethod .isCanonicalConstructor ()) {
4381+ AbstractVariableDeclaration [] parameters = getRecordComponents (syntheticMethod .declaringClass );
4382+ attributesNumber += generateRuntimeAnnotationsForParameters (parameters );
43734383 }
43744384 }
43754385 if (methodDeclaration != null ) {
@@ -4378,9 +4388,9 @@ public int generateMethodInfoAttributes(MethodBinding methodBinding) {
43784388 attributesNumber += generateRuntimeAnnotations (annotations , methodBinding .isConstructor () ? TagBits .AnnotationForConstructor : TagBits .AnnotationForMethod );
43794389 }
43804390 if ((methodBinding .tagBits & TagBits .HasParameterAnnotations ) != 0 ) {
4381- Argument [] arguments = methodDeclaration .arguments ;
4391+ AbstractVariableDeclaration [] arguments = methodBinding .isCompactConstructor () ?
4392+ getRecordComponents (methodBinding .declaringClass ) : methodDeclaration .arguments ;
43824393 if (arguments != null ) {
4383- propagateRecordComponentArguments (methodDeclaration );
43844394 attributesNumber += generateRuntimeAnnotationsForParameters (arguments );
43854395 }
43864396 }
@@ -4434,26 +4444,6 @@ private int completeRuntimeTypeAnnotations(int attributesNumber,
44344444 }
44354445 return attributesNumber ;
44364446 }
4437- private void propagateRecordComponentArguments (AbstractMethodDeclaration methodDeclaration ) {
4438- if ((methodDeclaration .bits & ASTNode .IsImplicit ) == 0 )
4439- return ;
4440- ReferenceBinding declaringClass = methodDeclaration .binding .declaringClass ;
4441- if (declaringClass instanceof SourceTypeBinding ) {
4442- assert declaringClass .isRecord ();
4443- RecordComponentBinding [] rcbs = ((SourceTypeBinding ) declaringClass ).components ();
4444- Argument [] arguments = methodDeclaration .arguments ;
4445- for (int i = 0 , length = rcbs .length ; i < length ; i ++) {
4446- RecordComponentBinding rcb = rcbs [i ];
4447- RecordComponent recordComponent = rcb .sourceRecordComponent ();
4448- if ((recordComponent .bits & ASTNode .HasTypeAnnotations ) != 0 ) {
4449- methodDeclaration .bits |= ASTNode .HasTypeAnnotations ;
4450- arguments [i ].bits |= ASTNode .HasTypeAnnotations ;
4451- }
4452- long rcMask = TagBits .AnnotationForParameter | TagBits .AnnotationForTypeUse ;
4453- arguments [i ].annotations = ASTNode .getRelevantAnnotations (recordComponent .annotations , rcMask , null );
4454- }
4455- }
4456- }
44574447
44584448 public int generateMethodInfoAttributes (MethodBinding methodBinding , AnnotationMethodDeclaration declaration ) {
44594449 int attributesNumber = generateMethodInfoAttributes (methodBinding );
@@ -4769,15 +4759,15 @@ private int generateRuntimeAnnotations(final Annotation[] annotations, final lon
47694759 return attributesNumber ;
47704760 }
47714761
4772- private int generateRuntimeAnnotationsForParameters (Argument [] arguments ) {
4762+ private int generateRuntimeAnnotationsForParameters (AbstractVariableDeclaration [] arguments ) {
47734763 final int argumentsLength = arguments .length ;
47744764 final int VISIBLE_INDEX = 0 ;
47754765 final int INVISIBLE_INDEX = 1 ;
47764766 int invisibleParametersAnnotationsCounter = 0 ;
47774767 int visibleParametersAnnotationsCounter = 0 ;
47784768 int [][] annotationsCounters = new int [argumentsLength ][2 ];
47794769 for (int i = 0 ; i < argumentsLength ; i ++) {
4780- Argument argument = arguments [i ];
4770+ AbstractVariableDeclaration argument = arguments [i ];
47814771 Annotation [] annotations = argument .annotations ;
47824772 if (annotations != null ) {
47834773 for (Annotation a : annotations ) {
@@ -4824,7 +4814,7 @@ private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
48244814 this .contentsOffset += 2 ;
48254815 int counter = 0 ;
48264816 if (numberOfInvisibleAnnotations != 0 ) {
4827- Argument argument = arguments [i ];
4817+ AbstractVariableDeclaration argument = arguments [i ];
48284818 Annotation [] annotations = argument .annotations ;
48294819 for (Annotation a : annotations ) {
48304820 Annotation annotation ;
@@ -4885,7 +4875,7 @@ private int generateRuntimeAnnotationsForParameters(Argument[] arguments) {
48854875 this .contentsOffset += 2 ;
48864876 int counter = 0 ;
48874877 if (numberOfVisibleAnnotations != 0 ) {
4888- Argument argument = arguments [i ];
4878+ AbstractVariableDeclaration argument = arguments [i ];
48894879 Annotation [] annotations = argument .annotations ;
48904880 for (Annotation a : annotations ) {
48914881 Annotation annotation ;
@@ -5039,6 +5029,7 @@ private int generateMethodParameters(final MethodBinding binding) {
50395029 AbstractMethodDeclaration methodDeclaration = binding .sourceMethod ();
50405030
50415031 boolean isConstructor = binding .isConstructor ();
5032+ boolean isCanonicalConstructor = binding .isCanonicalConstructor ();
50425033 TypeBinding [] targetParameters = binding .parameters ;
50435034 ReferenceBinding declaringClass = binding .declaringClass ;
50445035
@@ -5053,7 +5044,8 @@ private int generateMethodParameters(final MethodBinding binding) {
50535044 }
50545045 }
50555046
5056- boolean needSynthetics = isConstructor && declaringClass .isNestedType ();
5047+ boolean needSynthetics = isCanonicalConstructor ? false : // WYSIWYG
5048+ isConstructor && !isCanonicalConstructor && declaringClass .isNestedType ();
50575049 if (needSynthetics ) {
50585050 // Take into account the synthetic argument names
50595051 // This tracks JLS8, paragraph 8.8.9
@@ -5081,19 +5073,31 @@ private int generateMethodParameters(final MethodBinding binding) {
50815073 }
50825074 }
50835075 if (targetParameters != Binding .NO_PARAMETERS ) {
5084- Argument [] arguments = null ;
5085- if (methodDeclaration != null && methodDeclaration .arguments != null ) {
5086- arguments = methodDeclaration .arguments ;
5087- }
5088- for (int i = 0 , max = targetParameters .length , argumentsLength = arguments != null ? arguments .length : 0 ; i < max ; i ++) {
5089- if (argumentsLength > i && arguments [i ] != null ) {
5090- Argument argument = arguments [i ];
5091- int modifiers = argument .binding .modifiers ;
5092- if (binding .isCompactConstructor ())
5093- modifiers |= ClassFileConstants .AccMandated ;
5094- length = writeArgumentName (argument .name , modifiers , length );
5095- } else {
5096- length = writeArgumentName (null , ClassFileConstants .AccSynthetic , length );
5076+ if (binding .isCompactConstructor ()) {
5077+ LocalVariableBinding [] locals = binding .sourceMethod ().scope .locals ;
5078+ for (LocalVariableBinding local : locals ) {
5079+ if (local == null || !local .isParameter ())
5080+ continue ;
5081+ int modifiers = local .modifiers | ClassFileConstants .AccMandated ;
5082+ length = writeArgumentName (local .name , modifiers , length );
5083+ }
5084+ } else if (binding .isCanonicalConstructor () && methodDeclaration == null ) { // synthetic
5085+ for (RecordComponentBinding component : binding .declaringClass .components ()) {
5086+ length = writeArgumentName (component .name , ClassFileConstants .AccDefault , length );
5087+ }
5088+ } else {
5089+ Argument [] arguments = null ;
5090+ if (methodDeclaration != null && methodDeclaration .arguments != null ) {
5091+ arguments = methodDeclaration .arguments ;
5092+ }
5093+ for (int i = 0 , max = targetParameters .length , argumentsLength = arguments != null ? arguments .length : 0 ; i < max ; i ++) {
5094+ if (argumentsLength > i && arguments [i ] != null ) {
5095+ Argument argument = arguments [i ];
5096+ int modifiers = argument .binding .modifiers ;
5097+ length = writeArgumentName (argument .name , modifiers , length );
5098+ } else {
5099+ throw EclipseCompiler .UNEXPECTED_CONTROL_FLOW ;
5100+ }
50975101 }
50985102 }
50995103 }
0 commit comments