1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
<?php declare(strict_types=1);
use ast\flags;
const AST_DUMP_LINENOS = 1;
const AST_DUMP_EXCLUDE_DOC_COMMENT = 2;
function get_flag_info() : array {
static $info;
if ($info !== null) {
return $info;
}
foreach (ast\get_metadata() as $data) {
if (empty($data->flags)) {
continue;
}
$flagMap = [];
foreach ($data->flags as $fullName) {
$shortName = substr($fullName, strrpos($fullName, '\\') + 1);
$flagMap[constant($fullName)] = $shortName;
}
$info[(int) $data->flagsCombinable][$data->kind] = $flagMap;
}
return $info;
}
function is_combinable_flag(int $kind) : bool {
return isset(get_flag_info()[1][$kind]);
}
function format_flags(int $kind, int $flags) : string {
list($exclusive, $combinable) = get_flag_info();
if (isset($exclusive[$kind])) {
$flagInfo = $exclusive[$kind];
if (isset($flagInfo[$flags])) {
return "{$flagInfo[$flags]} ($flags)";
}
} else if (isset($combinable[$kind])) {
$flagInfo = $combinable[$kind];
$names = [];
foreach ($flagInfo as $flag => $name) {
if ($flags & $flag) {
$names[] = $name;
}
}
if (!empty($names)) {
return implode(" | ", $names) . " ($flags)";
}
}
return (string) $flags;
}
/** Dumps abstract syntax tree */
function ast_dump($ast, int $options = 0) : string {
if ($ast instanceof ast\Node) {
$result = ast\get_kind_name($ast->kind);
if ($options & AST_DUMP_LINENOS) {
$result .= " @ $ast->lineno";
if (isset($ast->endLineno)) {
$result .= "-$ast->endLineno";
}
}
if ((ast\kind_uses_flags($ast->kind) && !is_combinable_flag($ast->kind)) || $ast->flags != 0) {
$result .= "\n flags: " . format_flags($ast->kind, $ast->flags);
}
foreach ($ast->children as $i => $child) {
if (($options & AST_DUMP_EXCLUDE_DOC_COMMENT) && $i === 'docComment') {
continue;
}
$result .= "\n $i: " . str_replace("\n", "\n ", ast_dump($child, $options));
}
return $result;
} else if ($ast === null) {
return 'null';
} else if (is_string($ast)) {
return "\"$ast\"";
} else {
return (string) $ast;
}
}
|