annotate vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php @ 19:fa3358dc1485 tip

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