24
24
import org .openrewrite .java .*;
25
25
import org .openrewrite .java .search .UsesType ;
26
26
import org .openrewrite .java .tree .*;
27
+ import org .openrewrite .marker .Markers ;
27
28
28
29
import java .util .ArrayList ;
29
30
import java .util .List ;
30
31
import java .util .Objects ;
31
32
import java .util .Optional ;
32
33
import java .util .stream .Collectors ;
33
34
35
+ import static java .util .Collections .emptyList ;
36
+ import static org .openrewrite .Tree .randomId ;
37
+ import static org .openrewrite .java .trait .Traits .annotated ;
38
+
34
39
public class TemporaryFolderToTempDir extends Recipe {
35
40
36
41
@ Override
@@ -53,8 +58,12 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
53
58
54
59
class TemporaryFolderToTempDirVisitor extends JavaVisitor <ExecutionContext > {
55
60
56
- final AnnotationMatcher classRule = new AnnotationMatcher ("@org.junit.ClassRule" );
57
- final AnnotationMatcher rule = new AnnotationMatcher ("@org.junit.Rule" );
61
+ private static final String TEMPORARY_FOLDER = "org.junit.rules.TemporaryFolder" ;
62
+ private static final String TEMP_DIR = "org.junit.jupiter.api.io.TempDir" ;
63
+ private static final AnnotationMatcher CLASS_RULE = new AnnotationMatcher ("@org.junit.ClassRule" );
64
+ private static final AnnotationMatcher RULE = new AnnotationMatcher ("@org.junit.Rule" );
65
+ private static final MethodMatcher NEW_TEMPORARY_FOLDER = new MethodMatcher (TEMPORARY_FOLDER + "<constructor>()" );
66
+ private static final MethodMatcher NEW_TEMPORARY_FOLDER_WITH_ARG = new MethodMatcher (TEMPORARY_FOLDER + "<constructor>(java.io.File)" );
58
67
59
68
@ Override
60
69
public J visitCompilationUnit (J .CompilationUnit cu , ExecutionContext ctx ) {
@@ -64,6 +73,7 @@ public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
64
73
"org.junit.rules.TemporaryFolder" , "java.io.File" , true ).getVisitor ()
65
74
.visit (c , ctx );
66
75
maybeAddImport ("java.io.File" );
76
+ maybeAddImport ("java.nio.file.Files" );
67
77
maybeAddImport ("org.junit.jupiter.api.io.TempDir" );
68
78
maybeRemoveImport ("org.junit.ClassRule" );
69
79
maybeRemoveImport ("org.junit.Rule" );
@@ -75,30 +85,34 @@ public J visitCompilationUnit(J.CompilationUnit cu, ExecutionContext ctx) {
75
85
@ Override
76
86
public J visitVariableDeclarations (J .VariableDeclarations multiVariable , ExecutionContext ctx ) {
77
87
J .VariableDeclarations mv = (J .VariableDeclarations ) super .visitVariableDeclarations (multiVariable , ctx );
78
- if (!isRuleAnnotatedTemporaryFolder ( mv )) {
88
+ if (!TypeUtils . isOfClassType ( multiVariable . getTypeAsFullyQualified (), TEMPORARY_FOLDER )) {
79
89
return mv ;
80
90
}
81
- String fieldVars = mv .getVariables ().stream ()
82
- .map (fv -> fv .withInitializer (null ))
83
- .map (it -> it .print (getCursor ()))
84
- .collect (Collectors .joining ("," ));
85
- String modifiers = mv .getModifiers ().stream ().map (it -> it .getType ().name ().toLowerCase ()).collect (Collectors .joining (" " ));
86
- return JavaTemplate .builder ("@TempDir\n #{} File#{};" )
87
- .contextSensitive ()
88
- .imports ("java.io.File" , "org.junit.jupiter.api.io.TempDir" )
89
- .javaParser (JavaParser .fromJavaVersion ().classpathFromResources (ctx , "junit-jupiter-api-5" ))
90
- .build ()
91
- .apply (
92
- updateCursor (mv ),
93
- mv .getCoordinates ().replace (),
94
- modifiers ,
95
- fieldVars
96
- );
91
+ mv = mv .withTypeExpression (toFileIdentifier (mv .getTypeExpression ()));
92
+ return (J .VariableDeclarations ) annotated ("@org.junit.*Rule" )
93
+ .asVisitor (a -> JavaTemplate .builder ("@TempDir" )
94
+ .imports (TEMP_DIR )
95
+ .javaParser (JavaParser .fromJavaVersion ().classpathFromResources (ctx , "junit-jupiter-api-5" ))
96
+ .build ()
97
+ .apply (a .getCursor (), a .getTree ().getCoordinates ().replace ()))
98
+ .visitNonNull (mv , ctx , getCursor ().getParentOrThrow ());
97
99
}
98
100
99
- private boolean isRuleAnnotatedTemporaryFolder (J .VariableDeclarations vd ) {
100
- return TypeUtils .isOfClassType (vd .getTypeAsFullyQualified (), "org.junit.rules.TemporaryFolder" ) &&
101
- vd .getLeadingAnnotations ().stream ().anyMatch (anno -> classRule .matches (anno ) || rule .matches (anno ));
101
+ @ Override
102
+ public @ Nullable J visitNewClass (J .NewClass newClass , ExecutionContext ctx ) {
103
+ if (NEW_TEMPORARY_FOLDER .matches (newClass )) {
104
+ return hasRuleAnnotation () ? null : JavaTemplate .builder ("Files.createTempDirectory(\" junit\" ).toFile()" )
105
+ .imports ("java.nio.file.Files" )
106
+ .build ()
107
+ .apply (getCursor (), newClass .getCoordinates ().replace ());
108
+ }
109
+ if (NEW_TEMPORARY_FOLDER_WITH_ARG .matches (newClass )) {
110
+ return hasRuleAnnotation () ? null : JavaTemplate .builder ("Files.createTempDirectory(#{any(java.io.File)}.toPath(), \" junit\" ).toFile()" )
111
+ .imports ("java.nio.file.Files" )
112
+ .build ()
113
+ .apply (getCursor (), newClass .getCoordinates ().replace (), newClass .getArguments ().get (0 ));
114
+ }
115
+ return super .visitNewClass (newClass , ctx );
102
116
}
103
117
104
118
@ Override
@@ -125,6 +139,19 @@ private boolean isRuleAnnotatedTemporaryFolder(J.VariableDeclarations vd) {
125
139
return mi ;
126
140
}
127
141
142
+ private J .Identifier toFileIdentifier (TypeTree typeTree ) {
143
+ JavaType .ShallowClass fileType = JavaType .ShallowClass .build ("java.io.File" );
144
+ return new J .Identifier (randomId (), typeTree .getPrefix (), Markers .EMPTY , emptyList (), fileType .getClassName (), fileType , null );
145
+ }
146
+
147
+ private boolean hasRuleAnnotation () {
148
+ J .VariableDeclarations vd = getCursor ().firstEnclosing (J .VariableDeclarations .class );
149
+ if (vd == null ) {
150
+ return false ;
151
+ }
152
+ return vd .getLeadingAnnotations ().stream ().anyMatch (anno -> CLASS_RULE .matches (anno ) || RULE .matches (anno ));
153
+ }
154
+
128
155
private J convertToNewFile (J .MethodInvocation mi , ExecutionContext ctx ) {
129
156
if (mi .getSelect () == null ) {
130
157
return mi ;
0 commit comments