Skip to content

Commit

Permalink
improve method and property flags
Browse files Browse the repository at this point in the history
  • Loading branch information
eric-therond authored and nikic committed Dec 9, 2021
1 parent a9cecd2 commit 6f81f1e
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 25 deletions.
49 changes: 49 additions & 0 deletions lib/PHPCfg/Op/Stmt/ClassMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,55 @@

namespace PHPCfg\Op\Stmt;

use PHPCfg\Func;
use PhpParser\Node;

class ClassMethod extends Function_
{
public int $visibility;

public bool $static;

public bool $final;

public bool $abstract;

public function __construct(Func $func, int $visiblity, bool $static, bool $final, bool $abstract, array $attributes = [])
{
parent::__construct($func, $attributes);
$this->visibility = $visiblity;
$this->static = $static;
$this->final = $final;
$this->abstract = $abstract;
}

public function isPublic() : bool
{
return (bool) ($this->visibility & Node\Stmt\Class_::MODIFIER_PUBLIC);
}

public function isProtected() : bool
{
return (bool) ($this->visibility & Node\Stmt\Class_::MODIFIER_PROTECTED);
}

public function isPrivate() : bool
{
return (bool) ($this->visibility & Node\Stmt\Class_::MODIFIER_PRIVATE);
}

public function isAbstract() : bool
{
return $this->abstract;
}

public function isFinal() : bool
{
return $this->final;
}

public function isStatic() : bool
{
return $this->static;
}
}
4 changes: 2 additions & 2 deletions lib/PHPCfg/Op/Stmt/Function_.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ public function __construct(Func $func, array $attributes = [])
$this->func = $func;
}

public function getFunc(): Func {
public function getFunc(): Func
{
return $this->func;
}

}
31 changes: 30 additions & 1 deletion lib/PHPCfg/Op/Stmt/Property.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use PHPCfg\Op\Stmt;
use PHPCfg\Op;
use PhpCfg\Operand;
use PhpParser\Node;

