44
55namespace PhpMyAdmin \SqlParser \Tools ;
66
7+ use PhpMyAdmin \SqlParser \Token ;
8+
79use function array_map ;
810use function array_merge ;
911use function array_slice ;
1517use function implode ;
1618use function ksort ;
1719use function preg_match ;
18- use function round ;
1920use function scandir ;
2021use function sort ;
2122use function sprintf ;
22- use function str_repeat ;
2323use function str_replace ;
2424use function str_split ;
2525use function strlen ;
@@ -43,10 +43,10 @@ class ContextGenerator
4343 * @var array<string, int>
4444 */
4545 public static $ LABELS_FLAGS = [
46- '(R) ' => 2 , // reserved
47- '(D) ' => 8 , // data type
48- '(K) ' => 16 , // keyword
49- '(F) ' => 32 , // function name
46+ '(R) ' => Token:: FLAG_KEYWORD_RESERVED ,
47+ '(D) ' => Token:: FLAG_KEYWORD_DATA_TYPE ,
48+ '(K) ' => Token:: FLAG_KEYWORD_KEY ,
49+ '(F) ' => Token:: FLAG_KEYWORD_FUNCTION ,
5050 ];
5151
5252 /**
@@ -83,6 +83,20 @@ class ContextGenerator
8383 'MariaDb110400 ' => 'https://mariadb.com/kb/en/reserved-words/ ' ,
8484 ];
8585
86+ /**
87+ * Reversed const <=> int from {@see Token} class to write the constant name instead of its value.
88+ *
89+ * @var array<int, string>
90+ */
91+ private static $ typesNumToConst = [
92+ 1 => 'Token::FLAG_KEYWORD ' ,
93+ 2 => 'Token::FLAG_KEYWORD_RESERVED ' ,
94+ 4 => 'Token::FLAG_KEYWORD_COMPOSED ' ,
95+ 8 => 'Token::FLAG_KEYWORD_DATA_TYPE ' ,
96+ 16 => 'Token::FLAG_KEYWORD_KEY ' ,
97+ 32 => 'Token::FLAG_KEYWORD_FUNCTION ' ,
98+ ];
99+
86100 /**
87101 * The template of a context.
88102 *
@@ -117,9 +131,7 @@ class %2$s extends Context
117131 *
118132 * The value associated to each keyword represents its flags.
119133 *
120- * @see Token::FLAG_KEYWORD_RESERVED Token::FLAG_KEYWORD_COMPOSED
121- * Token::FLAG_KEYWORD_DATA_TYPE Token::FLAG_KEYWORD_KEY
122- * Token::FLAG_KEYWORD_FUNCTION
134+ * @see Token
123135 *
124136 * @var array<string,int>
125137 * @phpstan-var non-empty-array<non-empty-string,Token::FLAG_KEYWORD_*|int>
@@ -140,12 +152,9 @@ class %2$s extends Context
140152 public static function sortWords (array &$ arr )
141153 {
142154 ksort ($ arr );
143- foreach ($ arr as &$ wordsByLen ) {
144- ksort ($ wordsByLen );
145- foreach ($ wordsByLen as &$ words ) {
146- sort ($ words , SORT_STRING );
147- }
148- }
155+ foreach ($ arr as &$ words ) {
156+ sort ($ words , SORT_STRING );
157+ } unset($ words );
149158
150159 return $ arr ;
151160 }
@@ -159,17 +168,23 @@ public static function sortWords(array &$arr)
159168 */
160169 public static function readWords (array $ files )
161170 {
162- $ words = [];
163- foreach ($ files as $ file ) {
164- $ words = array_merge ($ words , file ($ file , FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ));
165- }
171+ $ wordsByFile = array_map (
172+ static function (string $ file ): array {
173+ return file ($ file , FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
174+ },
175+ $ files
176+ );
177+ $ words = array_merge (...$ wordsByFile );
166178
167179 /** @var array<string, int> $types */
168180 $ types = [];
169181
170182 for ($ i = 0 , $ count = count ($ words ); $ i !== $ count ; ++$ i ) {
171- $ type = 1 ;
172183 $ value = trim ($ words [$ i ]);
184+ if ($ value === '' ) {
185+ continue ;
186+ }
187+ $ type = Token::FLAG_KEYWORD ;
173188
174189 // Reserved, data types, keys, functions, etc. keywords.
175190 foreach (static ::$ LABELS_FLAGS as $ label => $ flags ) {
@@ -183,13 +198,8 @@ public static function readWords(array $files)
183198
184199 // Composed keyword.
185200 if (strstr ($ value , ' ' ) !== false ) {
186- $ type |= 2 ; // Reserved keyword.
187- $ type |= 4 ; // Composed keyword.
188- }
189-
190- $ len = strlen ($ words [$ i ]);
191- if ($ len === 0 ) {
192- continue ;
201+ $ type |= Token::FLAG_KEYWORD_RESERVED ;
202+ $ type |= Token::FLAG_KEYWORD_COMPOSED ;
193203 }
194204
195205 $ value = strtoupper ($ value );
@@ -200,18 +210,10 @@ public static function readWords(array $files)
200210 }
201211 }
202212
213+ // Prepare an array in a way to sort by type, then by word.
203214 $ ret = [];
204215 foreach ($ types as $ word => $ type ) {
205- $ len = strlen ($ word );
206- if (! isset ($ ret [$ type ])) {
207- $ ret [$ type ] = [];
208- }
209-
210- if (! isset ($ ret [$ type ][$ len ])) {
211- $ ret [$ type ][$ len ] = [];
212- }
213-
214- $ ret [$ type ][$ len ][] = $ word ;
216+ $ ret [$ type ][] = $ word ;
215217 }
216218
217219 return static ::sortWords ($ ret );
@@ -220,53 +222,34 @@ public static function readWords(array $files)
220222 /**
221223 * Prints an array of a words in PHP format.
222224 *
223- * @param array<int, array<int, array<int, string>>> $words the list of words to be formatted
224- * @param int $spaces the number of spaces that starts every line
225- * @param int $line the length of a line
226- *
227- * @return string
225+ * @param array<int, list<string>> $words the list of words to be formatted
228226 */
229- public static function printWords ($ words , $ spaces = 8 , $ line = 140 )
227+ public static function printWords (array $ words ): string
230228 {
231- $ typesCount = count ($ words );
232229 $ ret = '' ;
233- $ j = 0 ;
234-
235230 foreach ($ words as $ type => $ wordsByType ) {
236- foreach ($ wordsByType as $ len => $ wordsByLen ) {
237- $ count = round (($ line - $ spaces ) / ($ len + 9 )); // strlen("'' => 1, ") = 9
238- $ i = 0 ;
239-
240- foreach ($ wordsByLen as $ word ) {
241- if ($ i === 0 ) {
242- $ ret .= str_repeat (' ' , $ spaces );
243- }
244-
245- $ ret .= sprintf ('\'%s \' => %s, ' , $ word , $ type );
246- if (++$ i !== $ count && ++$ i <= $ count ) {
247- continue ;
248- }
249-
250- $ ret .= "\n" ;
251- $ i = 0 ;
252- }
253-
254- if ($ i === 0 ) {
255- continue ;
256- }
257-
258- $ ret .= "\n" ;
231+ foreach ($ wordsByType as $ word ) {
232+ $ ret .= sprintf (" '%s' => %s, \n" , $ word , self ::numTypeToConst ($ type ));
259233 }
234+ }
235+ return $ ret ;
236+ }
260237
261- if (++$ j >= $ typesCount ) {
262- continue ;
238+ /**
239+ * Convert a numeric value representing a set of const to a textual const value.
240+ *
241+ * @param int $type The numeric value.
242+ * @return string The text to write considering the given numeric value.
243+ */
244+ private static function numTypeToConst (int $ type ): string
245+ {
246+ $ matchingFlags = [];
247+ foreach (self ::$ typesNumToConst as $ num => $ value ) {
248+ if ($ type & $ num ) {
249+ $ matchingFlags [] = $ value ;
263250 }
264-
265- $ ret .= "\n" ;
266251 }
267-
268- // Trim trailing spaces and return.
269- return str_replace (" \n" , "\n" , $ ret );
252+ return implode (' | ' , $ matchingFlags );
270253 }
271254
272255 /**
0 commit comments