Skip to content

Commit

Permalink
support of anonymous classes (#72)
Browse files Browse the repository at this point in the history
Generate a name for anonymous classes and treat them the same way as normal classes.
  • Loading branch information
eric-therond committed Apr 12, 2021
1 parent 270be13 commit acc7cbc
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
9 changes: 9 additions & 0 deletions lib/PHPCfg/AstVisitor/NameResolver.php
Expand Up @@ -42,10 +42,19 @@ class NameResolver extends NameResolverParent
'resource',
'callable',
];

protected $anonymousClasses = 0;

public function enterNode(Node $node)
{
parent::enterNode($node);

if ($node instanceof Node\Stmt\Class_ && is_null($node->name)) {
$anonymousName = "{anonymousClass}#".++$this->anonymousClasses;
$node->name = new \PhpParser\Node\Identifier($anonymousName);
$node->namespacedName = new \PhpParser\Node\Name($anonymousName);
}

$comment = $node->getDocComment();
if ($comment) {
$regex = '(@(param|return|var|type)\\h+(\\S+))';
Expand Down
9 changes: 8 additions & 1 deletion lib/PHPCfg/Parser.php
Expand Up @@ -1159,8 +1159,15 @@ protected function parseExpr_MethodCall(Expr\MethodCall $expr)

protected function parseExpr_New(Expr\New_ $expr)
{
if ($expr->class instanceof Node\Stmt\Class_) {
$this->parseStmt_Class($expr->class);
$classExpr = $expr->class->name;
} else {
$classExpr = $expr->class;
}

return new Op\Expr\New_(
$this->readVariable($this->parseExprNode($expr->class)),
$this->readVariable($this->parseExprNode($classExpr)),
$this->parseExprList($expr->args, self::MODE_READ),
$this->mapAttributes($expr)
);
Expand Down
28 changes: 28 additions & 0 deletions test/code/anonymous_class.test
@@ -0,0 +1,28 @@
<?php
$var = new class {
function doSomething() {
echo "Hello World";
}
};
-----
Block#1
Stmt_Class
name: LITERAL('{anonymousClass}#1')
stmts: Block#2
Expr_New
class: LITERAL('{anonymousClass}#1')
result: Var#1
Expr_Assign
var: Var#2<$var>
expr: Var#1
result: Var#3
Terminal_Return

Block#2
Stmt_ClassMethod<doSomething>

Function {anonymousClass}#1::doSomething(): mixed
Block#1
Terminal_Echo
expr: LITERAL('Hello World')
Terminal_Return

0 comments on commit acc7cbc

Please sign in to comment.