Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 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
        $this->attributes = $attributes;
38
        $this->value = $value;
39
    }
40
 
41
    public function getSubNodeNames() : array {
42
        return ['value'];
43
    }
44
 
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
 
61
    /**
62
     * @internal
63
     *
64
     * Parses a string token.
65
     *
66
     * @param string $str String token content
67
     * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
68
     *
69
     * @return string The parsed string
70
     */
71
    public static function parse(string $str, bool $parseUnicodeEscape = true) : string {
72
        $bLength = 0;
73
        if ('b' === $str[0] || 'B' === $str[0]) {
74
            $bLength = 1;
75
        }
76
 
77
        if ('\'' === $str[$bLength]) {
78
            return str_replace(
79
                ['\\\\', '\\\''],
80
                ['\\', '\''],
81
                substr($str, $bLength + 1, -1)
82
            );
83
        } else {
84
            return self::parseEscapeSequences(
85
                substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape
86
            );
87
        }
88
    }
89
 
90
    /**
91
     * @internal
92
     *
93
     * Parses escape sequences in strings (all string types apart from single quoted).
94
     *
95
     * @param string      $str   String without quotes
96
     * @param null|string $quote Quote type
97
     * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes
98
     *
99
     * @return string String with escape sequences parsed
100
     */
101
    public static function parseEscapeSequences(string $str, $quote, bool $parseUnicodeEscape = true) : string {
102
        if (null !== $quote) {
103
            $str = str_replace('\\' . $quote, $quote, $str);
104
        }
105
 
106
        $extra = '';
107
        if ($parseUnicodeEscape) {
108
            $extra = '|u\{([0-9a-fA-F]+)\}';
109
        }
110
 
111
        return preg_replace_callback(
112
            '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~',
113
            function($matches) {
114
                $str = $matches[1];
115
 
116
                if (isset(self::$replacements[$str])) {
117
                    return self::$replacements[$str];
118
                } elseif ('x' === $str[0] || 'X' === $str[0]) {
119
                    return chr(hexdec(substr($str, 1)));
120
                } elseif ('u' === $str[0]) {
121
                    return self::codePointToUtf8(hexdec($matches[2]));
122
                } else {
123
                    return chr(octdec($str));
124
                }
125
            },
126
            $str
127
        );
128
    }
129
 
130
    /**
131
     * Converts a Unicode code point to its UTF-8 encoded representation.
132
     *
133
     * @param int $num Code point
134
     *
135
     * @return string UTF-8 representation of code point
136
     */
137
    private static function codePointToUtf8(int $num) : string {
138
        if ($num <= 0x7F) {
139
            return chr($num);
140
        }
141
        if ($num <= 0x7FF) {
142
            return chr(($num>>6) + 0xC0) . chr(($num&0x3F) + 0x80);
143
        }
144
        if ($num <= 0xFFFF) {
145
            return chr(($num>>12) + 0xE0) . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80);
146
        }
147
        if ($num <= 0x1FFFFF) {
148
            return chr(($num>>18) + 0xF0) . chr((($num>>12)&0x3F) + 0x80)
149
                 . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80);
150
        }
151
        throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large');
152
    }
153
 
154
    public function getType() : string {
155
        return 'Scalar_String';
156
    }
157
}