1: | <?php declare(strict_types = 1); |
2: | |
3: | namespace ApiGen\Info\Expr; |
4: | |
5: | use ApiGen\Info\ExprInfo; |
6: | |
7: | use function mb_ord; |
8: | use function ord; |
9: | use function preg_match; |
10: | use function preg_replace_callback; |
11: | use function sprintf; |
12: | use function strlen; |
13: | |
14: | |
15: | class StringExprInfo implements ExprInfo |
16: | { |
17: | public function __construct( |
18: | public string $value, |
19: | public ?string $raw = null, |
20: | ) { |
21: | } |
22: | |
23: | |
24: | public function toString(): string |
25: | { |
26: | $utf8 = (bool) preg_match('##u', $this->value); |
27: | $pattern = $utf8 ? '#[\p{C}"\'\\\\]#u' : '#[\x00-\x1F\x7F-\xFF"\'\\\\]#'; |
28: | $special = ["\r" => '\r', "\n" => '\n', "\t" => '\t', '\\' => '\\\\', '"' => '\\"', '\'' => '\'']; |
29: | |
30: | $s = preg_replace_callback( |
31: | $pattern, |
32: | function ($m) use ($special) { |
33: | if (isset($special[$m[0]])) { |
34: | return $special[$m[0]]; |
35: | |
36: | } elseif (strlen($m[0]) === 1) { |
37: | return sprintf('\x%02X', ord($m[0])); |
38: | |
39: | } else { |
40: | return sprintf('\u{%X}', mb_ord($m[0])); |
41: | } |
42: | }, |
43: | $this->value, |
44: | -1, |
45: | $count, |
46: | ); |
47: | |
48: | $quote = $count === 0 ? "'" : '"'; |
49: | return $quote . $s . $quote; |
50: | } |
51: | } |
52: | |