@@ -98,65 +98,103 @@ public function indexAction()
98
98
*/
99
99
public function getNodeTypes (): array
100
100
{
101
- return [ClassMethod::class, Class_::class];
101
+ return [Class_::class];
102
102
}
103
103
104
104
/**
105
- * @param Class_|ClassMethod $node
105
+ * @param Class_ $node
106
106
*/
107
107
public function refactor (Node $ node ): ?Node
108
108
{
109
- if ($ node instanceof Class_ ) {
110
- return $ this -> addAbstractControllerParentClassIfMissing ( $ node ) ;
109
+ if (! $ this -> annotationAnalyzer -> hasClassMethodWithTemplateAnnotation ( $ node) ) {
110
+ return null ;
111
111
}
112
112
113
- return $ this ->replaceTemplateAnnotation ($ node );
114
- }
113
+ $ this ->decorateAbstractControllerParentClass ($ node );
115
114
116
- private function addAbstractControllerParentClassIfMissing (Class_ $ class ): ?Class_
117
- {
118
- if ($ class ->extends instanceof Name) {
119
- return null ;
115
+ $ hasChanged = false ;
116
+
117
+ $ classDoctrineAnnotationTagValueNode = $ this ->annotationAnalyzer ->getDoctrineAnnotationTagValueNode (
118
+ $ node ,
119
+ SymfonyAnnotation::TEMPLATE
120
+ );
121
+
122
+ foreach ($ node ->getMethods () as $ classMethod ) {
123
+ if (! $ classMethod ->isPublic ()) {
124
+ continue ;
125
+ }
126
+
127
+ $ hasClassMethodChanged = $ this ->replaceTemplateAnnotation (
128
+ $ classMethod ,
129
+ $ classDoctrineAnnotationTagValueNode
130
+ );
131
+ if ($ hasClassMethodChanged ) {
132
+ $ hasChanged = true ;
133
+ }
120
134
}
121
135
122
- if (! $ this -> annotationAnalyzer -> hasClassMethodWithTemplateAnnotation ( $ class ) ) {
136
+ if (! $ hasChanged ) {
123
137
return null ;
124
138
}
125
139
126
- $ class ->extends = new FullyQualified ('Symfony\Bundle\FrameworkBundle\Controller\AbstractController ' );
140
+ // cleanup Class_ @Template annotaion
141
+ if ($ classDoctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
142
+ $ this ->removeDoctrineAnnotationTagValueNode ($ node , $ classDoctrineAnnotationTagValueNode );
143
+ }
127
144
128
- return $ class ;
145
+ return $ node ;
129
146
}
130
147
131
- private function replaceTemplateAnnotation ( ClassMethod $ classMethod ): ? ClassMethod
148
+ private function decorateAbstractControllerParentClass ( Class_ $ class ): void
132
149
{
150
+ if ($ class ->extends instanceof Name) {
151
+ return ;
152
+ }
153
+
154
+ // this will make $this->render() method available
155
+ $ class ->extends = new FullyQualified ('Symfony\Bundle\FrameworkBundle\Controller\AbstractController ' );
156
+ }
157
+
158
+ private function replaceTemplateAnnotation (
159
+ ClassMethod $ classMethod ,
160
+ ?DoctrineAnnotationTagValueNode $ classDoctrineAnnotationTagValueNode
161
+ ): bool {
133
162
if (! $ classMethod ->isPublic ()) {
134
- return null ;
163
+ return false ;
135
164
}
136
165
137
166
$ doctrineAnnotationTagValueNode = $ this ->annotationAnalyzer ->getDoctrineAnnotationTagValueNode (
138
167
$ classMethod ,
139
168
SymfonyAnnotation::TEMPLATE
140
169
);
141
170
142
- if (! $ doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
143
- return null ;
171
+ if ($ doctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
172
+ return $ this -> refactorClassMethod ( $ classMethod , $ doctrineAnnotationTagValueNode ) ;
144
173
}
145
174
146
- return $ this ->refactorClassMethod ($ classMethod , $ doctrineAnnotationTagValueNode );
175
+ // global @Template access
176
+ if ($ classDoctrineAnnotationTagValueNode instanceof DoctrineAnnotationTagValueNode) {
177
+ return $ this ->refactorClassMethod ($ classMethod , $ classDoctrineAnnotationTagValueNode );
178
+ }
179
+
180
+ return false ;
147
181
}
148
182
149
183
private function refactorClassMethod (
150
184
ClassMethod $ classMethod ,
151
185
DoctrineAnnotationTagValueNode $ templateDoctrineAnnotationTagValueNode
152
- ): ? ClassMethod {
186
+ ): bool {
153
187
$ hasThisRenderOrReturnsResponse = $ this ->hasLastReturnResponse ($ classMethod );
154
188
189
+ $ hasChanged = false ;
190
+
155
191
$ this ->traverseNodesWithCallable ($ classMethod , function (Node $ node ) use (
156
192
$ templateDoctrineAnnotationTagValueNode ,
157
193
$ hasThisRenderOrReturnsResponse ,
158
- $ classMethod
194
+ $ classMethod ,
195
+ &$ hasChanged
159
196
): ?int {
197
+
160
198
// keep as similar type
161
199
if ($ node instanceof Closure || $ node instanceof Function_) {
162
200
return NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN ;
@@ -173,11 +211,13 @@ private function refactorClassMethod(
173
211
$ classMethod
174
212
);
175
213
214
+ $ hasChanged = true ;
215
+
176
216
return null ;
177
217
});
178
218
179
219
if (! $ this ->emptyReturnNodeFinder ->hasNoOrEmptyReturns ($ classMethod )) {
180
- return null ;
220
+ return $ hasChanged ;
181
221
}
182
222
183
223
$ thisRenderMethodCall = $ this ->thisRenderFactory ->create (
@@ -188,7 +228,7 @@ private function refactorClassMethod(
188
228
189
229
$ this ->refactorNoReturn ($ classMethod , $ thisRenderMethodCall , $ templateDoctrineAnnotationTagValueNode );
190
230
191
- return $ classMethod ;
231
+ return true ;
192
232
}
193
233
194
234
private function hasLastReturnResponse (ClassMethod $ classMethod ): bool
@@ -288,13 +328,13 @@ private function refactorReturnWithValue(
288
328
}
289
329
290
330
private function removeDoctrineAnnotationTagValueNode (
291
- ClassMethod $ classMethod ,
331
+ Class_ | ClassMethod $ node ,
292
332
DoctrineAnnotationTagValueNode $ doctrineAnnotationTagValueNode
293
333
): void {
294
- $ phpDocInfo = $ this ->phpDocInfoFactory ->createFromNodeOrEmpty ($ classMethod );
334
+ $ phpDocInfo = $ this ->phpDocInfoFactory ->createFromNodeOrEmpty ($ node );
295
335
$ this ->phpDocTagRemover ->removeTagValueFromNode ($ phpDocInfo , $ doctrineAnnotationTagValueNode );
296
336
297
- $ this ->docBlockUpdater ->updateRefactoredNodeWithPhpDocInfo ($ classMethod );
337
+ $ this ->docBlockUpdater ->updateRefactoredNodeWithPhpDocInfo ($ node );
298
338
}
299
339
300
340
private function refactorStmtsAwareNode (
0 commit comments