1212use PhpParser \Node \Scalar \Int_ ;
1313use PhpParser \Node \Stmt \Expression ;
1414use PhpParser \Node \Stmt \If_ ;
15+ use PhpParser \NodeVisitor ;
16+ use Rector \Contract \PhpParser \Node \StmtsAwareInterface ;
1517use Rector \Contract \Rector \ConfigurableRectorInterface ;
1618use Rector \DeadCode \ValueObject \WrapFuncCallWithPhpVersionIdChecker ;
1719use Rector \Rector \AbstractRector ;
@@ -57,32 +59,49 @@ public function getRuleDefinition(): RuleDefinition
5759 */
5860 public function getNodeTypes (): array
5961 {
60- return [Expression ::class];
62+ return [StmtsAwareInterface ::class];
6163 }
6264
6365 /**
64- * @param Expression $node
66+ * @param StmtsAwareInterface $node
6567 */
66- public function refactor (Node $ node ): ? Node
68+ public function refactor (Node $ node ): null | Node | int
6769 {
68- if (! $ node ->expr instanceof FuncCall ) {
70+ if ($ node ->stmts === null ) {
6971 return null ;
7072 }
7173
72- $ funcCall = $ node ->expr ;
74+ if ($ this ->isWrappedFuncCall ($ node )) {
75+ return NodeVisitor::DONT_TRAVERSE_CHILDREN ;
76+ }
7377
74- foreach ($ this ->wrapFuncCallWithPhpVersionIdCheckers as $ wrapFuncCallWithPhpVersionIdChecker ) {
75- if ($ this ->getName ($ funcCall ) !== $ wrapFuncCallWithPhpVersionIdChecker ->getFunctionName ()) {
78+ $ hasChanged = false ;
79+ foreach ($ node ->stmts as $ key => $ stmt ) {
80+ if (! $ stmt instanceof Expression || ! $ stmt ->expr instanceof FuncCall) {
7681 continue ;
7782 }
7883
79- $ phpVersionIdConst = new ConstFetch (new Name ('PHP_VERSION_ID ' ));
80- $ if = new If_ (new Smaller ($ phpVersionIdConst , new Int_ (
81- $ wrapFuncCallWithPhpVersionIdChecker ->getPhpVersionId ()
82- )));
83- $ if ->stmts = [$ node ];
84+ $ funcCall = $ stmt ->expr ;
85+
86+ foreach ($ this ->wrapFuncCallWithPhpVersionIdCheckers as $ wrapFuncCallWithPhpVersionIdChecker ) {
87+ if ($ this ->getName ($ funcCall ) !== $ wrapFuncCallWithPhpVersionIdChecker ->getFunctionName ()) {
88+ continue ;
89+ }
90+
91+ $ phpVersionIdConst = new ConstFetch (new Name ('PHP_VERSION_ID ' ));
92+ $ if = new If_ (new Smaller ($ phpVersionIdConst , new Int_ (
93+ $ wrapFuncCallWithPhpVersionIdChecker ->getPhpVersionId ()
94+ )));
95+ $ if ->stmts = [$ stmt ];
96+
97+ $ node ->stmts [$ key ] = $ if ;
98+
99+ $ hasChanged = true ;
100+ }
101+ }
84102
85- return $ if ;
103+ if ($ hasChanged ) {
104+ return $ node ;
86105 }
87106
88107 return null ;
@@ -94,4 +113,46 @@ public function configure(array $configuration): void
94113
95114 $ this ->wrapFuncCallWithPhpVersionIdCheckers = $ configuration ;
96115 }
116+
117+ private function isWrappedFuncCall (StmtsAwareInterface $ node ): bool
118+ {
119+ if (! $ node instanceof If_) {
120+ return false ;
121+ }
122+
123+ if (! $ node ->cond instanceof Smaller) {
124+ return false ;
125+ }
126+
127+ if (! $ node ->cond ->left instanceof ConstFetch || ! $ this ->isName ($ node ->cond ->left ->name , 'PHP_VERSION_ID ' )) {
128+ return false ;
129+ }
130+
131+ if (! $ node ->cond ->right instanceof Int_) {
132+ return false ;
133+ }
134+
135+ if (count ($ node ->stmts ) !== 1 ) {
136+ return false ;
137+ }
138+
139+ $ childStmt = $ node ->stmts [0 ];
140+
141+ if (! $ childStmt instanceof Expression || ! $ childStmt ->expr instanceof FuncCall) {
142+ return false ;
143+ }
144+
145+ foreach ($ this ->wrapFuncCallWithPhpVersionIdCheckers as $ wrapFuncCallWithPhpVersionIdChecker ) {
146+ if (
147+ $ this ->getName ($ childStmt ->expr ) !== $ wrapFuncCallWithPhpVersionIdChecker ->getFunctionName ()
148+ || $ node ->cond ->right ->value !== $ wrapFuncCallWithPhpVersionIdChecker ->getPhpVersionId ()
149+ ) {
150+ continue ;
151+ }
152+
153+ return true ;
154+ }
155+
156+ return false ;
157+ }
97158}
0 commit comments