1616package org .openrewrite .java .migrate .lang .var ;
1717
1818import java .util .ArrayList ;
19+ import java .util .Collections ;
1920import java .util .List ;
20- import java .util .Objects ;
21- import java .util .stream .Collectors ;
2221
22+ import org .jetbrains .annotations .NotNull ;
2323import org .openrewrite .*;
24+ import org .openrewrite .internal .StringUtils ;
2425import org .openrewrite .internal .lang .Nullable ;
2526import org .openrewrite .java .JavaIsoVisitor ;
2627import org .openrewrite .java .JavaParser ;
@@ -73,11 +74,11 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v
7374 if (rightTypes == null || (leftTypes .isEmpty () && rightTypes .isEmpty ())) return vd ;
7475
7576 // skip generics with type bounds, it's not yet implemented
76- boolean genericHasBounds = leftTypes . stream ()
77- . filter ( t -> t instanceof JavaType . GenericTypeVariable )
78- . map ( t -> ( JavaType . GenericTypeVariable ) t )
79- . map ( t -> ! t . getBounds (). isEmpty ())
80- . reduce ( false , Boolean :: logicalOr );
77+ for ( JavaType type : leftTypes ) {
78+ if ( hasBounds ( type ) )
79+ return vd ;
80+ }
81+ boolean genericHasBounds = anyTypeHasBounds ( leftTypes );
8182 if (genericHasBounds ) return vd ;
8283
8384 // mark imports for removal if unused
@@ -86,6 +87,25 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v
8687 return transformToVar (vd , leftTypes , rightTypes );
8788 }
8889
90+ @ NotNull
91+ private static Boolean anyTypeHasBounds (List <JavaType > leftTypes ) {
92+ for (JavaType type : leftTypes ) {
93+ if (hasBounds (type ))
94+ return true ;
95+ }
96+ return false ;
97+ }
98+
99+ private static boolean hasBounds (JavaType type ) {
100+ if (type instanceof JavaType .Parameterized ) {
101+ return anyTypeHasBounds (((JavaType .Parameterized ) type ).getTypeParameters ());
102+ }
103+ if (type instanceof JavaType .GenericTypeVariable ) {
104+ return !((JavaType .GenericTypeVariable ) type ).getBounds ().isEmpty ();
105+ }
106+ return false ;
107+ }
108+
89109 /**
90110 * Tries to extract the generic parameters from the expression,
91111 * if the Initializer is no new class or not of a parameterized type, returns null to signale "no info".
@@ -98,15 +118,16 @@ public J.VariableDeclarations visitVariableDeclarations(J.VariableDeclarations v
98118 TypeTree clazz = ((J .NewClass ) initializer ).getClazz ();
99119 if (clazz instanceof J .ParameterizedType ) {
100120 List <Expression > typeParameters = ((J .ParameterizedType ) clazz ).getTypeParameters ();
121+ List <JavaType > params = new ArrayList <>();
101122 if (typeParameters != null ) {
102- return typeParameters
103- .stream ()
104- .map (Expression ::getType )
105- .filter (Objects ::nonNull )
106- .collect (Collectors .toList ());
107- } else {
108- return new ArrayList <>();
123+ for (Expression curType : typeParameters ) {
124+ JavaType type = curType .getType ();
125+ if (type != null ) {
126+ params .add (type );
127+ }
128+ }
109129 }
130+ return params ;
110131 }
111132 }
112133 return null ;
@@ -133,13 +154,14 @@ private J.VariableDeclarations transformToVar(J.VariableDeclarations vd, List<Ja
133154 // if left is defined but not right, copy types to initializer
134155 if (rightTypes .isEmpty () && !leftTypes .isEmpty ()) {
135156 // we need to switch type infos from left to right here
136- List <Expression > typeArgument = leftTypes .stream ()
137- .map (UseVarForGenericsConstructorsVisitor ::typeToExpression )
138- .collect (Collectors .toList ());
157+ List <Expression > typeExpressions = new ArrayList <>();
158+ for (JavaType curType : leftTypes ) {
159+ typeExpressions .add (typeToExpression (curType ));
160+ }
139161
140162 J .ParameterizedType typedInitializerClazz = ((J .ParameterizedType ) ((J .NewClass ) initializer )
141163 .getClazz ())
142- .withTypeParameters (typeArgument );
164+ .withTypeParameters (typeExpressions );
143165 initializer = ((J .NewClass ) initializer ).withClazz (typedInitializerClazz );
144166 }
145167
@@ -169,10 +191,20 @@ private J.VariableDeclarations transformToVar(J.VariableDeclarations vd, List<Ja
169191 * @return semantically equal Expression
170192 */
171193 private static Expression typeToExpression (JavaType type ) {
172- if (type instanceof JavaType .Class ) { // easy just parse to identifier
194+ if (type instanceof JavaType .Primitive ) {
195+ JavaType .Primitive primitiveType = JavaType .Primitive .fromKeyword (((JavaType .Primitive ) type ).getKeyword ());
196+ return new J .Primitive (Tree .randomId (), Space .EMPTY , Markers .EMPTY , primitiveType );
197+ }
198+ if (type instanceof JavaType .Class ) {
173199 String className = ((JavaType .Class ) type ).getClassName ();
174200 return new J .Identifier (Tree .randomId (), Space .EMPTY , Markers .EMPTY , className , type , null );
175201 }
202+ if (type instanceof JavaType .Array ){
203+ int dimensions = StringUtils .countOccurrences (type .toString (), "[]" );
204+ List <JRightPadded <Space >> dimensionsDefinition = Collections .nCopies (dimensions , JRightPadded .build (Space .EMPTY ));
205+ TypeTree elemType = (TypeTree ) typeToExpression (((JavaType .Array ) type ).getElemType ());
206+ return new J .ArrayType (Tree .randomId (), Space .EMPTY , Markers .EMPTY , elemType , dimensionsDefinition );
207+ }
176208 if (type instanceof JavaType .GenericTypeVariable ) {
177209 String variableName = ((JavaType .GenericTypeVariable ) type ).getName ();
178210 J .Identifier identifier = new J .Identifier (Tree .randomId (), Space .EMPTY , Markers .EMPTY , variableName , type , null );
@@ -193,13 +225,15 @@ private static Expression typeToExpression(JavaType type) {
193225 }
194226 }
195227 if (type instanceof JavaType .Parameterized ) { // recursively parse
196- List <JRightPadded <Expression >> typeParams = ((JavaType .Parameterized ) type ).getTypeParameters ().stream ()
197- .map (UseVarForGenericsConstructorsVisitor ::typeToExpression )
198- .map (JRightPadded ::build )
199- .collect (Collectors .toList ());
228+ List <JavaType > typeParameters = ((JavaType .Parameterized ) type ).getTypeParameters ();
229+
230+ List <JRightPadded <Expression >> typeParamsExpression = new ArrayList <>(typeParameters .size ());
231+ for (JavaType curType : typeParameters ) {
232+ typeParamsExpression .add (JRightPadded .build (typeToExpression (curType )));
233+ }
200234
201235 NameTree clazz = new J .Identifier (Tree .randomId (), Space .EMPTY , Markers .EMPTY , ((JavaType .Parameterized ) type ).getClassName (),null , null );
202- return new J .ParameterizedType (Tree .randomId (), Space .EMPTY , Markers .EMPTY , clazz , JContainer .build (typeParams ), type );
236+ return new J .ParameterizedType (Tree .randomId (), Space .EMPTY , Markers .EMPTY , clazz , JContainer .build (typeParamsExpression ), type );
203237 }
204238
205239 throw new IllegalArgumentException (String .format ("Unable to parse expression from JavaType %s" , type ));
0 commit comments