cf12e8c6d1ef4fe9fb0ae0f9e112da916d3bb5a1
[yaffs-website] / vendor / nikic / php-parser / lib / PhpParser / Node / Scalar / String_.php
1 <?php declare(strict_types=1);
2
3 namespace PhpParser\Node\Scalar;
4
5 use PhpParser\Error;
6 use PhpParser\Node\Scalar;
7
8 class String_ extends Scalar
9 {
10     /* For use in "kind" attribute */
11     const KIND_SINGLE_QUOTED = 1;
12     const KIND_DOUBLE_QUOTED = 2;
13     const KIND_HEREDOC = 3;
14     const KIND_NOWDOC = 4;
15
16     /** @var string String value */
17     public $value;
18
19     protected static $replacements = [
20         '\\' => '\\',
21         '$'  =>  '$',
22         'n'  => "\n",
23         'r'  => "\r",
24         't'  => "\t",
25         'f'  => "\f",
26         'v'  => "\v",
27         'e'  => "\x1B",
28     ];
29
30     /**
31      * Constructs a string scalar node.
32      *
33      * @param string $value      Value of the string
34      * @param array  $attributes Additional attributes
35      */
36     public function __construct(string $value, array $attributes = []) {
37         parent::__construct($attributes);
38         $this->value = $value;
39     }
40
41     public function getSubNodeNames() : array {
42         return ['value'];
43     }
44
45     /**
46      * @internal
47      *
48      * Parses a string token.
49      *
50      * @param string $str String token content
51      * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
52      *
53      * @return string The parsed string
54      */
55     public static function parse(string $str, bool $parseUnicodeEscape = true) : string {
56         $bLength = 0;
57         if ('b' === $str[0] || 'B' === $str[0]) {
58             $bLength = 1;
59         }
60
61         if ('\'' === $str[$bLength]) {
62             return str_replace(
63                 ['\\\\', '\\\''],
64                 ['\\', '\''],
65                 substr($str, $bLength + 1, -1)
66             );
67         } else {
68             return self::parseEscapeSequences(
69                 substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape
70             );
71         }
72     }
73
74     /**
75      * @internal
76      *
77      * Parses escape sequences in strings (all string types apart from single quoted).
78      *
79      * @param string      $str   String without quotes
80      * @param null|string $quote Quote type
81      * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
82      *
83      * @return string String with escape sequences parsed
84      */
85     public static function parseEscapeSequences(string $str, $quote, bool $parseUnicodeEscape = true) : string {
86         if (null !== $quote) {
87             $str = str_replace('\\' . $quote, $quote, $str);
88         }
89
90         $extra = '';
91         if ($parseUnicodeEscape) {
92             $extra = '|u\{([0-9a-fA-F]+)\}';
93         }
94
95         return preg_replace_callback(
96             '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~',
97             function($matches) {
98                 $str = $matches[1];
99
100                 if (isset(self::$replacements[$str])) {
101                     return self::$replacements[$str];
102                 } elseif ('x' === $str[0] || 'X' === $str[0]) {
103                     return chr(hexdec($str));
104                 } elseif ('u' === $str[0]) {
105                     return self::codePointToUtf8(hexdec($matches[2]));
106                 } else {
107                     return chr(octdec($str));
108                 }
109             },
110             $str
111         );
112     }
113
114     /**
115      * Converts a Unicode code point to its UTF-8 encoded representation.
116      *
117      * @param int $num Code point
118      *
119      * @return string UTF-8 representation of code point
120      */
121     private static function codePointToUtf8(int $num) : string {
122         if ($num <= 0x7F) {
123             return chr($num);
124         }
125         if ($num <= 0x7FF) {
126             return chr(($num>>6) + 0xC0) . chr(($num&0x3F) + 0x80);
127         }
128         if ($num <= 0xFFFF) {
129             return chr(($num>>12) + 0xE0) . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80);
130         }
131         if ($num <= 0x1FFFFF) {
132             return chr(($num>>18) + 0xF0) . chr((($num>>12)&0x3F) + 0x80)
133                  . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80);
134         }
135         throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large');
136     }
137     
138     public function getType() : string {
139         return 'Scalar_String';
140     }
141 }