Skip to content

Commit 55c0db4

Browse files
committed
Fix text printer and tests
1 parent 30735dd commit 55c0db4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1122
-885
lines changed

lib/PHPCfg/Printer/Printer.php

Lines changed: 34 additions & 208 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,22 @@
3030

3131
abstract class Printer
3232
{
33-
private SplObjectStorage $varIds;
33+
const MODE_DEFAULT = 0b00000;
34+
const MODE_RENDER_ATTRIBUTES = 0b00001;
3435

3536
private SplQueue $blockQueue;
3637

3738
private SplObjectStorage $blocks;
3839

39-
private bool $renderAttributes;
40+
public bool $renderAttributes = false;
4041

4142
protected array $renderers = [];
4243

43-
public function __construct(bool $renderAttributes = false)
44+
public function __construct(int $mode = self::MODE_DEFAULT)
4445
{
45-
$this->renderAttributes = $renderAttributes;
46+
if ($mode & self::MODE_RENDER_ATTRIBUTES) {
47+
$this->renderAttributes = true;
48+
}
4649
$this->loadRenderers();
4750
$this->reset();
4851

@@ -115,141 +118,28 @@ public function renderOperand(Operand $var): string
115118
return 'UNKNOWN';
116119
}
117120

118-
protected function renderOp(Op $op): array
121+
public function renderOp(Op $op): array
119122
{
120-
$result = $op->getType();
121-
122-
if ($op instanceof Op\CallableOp) {
123-
$func = $op->getFunc();
124-
$result .= "<'" . $func->name . "'>";
125-
}
126-
127-
if ($op instanceof Op\Expr\Assertion) {
128-
$result .= '<' . $this->renderAssertion($op->assertion) . '>';
129-
}
130-
131-
$result .= $this->renderAttributes($op->getAttributes());
132-
133-
if ($op instanceof Op\AttributableOp) {
134-
$result .= $this->renderAttrGroups($op);
135-
}
136-
137-
if ($op instanceof Op\Stmt\Property || $op instanceof Op\Stmt\ClassMethod) {
138-
$result .= "\n flags: " . $this->indent($this->renderFlags($op));
139-
}
140-
141-
if ($op instanceof Op\Stmt\TraitUse) {
142-
foreach ($op->traits as $index => $trait_) {
143-
$result .= "\n use[$index]: " . $this->indent($this->renderOperand($trait_));
144-
}
145-
foreach ($op->adaptations as $index => $adaptation) {
146-
if ($adaptation instanceof Op\TraitUseAdaptation\Alias) {
147-
$result .= "\n adaptation[$index]: Alias";
148-
if ($adaptation->trait != null) {
149-
$result .= "\n trait:" . $this->indent($this->renderOperand($adaptation->trait));
150-
}
151-
$result .= "\n method:" . $this->indent($this->renderOperand($adaptation->method));
152-
if ($adaptation->newName != null) {
153-
$result .= "\n newName:" . $this->indent($this->renderOperand($adaptation->newName));
154-
}
155-
if ($adaptation->newModifier != null) {
156-
$result .= "\n newModifier:";
157-
if ($adaptation->isPublic()) {
158-
$result .= "public";
159-
}
160-
if ($adaptation->isPrivate()) {
161-
$result .= "private";
162-
}
163-
if ($adaptation->isProtected()) {
164-
$result .= "protected";
165-
}
166-
}
167-
} elseif ($adaptation instanceof Op\TraitUseAdaptation\Precedence) {
168-
$result .= "\n adaptation[$index]: Insteadof";
169-
if ($adaptation->trait != null) {
170-
$result .= "\n trait:" . $this->indent($this->renderOperand($adaptation->trait));
171-
}
172-
$result .= "\n method:" . $this->indent($this->renderOperand($adaptation->method));
173-
foreach ($adaptation->insteadof as $index2 => $insteadof) {
174-
$result .= "\n insteadof[$index2]: " . $this->indent($this->renderOperand($insteadof));
175-
}
176-
}
177-
}
178-
} elseif ($op instanceof Op\Expr\Include_) {
179-
$result .= "\n type: " . $this->indent($this->renderIncludeType($op->type));
180-
}
181-
182-
foreach ($op->getTypeNames() as $typeName => $type) {
183-
if (is_array($type)) {
184-
foreach ($type as $key => $subType) {
185-
if (! $subType) {
186-
continue;
187-
}
188-
$result .= "\n {$typeName}[{$key}]: ";
189-
$result .= $this->indent($this->renderType($subType));
190-
}
191-
} elseif ($type) {
192-
$result .= "\n {$typeName}: ";
193-
$result .= $this->indent($this->renderType($type));
194-
}
195-
}
196-
197-
foreach ($op->getVariableNames() as $varName => $vars) {
198-
if (is_array($vars)) {
199-
foreach ($vars as $key => $var) {
200-
if (! $var) {
201-
continue;
202-
}
203-
$result .= "\n {$varName}[{$key}]: ";
204-
$result .= $this->indent($this->renderOperand($var));
205-
}
206-
} elseif ($vars) {
207-
$result .= "\n {$varName}: ";
208-
$result .= $this->indent($this->renderOperand($vars));
209-
}
210-
}
211-
212-
$childBlocks = [];
213-
foreach ($op->getSubBlocks() as $blockName => $sub) {
214-
if (is_array($sub)) {
215-
foreach ($sub as $key => $subBlock) {
216-
if (! $subBlock) {
217-
continue;
218-
}
219-
$this->enqueueBlock($subBlock);
220-
$childBlocks[] = [
221-
'block' => $subBlock,
222-
'name' => $blockName . '[' . $key . ']',
223-
];
224-
}
225-
} elseif ($sub) {
226-
$this->enqueueBlock($sub);
227-
$childBlocks[] = ['block' => $sub, 'name' => $blockName];
123+
foreach ($this->renderers as $renderer) {
124+
$result = $renderer->renderOp($op);
125+
if ($result !== null) {
126+
$kind = $result['kind'];
127+
$childblocks = $result['childblocks'];
128+
return [
129+
'op' => $op,
130+
'label' => $this->renderOpLabel($result),
131+
'childBlocks' => $childblocks,
132+
];
228133
}
229134
}
230135

231136
return [
232137
'op' => $op,
233-
'label' => $result,
138+
'label' => 'UNKNOWN',
234139
'childBlocks' => $childBlocks,
235140
];
236141
}
237142

238-
protected function renderAssertion(Assertion $assert): string
239-
{
240-
$kind = $assert->getKind();
241-
if ($assert->value instanceof Operand) {
242-
return $kind . '(' . $this->renderOperand($assert->value) . ')';
243-
}
244-
$combinator = $assert->mode === Assertion::MODE_UNION ? '|' : '&';
245-
$results = [];
246-
foreach ($assert->value as $child) {
247-
$results[] = $this->renderAssertion($child);
248-
}
249-
250-
return $kind . '(' . implode($combinator, $results) . ')';
251-
}
252-
253143
protected function indent($str, $levels = 1): string
254144
{
255145
if ($levels > 1) {
@@ -259,16 +149,14 @@ protected function indent($str, $levels = 1): string
259149
return str_replace("\n", "\n ", $str);
260150
}
261151

262-
protected function enqueueBlock(Block $block): void
152+
public function enqueueBlock(Block $block): void
263153
{
264154
if (! $this->blocks->contains($block)) {
265155
$this->blocks[$block] = count($this->blocks) + 1;
266156
$this->blockQueue->enqueue($block);
267157
}
268158
}
269159

270-
271-
272160
protected function render(Func $func)
273161
{
274162
if (null !== $func->cfg) {
@@ -308,7 +196,7 @@ protected function render(Func $func)
308196
];
309197
}
310198

311-
protected function renderType(?Op\Type $type): string
199+
public function renderType(?Op\Type $type): string
312200
{
313201
if ($type instanceof Op\Type\Mixed_) {
314202
return 'mixed';
@@ -341,85 +229,23 @@ protected function renderType(?Op\Type $type): string
341229
throw new LogicException("Unknown type rendering: " . get_class($type));
342230
}
343231

344-
protected function renderIncludeType(int $type): string
232+
public function renderOpLabel(array $desc): string
345233
{
346-
switch ($type) {
347-
case 1:
348-
return "include";
349-
case 2:
350-
return "include_once";
351-
case 3:
352-
return "require";
353-
case 4:
354-
return "require_once";
355-
default:
356-
throw new LogicException("Unknown include type rendering: " . $type);
357-
}
358-
}
359-
360-
protected function renderFlags(Op\Stmt $stmt): string
361-
{
362-
$result = '';
363-
364-
if ($stmt instanceof Op\Stmt\Property) {
365-
if ($stmt->isReadOnly()) {
366-
$result .= "readonly|";
367-
}
368-
} elseif ($stmt instanceof Op\Stmt\ClassMethod) {
369-
if ($stmt->isFinal()) {
370-
$result .= "final|";
371-
}
372-
if ($stmt->isAbstract()) {
373-
$result .= "abstract|";
374-
}
375-
}
376-
377-
if ($stmt->isStatic()) {
378-
$result .= "static|";
379-
}
380-
381-
if ($stmt->isProtected()) {
382-
$result .= "protected";
383-
} elseif ($stmt->isPrivate()) {
384-
$result .= "private";
385-
} else {
386-
$result .= "public";
387-
}
388-
389-
return $result;
390-
}
391-
392-
public function renderAttributes(array $attributes): string
393-
{
394-
$result = '';
395-
if ($this->renderAttributes) {
396-
foreach ($attributes as $key => $value) {
397-
if (is_string($value) || is_numeric($value)) {
398-
$result .= "\n attribute['" . $key . "']: " . $value;
399-
}
400-
}
401-
}
402-
403-
return $result;
404-
}
405-
406-
public function renderAttrGroups(Op\AttributableOp $op): string
407-
{
408-
$result = '';
409-
410-
foreach ($op->getAttributeGroups() as $indexGroup => $attrGroup) {
411-
$result .= "\n attrGroup[$indexGroup]: ";
412-
$result .= $this->indent($this->renderAttributes($attrGroup->getAttributes()));
413-
foreach ($attrGroup->attrs as $indexAttr => $attr) {
414-
$result .= "\n attr[$indexAttr]: ";
415-
$result .= $this->indent($this->renderAttributes($attr->getAttributes()), 2);
416-
$result .= "\n name: " . $this->renderOperand($attr->name);
417-
foreach ($attr->args as $indexArg => $arg) {
418-
$result .= "\n args[$indexArg]: " . $this->renderOperand($arg);
234+
$result = "{$desc['kind']}";
235+
unset($desc['kind'], $desc['childblocks']);
236+
foreach ($desc as $name => $val) {
237+
if (is_array($val)) {
238+
foreach ($val as $v) {
239+
if (is_array($v)) {
240+
$result .= $this->indent("\n" . implode("\n", $v));
241+
} else {
242+
$result .= $this->indent("\n{$v}");
243+
}
419244
}
245+
} else {
246+
$result .= $this->indent("\n{$val}");
420247
}
421248
}
422-
423249
return $result;
424250
}
425251
}

0 commit comments

Comments
 (0)