class Property extends Stmt
{
Expand All @@ -24,25 +25,53 @@ class Property extends Stmt

public bool $static;

public bool $readonly;

public ?Operand $defaultVar = null;

public ?Block $defaultBlock = null;

public Op\Type $declaredType ;

public function __construct(Operand $name, int $visiblity, bool $static, Op\Type $declaredType = null, Operand $defaultVar = null, Block $defaultBlock = null, array $attributes = [])
public function __construct(Operand $name, int $visiblity, bool $static, bool $readonly, Op\Type $declaredType = null, Operand $defaultVar = null, Block $defaultBlock = null, array $attributes = [])
{
parent::__construct($attributes);
$this->name = $this->addReadRef($name);
$this->visibility = $visiblity;
$this->static = $static;
$this->readonly = $readonly;
$this->declaredType = $declaredType;
if (!is_null($defaultVar)) {
$this->defaultVar = $this->addReadRef($defaultVar);
}
$this->defaultBlock = $defaultBlock;
}

public function isPublic() : bool
{
return (bool) ($this->visibility & Node\Stmt\Class_::MODIFIER_PUBLIC);
}

public function isProtected() : bool
{
return (bool) ($this->visibility & Node\Stmt\Class_::MODIFIER_PROTECTED);
}

public function isPrivate() : bool
{
return (bool) ($this->visibility & Node\Stmt\Class_::MODIFIER_PRIVATE);
}

public function isStatic() : bool
{
return $this->static;
}

public function isReadonly() : bool
{
return $this->readonly;
}

public function getVariableNames(): array
{
return ['name', 'defaultVar'];
Expand Down
60 changes: 45 additions & 15 deletions lib/PHPCfg/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ protected function parseNode(Node $node)
throw new \RuntimeException('Unknown Node Encountered : '.$type);
}

protected function parseTypeNode(?Node $node): Op\Type {
protected function parseTypeNode(?Node $node): Op\Type
{
if (is_null($node)) {
return new Op\Type\Mixed_;
}
Expand All @@ -188,8 +189,8 @@ protected function parseTypeNode(?Node $node): Op\Type {
}
if ($node instanceof Node\UnionType) {
$parsedTypes = [];
foreach($node->types as $type) {
$parsedTypes[] = $this->parseTypeNode($type);
foreach ($node->types as $type) {
$parsedTypes[] = $this->parseTypeNode($type);
}

return new Op\Type\Union(
Expand Down Expand Up @@ -240,7 +241,8 @@ protected function parseStmt_ClassConst(Stmt\ClassConst $node)

$this->block->children[] = new Op\Terminal\Const_(
$this->parseExprNode($const->name),
$value, $valueBlock,
$value,
$valueBlock,
$this->mapAttributes($node)
);
}
Expand All @@ -266,7 +268,19 @@ protected function parseStmt_ClassMethod(Stmt\ClassMethod $node)
$func->cfg = null;
}

$this->block->children[] = $class_method = new Op\Stmt\ClassMethod($func, $this->mapAttributes($node));
$visibility = $node->flags & Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK;
$static = $node->flags & Node\Stmt\Class_::MODIFIER_STATIC;
$final = $node->flags & Node\Stmt\Class_::MODIFIER_FINAL;
$abstract = $node->flags & Node\Stmt\Class_::MODIFIER_ABSTRACT;

$this->block->children[] = $class_method = new Op\Stmt\ClassMethod(
$func,
$visibility,
(bool) $static,
(bool) $final,
(bool) $abstract,
$this->mapAttributes($node)
);
$func->callableOp = $class_method;
}

Expand All @@ -280,7 +294,8 @@ protected function parseStmt_Const(Stmt\Const_ $node)

$this->block->children[] = new Op\Terminal\Const_(
$this->parseExprNode($const->namespacedName),
$value, $valueBlock,
$value,
$valueBlock,
$this->mapAttributes($node)
);
}
Expand Down Expand Up @@ -536,6 +551,7 @@ protected function parseStmt_Property(Stmt\Property $node)
{
$visibility = $node->flags & Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK;
$static = $node->flags & Node\Stmt\Class_::MODIFIER_STATIC;
$readonly = $node->flags & Node\Stmt\Class_::MODIFIER_READONLY;

foreach ($node->props as $prop) {
if ($prop->default) {
Expand All @@ -551,6 +567,7 @@ protected function parseStmt_Property(Stmt\Property $node)
$this->parseExprNode($prop->name),
$visibility,
(bool) $static,
(bool) $readonly,
$this->parseTypeNode($node->type),
$defaultVar,
$defaultBlock,
Expand Down Expand Up @@ -615,7 +632,9 @@ protected function parseStmt_Switch(Stmt\Switch_ $node)
if ($case->cond) {
$caseExpr = $this->parseExprNode($case->cond);
$this->block->children[] = $cmp = new Op\Expr\BinaryOp\Equal(
$this->readVariable($cond), $this->readVariable($caseExpr), $this->mapAttributes($case)
$this->readVariable($cond),
$this->readVariable($caseExpr),
$this->mapAttributes($case)
);

$elseBlock = new Block();
Expand Down Expand Up @@ -934,7 +953,9 @@ protected function parseExpr_AssignRef(Expr\AssignRef $expr)
protected function parseExpr_BitwiseNot(Expr\BitwiseNot $expr)
{
return new Op\Expr\BitwiseNot(
$this->readVariable($this->parseExprNode($expr->expr)), $this->mapAttributes($expr));
$this->readVariable($this->parseExprNode($expr->expr)),
$this->mapAttributes($expr)
);
}

protected function parseExpr_BooleanNot(Expr\BooleanNot $expr)
Expand Down Expand Up @@ -1152,7 +1173,8 @@ protected function parseListAssignment($expr, Operand $rhs)

$assign = new Op\Expr\Assign(
$this->writeVariable($this->parseExprNode($var)),
$fetch->result, $attributes
$fetch->result,
$attributes
);
$this->block->children[] = $assign;
}
Expand All @@ -1171,10 +1193,10 @@ 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;
$this->parseStmt_Class($expr->class);
$classExpr = $expr->class->name;
} else {
$classExpr = $expr->class;
$classExpr = $expr->class;
}

return new Op\Expr\New_(
Expand Down Expand Up @@ -1277,7 +1299,9 @@ protected function parseExpr_Ternary(Expr\Ternary $expr)
$ifVar = new Temporary();
if ($expr->if) {
$this->block->children[] = new Op\Expr\Assign(
$ifVar, $this->readVariable($this->parseExprNode($expr->if)), $attrs
$ifVar,
$this->readVariable($this->parseExprNode($expr->if)),
$attrs
);
} else {
$this->block->children[] = new Op\Expr\Assign($ifVar, $cond, $attrs);
Expand All @@ -1288,7 +1312,9 @@ protected function parseExpr_Ternary(Expr\Ternary $expr)
$this->block = $elseBlock;
$elseVar = new Temporary();
$this->block->children[] = new Op\Expr\Assign(
$elseVar, $this->readVariable($this->parseExprNode($expr->else)), $attrs
$elseVar,
$this->readVariable($this->parseExprNode($expr->else)),
$attrs
);
$this->block->children[] = new Jump($endBlock, $attrs);
$endBlock->addParent($this->block);
Expand Down Expand Up @@ -1421,7 +1447,11 @@ private function compileJumptableSwitch(Stmt\Switch_ $node)
$block = $this->parseNodes($case->stmts, $caseBlock);
}
$this->block->children[] = new Op\Stmt\Switch_(
$cond, $cases, $targets, $defaultBlock, $this->mapAttributes($node)
$cond,
$cases,
$targets,
$defaultBlock,
$this->mapAttributes($node)
);
if ($block && ! $block->dead) {
// wire end of block to endblock
Expand Down
51 changes: 44 additions & 7 deletions lib/PHPCfg/Printer.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,12 @@ protected function renderOp(Op $op)
$result .= '<'.$this->renderAssertion($op->assertion).'>';
}
if ($op instanceof Op\Stmt\Property) {
$result .= "\n flags: " . $this->indent($this->renderFlags($op));
$result .= "\n declaredType: " . $this->indent($this->renderType($op->declaredType));
}
if ($op instanceof Op\Stmt\ClassMethod) {
$result .= "\n flags: " . $this->indent($this->renderFlags($op));
}
if ($op instanceof Op\Expr\Param) {
$result .= "\n declaredType: " . $this->indent($this->renderType($op->declaredType));
}
Expand Down Expand Up @@ -244,7 +248,8 @@ protected function render(Func $func)
];
}

protected function renderType(?Op\Type $type): string {
protected function renderType(?Op\Type $type): string
{
if ($type instanceof Op\Type\Mixed_) {
return 'mixed';
}
Expand All @@ -257,12 +262,12 @@ protected function renderType(?Op\Type $type): string {
if ($type instanceof Op\Type\Union) {
$i = 1;
$strTypes = "";
foreach($type->subtypes as $subtype) {
$strTypes .= $this->renderType($subtype);
if($i < count($type->subtypes)) {
$strTypes .= "|";
}
$i ++;
foreach ($type->subtypes as $subtype) {
$strTypes .= $this->renderType($subtype);
if ($i < count($type->subtypes)) {
$strTypes .= "|";
}
$i ++;
}
return $strTypes;
}
Expand All @@ -277,4 +282,36 @@ protected function renderType(?Op\Type $type): string {
}
throw new \LogicException("Unknown type rendering: " . get_class($type));
}

protected function renderFlags(Op\Stmt $stmt): string
{
$result = '';

if ($stmt instanceof Op\Stmt\Property) {
if ($stmt->isReadOnly()) {
$result .= "readonly|";
}
} elseif ($stmt instanceof Op\Stmt\ClassMethod) {
if ($stmt->isFinal()) {
$result .= "final|";
}
if ($stmt->isAbstract()) {
$result .= "abstract|";
}
}

if ($stmt->isStatic()) {
$result .= "static|";
}

if ($stmt->isProtected()) {
$result .= "protected";
} elseif ($stmt->isPrivate()) {
$result .= "private";
} else {
$result .= "public";
}

return $result;
}
}
1 change: 1 addition & 0 deletions test/code/anonymous_class.test
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Block#1

Block#2
Stmt_ClassMethod<doSomething>
flags: public

Function {anonymousClass}#1::doSomething(): mixed
Block#1
Expand Down

0 comments on commit 6f81f1e

Please sign in to comment.