35
35
import java .util .Map ;
36
36
import java .util .Objects ;
37
37
import java .util .Optional ;
38
+ import java .util .concurrent .atomic .AtomicBoolean ;
38
39
39
40
import static org .openrewrite .java .migrate .lang .NullCheck .Matcher .nullCheck ;
40
41
import static org .openrewrite .java .tree .J .Block .createEmptyBlock ;
@@ -75,7 +76,9 @@ public J.Case visitCase(J.Case case_, ExecutionContext ctx) {
75
76
if (case_ .getBody () instanceof J .Block &&
76
77
((J .Block ) case_ .getBody ()).getStatements ().isEmpty () &&
77
78
!((J .Block ) case_ .getBody ()).getEnd ().isEmpty ()) {
78
- return case_ .withBody (((J .Block ) case_ .getBody ()).withEnd (Space .EMPTY ));
79
+ return case_ .withBody (((J .Block ) case_ .getBody ())
80
+ .withPrefix (Space .SINGLE_SPACE )
81
+ .withEnd (Space .EMPTY ));
79
82
}
80
83
return case_ .withBody (case_ .getBody ().withPrefix (Space .SINGLE_SPACE ));
81
84
}
@@ -100,6 +103,11 @@ private static class SwitchCandidate {
100
103
private SwitchCandidate (J .If if_ , Cursor cursor ) {
101
104
this .if_ = if_ ;
102
105
this .cursor = cursor ;
106
+ Cursor parent = cursor .getParent (2 );
107
+ if (parent == null || parent .getValue () instanceof J .If .Else ) {
108
+ potentialCandidate = false ;
109
+ return ;
110
+ }
103
111
J .If ifPart = if_ ;
104
112
while (potentialCandidate && ifPart != null ) {
105
113
if (ifPart .getIfCondition ().getTree () instanceof J .Binary ) {
@@ -157,6 +165,11 @@ private boolean validatePotentialCandidate() {
157
165
if (patternMatchers .keySet ().stream ().anyMatch (instanceOf -> instanceOf .getPattern () == null )) {
158
166
return false ;
159
167
}
168
+ // The blocks cannot do a return as that would lead to all blocks having to do a return,
169
+ // the block/expression difference in return for switch statements / expressions being different...
170
+ if (returns (nullCheckedStatement ) || patternMatchers .values ().stream ().anyMatch (this ::returns ) || returns (else_ )) {
171
+ return false ;
172
+ }
160
173
// Do no harm -> If we do not know how to replace(yet), do not replace
161
174
if (patternMatchers .keySet ().stream ().anyMatch (instanceOf -> {
162
175
J clazz = instanceOf .getClazz ();
@@ -173,6 +186,16 @@ private boolean validatePotentialCandidate() {
173
186
(hasLastElseBlock ? 1 : 0 );
174
187
}
175
188
189
+ private boolean returns (@ Nullable Statement statement ) {
190
+ return statement != null && new JavaIsoVisitor <AtomicBoolean >() {
191
+ @ Override
192
+ public J .Return visitReturn (J .Return return_ , AtomicBoolean atomicBoolean ) {
193
+ atomicBoolean .set (true );
194
+ return return_ ;
195
+ }
196
+ }.reduce (statement , new AtomicBoolean (false )).get ();
197
+ }
198
+
176
199
public J .@ Nullable Switch buildSwitchTemplate () {
177
200
Optional <Expression > switchOn = switchOn ();
178
201
if (!this .potentialCandidate || !switchOn .isPresent ()) {
@@ -183,36 +206,20 @@ private boolean validatePotentialCandidate() {
183
206
StringBuilder switchBody = new StringBuilder ("switch (#{any()}) {\n " );
184
207
int i = 1 ;
185
208
if (nullCheckedParameter != null ) {
186
- Statement statement = getStatement (Objects .requireNonNull (nullCheckedStatement ));
187
- if (statement instanceof J .Block ) {
188
- switchBody .append ("case null -> #{}\n " );
189
- } else {
190
- switchBody .append ("case null -> #{any()};\n " );
191
- }
192
- arguments [i ++] = statement ;
209
+ switchBody .append ("case null -> #{any()};\n " );
210
+ arguments [i ++] = getStatement (Objects .requireNonNull (nullCheckedStatement ));
193
211
}
194
212
for (Map .Entry <J .InstanceOf , Statement > entry : patternMatchers .entrySet ()) {
195
213
J .InstanceOf instanceOf = entry .getKey ();
196
- Statement statement = getStatement (entry .getValue ());
197
- if (statement instanceof J .Block ) {
198
- switchBody .append ("case #{}#{} -> #{}\n " );
199
- } else {
200
- switchBody .append ("case #{}#{} -> #{any()};\n " );
201
- }
214
+ switchBody .append ("case #{}#{} -> #{any()};\n " );
202
215
arguments [i ++] = getClassName (instanceOf );
203
216
arguments [i ++] = getPattern (instanceOf );
204
- arguments [i ++] = statement ;
217
+ arguments [i ++] = getStatement ( entry . getValue ()) ;
205
218
}
219
+ switchBody .append ("default -> #{any()};\n " );
206
220
if (else_ != null ) {
207
- Statement statement = getStatement (else_ );
208
- if (statement instanceof J .Block ) {
209
- switchBody .append ("default -> #{}\n " );
210
- } else {
211
- switchBody .append ("default -> #{any()};\n " );
212
- }
213
- arguments [i ] = statement ;
221
+ arguments [i ] = getStatement (else_ );
214
222
} else {
215
- switchBody .append ("default -> #{}\n " );
216
223
arguments [i ] = createEmptyBlock ();
217
224
}
218
225
switchBody .append ("}\n " );
@@ -243,11 +250,13 @@ private String getPattern(J.InstanceOf statement) {
243
250
}
244
251
245
252
private Statement getStatement (Statement statement ) {
246
- Statement toAdd = statement ;
247
253
if (statement instanceof J .Block && ((J .Block ) statement ).getStatements ().size () == 1 ) {
248
- toAdd = ((J .Block ) statement ).getStatements ().get (0 );
254
+ Statement firstStatement = ((J .Block ) statement ).getStatements ().get (0 );
255
+ if (firstStatement instanceof Expression || firstStatement instanceof J .Throw ) {
256
+ return firstStatement ;
257
+ }
249
258
}
250
- return toAdd ;
259
+ return statement ;
251
260
}
252
261
}
253
262
}
0 commit comments