Skip to content

Commit 5d83adc

Browse files
authored
[String_] Add rawValue attribute (#831)
1 parent 3bf0082 commit 5d83adc

File tree

8 files changed

+46
-25
lines changed

8 files changed

+46
-25
lines changed

grammar/php5.y

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -689,9 +689,7 @@ array_expr:
689689

690690
scalar_dereference:
691691
array_expr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
692-
| T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']'
693-
{ $attrs = attributes(); $attrs['kind'] = strKind($1);
694-
$$ = Expr\ArrayDimFetch[new Scalar\String_(Scalar\String_::parse($1), $attrs), $3]; }
692+
| T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[Scalar\String_::fromString($1, attributes()), $3]; }
695693
| constant '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
696694
| scalar_dereference '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; }
697695
/* alternative array syntax missing intentionally */
@@ -794,9 +792,7 @@ ctor_arguments:
794792
common_scalar:
795793
T_LNUMBER { $$ = $this->parseLNumber($1, attributes(), true); }
796794
| T_DNUMBER { $$ = Scalar\DNumber::fromString($1, attributes()); }
797-
| T_CONSTANT_ENCAPSED_STRING
798-
{ $attrs = attributes(); $attrs['kind'] = strKind($1);
799-
$$ = new Scalar\String_(Scalar\String_::parse($1, false), $attrs); }
795+
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar\String_::fromString($1, attributes(), false); }
800796
| T_LINE { $$ = Scalar\MagicConst\Line[]; }
801797
| T_FILE { $$ = Scalar\MagicConst\File[]; }
802798
| T_DIR { $$ = Scalar\MagicConst\Dir[]; }

grammar/php7.y

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,9 +1014,7 @@ dereferencable_scalar:
10141014
{ $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG;
10151015
$$ = new Expr\Array_($3, $attrs); }
10161016
| array_short_syntax { $$ = $1; }
1017-
| T_CONSTANT_ENCAPSED_STRING
1018-
{ $attrs = attributes(); $attrs['kind'] = strKind($1);
1019-
$$ = new Scalar\String_(Scalar\String_::parse($1), $attrs); }
1017+
| T_CONSTANT_ENCAPSED_STRING { $$ = Scalar\String_::fromString($1, attributes()); }
10201018
| '"' encaps_list '"'
10211019
{ $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;
10221020
parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); }

grammar/phpyLang.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,6 @@ function($matches) {
128128
. ' else { ' . $args[0] . ' = null; }';
129129
}
130130

131-
if ('strKind' === $name) {
132-
assertArgs(1, $args, $name);
133-
134-
return '(' . $args[0] . '[0] === "\'" || (' . $args[0] . '[1] === "\'" && '
135-
. '(' . $args[0] . '[0] === \'b\' || ' . $args[0] . '[0] === \'B\')) '
136-
. '? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED)';
137-
}
138-
139131
if ('prependLeadingComments' === $name) {
140132
assertArgs(1, $args, $name);
141133

lib/PhpParser/Node/Scalar/String_.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@ public function getSubNodeNames() : array {
4242
return ['value'];
4343
}
4444

45+
/**
46+
* @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
47+
*/
48+
public static function fromString(string $str, array $attributes = [], bool $parseUnicodeEscape = true): self
49+
{
50+
$attributes['kind'] = ($str[0] === "'" || ($str[1] === "'" && ($str[0] === 'b' || $str[0] === 'B')))
51+
? Scalar\String_::KIND_SINGLE_QUOTED
52+
: Scalar\String_::KIND_DOUBLE_QUOTED;
53+
54+
$attributes['rawValue'] = $str;
55+
56+
$string = self::parse($str, $parseUnicodeEscape);
57+
58+
return new self($string, $attributes);
59+
}
60+
4561
/**
4662
* @internal
4763
*

lib/PhpParser/Parser/Php5.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2147,8 +2147,7 @@ protected function initReduceCallbacks() {
21472147
$this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes);
21482148
},
21492149
392 => function ($stackPos) {
2150-
$attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(4-1)][0] === "'" || ($this->semStack[$stackPos-(4-1)][1] === "'" && ($this->semStack[$stackPos-(4-1)][0] === 'b' || $this->semStack[$stackPos-(4-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED);
2151-
$this->semValue = new Expr\ArrayDimFetch(new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(4-1)]), $attrs), $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes);
2150+
$this->semValue = new Expr\ArrayDimFetch(Scalar\String_::fromString($this->semStack[$stackPos-(4-1)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes), $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes);
21522151
},
21532152
393 => function ($stackPos) {
21542153
$this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes);
@@ -2278,8 +2277,7 @@ protected function initReduceCallbacks() {
22782277
$this->semValue = Scalar\DNumber::fromString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes);
22792278
},
22802279
435 => function ($stackPos) {
2281-
$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);
2282-
$this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)], false), $attrs);
2280+
$this->semValue = Scalar\String_::fromString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes, false);
22832281
},
22842282
436 => function ($stackPos) {
22852283
$this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes);

lib/PhpParser/Parser/Php7.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2543,8 +2543,7 @@ protected function initReduceCallbacks() {
25432543
$this->semValue = $this->semStack[$stackPos-(1-1)];
25442544
},
25452545
512 => function ($stackPos) {
2546-
$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);
2547-
$this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)]), $attrs);
2546+
$this->semValue = Scalar\String_::fromString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes);
25482547
},
25492548
513 => function ($stackPos) {
25502549
$attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED;

test/PhpParser/Node/Scalar/StringTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,28 @@
22

33
namespace PhpParser\Node\Scalar;
44

5+
use PhpParser\Node\Stmt\Echo_;
6+
use PhpParser\ParserFactory;
7+
58
class StringTest extends \PHPUnit\Framework\TestCase
69
{
10+
public function testRawValue()
11+
{
12+
$parser = (new ParserFactory())->create(ParserFactory::PREFER_PHP7);
13+
$nodes = $parser->parse('<?php echo "sequence \x41";');
14+
15+
$echo = $nodes[0];
16+
$this->assertInstanceOf(Echo_::class, $echo);
17+
18+
/** @var Echo_ $echo */
19+
$string = $echo->exprs[0];
20+
$this->assertInstanceOf(String_::class, $string);
21+
22+
/** @var String_ $string */
23+
$this->assertSame('sequence A', $string->value);
24+
$this->assertSame('"sequence \\x41"', $string->getAttribute('rawValue'));
25+
}
26+
727
/**
828
* @dataProvider provideTestParseEscapeSequences
929
*/

test/PhpParser/NodeAbstractTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ function functionName(&$a = 0, $b = 1.0) {
297297
"attributes": {
298298
"startLine": 5,
299299
"endLine": 5,
300-
"kind": 1
300+
"kind": 1,
301+
"rawValue": "'Foo'"
301302
}
302303
}
303304
],
@@ -452,7 +453,8 @@ function functionName(&$a = 0, $b = 1.0) {
452453
"attributes": {
453454
"startLine": 5,
454455
"endLine": 5,
455-
"kind": 1
456+
"kind": 1,
457+
"rawValue": "'Foo'"
456458
},
457459
"value": "Foo"
458460
}

0 commit comments

Comments
 (0)