88use Coduo \PHPMatcher \Exception \PatternException ;
99use Coduo \PHPMatcher \Matcher \Pattern ;
1010use Coduo \PHPMatcher \Parser \ExpanderInitializer ;
11+ use Doctrine \Common \Lexer \Token ;
1112
1213final class Parser
1314{
@@ -66,8 +67,8 @@ private function getPattern() : AST\Pattern
6667
6768 $ pattern = null ;
6869
69- if ($ this ->lexer ->lookahead [ ' type ' ] == Lexer::T_TYPE_PATTERN ) {
70- $ pattern = new AST \Pattern (new AST \Type ($ this ->lexer ->lookahead [ ' value ' ] ));
70+ if ($ this ->lexer ->lookahead -> type == Lexer::T_TYPE_PATTERN ) {
71+ $ pattern = new AST \Pattern (new AST \Type ($ this ->lexer ->lookahead -> value ));
7172 } else {
7273 throw PatternException::syntaxError ($ this ->unexpectedSyntaxError ($ this ->lexer ->lookahead , '@type@ pattern ' ));
7374 }
@@ -119,23 +120,19 @@ private function getNextExpanderNode() : ?AST\Expander
119120
120121 private function getExpanderName () : string
121122 {
122- if ($ this ->lexer ->lookahead ['type ' ] !== Lexer::T_EXPANDER_NAME ) {
123- throw PatternException::syntaxError ($ this ->unexpectedSyntaxError ($ this ->lexer ->lookahead , '.expanderName(args) definition ' ));
124- }
123+ $ lookahead = $ this ->lexer ->lookahead ;
125124
126- $ expander = $ this ->lexer ->lookahead ['value ' ];
125+ if ($ lookahead === null ) {
126+ throw PatternException::syntaxError ($ this ->unexpectedSyntaxError ($ lookahead , '.expanderName(args) definition ' ));
127+ }
127128
128- if ($ expander === null ) {
129- throw PatternException::syntaxError ($ this ->unexpectedSyntaxError ($ this -> lexer -> lookahead , '.expanderName(args) definition ' ));
129+ if ($ lookahead -> type !== Lexer:: T_EXPANDER_NAME ) {
130+ throw PatternException::syntaxError ($ this ->unexpectedSyntaxError ($ lookahead , '.expanderName(args) definition ' ));
130131 }
131132
132133 $ this ->lexer ->moveNext ();
133134
134- if (\is_int ($ expander )) {
135- return (string ) $ expander ;
136- }
137-
138- return $ expander ;
135+ return $ lookahead ->value ;
139136 }
140137
141138 /**
@@ -144,8 +141,9 @@ private function getExpanderName() : string
144141 private function addArgumentValues (AST \Expander $ expander ) : void
145142 {
146143 while (($ argument = $ this ->getNextArgumentValue ()) !== null ) {
147- $ argument = ($ argument === self ::NULL_VALUE ) ? null : $ argument ;
148- $ expander ->addArgument ($ argument );
144+ $ coercedArgument = $ this ->coerceArgumentValue ($ argument );
145+
146+ $ expander ->addArgument ($ coercedArgument );
149147
150148 if (!$ this ->lexer ->isNextToken (Lexer::T_COMMA )) {
151149 break ;
@@ -159,6 +157,33 @@ private function addArgumentValues(AST\Expander $expander) : void
159157 }
160158 }
161159
160+ private function coerceArgumentValue (mixed $ argument ) : mixed
161+ {
162+ $ coercedArgument = $ argument ;
163+
164+ if (\is_string ($ argument )) {
165+ $ lowercaseArgument = \strtolower ($ argument );
166+
167+ if ($ lowercaseArgument === self ::NULL_VALUE ) {
168+ $ coercedArgument = null ;
169+ } elseif ($ lowercaseArgument === 'true ' ) {
170+ $ coercedArgument = true ;
171+ } elseif ($ lowercaseArgument === 'false ' ) {
172+ $ coercedArgument = false ;
173+ } elseif (\is_numeric ($ argument )) {
174+ $ coercedArgument = (\strpos ($ argument , '. ' ) === false ) ? (int ) $ argument : (float ) $ argument ;
175+ }
176+ } elseif (\is_array ($ argument )) {
177+ $ coercedArgument = [];
178+
179+ foreach ($ argument as $ key => $ arg ) {
180+ $ coercedArgument [$ key ] = $ this ->coerceArgumentValue ($ arg );
181+ }
182+ }
183+
184+ return $ coercedArgument ;
185+ }
186+
162187 /**
163188 * Try to get next argument. Return false if there are no arguments left before ")".
164189 */
@@ -187,8 +212,8 @@ private function getNextArgumentValue()
187212 throw PatternException::syntaxError ($ this ->unexpectedSyntaxError ($ this ->lexer ->lookahead , 'string, number, boolean or null argument ' ));
188213 }
189214
190- $ tokenType = $ this ->lexer ->lookahead [ ' type ' ] ;
191- $ argument = $ this ->lexer ->lookahead [ ' value ' ] ;
215+ $ tokenType = $ this ->lexer ->lookahead -> type ;
216+ $ argument = $ this ->lexer ->lookahead -> value ;
192217 $ this ->lexer ->moveNext ();
193218
194219 if ($ tokenType === Lexer::T_NULL ) {
@@ -258,15 +283,15 @@ private function isNextCloseParenthesis() : bool
258283 }
259284
260285 /**
261- * @param mixed $unexpectedToken
286+ * @param ?Token<Lexer::T_*, string> $unexpectedToken
262287 * @param string $expected
263288 */
264289 private function unexpectedSyntaxError ($ unexpectedToken , string $ expected = null ) : string
265290 {
266- $ tokenPos = ( isset ( $ unexpectedToken[ ' position ' ])) ? $ unexpectedToken[ ' position ' ] : '-1 ' ;
291+ $ tokenPos = $ unexpectedToken !== null ? $ unexpectedToken-> position : '-1 ' ;
267292 $ message = \sprintf ('line 0, col %d: Error: ' , $ tokenPos );
268293 $ message .= (isset ($ expected )) ? \sprintf ('Expected "%s", got ' , $ expected ) : 'Unexpected ' ;
269- $ message .= \sprintf ('"%s" ' , $ unexpectedToken[ ' value ' ] );
294+ $ message .= \sprintf ('"%s" ' , $ unexpectedToken-> value );
270295
271296 return $ message ;
272297 }
@@ -278,7 +303,8 @@ private function unexpectedSyntaxError($unexpectedToken, string $expected = null
278303 */
279304 private function unexpectedEndOfString (string $ expected = null ) : void
280305 {
281- $ tokenPos = (isset ($ this ->lexer ->token ['position ' ])) ? $ this ->lexer ->token ['position ' ] + \strlen ((string ) $ this ->lexer ->token ['value ' ]) : '-1 ' ;
306+ $ tokenPos = (isset ($ this ->lexer ->token ->position ))
307+ ? $ this ->lexer ->token ->position + \strlen ((string ) $ this ->lexer ->token ->value ) : '-1 ' ;
282308 $ message = \sprintf ('line 0, col %d: Error: ' , $ tokenPos );
283309 $ message .= (isset ($ expected )) ? \sprintf ('Expected "%s", got end of string. ' , $ expected ) : 'Unexpected ' ;
284310 $ message .= 'end of string ' ;
0 commit comments