@@ -42,17 +42,17 @@ abstract class AbstractNoGuavaImmutableOf extends Recipe {
4242 "The default value is false." ,
4343 example = "true" ,
4444 required = false )
45- boolean isAbleToConvertReturnType ;
45+ Boolean convertReturnType ;
4646
4747 AbstractNoGuavaImmutableOf (String guavaType , String javaType ) {
4848 this .guavaType = guavaType ;
4949 this .javaType = javaType ;
5050 }
5151
52- AbstractNoGuavaImmutableOf (String guavaType , String javaType , boolean isAbleToConvertReturnType ) {
52+ AbstractNoGuavaImmutableOf (String guavaType , String javaType , boolean convertReturnType ) {
5353 this .guavaType = guavaType ;
5454 this .javaType = javaType ;
55- this .isAbleToConvertReturnType = isAbleToConvertReturnType ;
55+ this .convertReturnType = convertReturnType ;
5656 }
5757
5858 private String getShortType (String fullyQualifiedType ) {
@@ -80,6 +80,56 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
8080 new UsesType <>(guavaType , false ));
8181 final MethodMatcher IMMUTABLE_MATCHER = new MethodMatcher (guavaType + " of(..)" );
8282 return Preconditions .check (check , new JavaVisitor <ExecutionContext >() {
83+ @ Override
84+ public J .VariableDeclarations visitVariableDeclarations (J .VariableDeclarations multiVariable , ExecutionContext ctx ) {
85+ J .VariableDeclarations mv = (J .VariableDeclarations ) super .visitVariableDeclarations (multiVariable , ctx );
86+ if (!convertReturnType ) {
87+ return mv ;
88+ }
89+ if (multiVariable != mv && TypeUtils .isOfClassType (mv .getType (), guavaType )) {
90+ JavaType newType = JavaType .buildType (javaType );
91+ mv = mv .withTypeExpression (mv .getTypeExpression () == null ?
92+ null : createNewTypeExpression (mv .getTypeExpression (), newType ));
93+
94+ mv = mv .withVariables (ListUtils .map (mv .getVariables (), variable -> {
95+ JavaType .FullyQualified varType = TypeUtils .asFullyQualified (variable .getType ());
96+ if (varType != null && !varType .equals (newType )) {
97+ return variable .withType (newType ).withName (variable .getName ().withType (newType ));
98+ }
99+ return variable ;
100+ }));
101+ }
102+
103+ return mv ;
104+ }
105+
106+ private TypeTree createNewTypeExpression (TypeTree typeTree , JavaType newType ) {
107+ if (typeTree instanceof J .ParameterizedType ) {
108+ J .ParameterizedType parameterizedType = (J .ParameterizedType ) typeTree ;
109+ List <JRightPadded <Expression >> jRightPaddedList = new ArrayList <>();
110+ parameterizedType .getTypeParameters ().forEach (
111+ expression -> {
112+ if (expression instanceof J .ParameterizedType && TypeUtils .isOfClassType (expression .getType (), guavaType )) {
113+ jRightPaddedList .add (JRightPadded .build (((J .ParameterizedType ) createNewTypeExpression ((TypeTree ) expression , newType ))));
114+ } else {
115+ jRightPaddedList .add (JRightPadded .build (expression ));
116+ }
117+ });
118+ NameTree clazz = new J .Identifier (
119+ Tree .randomId (), Space .EMPTY , Markers .EMPTY , emptyList (), getShortType (javaType ), null , null );
120+ return parameterizedType .withClazz (clazz ).withType (newType ).getPadding ().withTypeParameters (JContainer .build (jRightPaddedList ));
121+ }
122+ return new J .Identifier (
123+ typeTree .getId (),
124+ typeTree .getPrefix (),
125+ Markers .EMPTY ,
126+ emptyList (),
127+ getShortType (javaType ),
128+ newType ,
129+ null
130+ );
131+ }
132+
83133 @ Override
84134 public J visitMethodInvocation (J .MethodInvocation method , ExecutionContext ctx ) {
85135 J .MethodInvocation mi = (J .MethodInvocation ) super .visitMethodInvocation (method , ctx );
@@ -170,61 +220,11 @@ private boolean isParentTypeDownCast(MethodCall immutableMethod) {
170220 return isParentTypeDownCast ;
171221 }
172222
173- @ Override
174- public J .VariableDeclarations visitVariableDeclarations (J .VariableDeclarations multiVariable , ExecutionContext ctx ) {
175- J .VariableDeclarations mv = (J .VariableDeclarations ) super .visitVariableDeclarations (multiVariable , ctx );
176- if (!isAbleToConvertReturnType ) {
177- return mv ;
178- }
179- if (multiVariable != mv && TypeUtils .isOfClassType (mv .getType (), guavaType )) {
180- JavaType newType = JavaType .buildType (javaType );
181- mv = mv .withTypeExpression (mv .getTypeExpression () == null ?
182- null : createNewTypeExpression (mv .getTypeExpression (), newType ));
183-
184- mv = mv .withVariables (ListUtils .map (mv .getVariables (), variable -> {
185- JavaType .FullyQualified varType = TypeUtils .asFullyQualified (variable .getType ());
186- if (varType != null && !varType .equals (newType )) {
187- return variable .withType (newType ).withName (variable .getName ().withType (newType ));
188- }
189- return variable ;
190- }));
191- }
192-
193- return mv ;
194- }
195-
196- private TypeTree createNewTypeExpression (TypeTree typeTree , JavaType newType ) {
197- if (typeTree instanceof J .ParameterizedType ) {
198- J .ParameterizedType parameterizedType = (J .ParameterizedType ) typeTree ;
199- List <JRightPadded <Expression >> jRightPaddedList = new ArrayList <>();
200- parameterizedType .getTypeParameters ().forEach (
201- expression -> {
202- if (expression instanceof J .ParameterizedType && TypeUtils .isOfClassType (expression .getType (), guavaType )) {
203- jRightPaddedList .add (JRightPadded .build (((J .ParameterizedType ) createNewTypeExpression ((TypeTree ) expression , newType ))));
204- } else {
205- jRightPaddedList .add (JRightPadded .build (expression ));
206- }
207- });
208- NameTree clazz = new J .Identifier (
209- Tree .randomId (), Space .EMPTY , Markers .EMPTY , emptyList (), getShortType (javaType ), null , null );
210- return parameterizedType .withClazz (clazz ).withType (newType ).getPadding ().withTypeParameters (JContainer .build (jRightPaddedList ));
211- }
212- return new J .Identifier (
213- typeTree .getId (),
214- typeTree .getPrefix (),
215- Markers .EMPTY ,
216- emptyList (),
217- getShortType (javaType ),
218- newType ,
219- null
220- );
221- }
222-
223223
224224 private boolean isParentTypeMatched (@ Nullable JavaType type ) {
225225 JavaType .FullyQualified fq = TypeUtils .asFullyQualified (type );
226226 return TypeUtils .isOfClassType (fq , javaType ) ||
227- (isAbleToConvertReturnType && TypeUtils .isOfClassType (fq , guavaType )) ||
227+ (convertReturnType && TypeUtils .isOfClassType (fq , guavaType )) ||
228228 TypeUtils .isOfClassType (fq , "java.lang.Object" );
229229 }
230230 });
0 commit comments