Skip to content

Commit d90d60d

Browse files
committed
WIP - support more node types
1 parent 30d1ca0 commit d90d60d

File tree

5 files changed

+107
-22
lines changed

5 files changed

+107
-22
lines changed

src/ASTConverter/ASTConverter.php

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,17 @@ private static function _init_handle_map() : array {
312312
$startLine
313313
);
314314
},
315+
'PhpParser\Node\Expr\StaticPropertyFetch' => function(PhpParser\Node\Expr\StaticPropertyFetch $n, int $startLine) : \ast\Node {
316+
return astnode(
317+
\ast\AST_STATIC_PROP,
318+
0,
319+
[
320+
'class' => self::_phpparser_node_to_ast_node($n->class),
321+
'prop' => is_string($n->name) ? $n->name : self::_phpparser_node_to_ast_node($n->name),
322+
],
323+
$startLine
324+
);
325+
},
315326
'PhpParser\Node\Expr\UnaryMinus' => function(PhpParser\Node\Expr\UnaryMinus $n, int $startLine) : \ast\Node {
316327
return self::_ast_node_unary_op(\ast\flags\UNARY_MINUS, self::_phpparser_node_to_ast_node($n->expr), $startLine);
317328
},
@@ -404,12 +415,32 @@ private static function _init_handle_map() : array {
404415
$n->implements ?: null,
405416
self::_phpparser_stmtlist_to_ast_node($n->stmts, $startLine),
406417
$startLine,
407-
$endLine
418+
$endLine,
419+
self::_extract_phpdoc_comment($n->getAttribute('comments'))
408420
);
409421
},
410422
'PhpParser\Node\Stmt\ClassConst' => function(PhpParser\Node\Stmt\ClassConst $n, int $startLine) : \ast\Node {
411423
return self::_phpparser_class_const_to_ast_node($n, $startLine);
412424
},
425+
'PhpParser\Node\Stmt\ClassMethod' => function(PhpParser\Node\Stmt\ClassMethod $n, int $startLine) : \ast\Node {
426+
return astdecl(
427+
\ast\AST_METHOD,
428+
self::_phpparser_visibility_to_ast_visibility($n->flags) | ($n->byRef ? \ast\flags\RETURNS_REF : 0),
429+
[
430+
'params' => self::_phpparser_params_to_ast_params($n->params, $startLine),
431+
'uses' => null, // TODO: anonymous class?
432+
'stmts' => is_array($n->stmts) ? self::_phpparser_stmtlist_to_ast_node($n->stmts, $startLine) : null,
433+
'returnType' => self::_phpparser_type_to_ast_node($n->returnType, sl($n->returnType) ?: $startLine)
434+
],
435+
$startLine,
436+
self::_extract_phpdoc_comment($n->getAttribute('comments')),
437+
$n->name,
438+
$n->getAttribute('endLine')
439+
);
440+
},
441+
'PhpParser\Node\Stmt\Const_' => function(PhpParser\Node\Stmt\Const_ $n, int $startLine) : \ast\Node {
442+
return self::_phpparser_const_to_ast_node($n, $startLine);
443+
},
413444
'PhpParser\Node\Stmt\Declare_' => function(PhpParser\Node\Stmt\Declare_ $n, int $startLine) : \ast\Node {
414445
return self::_ast_stmt_declare(
415446
self::_phpparser_declare_list_to_ast_declares($n->declares, $startLine),
@@ -484,9 +515,10 @@ private static function _init_handle_map() : array {
484515
$n->name,
485516
null,
486517
null,
487-
self::_phpparser_stmtlist_to_ast_node($n->stmts, $startLine),
518+
is_array($n->stmts) ? self::_phpparser_stmtlist_to_ast_node($n->stmts, $startLine) : null,
488519
$startLine,
489-
$endLine
520+
$endLine,
521+
self::_extract_phpdoc_comment($n->getAttribute('comments'))
490522
);
491523
},
492524
/**
@@ -531,7 +563,8 @@ private static function _init_handle_map() : array {
531563
null,
532564
self::_phpparser_stmtlist_to_ast_node($n->stmts, $startLine),
533565
$startLine,
534-
$endLine
566+
$endLine,
567+
self::_extract_phpdoc_comment($n->getAttribute('comments'))
535568
);
536569
},
537570
'PhpParser\Node\Stmt\TryCatch' => function(PhpParser\Node\Stmt\TryCatch $n, int $startLine) : \ast\Node {
@@ -914,7 +947,7 @@ private static function _phpparser_class_flags_to_ast_class_flags(int $flags) {
914947
* @param ?string $name
915948
* @param mixed|null $extends TODO
916949
* @param ?array $implements
917-
* @param \ast\Node|null $stmts
950+
* @param ?\ast\Node $stmts
918951
* @param int $line
919952
* @param int $endLine
920953
* @suppress PhanTypeMismatchProperty (?string to string|null is incorrectly reported)
@@ -926,25 +959,26 @@ private static function _ast_stmt_class(
926959
?array $implements,
927960
?\ast\Node $stmts,
928961
int $line,
929-
int $endLine
962+
int $endLine,
963+
?string $docComment
930964
) : \ast\Node\Decl {
931965
if ($name === null) {
932966
$flags |= \ast\flags\CLASS_ANONYMOUS;
933967
}
934968

935-
$node = new \ast\Node\Decl;
936-
$node->kind = \ast\AST_CLASS;
937-
$node->flags = $flags;
938-
$node->lineno = $line;
939-
$node->endLineno = $endLine;
940-
$node->children = [
941-
'extends' => $extends, // FIXME
942-
'implements' => $implements, // FIXME
943-
'stmts' => $stmts,
944-
];
945-
$node->name = $name;
946-
947-
return $node;
969+
return astdecl(
970+
\ast\AST_CLASS,
971+
$flags,
972+
[
973+
'extends' => $extends, // FIXME
974+
'implements' => $implements, // FIXME
975+
'stmts' => $stmts,
976+
],
977+
$line,
978+
$docComment,
979+
$name,
980+
$endLine
981+
);
948982
}
949983

950984
private static function _phpparser_arg_list_to_ast_arg_list(array $args, int $line) : \ast\Node {
@@ -1121,6 +1155,7 @@ private static function _phpparser_constelem_to_ast_constelem(PhpParser\Node\Con
11211155

11221156
return astnode(\ast\AST_CONST_ELEM, 0, $children, $startLine, self::_extract_phpdoc_comment($n->getAttribute('comments') ?? $docComment));
11231157
}
1158+
11241159
private static function _phpparser_visibility_to_ast_visibility(int $visibility) : int {
11251160
$ast_visibility = 0;
11261161
if ($visibility & \PHPParser\Node\Stmt\Class_::MODIFIER_PUBLIC) {
@@ -1157,9 +1192,7 @@ private static function _phpparser_property_to_ast_node(PhpParser\Node $n, int $
11571192
return astnode(\ast\AST_PROP_DECL, $flags, $propElems, $propElems[0]->lineno ?: $startLine);
11581193
}
11591194

1160-
private static function _phpparser_class_const_to_ast_node(PhpParser\Node $n, int $startLine) : \ast\Node {
1161-
assert($n instanceof \PHPParser\Node\Stmt\ClassConst);
1162-
1195+
private static function _phpparser_class_const_to_ast_node(PhpParser\Node\Stmt\ClassConst $n, int $startLine) : \ast\Node {
11631196
$constElems = [];
11641197
$docComment = self::_extract_phpdoc_comment($n->getAttribute('comments'));
11651198
foreach ($n->consts as $i => $prop) {
@@ -1170,6 +1203,16 @@ private static function _phpparser_class_const_to_ast_node(PhpParser\Node $n, in
11701203
return astnode(\ast\AST_CLASS_CONST_DECL, $flags, $constElems, $constElems[0]->lineno ?: $startLine);
11711204
}
11721205

1206+
private static function _phpparser_const_to_ast_node(PhpParser\Node\Stmt\Const_ $n, int $startLine) : \ast\Node {
1207+
$constElems = [];
1208+
$docComment = self::_extract_phpdoc_comment($n->getAttribute('comments'));
1209+
foreach ($n->consts as $i => $prop) {
1210+
$constElems[] = self::_phpparser_constelem_to_ast_constelem($prop, $i === 0 ? $docComment : null);
1211+
}
1212+
1213+
return astnode(\ast\AST_CONST_DECL, 0, $constElems, $constElems[0]->lineno ?: $startLine);
1214+
}
1215+
11731216
private static function _phpparser_declare_list_to_ast_declares(array $declares, int $startLine) : \ast\Node {
11741217
$astDeclareElements = [];
11751218
foreach ($declares as $declare) {
@@ -1324,6 +1367,27 @@ function astnode(int $kind, int $flags, ?array $children, int $lineno, ?string $
13241367
return $node;
13251368
}
13261369

1370+
/**
1371+
* @suppress PhanTypeMismatchProperty https://github.com/etsy/phan/issues/609
1372+
* @suppress PhanUndeclaredProperty - docComment really exists.
1373+
* NOTE: this may be removed in the future.
1374+
*
1375+
* Phan was used while developing this. The asserts can be cleaned up in the future.
1376+
*/
1377+
function astdecl(int $kind, int $flags, ?array $children, int $lineno, string $docComment = null, string $name = null, int $endLineno = 0) : \ast\Node\Decl {
1378+
$node = new \ast\Node\Decl();
1379+
$node->kind = $kind;
1380+
$node->flags = $flags;
1381+
$node->lineno = $lineno;
1382+
$node->children = $children;
1383+
if (\is_string($docComment)) {
1384+
$node->docComment = $docComment;
1385+
}
1386+
$node->name = $name;
1387+
$node->endLineno = $endLineno;
1388+
return $node;
1389+
}
1390+
13271391
function sl($node) : ?int {
13281392
if ($node instanceof PhpParser\Node) {
13291393
return $node->getAttribute('startLine');

test_files/src/classmethod.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
abstract class A {
3+
private $x;
4+
protected $y = ['val'];
5+
6+
const X = 2;
7+
private const Y = 3;
8+
9+
public function foo(string $x) : string {}
10+
protected abstract static function fooAbstract(string $x);
11+
function old() {}
12+
}

test_files/src/classmethod2.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
interface A {
3+
public function &foo(string $x) : string;
4+
}

test_files/src/const.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
const FOO = 4;
3+
const A = 'value', B = FOO;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
A::$x += 2;

0 commit comments

Comments
 (0)