@@ -64,8 +64,8 @@ public function isRisky()
64
64
protected function applyFix (\SplFileInfo $ file , Tokens $ tokens )
65
65
{
66
66
$ analyzer = new TokensAnalyzer ($ tokens );
67
-
68
67
$ expectedFunctionKinds = [T_FUNCTION ];
68
+
69
69
if (\PHP_VERSION_ID >= 70400 ) {
70
70
$ expectedFunctionKinds [] = T_FN ;
71
71
}
@@ -76,21 +76,22 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
76
76
}
77
77
78
78
$ prev = $ tokens ->getPrevMeaningfulToken ($ index );
79
+
79
80
if ($ tokens [$ prev ]->isGivenKind (T_STATIC )) {
80
81
continue ; // lambda is already 'static'
81
82
}
82
83
83
84
$ argumentsStartIndex = $ tokens ->getNextTokenOfKind ($ index , ['( ' ]);
84
85
$ argumentsEndIndex = $ tokens ->findBlockEnd (Tokens::BLOCK_TYPE_PARENTHESIS_BRACE , $ argumentsStartIndex );
85
86
86
- // figure out where the lambda starts ...
87
- $ lambdaOpenIndex = $ tokens ->getNextTokenOfKind ($ argumentsEndIndex , ['{ ' , [T_DOUBLE_ARROW ]]);
87
+ // figure out where the lambda starts and ends
88
88
89
- // ... and where it ends
90
- if ($ tokens [$ lambdaOpenIndex ]->isGivenKind (T_DOUBLE_ARROW )) {
91
- $ lambdaEndIndex = $ tokens ->getNextTokenOfKind ($ lambdaOpenIndex , ['; ' ]);
92
- } else {
89
+ if ($ tokens [$ index ]->isGivenKind (T_FUNCTION )) {
90
+ $ lambdaOpenIndex = $ tokens ->getNextTokenOfKind ($ argumentsEndIndex , ['{ ' ]);
93
91
$ lambdaEndIndex = $ tokens ->findBlockEnd (Tokens::BLOCK_TYPE_CURLY_BRACE , $ lambdaOpenIndex );
92
+ } else { // T_FN
93
+ $ lambdaOpenIndex = $ tokens ->getNextTokenOfKind ($ argumentsEndIndex , [[T_DOUBLE_ARROW ]]);
94
+ $ lambdaEndIndex = $ this ->findExpressionEnd ($ tokens , $ lambdaOpenIndex );
94
95
}
95
96
96
97
if ($ this ->hasPossibleReferenceToThis ($ tokens , $ lambdaOpenIndex , $ lambdaEndIndex )) {
@@ -110,6 +111,37 @@ protected function applyFix(\SplFileInfo $file, Tokens $tokens)
110
111
}
111
112
}
112
113
114
+ /**
115
+ * @param int $index
116
+ *
117
+ * @return int
118
+ */
119
+ private function findExpressionEnd (Tokens $ tokens , $ index )
120
+ {
121
+ $ nextIndex = $ tokens ->getNextMeaningfulToken ($ index );
122
+
123
+ while (null !== $ nextIndex ) {
124
+ /** @var Token $nextToken */
125
+ $ nextToken = $ tokens [$ nextIndex ];
126
+
127
+ if ($ nextToken ->equalsAny ([', ' , '; ' , [T_CLOSE_TAG ]])) {
128
+ break ;
129
+ }
130
+
131
+ /** @var null|array{isStart: bool, type: int} $blockType */
132
+ $ blockType = Tokens::detectBlockType ($ nextToken );
133
+
134
+ if (null !== $ blockType && $ blockType ['isStart ' ]) {
135
+ $ nextIndex = $ tokens ->findBlockEnd ($ blockType ['type ' ], $ nextIndex );
136
+ }
137
+
138
+ $ index = $ nextIndex ;
139
+ $ nextIndex = $ tokens ->getNextMeaningfulToken ($ index );
140
+ }
141
+
142
+ return $ index ;
143
+ }
144
+
113
145
/**
114
146
* Returns 'true' if there is a possible reference to '$this' within the given tokens index range.
115
147
*
@@ -138,6 +170,7 @@ private function hasPossibleReferenceToThis(Tokens $tokens, $startIndex, $endInd
138
170
139
171
if ($ tokens [$ i ]->equals ('$ ' )) {
140
172
$ nextIndex = $ tokens ->getNextMeaningfulToken ($ i );
173
+
141
174
if ($ tokens [$ nextIndex ]->isGivenKind (T_VARIABLE )) {
142
175
return true ; // "$$a" case
143
176
}
0 commit comments