@@ -456,109 +456,24 @@ private J.EnumValue visitEnumField(FieldNode field) {
456456 if (sourceStartsWith ("(" )) {
457457 Space prefixNewClass = whitespace ();
458458 skip ("(" );
459-
460- // The Groovy AST does not list the enum constructor arguments anywhere, thus first get the arguments as string
461- int start = cursor ;
462- int argCount = 0 ;
463- int depth = 0 ;
464- cursor = indexOfNextNonWhitespace (cursor , source );
465- // Check if there are any arguments at all
466- if (source .charAt (cursor ) != ')' ) {
467- argCount = 1 ; // Start with 1 since there's at least one argument
468- }
469- while (!(source .charAt (cursor ) == ')' && depth == 0 )) {
470- int cursorBeforeIteration = cursor ;
471-
472- Delimiter delimiter = getDelimiter (null , cursor );
473- if (delimiter != null ) {
474- cursor += delimiter .open .length ();
475- if ("\" " .equals (delimiter .close )) {
476- // This is to prevent sourceBefore interpreting // in strings as comments
477- cursor = source .indexOf ("\" " , cursor ) + 1 ;
478- while (source .charAt (cursor - 2 ) == '\\' ) {
479- cursor = source .indexOf ("\" " , cursor ) + 1 ;
480- }
481- } else {
482- sourceBefore (delimiter .close );
483- }
484- } else {
485- name ();
486- // Check for named argument syntax (colon after name)
487- cursor = indexOfNextNonWhitespace (cursor , source );
488- if (source .charAt (cursor ) == ':' ) {
489- cursor ++; // Skip the colon
490- cursor = indexOfNextNonWhitespace (cursor , source );
491- // Parse the value after the colon
492- delimiter = getDelimiter (null , cursor );
493- if (delimiter != null ) {
494- cursor += delimiter .open .length ();
495- if ("\" " .equals (delimiter .close )) {
496- cursor = source .indexOf ("\" " , cursor ) + 1 ;
497- while (source .charAt (cursor - 2 ) == '\\' ) {
498- cursor = source .indexOf ("\" " , cursor ) + 1 ;
499- }
500- } else {
501- sourceBefore (delimiter .close );
502- }
503- } else {
504- name ();
505- }
506- }
507- }
508- cursor = indexOfNextNonWhitespace (cursor , source );
509- skip ("," );
510- cursor = indexOfNextNonWhitespace (cursor , source );
511- if (source .charAt (cursor ) == '(' ) {
512- depth ++;
513- cursor ++;
514- } else if (depth > 0 && source .charAt (cursor ) == ')' ) {
515- depth --;
516- cursor ++;
517- }
518- if (cursor == cursorBeforeIteration ) {
519- // We are not facing an opening of a new parens/delimiter, no whitespace, just a usual piece of code - e.g. an operator like `+`.
520- // As we are not parsing it, just grabing the code into a String, it's safe to advance.
459+ RewriteGroovyVisitor visitor = new RewriteGroovyVisitor (field , this );
460+ ListExpression arguments = (ListExpression ) field .getInitialExpression ();
461+ List <JRightPadded <Expression >> list = visitor .convertAll (arguments .getExpressions (), n -> sourceBefore ("," ), n -> whitespace (), n -> {
462+ if (n == arguments .getExpression (arguments .getExpressions ().size () - 1 ) && source .charAt (cursor ) == ',' ) {
521463 cursor ++;
522- } else {
523- argCount ++;
464+ return Markers .build (singleton (new TrailingComma (randomId (), whitespace ())));
524465 }
525- }
526- String argsAsString = source . substring ( start , cursor );
466+ return Markers . EMPTY ;
467+ } );
527468 skip (")" );
528469
529- // ... then grab the constructor arguments ...
530- StringBuilder constructorDeclarationArgs = new StringBuilder ();
531- ConstructorNode ctor = null ;
532- for (ConstructorNode node : field .getDeclaringClass ().getDeclaredConstructors ()) {
533- if ((node .getParameters ().length - 2 ) == argCount ) {
534- ctor = node ;
535- break ;
470+ MethodNode ctor = null ;
471+ for (ConstructorNode constructor : field .getOwner ().getDeclaredConstructors ()) {
472+ if (constructor .getParameters ().length == arguments .getExpressions ().size ()) {
473+ ctor = constructor ;
536474 }
537475 }
538- if (ctor != null ) {
539- for (int i = 2 ; i < ctor .getParameters ().length ; i ++) {
540- Parameter param = ctor .getParameters ()[i ];
541- if (i != 2 ) {
542- constructorDeclarationArgs .append (", " );
543- }
544- constructorDeclarationArgs .append (param .getType ().getName ()).append (" " ).append (param .getName ());
545- }
546- }
547-
548- // ... and use the information in a small class to get the constructor invocation arguments anyway
549- G .CompilationUnit cu = (G .CompilationUnit ) GroovyParser .builder ().build ()
550- .parse ("class A {\n " +
551- " A(" + constructorDeclarationArgs + ") {}\n " +
552- " def use() {\n " +
553- " new A(" + argsAsString + ")\n " +
554- " }\n " +
555- "}" )
556- .findFirst ().get ();
557-
558- JContainer <Expression > args = ((J .NewClass ) (((J .Return ) ((J .MethodDeclaration ) ((J .ClassDeclaration ) cu .getStatements ().get (0 )).getBody ().getStatements ().get (1 )).getBody ().getStatements ().get (0 )).getExpression ()))
559- .getPadding ().getArguments ();
560-
561- initializer = new J .NewClass (randomId (), prefixNewClass , Markers .EMPTY , null , EMPTY , null , args , null , typeMapping .methodType (ctor ));
476+ initializer = new J .NewClass (randomId (), prefixNewClass , Markers .EMPTY , null , EMPTY , null , JContainer .build (list ), null , typeMapping .methodType (ctor ));
562477 }
563478
564479 return new J .EnumValue (randomId (), prefix , Markers .EMPTY , annotations , name , initializer );
@@ -2351,7 +2266,7 @@ public TypeTree visitVariableExpressionType(@Nullable VariableExpression express
23512266
23522267 if (!expression .isDynamicTyped () && source .startsWith (expression .getOriginType ().getUnresolvedName (), cursor )) {
23532268 if (cursor + expression .getOriginType ().getUnresolvedName ().length () < source .length () &&
2354- !Character . isJavaIdentifierPart (source .charAt (cursor + expression .getOriginType ().getUnresolvedName ().length ()))) {
2269+ !isJavaIdentifierPart (source .charAt (cursor + expression .getOriginType ().getUnresolvedName ().length ()))) {
23552270 typeName = expression .getOriginType ().getUnresolvedName ();
23562271 skip (typeName );
23572272 }
0 commit comments