3030use const T_WHITESPACE ;
3131
3232/**
33- * @phpstan-type NameWithValueShape array{
33+ * @phpstan-type TypeNameValueShape array{
34+ * type: TypeShape|null,
3435 * name: NameShape,
3536 * value: ValueShape
3637 * }
38+ * @phpstan-type TypeNameShape array{
39+ * type: TypeShape|null,
40+ * name: NameShape
41+ * }
42+ * @phpstan-type TypeShape array{
43+ * content: string,
44+ * ptr: int
45+ * }
3746 * @phpstan-type NameShape array{
3847 * content: string,
3948 * lowercaseContent: string,
@@ -89,7 +98,7 @@ public function process(File $phpcsFile, mixed $stackPtr): void
8998 }
9099 }
91100
92- /** @param list<NameWithValueShape > $namesWithValues */
101+ /** @param list<TypeNameValueShape > $namesWithValues */
93102 private function fix (File $ file , array $ namesWithValues ): void
94103 {
95104 $ fixer = $ file ->fixer ;
@@ -104,9 +113,19 @@ private function fix(File $file, array $namesWithValues): void
104113 foreach ($ namesWithValues as $ key => $ nameWithValue ) {
105114 $ sortedNameAndValueToken = $ sortedNameAndValueTokens [$ key ];
106115
116+ $ typePointer = $ nameWithValue ['type ' ]['ptr ' ] ?? null ;
107117 $ namePointer = $ nameWithValue ['name ' ]['ptr ' ];
108- FixerHelper::removeBetweenIncluding ($ file , $ namePointer , $ namePointer );
109- $ fixer ->addContent ($ namePointer , $ sortedNameAndValueToken ['name ' ]['content ' ]);
118+ FixerHelper::removeBetweenIncluding ($ file , $ typePointer ?? $ namePointer , $ namePointer );
119+ $ fixer ->addContent (
120+ $ typePointer ?? $ namePointer ,
121+ $ sortedNameAndValueToken ['type ' ] === null ?
122+ $ sortedNameAndValueToken ['name ' ]['content ' ]
123+ : sprintf (
124+ '%s %s ' ,
125+ $ sortedNameAndValueToken ['type ' ]['content ' ],
126+ $ sortedNameAndValueToken ['name ' ]['content ' ],
127+ ),
128+ );
110129
111130 $ value = $ nameWithValue ['value ' ];
112131 FixerHelper::removeBetweenIncluding ($ file , $ value ['startPtr ' ], $ value ['endPtr ' ]);
@@ -116,7 +135,7 @@ private function fix(File $file, array $namesWithValues): void
116135 $ fixer ->endChangeset ();
117136 }
118137
119- /** @return array<string, list<NameWithValueShape >> */
138+ /** @return array<string, list<TypeNameValueShape >> */
120139 private function findConstantNamesWithValuesByVisibility (File $ phpcsFile ): array
121140 {
122141 $ constantNamesWithValues = [];
@@ -128,13 +147,13 @@ private function findConstantNamesWithValuesByVisibility(File $phpcsFile): array
128147 }
129148
130149 $ visibility = $ this ->getVisibility ($ phpcsFile , $ stackPtr );
131- $ constantName = $ this ->findConstantName ($ phpcsFile , $ stackPtr );
150+ $ typeAndConstantName = $ this ->findTypeAndConstantName ($ phpcsFile , $ stackPtr );
132151
133- if ($ constantName === null ) {
152+ if ($ typeAndConstantName === null ) {
134153 continue ;
135154 }
136155
137- $ equalsTokenPointer = $ this ->findEqualsPointer ($ phpcsFile , $ constantName ['ptr ' ]);
156+ $ equalsTokenPointer = $ this ->findEqualsPointer ($ phpcsFile , $ typeAndConstantName [ ' name ' ] ['ptr ' ]);
138157
139158 if ($ equalsTokenPointer === null ) {
140159 continue ;
@@ -147,7 +166,8 @@ private function findConstantNamesWithValuesByVisibility(File $phpcsFile): array
147166 }
148167
149168 $ constantNamesWithValues [$ visibility ][] = [
150- 'name ' => $ constantName ,
169+ 'type ' => $ typeAndConstantName ['type ' ],
170+ 'name ' => $ typeAndConstantName ['name ' ],
151171 'value ' => $ value ,
152172 ];
153173 }
@@ -170,25 +190,52 @@ private function getVisibility(File $phpcsFile, int $constStackPtr): string
170190 : 'public ' ;
171191 }
172192
173- /** @phpstan-return NameShape |null */
174- private function findConstantName (File $ phpcsFile , int $ constStackPtr ): array |null
193+ /** @phpstan-return TypeNameShape |null */
194+ private function findTypeAndConstantName (File $ phpcsFile , int $ constStackPtr ): array |null
175195 {
176196 $ tokens = $ phpcsFile ->getTokens ();
177- $ constantNameTokenPointer = $ phpcsFile ->findNext (
178- types: Tokens:: $ emptyTokens ,
197+ $ assignmentOperatorTokenPtr = $ phpcsFile ->findNext (
198+ types: [ T_EQUAL , T_SEMICOLON ] ,
179199 start: $ constStackPtr + 1 ,
200+ );
201+
202+ if ($ assignmentOperatorTokenPtr === false || $ tokens [$ assignmentOperatorTokenPtr ]['code ' ] !== T_EQUAL ) {
203+ return null ;
204+ }
205+
206+ $ constNameTokenPtr = $ phpcsFile ->findPrevious (
207+ types: Tokens::$ emptyTokens ,
208+ start: $ assignmentOperatorTokenPtr - 1 ,
209+ end: $ constStackPtr + 1 ,
180210 exclude: true ,
181- local: true ,
182211 );
183212
184- if ($ constantNameTokenPointer === false || $ tokens [$ constantNameTokenPointer ]['code ' ] !== T_STRING ) {
213+ if ($ constNameTokenPtr === false || $ tokens [$ constNameTokenPtr ]['code ' ] !== T_STRING ) {
185214 return null ;
186215 }
187216
217+ $ type = null ;
218+ $ typeTokenPtr = $ phpcsFile ->findPrevious (
219+ types: Tokens::$ emptyTokens ,
220+ start: $ constNameTokenPtr - 1 ,
221+ end: $ constStackPtr ,
222+ exclude: true ,
223+ );
224+
225+ if ($ typeTokenPtr !== false && $ tokens [$ typeTokenPtr ]['code ' ] === T_STRING ) {
226+ $ type = [
227+ 'content ' => $ tokens [$ typeTokenPtr ]['content ' ],
228+ 'ptr ' => $ typeTokenPtr ,
229+ ];
230+ }
231+
188232 return [
189- 'content ' => $ tokens [$ constantNameTokenPointer ]['content ' ],
190- 'lowercaseContent ' => strtolower ($ tokens [$ constantNameTokenPointer ]['content ' ]),
191- 'ptr ' => $ constantNameTokenPointer ,
233+ 'type ' => $ type ,
234+ 'name ' => [
235+ 'content ' => $ tokens [$ constNameTokenPtr ]['content ' ],
236+ 'lowercaseContent ' => strtolower ($ tokens [$ constNameTokenPtr ]['content ' ]),
237+ 'ptr ' => $ constNameTokenPtr ,
238+ ],
192239 ];
193240 }
194241
0 commit comments