1: | <?php declare(strict_types=1); |
2: | |
3: | namespace Salient\PHPDoc; |
4: | |
5: | use Salient\Contract\Core\DictionaryInterface; |
6: | |
7: | |
8: | |
9: | |
10: | interface PHPDocRegex extends DictionaryInterface |
11: | { |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | |
18: | public const PHP_DOCBLOCK = <<<'REGEX' |
19: | (?x) |
20: | /\*\* (?= \s ) |
21: | (?<content> (?: |
22: | (?: (?! \*/ ) . )*+ |
23: | (?: (?<line> (?: \r\n | \n | \r ) \h* ) (?! \*/ ) \* )? |
24: | )*+ (?&line)? ) |
25: | \*/ |
26: | REGEX; |
27: | |
28: | |
29: | |
30: | |
31: | |
32: | |
33: | public const PHPDOC_TAG = <<<'REGEX' |
34: | (?x) |
35: | (?<= ^ | \r\n | \n | \r ) |
36: | @ (?<tag> [[:alpha:]\\] [[:alnum:]\\_-]*+ ) (?= [\s(:] | $ ) |
37: | REGEX; |
38: | |
39: | |
40: | |
41: | |
42: | |
43: | |
44: | |
45: | |
46: | public const PHPDOC_TYPE = <<<'REGEX' |
47: | (?xi) |
48: | (?(DEFINE) |
49: | (?<sp> [\f\n\r\t\x0b ] ) |
50: | (?<lnum> [0-9]+ (?: _ [0-9]+ )* ) |
51: | (?<dnum> (?: [0-9]* (?: _ [0-9]+ )* \. (?&lnum) ) | (?: (?&lnum) \. [0-9]* (?: _ [0-9]+ )* ) ) |
52: | (?<exponent_dnum> (?: (?&lnum) | (?&dnum) ) e [+-]? (?&lnum) ) |
53: | (?<php_identifier> [[:alpha:]_\x80-\xff] [[:alnum:]_\x80-\xff]* ) |
54: | (?<php_type> \\ (?&php_identifier) (?: \\ (?&php_identifier) )* | (?&php_identifier) (?: \\ (?&php_identifier) )+ ) |
55: | (?<phpdoc_type> (?&php_identifier) (?: - [[:alnum:]_\x80-\xff]+ )+ ) |
56: | (?<variable> \$ (?&php_identifier) ) |
57: | (?<variance> covariant | contravariant ) |
58: | (?<param> \s*+ (?: & \s*+ )? (?: \.\.\. \s*+ )? (?: (?&variable) \s*+ )? =? ) |
59: | (?<trailing> (?: \s*+ , (?: \s*+ \.\.\. (?: \s*+ , )? )? )? \s*+ ) |
60: | ) |
61: | ( |
62: | (?: |
63: | \* | |
64: | |
65: | \$this | |
66: | |
67: | # String |
68: | ' (?: [^'\\]*+ | \\' | \\ )*+ ' | |
69: | " (?: [^"\\]*+ | \\" | \\ )*+ " | |
70: | |
71: | # Number |
72: | [+-]? (?: |
73: | (?&exponent_dnum) | |
74: | (?&dnum) | |
75: | 0x [0-9a-f]++ (?: _ [0-9a-f]++ )*+ | |
76: | 0b [01]++ (?: _ [01]++ )*+ | |
77: | 0o? [0-7]++ (?: _ [0-7]++ )*+ | |
78: | [1-9] [0-9]*+ (?: _ [0-9]++ )*+ | |
79: | 0 |
80: | ) | |
81: | |
82: | # Closure with optional "<Type,...>", and optional parameter and |
83: | # return types |
84: | (?: callable | \\? Closure ) \s*+ |
85: | (?: \s* < (?&sp)*+ (?: (?&variance) (?&sp)*+ )? (?! (?&variance) \b ) (?: (?&php_identifier) \s++ (?: of | as ) \b (?&sp)*+ )? (?-1) |
86: | (?: \s*+ , (?&sp)*+ (?: (?&variance) (?&sp)*+ )? (?! (?&variance) \b ) (?: (?&php_identifier) \s++ (?: of | as ) \b (?&sp)*+ )? (?-1) )*+ |
87: | (?&trailing) > )? |
88: | \( (?&sp)*+ (?: (?-1) (?¶m) |
89: | (?: \s*+ , (?&sp)*+ (?-1) (?¶m) )*+ |
90: | (?&trailing) | \.\.\. \s*+ )? \) |
91: | (?: \s* : (?&sp)*+ (?-1) )? | |
92: | |
93: | # Native or PHPDoc type, possibly nullable, with optional |
94: | # "::CONST_*", "<Type,...>", and/or "{0?:Type,...}" |
95: | (?: \? (?&sp)*+ )? |
96: | (?: (?&php_type) | (?&phpdoc_type) | (?&php_identifier) ) |
97: | (?: :: [[:alpha:]_\x80-\xff*] [[:alnum:]_\x80-\xff*]*+ )? |
98: | (?: \s* < (?&sp)*+ (?: (?&variance) (?&sp)*+ )? (?! (?&variance) \b ) (?-1) |
99: | (?: \s*+ , (?&sp)*+ (?: (?&variance) (?&sp)*+ )? (?! (?&variance) \b ) (?-1) )*+ |
100: | (?&trailing) > )? |
101: | (?: \s* \{ (?&sp)*+ (?: |
102: | (?: (?-1) \s*+ (?: \? \s*+ )? : (?&sp)*+ )? (?-1) |
103: | (?: \s*+ , (?&sp)*+ (?: (?-1) \s*+ (?: \? \s*+ )? : (?&sp)*+ )? (?-1) )*+ |
104: | (?&trailing) | \.\.\. \s*+ )? \} )*+ | |
105: | |
106: | # Conditional return type |
107: | (?: (?&variable) | (?&php_identifier) ) \s+ is (?: \s++ not )? \b (?&sp)*+ (?-1) |
108: | \s*+ \? (?&sp)*+ (?-1) |
109: | \s*+ : (?&sp)*+ (?-1) | |
110: | |
111: | # Enclosing parentheses |
112: | (?: \? \s*+ )? \( (?&sp)*+ (?-1) \s*+ \) |
113: | ) |
114: | (?: \s* \[ (?&sp)*+ (?: (?-1) \s*+ )? \] )*+ |
115: | (?: \s* (?: \| | & ) (?&sp)* (?-1) )? |
116: | ) |
117: | REGEX; |
118: | } |
119: | |