diff --git a/grammar/php5.y b/grammar/php5.y index f9e7e7dd16..927762b450 100644 --- a/grammar/php5.y +++ b/grammar/php5.y @@ -793,7 +793,7 @@ ctor_arguments: common_scalar: T_LNUMBER { $$ = $this->parseLNumber($1, attributes(), true); } - | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } + | T_DNUMBER { $$ = Scalar\DNumber::fromString($1, attributes()); } | T_CONSTANT_ENCAPSED_STRING { $attrs = attributes(); $attrs['kind'] = strKind($1); $$ = new Scalar\String_(Scalar\String_::parse($1, false), $attrs); } diff --git a/grammar/php7.y b/grammar/php7.y index eac68d095a..379581f6a0 100644 --- a/grammar/php7.y +++ b/grammar/php7.y @@ -1024,7 +1024,7 @@ dereferencable_scalar: scalar: T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); } - | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } + | T_DNUMBER { $$ = Scalar\DNumber::fromString($1, attributes()); } | dereferencable_scalar { $$ = $1; } | constant { $$ = $1; } | class_constant { $$ = $1; } diff --git a/lib/PhpParser/Node/Scalar/DNumber.php b/lib/PhpParser/Node/Scalar/DNumber.php index 29ce0dd401..d4796d65bb 100644 --- a/lib/PhpParser/Node/Scalar/DNumber.php +++ b/lib/PhpParser/Node/Scalar/DNumber.php @@ -24,6 +24,17 @@ public function getSubNodeNames() : array { return ['value']; } + /** + * @param mixed[] $attributes + */ + public static function fromString(string $str, array $attributes = []): DNumber + { + $attributes['rawValue'] = $str; + $float = self::parse($str); + + return new DNumber($float, $attributes); + } + /** * @internal * @@ -63,7 +74,7 @@ public static function parse(string $str) : float { // dec return (float) $str; } - + public function getType() : string { return 'Scalar_DNumber'; } diff --git a/lib/PhpParser/Parser/Php5.php b/lib/PhpParser/Parser/Php5.php index c62adfd2ce..9ab8d6b9bd 100644 --- a/lib/PhpParser/Parser/Php5.php +++ b/lib/PhpParser/Parser/Php5.php @@ -2275,7 +2275,7 @@ protected function initReduceCallbacks() { $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes, true); }, 434 => function ($stackPos) { - $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + $this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, 435 => function ($stackPos) { $attrs = $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(1-1)][0] === "'" || ($this->semStack[$stackPos-(1-1)][1] === "'" && ($this->semStack[$stackPos-(1-1)][0] === 'b' || $this->semStack[$stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); diff --git a/lib/PhpParser/Parser/Php7.php b/lib/PhpParser/Parser/Php7.php index 7a0854b306..4eb291ea5f 100644 --- a/lib/PhpParser/Parser/Php7.php +++ b/lib/PhpParser/Parser/Php7.php @@ -2554,7 +2554,7 @@ protected function initReduceCallbacks() { $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, 515 => function ($stackPos) { - $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + $this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); }, 516 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(1-1)]; diff --git a/test/PhpParser/Node/Scalar/DNumberTest.php b/test/PhpParser/Node/Scalar/DNumberTest.php new file mode 100644 index 0000000000..b3e7c76a3c --- /dev/null +++ b/test/PhpParser/Node/Scalar/DNumberTest.php @@ -0,0 +1,27 @@ +create(ParserFactory::PREFER_PHP7); + $nodes = $parser->parse('assertInstanceOf(Echo_::class, $echo); + + /** @var Echo_ $echo */ + $lLumber = $echo->exprs[0]; + $this->assertInstanceOf(DNumber::class, $lLumber); + + /** @var DNumber $dnumber */ + $this->assertSame(1234.56, $lLumber->value); + $this->assertSame('1_234.56', $lLumber->getAttribute('rawValue')); + } +} diff --git a/test/PhpParser/NodeAbstractTest.php b/test/PhpParser/NodeAbstractTest.php index 3553c4c87b..2ea13cd3db 100644 --- a/test/PhpParser/NodeAbstractTest.php +++ b/test/PhpParser/NodeAbstractTest.php @@ -273,7 +273,8 @@ function functionName(&$a = 0, $b = 1.0) { "value": 1, "attributes": { "startLine": 4, - "endLine": 4 + "endLine": 4, + "rawValue": "1.0" } }, "flags": 0, @@ -426,7 +427,8 @@ function functionName(&$a = 0, $b = 1.0) { "nodeType": "Scalar_DNumber", "attributes": { "startLine": 4, - "endLine": 4 + "endLine": 4, + "rawValue": "1.0" }, "value": 1 },