diff --git a/CHANGELOG.md b/CHANGELOG.md index 923ce16..bc31590 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,14 +1,16 @@ Version 3.0.3-dev ----------------- -Nothing yet. +### Fixed + +* In `"$foo[0]"` the `0` is now parsed as an `LNumber` rather than `String`. (#325) Version 3.0.2 (2016-12-06) -------------------------- ### Fixed -* Fixed name resolution of nullable types. +* Fixed name resolution of nullable types. (#324) * Fixed pretty-printing of nullable types. Version 3.0.1 (2016-12-01) @@ -18,7 +20,7 @@ Version 3.0.1 (2016-12-01) * Fixed handling of nested `list()`s: If the nested list was unkeyed, it was directly included in the list items. If it was keyed, it was wrapped in `ArrayItem`. Now nested `List_` nodes are - always wrapped in `ArrayItem`s. + always wrapped in `ArrayItem`s. (#321) Version 3.0.0 (2016-11-30) -------------------------- diff --git a/grammar/php5.y b/grammar/php5.y index 943e933..4c32f20 100644 --- a/grammar/php5.y +++ b/grammar/php5.y @@ -988,7 +988,7 @@ encaps_var: encaps_var_offset: T_STRING { $$ = Scalar\String_[$1]; } - | T_NUM_STRING { $$ = Scalar\String_[$1]; } + | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } ; diff --git a/grammar/php7.y b/grammar/php7.y index 5c9d586..55b04c8 100644 --- a/grammar/php7.y +++ b/grammar/php7.y @@ -875,7 +875,7 @@ encaps_var: encaps_var_offset: T_STRING { $$ = Scalar\String_[$1]; } - | T_NUM_STRING { $$ = Scalar\String_[$1]; } + | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } ; diff --git a/lib/PhpParser/Parser/Php5.php b/lib/PhpParser/Parser/Php5.php index 46d31db..23afafb 100644 --- a/lib/PhpParser/Parser/Php5.php +++ b/lib/PhpParser/Parser/Php5.php @@ -3131,7 +3131,7 @@ class Php5 extends \PhpParser\ParserAbstract } protected function reduceRule547() { - $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule548() { diff --git a/lib/PhpParser/Parser/Php7.php b/lib/PhpParser/Parser/Php7.php index 1727dd9..28446d4 100644 --- a/lib/PhpParser/Parser/Php7.php +++ b/lib/PhpParser/Parser/Php7.php @@ -2761,7 +2761,7 @@ class Php7 extends \PhpParser\ParserAbstract } protected function reduceRule486() { - $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); } protected function reduceRule487() { diff --git a/lib/PhpParser/ParserAbstract.php b/lib/PhpParser/ParserAbstract.php index e9101f2..c0be948 100644 --- a/lib/PhpParser/ParserAbstract.php +++ b/lib/PhpParser/ParserAbstract.php @@ -9,6 +9,7 @@ namespace PhpParser; use PhpParser\Node\Name; use PhpParser\Node\Param; use PhpParser\Node\Scalar\LNumber; +use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassConst; use PhpParser\Node\Stmt\ClassMethod; @@ -554,6 +555,19 @@ abstract class ParserAbstract implements Parser } } + protected function parseNumString($str, $attributes) { + if (!preg_match('/^(?:0|[1-9][0-9]*)$/', $str)) { + return new String_($str, $attributes); + } + + $num = +$str; + if (!is_int($num)) { + return new String_($str, $attributes); + } + + return new LNumber($num, $attributes); + } + protected function checkModifier($a, $b, $modifierPos) { // Jumping through some hoops here because verifyModifier() is also used elsewhere try { diff --git a/test/code/parser/scalar/encapsedString.test b/test/code/parser/scalar/encapsedString.test index af05567..1090eff 100644 --- a/test/code/parser/scalar/encapsedString.test +++ b/test/code/parser/scalar/encapsedString.test @@ -6,7 +6,11 @@ Encapsed strings "$A->B"; "$A[B]"; "$A[0]"; +"$A[1234]"; +"$A[9223372036854775808]"; +"$A[000]"; "$A[0x0]"; +"$A[0b0]"; "$A[$B]"; "{$A}"; "{$A['B']}"; @@ -59,13 +63,49 @@ array( var: Expr_Variable( name: A ) - dim: Scalar_String( + dim: Scalar_LNumber( value: 0 ) ) ) ) 4: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_LNumber( + value: 1234 + ) + ) + ) + ) + 5: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 9223372036854775808 + ) + ) + ) + ) + 6: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 000 + ) + ) + ) + ) + 7: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( @@ -77,7 +117,19 @@ array( ) ) ) - 5: Scalar_Encapsed( + 8: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 0b0 + ) + ) + ) + ) + 9: Scalar_Encapsed( parts: array( 0: Expr_ArrayDimFetch( var: Expr_Variable( @@ -89,45 +141,45 @@ array( ) ) ) - 6: Scalar_Encapsed( - parts: array( - 0: Expr_Variable( - name: A - ) - ) - ) - 7: Scalar_Encapsed( - parts: array( - 0: Expr_ArrayDimFetch( - var: Expr_Variable( - name: A - ) - dim: Scalar_String( - value: B - ) - ) - ) - ) - 8: Scalar_Encapsed( - parts: array( - 0: Expr_Variable( - name: A - ) - ) - ) - 9: Scalar_Encapsed( - parts: array( - 0: Expr_ArrayDimFetch( - var: Expr_Variable( - name: A - ) - dim: Scalar_String( - value: B - ) - ) - ) - ) 10: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + 11: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: B + ) + ) + ) + ) + 12: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + 13: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: B + ) + ) + ) + ) + 14: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: Expr_Variable( @@ -136,7 +188,7 @@ array( ) ) ) - 11: Scalar_Encapsed( + 15: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \{ @@ -149,7 +201,7 @@ array( ) ) ) - 12: Scalar_Encapsed( + 16: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \{ @@ -162,7 +214,7 @@ array( ) ) ) - 13: Scalar_Encapsed( + 17: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \ @@ -172,7 +224,7 @@ array( ) ) ) - 14: Scalar_Encapsed( + 18: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: \{ @@ -185,7 +237,7 @@ array( ) ) ) - 15: Scalar_Encapsed( + 19: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: Expr_Variable( @@ -197,7 +249,7 @@ array( ) ) ) - 16: Scalar_Encapsed( + 20: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: $ @@ -212,7 +264,7 @@ array( ) ) ) - 17: Scalar_Encapsed( + 21: Scalar_Encapsed( parts: array( 0: Scalar_EncapsedStringPart( value: A @@ -225,14 +277,14 @@ array( ) ) ) - 18: Scalar_Encapsed( + 22: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A ) ) ) - 19: Scalar_Encapsed( + 23: Scalar_Encapsed( parts: array( 0: Expr_Variable( name: A