@@ -70,67 +70,24 @@ public function process(File $phpcsFile, $returnPointer): void
7070
7171 $ variableName = $ tokens [$ variablePointer ]['content ' ];
7272
73- $ previousVariablePointer = null ;
74- for ($ i = $ returnPointer - 1 ; $ i >= 0 ; $ i --) {
75- if (
76- in_array ($ tokens [$ i ]['code ' ], TokenHelper::$ functionTokenCodes , true )
77- && $ this ->isInSameScope ($ phpcsFile , $ tokens [$ i ]['scope_opener ' ] + 1 , $ returnPointer )
78- ) {
79- return ;
80- }
81-
82- if ($ tokens [$ i ]['code ' ] !== T_VARIABLE ) {
83- continue ;
84- }
85-
86- if ($ tokens [$ i ]['content ' ] !== $ variableName ) {
87- continue ;
88- }
89-
90- if (!$ this ->isInSameScope ($ phpcsFile , $ i , $ variablePointer )) {
91- continue ;
92- }
93-
94- $ previousVariablePointer = $ i ;
95- break ;
73+ $ previousVariablePointer = $ this ->findPreviousVariablePointer ($ phpcsFile , $ returnPointer , $ variableName );
74+ if ($ previousVariablePointer === null ) {
75+ return ;
9676 }
9777
98- if ($ previousVariablePointer === null ) {
78+ if (! $ this -> isAssigmentToVariable ( $ phpcsFile , $ previousVariablePointer ) ) {
9979 return ;
10080 }
10181
102- $ effectivePointerBeforePreviousVariable = TokenHelper::findPreviousEffective ($ phpcsFile , $ previousVariablePointer - 1 );
103- if ($ tokens [$ effectivePointerBeforePreviousVariable ]['code ' ] === T_STATIC ) {
82+ if ($ this ->isStaticVariable ($ phpcsFile , $ previousVariablePointer )) {
10483 return ;
10584 }
10685
107- $ pointerBeforePreviousVariable = TokenHelper::findPreviousExcluding ($ phpcsFile , T_WHITESPACE , $ previousVariablePointer - 1 );
108- if (
109- $ tokens [$ pointerBeforePreviousVariable ]['code ' ] === T_DOC_COMMENT_CLOSE_TAG
110- ) {
111- $ docCommentContent = TokenHelper::getContent ($ phpcsFile , $ tokens [$ pointerBeforePreviousVariable ]['comment_opener ' ], $ pointerBeforePreviousVariable );
112- if (preg_match ('~@var \\s+ \\S+ \\s+ ' . preg_quote ($ variableName , '~ ' ) . '~ ' , $ docCommentContent )) {
113- return ;
114- }
86+ if ($ this ->hasVariableVarAnnotation ($ phpcsFile , $ previousVariablePointer )) {
87+ return ;
11588 }
11689
117- /** @var int $assigmentPointer */
118- $ assigmentPointer = TokenHelper::findNextEffective ($ phpcsFile , $ previousVariablePointer + 1 );
119- if (!in_array ($ tokens [$ assigmentPointer ]['code ' ], [
120- T_EQUAL ,
121- T_PLUS_EQUAL ,
122- T_MINUS_EQUAL ,
123- T_MUL_EQUAL ,
124- T_DIV_EQUAL ,
125- T_POW_EQUAL ,
126- T_MOD_EQUAL ,
127- T_AND_EQUAL ,
128- T_OR_EQUAL ,
129- T_XOR_EQUAL ,
130- T_SL_EQUAL ,
131- T_SR_EQUAL ,
132- T_CONCAT_EQUAL ,
133- ], true )) {
90+ if ($ this ->hasAnotherAssigmentBefore ($ phpcsFile , $ previousVariablePointer , $ variableName )) {
13491 return ;
13592 }
13693
@@ -199,6 +156,9 @@ public function process(File $phpcsFile, $returnPointer): void
199156 return ;
200157 }
201158
159+ /** @var int $assigmentPointer */
160+ $ assigmentPointer = TokenHelper::findNextEffective ($ phpcsFile , $ previousVariablePointer + 1 );
161+
202162 $ assigmentFixerMapping = [
203163 T_PLUS_EQUAL => '+ ' ,
204164 T_MINUS_EQUAL => '- ' ,
@@ -252,4 +212,90 @@ private function isInSameScope(File $phpcsFile, int $firstPointer, int $secondPo
252212 return $ getScopeLevel ($ firstPointer ) === $ getScopeLevel ($ secondPointer );
253213 }
254214
215+ private function findPreviousVariablePointer (File $ phpcsFile , int $ pointer , string $ variableName ): ?int
216+ {
217+ $ tokens = $ phpcsFile ->getTokens ();
218+
219+ for ($ i = $ pointer - 1 ; $ i >= 0 ; $ i --) {
220+ if (
221+ in_array ($ tokens [$ i ]['code ' ], TokenHelper::$ functionTokenCodes , true )
222+ && $ this ->isInSameScope ($ phpcsFile , $ tokens [$ i ]['scope_opener ' ] + 1 , $ pointer )
223+ ) {
224+ return null ;
225+ }
226+
227+ if ($ tokens [$ i ]['code ' ] !== T_VARIABLE ) {
228+ continue ;
229+ }
230+
231+ if ($ tokens [$ i ]['content ' ] !== $ variableName ) {
232+ continue ;
233+ }
234+
235+ if (!$ this ->isInSameScope ($ phpcsFile , $ i , $ pointer )) {
236+ continue ;
237+ }
238+
239+ return $ i ;
240+ }
241+
242+ return null ;
243+ }
244+
245+ private function isAssigmentToVariable (File $ phpcsFile , int $ pointer ): bool
246+ {
247+ $ assigmentPointer = TokenHelper::findNextEffective ($ phpcsFile , $ pointer + 1 );
248+ return in_array ($ phpcsFile ->getTokens ()[$ assigmentPointer ]['code ' ], [
249+ T_EQUAL ,
250+ T_PLUS_EQUAL ,
251+ T_MINUS_EQUAL ,
252+ T_MUL_EQUAL ,
253+ T_DIV_EQUAL ,
254+ T_POW_EQUAL ,
255+ T_MOD_EQUAL ,
256+ T_AND_EQUAL ,
257+ T_OR_EQUAL ,
258+ T_XOR_EQUAL ,
259+ T_SL_EQUAL ,
260+ T_SR_EQUAL ,
261+ T_CONCAT_EQUAL ,
262+ ], true );
263+ }
264+
265+ private function isStaticVariable (File $ phpcsFile , int $ variablePointer ): bool
266+ {
267+ $ pointerBeforeVariable = TokenHelper::findPreviousEffective ($ phpcsFile , $ variablePointer - 1 );
268+ return $ phpcsFile ->getTokens ()[$ pointerBeforeVariable ]['code ' ] === T_STATIC ;
269+ }
270+
271+ private function hasVariableVarAnnotation (File $ phpcsFile , int $ variablePointer ): bool
272+ {
273+ $ tokens = $ phpcsFile ->getTokens ();
274+
275+ $ pointerBeforeVariable = TokenHelper::findPreviousExcluding ($ phpcsFile , T_WHITESPACE , $ variablePointer - 1 );
276+ if ($ tokens [$ pointerBeforeVariable ]['code ' ] !== T_DOC_COMMENT_CLOSE_TAG ) {
277+ return false ;
278+ }
279+
280+ $ docCommentContent = TokenHelper::getContent ($ phpcsFile , $ tokens [$ pointerBeforeVariable ]['comment_opener ' ], $ pointerBeforeVariable );
281+ return preg_match ('~@var \\s+ \\S+ \\s+ ' . preg_quote ($ tokens [$ variablePointer ]['content ' ], '~ ' ) . '~ ' , $ docCommentContent ) > 0 ;
282+ }
283+
284+ private function hasAnotherAssigmentBefore (File $ phpcsFile , int $ variablePointer , string $ variableName ): bool
285+ {
286+ $ previousVariablePointer = $ this ->findPreviousVariablePointer ($ phpcsFile , $ variablePointer , $ variableName );
287+ if ($ previousVariablePointer === null ) {
288+ return false ;
289+ }
290+
291+ if (!$ this ->isAssigmentToVariable ($ phpcsFile , $ previousVariablePointer )) {
292+ return false ;
293+ }
294+
295+ $ previousVariableSemicolonPointer = TokenHelper::findNext ($ phpcsFile , T_SEMICOLON , $ previousVariablePointer + 1 );
296+ $ pointerAfterPreviousVariableSemicolon = TokenHelper::findNextEffective ($ phpcsFile , $ previousVariableSemicolonPointer + 1 );
297+
298+ return $ pointerAfterPreviousVariableSemicolon === $ variablePointer ;
299+ }
300+
255301}
0 commit comments