From 841e4990997715030938ddf38f848c03c6458baf Mon Sep 17 00:00:00 2001 From: eric-therond Date: Sun, 26 Oct 2025 13:23:42 +0100 Subject: [PATCH 1/4] support protobuf printer --- composer.json | 3 +- lib/PHPCfg/Parser.php | 3 +- lib/PHPCfg/ParserHandler/Batch/Scalar.php | 1 - lib/PHPCfg/ParserHandler/Batch/Unary.php | 1 + lib/PHPCfg/ParserHandler/Expr/ConstFetch.php | 2 +- lib/PHPCfg/Printer/Printer.php | 57 +- lib/PHPCfg/Printer/Protobuf.php | 241 ++ lib/PHPCfg/Printer/Protobuf/PrimitiveType.php | 153 ++ lib/PHPCfg/Printer/Protobuf/Script.php | 59 + .../Printer/Protobuf/Script/PBFunction.php | 150 ++ .../Protobuf/Script/PBFunction/Block.php | 177 ++ .../Script/PBFunction/Block/CatchTarget.php | 123 + .../Script/PBFunction/Block/FinallyTarget.php | 59 + .../Protobuf/Script/PBFunction/Block/Op.php | 96 + .../Script/PBFunction/Block/Op/MapLabel.php | 59 + .../PBFunction/Block/Op/OneLabelType.php | 125 + .../Script/PBFunction/Block/Operand.php | 32 + .../PBFunction/Block/Operand/Literal.php | 96 + .../PBFunction/Block/Operand/OneOperand.php | 153 ++ .../PBFunction/Block/Operand/PBNull.php | 32 + .../PBFunction/Block/Operand/Temporary.php | 123 + .../PBFunction/Block/Operand/Variable.php | 160 ++ lib/PHPCfg/Printer/Protobuf/Specs.php | 25 + lib/PHPCfg/Printer/Protobuf/specs.proto | 95 + lib/PHPCfg/Printer/Renderer/GenericOp.php | 55 +- lib/PHPCfg/Printer/Renderer/Op/Assertion.php | 17 +- lib/PHPCfg/Printer/Renderer/Op/Include_.php | 10 +- lib/PHPCfg/Printer/Renderer/Op/TraitUse.php | 31 +- .../Printer/Renderer/Operand/Literal.php | 5 +- .../Printer/Renderer/Operand/Temporary.php | 7 +- .../Printer/Renderer/Operand/Variable.php | 21 +- lib/PHPCfg/Printer/Text.php | 74 + test/CodeTest.php | 6 +- test/code/and.test | 7 +- test/code/anonymous_class.test | 6 +- test/code/arrayList.test | 2 +- test/code/arrow_fn.test | 2 +- test/code/assign_coalesce.test | 2 +- test/code/block.test | 6 +- test/code/cast.test | 1 - test/code/classMethod_empty.test | 2 +- test/code/class_attributes.test | 59 +- test/code/class_this.test | 2 +- test/code/class_typed_property.test | 50 +- test/code/closure.test | 2 +- test/code/closure_empty.test | 2 +- test/code/constDecl.test | 2 +- test/code/constFetch.test | 4 +- test/code/duplicate_label.test | 2 +- test/code/empty.test | 2 +- test/code/error_supress.test | 2 +- test/code/exprFuncCall.test | 2 +- test/code/foreach.test | 2 +- test/code/function.test | 2 +- test/code/function_attributes.test | 26 +- test/code/function_empty.test | 2 +- test/code/function_namespace.test | 2 +- test/code/function_return_type.test | 36 +- test/code/goto_forever.test | 2 +- test/code/goto_undefined.test | 2 +- test/code/if_else.test | 2 +- test/code/if_else_if_else.test | 2 +- test/code/if_elseif_else.test | 2 +- test/code/include.test | 2 - test/code/interface.test | 2 +- test/code/intersection_type.test | 1 - test/code/isset.test | 2 +- test/code/list.test | 2 +- test/code/listKeys.test | 2 +- test/code/literal.test | 2 +- test/code/match.test | 10 +- test/code/match2.test | 12 +- test/code/namespaced_conditionals.test | 2 +- test/code/nested_phi.test | 16 +- test/code/nop.test | 2 +- test/code/nsFuncCall.test | 2 +- test/code/or.test | 11 +- test/code/property.test | 12 +- test/code/shellExec.test | 2 +- test/code/switch.test | 2 +- test/code/switch2.test | 2 +- test/code/ternary.test | 7 +- test/code/ternary2.test | 16 +- test/code/throw.test | 5 +- test/code/traitUse.test | 39 +- test/code/traitUse2.test | 14 +- test/code/try.test | 2 +- test/code/try_bodyblocks.test | 10 +- test/code/try_bodyblocks2.test | 10 +- test/code/try_finally.test | 2 +- test/code/try_nested.test | 11 +- test/code/type_assert.test | 25 +- test/code/unary.test | 3 +- test/code/unionType.test | 1 - test/code/variablevariable.test | 4 +- test/code/while.test | 3 +- test/code/yeild_from.test | 13 +- test/code/yield.test | 15 +- test/integration/ParserAttributesTest.php | 69 +- test/integration/PrinterProtobufTest.php | 80 + .../protobuf/class_attributes.test | 2135 +++++++++++++++++ test/integration/protobuf/try_nested.test | 842 +++++++ 102 files changed, 5465 insertions(+), 415 deletions(-) create mode 100644 lib/PHPCfg/Printer/Protobuf.php create mode 100644 lib/PHPCfg/Printer/Protobuf/PrimitiveType.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/CatchTarget.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/FinallyTarget.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/MapLabel.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/OneLabelType.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Literal.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/OneOperand.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/PBNull.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Temporary.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Variable.php create mode 100644 lib/PHPCfg/Printer/Protobuf/Specs.php create mode 100644 lib/PHPCfg/Printer/Protobuf/specs.proto create mode 100644 test/integration/PrinterProtobufTest.php create mode 100644 test/integration/protobuf/class_attributes.test create mode 100644 test/integration/protobuf/try_nested.test diff --git a/composer.json b/composer.json index d78f5ac..139bfb8 100755 --- a/composer.json +++ b/composer.json @@ -12,7 +12,8 @@ "php": ">=8.1", "nikic/php-parser": "^5.0", "phpdocumentor/graphviz": "^1.0.4", - "adhocore/cli": "^v1.0.0" + "adhocore/cli": "^v1.0.0", + "google/protobuf": "^4.32" }, "require-dev": { "phpunit/phpunit": ">=10.0", diff --git a/lib/PHPCfg/Parser.php b/lib/PHPCfg/Parser.php index bcf7dac..34be63c 100755 --- a/lib/PHPCfg/Parser.php +++ b/lib/PHPCfg/Parser.php @@ -310,7 +310,7 @@ public function parseExprNode($expr): ?Operand if (isset($this->exprHandlers[$expr->getType()])) { return $this->exprHandlers[$expr->getType()]->handleExpr($expr); } - var_dump(array_keys($this->exprHandlers)); + throw new RuntimeException('Unknown Expr Type ' . $expr->getType()); } @@ -456,6 +456,7 @@ public function readVariableRecursive(string $name, Block $block): Operand return $var; } + $var = new Temporary(new Variable(new Literal($name))); $phi = new Op\Phi($var, ['block' => $block]); $this->ctx->addToIncompletePhis($block, $name, $phi); diff --git a/lib/PHPCfg/ParserHandler/Batch/Scalar.php b/lib/PHPCfg/ParserHandler/Batch/Scalar.php index 7523ff5..8019387 100644 --- a/lib/PHPCfg/ParserHandler/Batch/Scalar.php +++ b/lib/PHPCfg/ParserHandler/Batch/Scalar.php @@ -78,7 +78,6 @@ public function handleExpr(Node\Expr $scalar): Operand // TODO return new Operand\Literal('__FUNCTION__'); default: - var_dump($scalar); throw new RuntimeException('Unknown how to deal with scalar type ' . $scalar->getType()); } } diff --git a/lib/PHPCfg/ParserHandler/Batch/Unary.php b/lib/PHPCfg/ParserHandler/Batch/Unary.php index 921c09e..58b41fe 100644 --- a/lib/PHPCfg/ParserHandler/Batch/Unary.php +++ b/lib/PHPCfg/ParserHandler/Batch/Unary.php @@ -9,6 +9,7 @@ namespace PHPCfg\ParserHandler\Batch; +use PHPCfg\Assertion; use PHPCfg\Op; use PHPCfg\Operand; use PHPCfg\ParserHandler; diff --git a/lib/PHPCfg/ParserHandler/Expr/ConstFetch.php b/lib/PHPCfg/ParserHandler/Expr/ConstFetch.php index 395f2a0..1c43ccf 100644 --- a/lib/PHPCfg/ParserHandler/Expr/ConstFetch.php +++ b/lib/PHPCfg/ParserHandler/Expr/ConstFetch.php @@ -23,7 +23,7 @@ public function handleExpr(Node\Expr $expr): Operand $lcname = strtolower($expr->name->toString()); switch ($lcname) { case 'null': - return new Operand\Literal(null); + return new Operand\NullOperand(); case 'true': return new Operand\Literal(true); case 'false': diff --git a/lib/PHPCfg/Printer/Printer.php b/lib/PHPCfg/Printer/Printer.php index 53f838c..8ae8a1e 100755 --- a/lib/PHPCfg/Printer/Printer.php +++ b/lib/PHPCfg/Printer/Printer.php @@ -80,9 +80,13 @@ protected function loadRenderers(): void } } - abstract public function printScript(Script $script): string; + abstract public function printScript(Script $script): mixed; - abstract public function printFunc(Func $func): string; + abstract public function printFunc(Func $func): mixed; + + abstract public function renderOperand(Operand $var): mixed; + + abstract public function renderOpLabel(array $desc): mixed; protected function reset(): void { @@ -98,20 +102,6 @@ protected function getBlockId(Block $block): int return $this->blocks[$block]; } - public function renderOperand(Operand $var): string - { - foreach ($this->renderers as $renderer) { - $result = $renderer->renderOperand($var); - if ($result !== null) { - $kind = $result['kind']; - $type = $result['type']; - unset($result['kind'], $result['type']); - return strtoupper($kind) . $type . '(' . trim(implode(" ", $result)) . ')'; - } - } - return 'UNKNOWN'; - } - public function renderOp(Op $op): array { foreach ($this->renderers as $renderer) { @@ -127,11 +117,7 @@ public function renderOp(Op $op): array } } - return [ - 'op' => $op, - 'label' => 'UNKNOWN', - 'childBlocks' => $childBlocks, - ]; + throw new LogicException("Unknown op rendering: " . get_class($op)); } protected function indent($str, $levels = 1): string @@ -163,14 +149,7 @@ protected function render(Func $func) $block = $this->blockQueue->dequeue(); $ops = []; foreach ($block->phi as $phi) { - $result = $this->indent($this->renderOperand($phi->result) . ' = Phi('); - $result .= implode(', ', array_map([$this, 'renderOperand'], $phi->vars)); - $result .= ')'; - $renderedOps[$phi] = $ops[] = [ - 'op' => $phi, - 'label' => $result, - 'childBlocks' => [], - ]; + $renderedOps[$phi] = $ops[] = $this->renderOp($phi); } foreach ($block->children as $child) { $renderedOps[$child] = $ops[] = $this->renderOp($child); @@ -222,24 +201,4 @@ public function renderType(?Op\Type $type): string } throw new LogicException("Unknown type rendering: " . get_class($type)); } - - public function renderOpLabel(array $desc): string - { - $result = "{$desc['kind']}"; - unset($desc['kind'], $desc['childblocks']); - foreach ($desc as $name => $val) { - if (is_array($val)) { - foreach ($val as $v) { - if (is_array($v)) { - $result .= $this->indent("\n" . implode("\n", $v)); - } else { - $result .= $this->indent("\n{$v}"); - } - } - } else { - $result .= $this->indent("\n{$val}"); - } - } - return $result; - } } diff --git a/lib/PHPCfg/Printer/Protobuf.php b/lib/PHPCfg/Printer/Protobuf.php new file mode 100644 index 0000000..8275717 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf.php @@ -0,0 +1,241 @@ +printFunc($script->main); + + foreach ($script->functions as $func) { + $functions[] = $this->printFunc($func); + } + + $protoscript->setFunctions($functions); + return $protoscript; + } + + public function printFunc(Func $func): PBFunction + { + $function = new PBFunction(); + $function->setName($func->name); + if($func->class) { + $function->setClass($func->class->name); + } + + $function->setReturnType($this->renderType($func->returnType)); + + $pbblocks = []; + $rendered = $this->render($func); + foreach ($rendered['blocks'] as $block) { + $pbblock = new PBBlock(); + $pbblock->setId($rendered['blockIds'][$block]); + + $pbblockParents = []; + foreach ($block->parents as $prev) { + if ($rendered['blockIds']->contains($prev)) { + $pbblockParents[] = $rendered['blockIds'][$prev]; + } + } + $pbblock->setParentIds($pbblockParents); + + if ($block->catchTarget !== null) { + $pbcatchTargets = []; + foreach ($block->catchTarget->catches as $catch) { + $pbcatchTarget = new PBCatchTarget(); + $pbcatchTarget->setType($this->renderType($catch['type'])); + $pbcatchTarget->setVar($this->renderOperand($catch['var'])); + $pbcatchTarget->setBlockId($rendered['blockIds'][$catch['block']]); + $pbcatchTargets[] = $pbcatchTarget; + } + + if ($rendered['blockIds']->contains($block->catchTarget->finally)) { + $pbfinallyTarget = new PBFinallyTarget(); + $pbfinallyTarget->setBlockId($rendered['blockIds'][$block->catchTarget->finally]); + $pbblock->setFinallyTarget($pbfinallyTarget); + } + + $pbblock->setCatchTargets($pbcatchTargets); + } + + $ops = $rendered['blocks'][$block]; + $pbops = []; + foreach ($ops as $op) { + $pbop = new PBOp(); + $pbop->setLabel($op['label']); + + $childpbblocks = []; + foreach ($op['childBlocks'] as $child) { + $childpbblocks[$child['name']] = $rendered['blockIds'][$child['block']]; + } + + $pbop->setChildBlocks($childpbblocks); + $pbops[] = $pbop; + } + + $pbblock->setOps($pbops); + $pbblocks[] = $pbblock; + } + + $function->setBlocks($pbblocks); + + return $function; + } + + public function renderOperand(Operand $var): PBOneOperand + { + foreach ($this->renderers as $renderer) { + $result = $renderer->renderOperand($var); + if ($result !== null) { + $kind = $result['kind']; + $type = $result['type']; + + if($kind == "NULL") { + $pboneOperand = new PBOneOperand(); + $pboneOperand->setNull(new PBNull()); + return $pboneOperand; + } else if($kind == "LITERAL") { + $pboneOperand = new PBOneOperand(); + $literaloperand = new PBLiteral(); + $literaloperand->setType($type); + $primitive = $this->renderPrimitiveType($result["value"]); + if($primitive) { + $literaloperand->setValue($primitive); + } + $pboneOperand->setLiteral($literaloperand); + return $pboneOperand; + } else if($kind == "TEMP") { + $pboneOperand = new PBOneOperand(); + $tempoperand = new PBTemporary(); + $tempoperand->setType($type); + $tempoperand->setId($result["id"]); + if($result["original"] && $result["original"]->hasVariable()) { + $tempoperand->setOriginal($result["original"]->getVariable()); + } + $pboneOperand->setTemporary($tempoperand); + return $pboneOperand; + + } else if($kind == "VARIABLE") { + $pboneOperand = new PBOneOperand(); + $varoperand = new PBVariable(); + $varoperand->setType($type); + $varoperand->setName("$" . $result["name"]); + if(!empty($result["scope"])) { + $varoperand->setScope($result["scope"]); + } + $varoperand->setReference($result["reference"]); + $pboneOperand->setVariable($varoperand); + return $pboneOperand; + } + } + } + + throw new LogicException("Unknown operand rendering: " . get_class($var)); + } + + public function renderPrimitiveType(string | float | int | bool $value): ?PBPrimitiveType + { + if(is_string($value)) { + $primitive = new PBPrimitiveType(); + $primitive->setString($value); + return $primitive; + } else if(is_bool($value)) { + $primitive = new PBPrimitiveType(); + $primitive->setBool($value); + return $primitive; + } else if(is_float($value)) { + $primitive = new PBPrimitiveType(); + $primitive->setFloat($value); + return $primitive; + } else if(is_int($value)) { + $primitive = new PBPrimitiveType(); + $primitive->setInt($value); + return $primitive; + } + + return null; + } + + public function renderOpLabelValue(mixed $value): PBOneLabelType + { + $result = new PBOneLabelType(); + + if (is_array($value)) { + $maplabel = new PBMapLabel(); + $map = []; + foreach ($value as $k => $v) { + $map[$k] = $this->renderOpLabelValue($v); + } + + $maplabel->setValue($map); + $result ->setMap($maplabel); + } else if($value instanceof PBOneOperand) { + $result->setOperand($value); + } else { + $primitive = $this->renderPrimitiveType($value); + if($primitive) { + $result->setPrimitive($primitive); + } + } + + return $result; + } + + public function renderOpLabel(array $desc): PBMapLabel + { + unset($desc['childblocks']); + + foreach ($desc as $name => $val) { + if (is_array($val)) { + foreach ($val as $k => $v) { + $map[$k] = $this->renderOpLabelValue($v); + } + } else { + $stringlabel = new PBOneLabelType(); + $primitive = new PBPrimitiveType(); + $primitive->setString($val); + $stringlabel->setPrimitive($primitive); + $map[$name] = $stringlabel; + } + } + + $result = new PBMapLabel(); + $result->setValue($map); + + return $result; + } +} diff --git a/lib/PHPCfg/Printer/Protobuf/PrimitiveType.php b/lib/PHPCfg/Printer/Protobuf/PrimitiveType.php new file mode 100644 index 0000000..9df6cee --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/PrimitiveType.php @@ -0,0 +1,153 @@ +protos.PrimitiveType + */ +class PrimitiveType extends \Google\Protobuf\Internal\Message +{ + protected $value; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $string + * @type float $float + * @type int $int + * @type bool $bool + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field string string = 1; + * @return string + */ + public function getString() + { + return $this->readOneof(1); + } + + public function hasString() + { + return $this->hasOneof(1); + } + + /** + * Generated from protobuf field string string = 1; + * @param string $var + * @return $this + */ + public function setString($var) + { + GPBUtil::checkString($var, True); + $this->writeOneof(1, $var); + + return $this; + } + + /** + * Generated from protobuf field float float = 2; + * @return float + */ + public function getFloat() + { + return $this->readOneof(2); + } + + public function hasFloat() + { + return $this->hasOneof(2); + } + + /** + * Generated from protobuf field float float = 2; + * @param float $var + * @return $this + */ + public function setFloat($var) + { + GPBUtil::checkFloat($var); + $this->writeOneof(2, $var); + + return $this; + } + + /** + * Generated from protobuf field uint32 int = 3; + * @return int + */ + public function getInt() + { + return $this->readOneof(3); + } + + public function hasInt() + { + return $this->hasOneof(3); + } + + /** + * Generated from protobuf field uint32 int = 3; + * @param int $var + * @return $this + */ + public function setInt($var) + { + GPBUtil::checkUint32($var); + $this->writeOneof(3, $var); + + return $this; + } + + /** + * Generated from protobuf field bool bool = 4; + * @return bool + */ + public function getBool() + { + return $this->readOneof(4); + } + + public function hasBool() + { + return $this->hasOneof(4); + } + + /** + * Generated from protobuf field bool bool = 4; + * @param bool $var + * @return $this + */ + public function setBool($var) + { + GPBUtil::checkBool($var); + $this->writeOneof(4, $var); + + return $this; + } + + /** + * @return string + */ + public function getValue() + { + return $this->whichOneof("value"); + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script.php b/lib/PHPCfg/Printer/Protobuf/Script.php new file mode 100644 index 0000000..7c6e590 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script.php @@ -0,0 +1,59 @@ +protos.Script + */ +class Script extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field repeated .protos.Script.Function functions = 1; + */ + private $functions; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type array<\PHPCfg\Printer\Protobuf\Script\PBFunction>|\Google\Protobuf\Internal\RepeatedField $functions + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field repeated .protos.Script.Function functions = 1; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getFunctions() + { + return $this->functions; + } + + /** + * Generated from protobuf field repeated .protos.Script.Function functions = 1; + * @param array<\PHPCfg\Printer\Protobuf\Script\PBFunction>|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setFunctions($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \PHPCfg\Printer\Protobuf\Script\PBFunction::class); + $this->functions = $arr; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction.php new file mode 100644 index 0000000..6cd8688 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction.php @@ -0,0 +1,150 @@ +protos.Script.Function + */ +class PBFunction extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field repeated .protos.Script.Function.Block blocks = 1; + */ + private $blocks; + /** + * Generated from protobuf field string name = 2; + */ + protected $name = ''; + /** + * Generated from protobuf field optional string class = 3; + */ + protected $class = null; + /** + * Generated from protobuf field string returnType = 4; + */ + protected $returnType = ''; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type array<\PHPCfg\Printer\Protobuf\Script\PBFunction\Block>|\Google\Protobuf\Internal\RepeatedField $blocks + * @type string $name + * @type string $class + * @type string $returnType + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field repeated .protos.Script.Function.Block blocks = 1; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getBlocks() + { + return $this->blocks; + } + + /** + * Generated from protobuf field repeated .protos.Script.Function.Block blocks = 1; + * @param array<\PHPCfg\Printer\Protobuf\Script\PBFunction\Block>|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setBlocks($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block::class); + $this->blocks = $arr; + + return $this; + } + + /** + * Generated from protobuf field string name = 2; + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Generated from protobuf field string name = 2; + * @param string $var + * @return $this + */ + public function setName($var) + { + GPBUtil::checkString($var, True); + $this->name = $var; + + return $this; + } + + /** + * Generated from protobuf field optional string class = 3; + * @return string + */ + public function getClass() + { + return isset($this->class) ? $this->class : ''; + } + + public function hasClass() + { + return isset($this->class); + } + + public function clearClass() + { + unset($this->class); + } + + /** + * Generated from protobuf field optional string class = 3; + * @param string $var + * @return $this + */ + public function setClass($var) + { + GPBUtil::checkString($var, True); + $this->class = $var; + + return $this; + } + + /** + * Generated from protobuf field string returnType = 4; + * @return string + */ + public function getReturnType() + { + return $this->returnType; + } + + /** + * Generated from protobuf field string returnType = 4; + * @param string $var + * @return $this + */ + public function setReturnType($var) + { + GPBUtil::checkString($var, True); + $this->returnType = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block.php new file mode 100644 index 0000000..e1e09a2 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block.php @@ -0,0 +1,177 @@ +protos.Script.Function.Block + */ +class Block extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field repeated .protos.Script.Function.Block.Op ops = 1; + */ + private $ops; + /** + * Generated from protobuf field uint32 id = 2; + */ + protected $id = 0; + /** + * Generated from protobuf field repeated uint32 parentIds = 3; + */ + private $parentIds; + /** + * Generated from protobuf field repeated .protos.Script.Function.Block.CatchTarget catchTargets = 4; + */ + private $catchTargets; + /** + * Generated from protobuf field optional .protos.Script.Function.Block.FinallyTarget finallyTarget = 5; + */ + protected $finallyTarget = null; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type array<\PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op>|\Google\Protobuf\Internal\RepeatedField $ops + * @type int $id + * @type array|\Google\Protobuf\Internal\RepeatedField $parentIds + * @type array<\PHPCfg\Printer\Protobuf\Script\PBFunction\Block\CatchTarget>|\Google\Protobuf\Internal\RepeatedField $catchTargets + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\FinallyTarget $finallyTarget + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field repeated .protos.Script.Function.Block.Op ops = 1; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getOps() + { + return $this->ops; + } + + /** + * Generated from protobuf field repeated .protos.Script.Function.Block.Op ops = 1; + * @param array<\PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op>|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setOps($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op::class); + $this->ops = $arr; + + return $this; + } + + /** + * Generated from protobuf field uint32 id = 2; + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Generated from protobuf field uint32 id = 2; + * @param int $var + * @return $this + */ + public function setId($var) + { + GPBUtil::checkUint32($var); + $this->id = $var; + + return $this; + } + + /** + * Generated from protobuf field repeated uint32 parentIds = 3; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getParentIds() + { + return $this->parentIds; + } + + /** + * Generated from protobuf field repeated uint32 parentIds = 3; + * @param array|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setParentIds($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::UINT32); + $this->parentIds = $arr; + + return $this; + } + + /** + * Generated from protobuf field repeated .protos.Script.Function.Block.CatchTarget catchTargets = 4; + * @return \Google\Protobuf\Internal\RepeatedField + */ + public function getCatchTargets() + { + return $this->catchTargets; + } + + /** + * Generated from protobuf field repeated .protos.Script.Function.Block.CatchTarget catchTargets = 4; + * @param array<\PHPCfg\Printer\Protobuf\Script\PBFunction\Block\CatchTarget>|\Google\Protobuf\Internal\RepeatedField $var + * @return $this + */ + public function setCatchTargets($var) + { + $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\CatchTarget::class); + $this->catchTargets = $arr; + + return $this; + } + + /** + * Generated from protobuf field optional .protos.Script.Function.Block.FinallyTarget finallyTarget = 5; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\FinallyTarget|null + */ + public function getFinallyTarget() + { + return $this->finallyTarget; + } + + public function hasFinallyTarget() + { + return isset($this->finallyTarget); + } + + public function clearFinallyTarget() + { + unset($this->finallyTarget); + } + + /** + * Generated from protobuf field optional .protos.Script.Function.Block.FinallyTarget finallyTarget = 5; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\FinallyTarget $var + * @return $this + */ + public function setFinallyTarget($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\FinallyTarget::class); + $this->finallyTarget = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/CatchTarget.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/CatchTarget.php new file mode 100644 index 0000000..c8491fd --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/CatchTarget.php @@ -0,0 +1,123 @@ +protos.Script.Function.Block.CatchTarget + */ +class CatchTarget extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field string type = 1; + */ + protected $type = ''; + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.OneOperand var = 2; + */ + protected $var = null; + /** + * Generated from protobuf field uint32 blockId = 3; + */ + protected $blockId = 0; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $type + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand $var + * @type int $blockId + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field string type = 1; + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Generated from protobuf field string type = 1; + * @param string $var + * @return $this + */ + public function setType($var) + { + GPBUtil::checkString($var, True); + $this->type = $var; + + return $this; + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.OneOperand var = 2; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand|null + */ + public function getVar() + { + return $this->var; + } + + public function hasVar() + { + return isset($this->var); + } + + public function clearVar() + { + unset($this->var); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.OneOperand var = 2; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand $var + * @return $this + */ + public function setVar($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand::class); + $this->var = $var; + + return $this; + } + + /** + * Generated from protobuf field uint32 blockId = 3; + * @return int + */ + public function getBlockId() + { + return $this->blockId; + } + + /** + * Generated from protobuf field uint32 blockId = 3; + * @param int $var + * @return $this + */ + public function setBlockId($var) + { + GPBUtil::checkUint32($var); + $this->blockId = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/FinallyTarget.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/FinallyTarget.php new file mode 100644 index 0000000..649240d --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/FinallyTarget.php @@ -0,0 +1,59 @@ +protos.Script.Function.Block.FinallyTarget + */ +class FinallyTarget extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field uint32 blockId = 1; + */ + protected $blockId = 0; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type int $blockId + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field uint32 blockId = 1; + * @return int + */ + public function getBlockId() + { + return $this->blockId; + } + + /** + * Generated from protobuf field uint32 blockId = 1; + * @param int $var + * @return $this + */ + public function setBlockId($var) + { + GPBUtil::checkUint32($var); + $this->blockId = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op.php new file mode 100644 index 0000000..b91e81a --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op.php @@ -0,0 +1,96 @@ +protos.Script.Function.Block.Op + */ +class Op extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field .protos.Script.Function.Block.Op.MapLabel label = 1; + */ + protected $label = null; + /** + * Generated from protobuf field map childBlocks = 2; + */ + private $childBlocks; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel $label + * @type array|\Google\Protobuf\Internal\MapField $childBlocks + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Op.MapLabel label = 1; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel|null + */ + public function getLabel() + { + return $this->label; + } + + public function hasLabel() + { + return isset($this->label); + } + + public function clearLabel() + { + unset($this->label); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Op.MapLabel label = 1; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel $var + * @return $this + */ + public function setLabel($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel::class); + $this->label = $var; + + return $this; + } + + /** + * Generated from protobuf field map childBlocks = 2; + * @return \Google\Protobuf\Internal\MapField + */ + public function getChildBlocks() + { + return $this->childBlocks; + } + + /** + * Generated from protobuf field map childBlocks = 2; + * @param array|\Google\Protobuf\Internal\MapField $var + * @return $this + */ + public function setChildBlocks($var) + { + $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::UINT32); + $this->childBlocks = $arr; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/MapLabel.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/MapLabel.php new file mode 100644 index 0000000..cf5a175 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/MapLabel.php @@ -0,0 +1,59 @@ +protos.Script.Function.Block.Op.MapLabel + */ +class MapLabel extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field map value = 1; + */ + private $value; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type array|\Google\Protobuf\Internal\MapField $value + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field map value = 1; + * @return \Google\Protobuf\Internal\MapField + */ + public function getValue() + { + return $this->value; + } + + /** + * Generated from protobuf field map value = 1; + * @param array|\Google\Protobuf\Internal\MapField $var + * @return $this + */ + public function setValue($var) + { + $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::MESSAGE, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\OneLabelType::class); + $this->value = $arr; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/OneLabelType.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/OneLabelType.php new file mode 100644 index 0000000..d28101a --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Op/OneLabelType.php @@ -0,0 +1,125 @@ +protos.Script.Function.Block.Op.OneLabelType + */ +class OneLabelType extends \Google\Protobuf\Internal\Message +{ + protected $value; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel $map + * @type \PHPCfg\Printer\Protobuf\PrimitiveType $primitive + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand $operand + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Op.MapLabel map = 1; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel|null + */ + public function getMap() + { + return $this->readOneof(1); + } + + public function hasMap() + { + return $this->hasOneof(1); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Op.MapLabel map = 1; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel $var + * @return $this + */ + public function setMap($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Op\MapLabel::class); + $this->writeOneof(1, $var); + + return $this; + } + + /** + * Generated from protobuf field .protos.PrimitiveType primitive = 2; + * @return \PHPCfg\Printer\Protobuf\PrimitiveType|null + */ + public function getPrimitive() + { + return $this->readOneof(2); + } + + public function hasPrimitive() + { + return $this->hasOneof(2); + } + + /** + * Generated from protobuf field .protos.PrimitiveType primitive = 2; + * @param \PHPCfg\Printer\Protobuf\PrimitiveType $var + * @return $this + */ + public function setPrimitive($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\PrimitiveType::class); + $this->writeOneof(2, $var); + + return $this; + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.OneOperand operand = 3; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand|null + */ + public function getOperand() + { + return $this->readOneof(3); + } + + public function hasOperand() + { + return $this->hasOneof(3); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.OneOperand operand = 3; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand $var + * @return $this + */ + public function setOperand($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\OneOperand::class); + $this->writeOneof(3, $var); + + return $this; + } + + /** + * @return string + */ + public function getValue() + { + return $this->whichOneof("value"); + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand.php new file mode 100644 index 0000000..381c1e1 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand.php @@ -0,0 +1,32 @@ +protos.Script.Function.Block.Operand + */ +class Operand extends \Google\Protobuf\Internal\Message +{ + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Literal.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Literal.php new file mode 100644 index 0000000..323970c --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Literal.php @@ -0,0 +1,96 @@ +protos.Script.Function.Block.Operand.Literal + */ +class Literal extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field string type = 1; + */ + protected $type = ''; + /** + * Generated from protobuf field .protos.PrimitiveType value = 2; + */ + protected $value = null; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $type + * @type \PHPCfg\Printer\Protobuf\PrimitiveType $value + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field string type = 1; + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Generated from protobuf field string type = 1; + * @param string $var + * @return $this + */ + public function setType($var) + { + GPBUtil::checkString($var, True); + $this->type = $var; + + return $this; + } + + /** + * Generated from protobuf field .protos.PrimitiveType value = 2; + * @return \PHPCfg\Printer\Protobuf\PrimitiveType|null + */ + public function getValue() + { + return $this->value; + } + + public function hasValue() + { + return isset($this->value); + } + + public function clearValue() + { + unset($this->value); + } + + /** + * Generated from protobuf field .protos.PrimitiveType value = 2; + * @param \PHPCfg\Printer\Protobuf\PrimitiveType $var + * @return $this + */ + public function setValue($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\PrimitiveType::class); + $this->value = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/OneOperand.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/OneOperand.php new file mode 100644 index 0000000..73f7504 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/OneOperand.php @@ -0,0 +1,153 @@ +protos.Script.Function.Block.Operand.OneOperand + */ +class OneOperand extends \Google\Protobuf\Internal\Message +{ + protected $value; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\PBNull $null + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Literal $literal + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Temporary $temporary + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable $variable + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Null null = 1; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\PBNull|null + */ + public function getNull() + { + return $this->readOneof(1); + } + + public function hasNull() + { + return $this->hasOneof(1); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Null null = 1; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\PBNull $var + * @return $this + */ + public function setNull($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\PBNull::class); + $this->writeOneof(1, $var); + + return $this; + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Literal literal = 2; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Literal|null + */ + public function getLiteral() + { + return $this->readOneof(2); + } + + public function hasLiteral() + { + return $this->hasOneof(2); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Literal literal = 2; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Literal $var + * @return $this + */ + public function setLiteral($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Literal::class); + $this->writeOneof(2, $var); + + return $this; + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Temporary temporary = 3; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Temporary|null + */ + public function getTemporary() + { + return $this->readOneof(3); + } + + public function hasTemporary() + { + return $this->hasOneof(3); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Temporary temporary = 3; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Temporary $var + * @return $this + */ + public function setTemporary($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Temporary::class); + $this->writeOneof(3, $var); + + return $this; + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Variable variable = 4; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable|null + */ + public function getVariable() + { + return $this->readOneof(4); + } + + public function hasVariable() + { + return $this->hasOneof(4); + } + + /** + * Generated from protobuf field .protos.Script.Function.Block.Operand.Variable variable = 4; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable $var + * @return $this + */ + public function setVariable($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable::class); + $this->writeOneof(4, $var); + + return $this; + } + + /** + * @return string + */ + public function getValue() + { + return $this->whichOneof("value"); + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/PBNull.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/PBNull.php new file mode 100644 index 0000000..c8c38a0 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/PBNull.php @@ -0,0 +1,32 @@ +protos.Script.Function.Block.Operand.Null + */ +class PBNull extends \Google\Protobuf\Internal\Message +{ + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Temporary.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Temporary.php new file mode 100644 index 0000000..e07b306 --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Temporary.php @@ -0,0 +1,123 @@ +protos.Script.Function.Block.Operand.Temporary + */ +class Temporary extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field string type = 1; + */ + protected $type = ''; + /** + * Generated from protobuf field uint32 id = 2; + */ + protected $id = 0; + /** + * Generated from protobuf field optional .protos.Script.Function.Block.Operand.Variable original = 3; + */ + protected $original = null; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $type + * @type int $id + * @type \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable $original + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field string type = 1; + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Generated from protobuf field string type = 1; + * @param string $var + * @return $this + */ + public function setType($var) + { + GPBUtil::checkString($var, True); + $this->type = $var; + + return $this; + } + + /** + * Generated from protobuf field uint32 id = 2; + * @return int + */ + public function getId() + { + return $this->id; + } + + /** + * Generated from protobuf field uint32 id = 2; + * @param int $var + * @return $this + */ + public function setId($var) + { + GPBUtil::checkUint32($var); + $this->id = $var; + + return $this; + } + + /** + * Generated from protobuf field optional .protos.Script.Function.Block.Operand.Variable original = 3; + * @return \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable|null + */ + public function getOriginal() + { + return $this->original; + } + + public function hasOriginal() + { + return isset($this->original); + } + + public function clearOriginal() + { + unset($this->original); + } + + /** + * Generated from protobuf field optional .protos.Script.Function.Block.Operand.Variable original = 3; + * @param \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable $var + * @return $this + */ + public function setOriginal($var) + { + GPBUtil::checkMessage($var, \PHPCfg\Printer\Protobuf\Script\PBFunction\Block\Operand\Variable::class); + $this->original = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Variable.php b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Variable.php new file mode 100644 index 0000000..e6c545d --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Script/PBFunction/Block/Operand/Variable.php @@ -0,0 +1,160 @@ +protos.Script.Function.Block.Operand.Variable + */ +class Variable extends \Google\Protobuf\Internal\Message +{ + /** + * Generated from protobuf field string type = 1; + */ + protected $type = ''; + /** + * Generated from protobuf field string name = 2; + */ + protected $name = ''; + /** + * Generated from protobuf field optional string scope = 3; + */ + protected $scope = null; + /** + * Generated from protobuf field optional bool reference = 4; + */ + protected $reference = null; + + /** + * Constructor. + * + * @param array $data { + * Optional. Data for populating the Message object. + * + * @type string $type + * @type string $name + * @type string $scope + * @type bool $reference + * } + */ + public function __construct($data = NULL) { + \PHPCfg\Printer\Protobuf\Specs::initOnce(); + parent::__construct($data); + } + + /** + * Generated from protobuf field string type = 1; + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * Generated from protobuf field string type = 1; + * @param string $var + * @return $this + */ + public function setType($var) + { + GPBUtil::checkString($var, True); + $this->type = $var; + + return $this; + } + + /** + * Generated from protobuf field string name = 2; + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Generated from protobuf field string name = 2; + * @param string $var + * @return $this + */ + public function setName($var) + { + GPBUtil::checkString($var, True); + $this->name = $var; + + return $this; + } + + /** + * Generated from protobuf field optional string scope = 3; + * @return string + */ + public function getScope() + { + return isset($this->scope) ? $this->scope : ''; + } + + public function hasScope() + { + return isset($this->scope); + } + + public function clearScope() + { + unset($this->scope); + } + + /** + * Generated from protobuf field optional string scope = 3; + * @param string $var + * @return $this + */ + public function setScope($var) + { + GPBUtil::checkString($var, True); + $this->scope = $var; + + return $this; + } + + /** + * Generated from protobuf field optional bool reference = 4; + * @return bool + */ + public function getReference() + { + return isset($this->reference) ? $this->reference : false; + } + + public function hasReference() + { + return isset($this->reference); + } + + public function clearReference() + { + unset($this->reference); + } + + /** + * Generated from protobuf field optional bool reference = 4; + * @param bool $var + * @return $this + */ + public function setReference($var) + { + GPBUtil::checkBool($var); + $this->reference = $var; + + return $this; + } + +} + diff --git a/lib/PHPCfg/Printer/Protobuf/Specs.php b/lib/PHPCfg/Printer/Protobuf/Specs.php new file mode 100644 index 0000000..a6c773a --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/Specs.php @@ -0,0 +1,25 @@ +internalAddGeneratedFile( + "\x0A\x8C\x0F\x0A'lib/PHPCfg/Printer/Protobuf/specs.proto\x12\x06protos\"Z\x0A\x0DPrimitiveType\x12\x10\x0A\x06string\x18\x01 \x01(\x09H\x00\x12\x0F\x0A\x05float\x18\x02 \x01(\x02H\x00\x12\x0D\x0A\x03int\x18\x03 \x01(\x0DH\x00\x12\x0E\x0A\x04bool\x18\x04 \x01(\x08H\x00B\x07\x0A\x05value\"\xBE\x0D\x0A\x06Script\x12*\x0A\x09functions\x18\x01 \x03(\x0B2\x17.protos.Script.Function\x1A\x87\x0D\x0A\x08Function\x12-\x0A\x06blocks\x18\x01 \x03(\x0B2\x1D.protos.Script.Function.Block\x12\x0C\x0A\x04name\x18\x02 \x01(\x09\x12\x12\x0A\x05class\x18\x03 \x01(\x09H\x00\x88\x01\x01\x12\x12\x0A\x0AreturnType\x18\x04 \x01(\x09\x1A\x8B\x0C\x0A\x05Block\x12-\x0A\x03ops\x18\x01 \x03(\x0B2 .protos.Script.Function.Block.Op\x12\x0A\x0A\x02id\x18\x02 \x01(\x0D\x12\x11\x0A\x09parentIds\x18\x03 \x03(\x0D\x12?\x0A\x0CcatchTargets\x18\x04 \x03(\x0B2).protos.Script.Function.Block.CatchTarget\x12G\x0A\x0DfinallyTarget\x18\x05 \x01(\x0B2+.protos.Script.Function.Block.FinallyTargetH\x00\x88\x01\x01\x1Ak\x0A\x0BCatchTarget\x12\x0C\x0A\x04type\x18\x01 \x01(\x09\x12=\x0A\x03var\x18\x02 \x01(\x0B20.protos.Script.Function.Block.Operand.OneOperand\x12\x0F\x0A\x07blockId\x18\x03 \x01(\x0D\x1A \x0A\x0DFinallyTarget\x12\x0F\x0A\x07blockId\x18\x01 \x01(\x0D\x1A\xD7\x04\x0A\x07Operand\x1A\x06\x0A\x04Null\x1A=\x0A\x07Literal\x12\x0C\x0A\x04type\x18\x01 \x01(\x09\x12\$\x0A\x05value\x18\x02 \x01(\x0B2\x15.protos.PrimitiveType\x1Ay\x0A\x09Temporary\x12\x0C\x0A\x04type\x18\x01 \x01(\x09\x12\x0A\x0A\x02id\x18\x02 \x01(\x0D\x12E\x0A\x08original\x18\x03 \x01(\x0B2..protos.Script.Function.Block.Operand.VariableH\x00\x88\x01\x01B\x0B\x0A\x09_original\x1Aj\x0A\x08Variable\x12\x0C\x0A\x04type\x18\x01 \x01(\x09\x12\x0C\x0A\x04name\x18\x02 \x01(\x09\x12\x12\x0A\x05scope\x18\x03 \x01(\x09H\x00\x88\x01\x01\x12\x16\x0A\x09reference\x18\x04 \x01(\x08H\x01\x88\x01\x01B\x08\x0A\x06_scopeB\x0C\x0A\x0A_reference\x1A\x9D\x02\x0A\x0AOneOperand\x12:\x0A\x04null\x18\x01 \x01(\x0B2*.protos.Script.Function.Block.Operand.NullH\x00\x12@\x0A\x07literal\x18\x02 \x01(\x0B2-.protos.Script.Function.Block.Operand.LiteralH\x00\x12D\x0A\x09temporary\x18\x03 \x01(\x0B2/.protos.Script.Function.Block.Operand.TemporaryH\x00\x12B\x0A\x08variable\x18\x04 \x01(\x0B2..protos.Script.Function.Block.Operand.VariableH\x00B\x07\x0A\x05value\x1A\xAE\x04\x0A\x02Op\x128\x0A\x05label\x18\x01 \x01(\x0B2).protos.Script.Function.Block.Op.MapLabel\x12F\x0A\x0BchildBlocks\x18\x02 \x03(\x0B21.protos.Script.Function.Block.Op.ChildBlocksEntry\x1A\xAC\x01\x0A\x08MapLabel\x12C\x0A\x05value\x18\x01 \x03(\x0B24.protos.Script.Function.Block.Op.MapLabel.ValueEntry\x1A[\x0A\x0AValueEntry\x12\x0B\x0A\x03key\x18\x01 \x01(\x09\x12<\x0A\x05value\x18\x02 \x01(\x0B2-.protos.Script.Function.Block.Op.OneLabelType:\x028\x01\x1A\xC2\x01\x0A\x0COneLabelType\x128\x0A\x03map\x18\x01 \x01(\x0B2).protos.Script.Function.Block.Op.MapLabelH\x00\x12*\x0A\x09primitive\x18\x02 \x01(\x0B2\x15.protos.PrimitiveTypeH\x00\x12C\x0A\x07operand\x18\x03 \x01(\x0B20.protos.Script.Function.Block.Operand.OneOperandH\x00B\x07\x0A\x05value\x1A2\x0A\x10ChildBlocksEntry\x12\x0B\x0A\x03key\x18\x01 \x01(\x09\x12\x0D\x0A\x05value\x18\x02 \x01(\x0D:\x028\x01B\x10\x0A\x0E_finallyTargetB\x08\x0A\x06_classB4\xCA\x02\x17PHPCfg\\Printer\\Protobuf\xE2\x02\x17PHPCfg\\Printer\\Protobufb\x06proto3" + , true); + + static::$is_initialized = true; + } +} + diff --git a/lib/PHPCfg/Printer/Protobuf/specs.proto b/lib/PHPCfg/Printer/Protobuf/specs.proto new file mode 100644 index 0000000..2fcc1fd --- /dev/null +++ b/lib/PHPCfg/Printer/Protobuf/specs.proto @@ -0,0 +1,95 @@ +// protoc --proto_path=./ --php_out=./lib/ ./lib/PHPCfg/Printer/Protobuf/specs.proto + +syntax = "proto3"; + +package protos; + +option php_namespace = "PHPCfg\\Printer\\Protobuf"; +option php_metadata_namespace = "PHPCfg\\Printer\\Protobuf"; + +message PrimitiveType { + oneof value { + string string = 1; + float float = 2; + uint32 int = 3; + bool bool = 4; + } +} + +message Script { + repeated Function functions = 1; + + message Function { + repeated Block blocks = 1; + string name = 2; + optional string class = 3; + string returnType = 4; + + message Block { + repeated Op ops = 1; + uint32 id = 2; + repeated uint32 parentIds = 3; + repeated CatchTarget catchTargets = 4; + optional FinallyTarget finallyTarget = 5; + + message CatchTarget { + string type = 1; + Operand.OneOperand var = 2; + uint32 blockId = 3; + } + + message FinallyTarget { + uint32 blockId = 1; + } + + message Operand { + message Null { + } + + message Literal { + string type = 1; + PrimitiveType value = 2; + } + + message Temporary { + string type = 1; + uint32 id = 2; + optional Variable original = 3; + } + + message Variable { + string type = 1; + string name = 2; + optional string scope = 3; + optional bool reference = 4; + } + + message OneOperand { + oneof value { + Operand.Null null = 1; + Operand.Literal literal = 2; + Operand.Temporary temporary = 3; + Operand.Variable variable = 4; + } + } + } + + message Op { + message MapLabel { + map value = 1; + } + + message OneLabelType { + oneof value { + MapLabel map = 1; + PrimitiveType primitive = 2; + Operand.OneOperand operand = 3; + } + } + + MapLabel label = 1; + map childBlocks = 2; + } + } + } +} \ No newline at end of file diff --git a/lib/PHPCfg/Printer/Renderer/GenericOp.php b/lib/PHPCfg/Printer/Renderer/GenericOp.php index df97452..9a66090 100644 --- a/lib/PHPCfg/Printer/Renderer/GenericOp.php +++ b/lib/PHPCfg/Printer/Renderer/GenericOp.php @@ -30,46 +30,52 @@ public function reset(): void {} public function renderOp(Op $op): ?array { $result = [ + 'attributes' => $this->renderAttributes($op->getAttributes()), + 'attrGroups' => [], + 'childblocks' => [], 'kind' => $op->getType(), 'types' => [], 'vars' => [], - 'attributes' => $this->renderAttributes($op->getAttributes()), - 'childblocks' => [], ]; + if ($op instanceof Op\AttributableOp) { + $result['attrGroups'] = $this->renderAttrGroups($op); + } + if ($op instanceof Op\CallableOp) { $func = $op->getFunc(); - $result['vars'][] = "name: {$func->name}"; + $result['vars']['name'] = $func->name; } if ($op instanceof Op\Stmt\Property || $op instanceof Op\Stmt\ClassMethod) { - $result['vars'][] = "flags: " . $this->renderFlags($op); + $result['vars']['flags'] = $this->renderFlags($op); } - foreach ($op->getTypeNames() as $typeName => $type) { if (is_array($type)) { + $result['vars'][$typeName] = []; foreach ($type as $key => $subType) { if (! $subType) { continue; } - $result['types'][] = "{$typeName}[{$key}]: " . $this->printer->renderType($subType); + $result['types'][$typeName][$key] = $this->printer->renderType($subType); } } elseif ($type) { - $result['types'][] = "{$typeName}: " . $this->printer->renderType($type); + $result['types'][$typeName] = $this->printer->renderType($type); } } foreach ($op->getVariableNames() as $varName => $vars) { if (is_array($vars)) { + $result['vars'][$varName] = []; foreach ($vars as $key => $var) { if (! $var) { continue; } - $result['vars'][] = "{$varName}[{$key}]: " . $this->printer->renderOperand($var); + $result['vars'][$varName][$key] = $this->printer->renderOperand($var); } } elseif ($vars) { - $result['vars'][] = "{$varName}: " . $this->printer->renderOperand($vars); + $result['vars'][$varName] = $this->printer->renderOperand($vars); } } @@ -91,12 +97,6 @@ public function renderOp(Op $op): ?array } } - if ($op instanceof Op\AttributableOp) { - $result['attrGroups'] = $this->renderAttrGroups($op); - } - - - return $result; } @@ -105,8 +105,6 @@ public function renderOperand(Operand $operand): ?array return null; } - - protected function renderAttributes(array $attributes): array { if (!$this->printer->renderAttributes) { @@ -115,30 +113,29 @@ protected function renderAttributes(array $attributes): array $result = []; foreach ($attributes as $key => $value) { if (is_string($value) || is_numeric($value)) { - $result[] = "attribute['" . $key . "']: " . $value; + $result['attribute'][$key] = $value; } } return $result; } - protected function renderAttrGroups(Op\AttributableOp $op): array { $result = []; + $result['attrGroup'] = []; foreach ($op->getAttributeGroups() as $indexGroup => $attrGroup) { - $result[$indexGroup] = []; - $result[$indexGroup][] = "attrGroup[$indexGroup]: "; - foreach ($this->renderAttributes($attrGroup->getAttributes()) as $attr) { - $result[$indexGroup][] = " {$attr}"; + $result['attrGroup'][$indexGroup] = []; + foreach ($this->renderAttributes($attrGroup->getAttributes()) as $i => $attr) { + $result['attrGroup'][$indexGroup][$i] = $attr; } foreach ($attrGroup->attrs as $indexAttr => $attr) { - $result[$indexGroup][] = " attr[$indexAttr]: "; - foreach ($this->renderAttributes($attr->getAttributes()) as $rendered) { - $result[$indexGroup][] = " {$rendered}"; + $result['attrGroup'][$indexGroup][$indexAttr] = []; + foreach ($this->renderAttributes($attr->getAttributes()) as $j => $rendered) { + $result['attrGroup'][$indexGroup][$indexAttr][$j] = $rendered; } - $result[$indexGroup][] = " name: " . $this->printer->renderOperand($attr->name); + $result['attrGroup'][$indexGroup][$indexAttr]['name'] = $this->printer->renderOperand($attr->name); foreach ($attr->args as $indexArg => $arg) { - $result[$indexGroup][] = " args[$indexArg]: " . $this->printer->renderOperand($arg); + $result['attrGroup'][$indexGroup][$indexAttr]['arg'][$indexArg] = $this->printer->renderOperand($arg); } } } @@ -146,7 +143,6 @@ protected function renderAttrGroups(Op\AttributableOp $op): array return $result; } - protected function renderFlags(Op\Stmt $stmt): string { $result = ''; @@ -178,5 +174,4 @@ protected function renderFlags(Op\Stmt $stmt): string return $result; } - } diff --git a/lib/PHPCfg/Printer/Renderer/Op/Assertion.php b/lib/PHPCfg/Printer/Renderer/Op/Assertion.php index 1fbfb58..379aeaf 100644 --- a/lib/PHPCfg/Printer/Renderer/Op/Assertion.php +++ b/lib/PHPCfg/Printer/Renderer/Op/Assertion.php @@ -24,25 +24,30 @@ public function renderOp(Op $op): ?array } $result = parent::renderOp($op); - $result['assert'] = 'assert: ' . $this->renderAssertion($op->assertion); + $result['vars']['assert'] = $this->renderAssertion($op->assertion); return $result; } - protected function renderAssertion(CoreAssertion $assert): string + protected function renderAssertion(CoreAssertion $assert): mixed { - if (is_array($assert->value)) { $combinator = $assert->mode === CoreAssertion::MODE_UNION ? '|' : '&'; - - $ret = implode($combinator, array_map([$this, 'renderAssertion'], $assert->value)); + if(count($assert->value) == 1) { + $ret = $this->renderAssertion($assert->value[0]); + } else { + foreach($assert->value as $value) { + $ret[$combinator][] = $this->renderAssertion($value); + } + } } else { $ret = $this->printer->renderOperand($assert->value); } + $kind = $assert->getKind(); if ($kind === 'type' || empty($kind)) { return $ret; } - return "$kind({$ret})"; + return [$kind => $ret]; } } diff --git a/lib/PHPCfg/Printer/Renderer/Op/Include_.php b/lib/PHPCfg/Printer/Renderer/Op/Include_.php index 2bc7e8f..1c5f07d 100644 --- a/lib/PHPCfg/Printer/Renderer/Op/Include_.php +++ b/lib/PHPCfg/Printer/Renderer/Op/Include_.php @@ -25,21 +25,21 @@ public function renderOp(Op $op): ?array switch ($op->type) { case 1: - $result['vars'][] = "type: include"; + $result['vars']['type'] = "include"; break; case 2: - $result['vars'][] = "type: include_once"; + $result['vars']['type'] = "include_once"; break; case 3: - $result['vars'][] = "type: require"; + $result['vars']['type'] = "require"; break; case 4: - $result['vars'][] = "type: require_once"; + $result['vars']['type'] = "require_once"; break; default: throw new LogicException("Unknown include type rendering: " . $type); } + return $result; } - } diff --git a/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php b/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php index 0980cd3..b93fd92 100644 --- a/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php +++ b/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php @@ -24,21 +24,23 @@ public function renderOp(Op $op): ?array $result = parent::renderOp($op); foreach ($op->traits as $index => $trait_) { - $result['vars'][] = "use[$index]: " . $this->printer->renderOperand($trait_); + $result['vars']['use'][$index] = $this->printer->renderOperand($trait_); } + + $adapt = []; foreach ($op->adaptations as $index => $adaptation) { - $adapt = []; if ($adaptation instanceof Op\TraitUseAdaptation\Alias) { - $adapt[] = "adaptation[$index]: Alias"; + $adapt['adaptation'][$index] = []; + $adapt['adaptation'][$index]['alias'] = []; if ($adaptation->trait != null) { - $adapt[] = " trait: " . $this->printer->renderOperand($adaptation->trait); + $adapt['adaptation'][$index]['alias']['trait'] = $this->printer->renderOperand($adaptation->trait); } - $adapt[] = " method: " . $this->printer->renderOperand($adaptation->method); + $adapt['adaptation'][$index]['alias']['method'] = $this->printer->renderOperand($adaptation->method); if ($adaptation->newName != null) { - $adapt[] = " newName: " . $this->printer->renderOperand($adaptation->newName); + $adapt['adaptation'][$index]['alias']['newName'] = $this->printer->renderOperand($adaptation->newName); } if ($adaptation->newModifier != null) { - $mod = " newModifier: "; + $mod = ""; if ($adaptation->isPublic()) { $mod .= "public"; } @@ -48,21 +50,22 @@ public function renderOp(Op $op): ?array if ($adaptation->isProtected()) { $mod .= "protected"; } - $adapt[] = $mod; + $adapt['adaptation'][$index]['alias']['newModifier'] = $mod; } } elseif ($adaptation instanceof Op\TraitUseAdaptation\Precedence) { - $adapt[] = "adaptation[$index]: Insteadof"; + $adapt['adaptation'][$index]['Insteadof'] = []; if ($adaptation->trait != null) { - $adapt[] = " trait: " . $this->printer->renderOperand($adaptation->trait); + $adapt['adaptation'][$index]['Insteadof']['trait'] = $this->printer->renderOperand($adaptation->trait); } - $adapt[] = " method: " . $this->printer->renderOperand($adaptation->method); + $adapt['adaptation'][$index]['Insteadof']['method'] = $this->printer->renderOperand($adaptation->method); foreach ($adaptation->insteadof as $index2 => $insteadof) { - $adapt[] = " insteadof[$index2]: " . $this->printer->renderOperand($insteadof); + $adapt['adaptation'][$index]['Insteadof']['insteadof'][$index2] = $this->printer->renderOperand($insteadof); } } - $result['vars'] = array_merge($result['vars'], $adapt); } + + $result['vars'] = array_merge($result['vars'], $adapt); + return $result; } - } diff --git a/lib/PHPCfg/Printer/Renderer/Operand/Literal.php b/lib/PHPCfg/Printer/Renderer/Operand/Literal.php index 59e3862..e0010bc 100644 --- a/lib/PHPCfg/Printer/Renderer/Operand/Literal.php +++ b/lib/PHPCfg/Printer/Renderer/Operand/Literal.php @@ -41,14 +41,15 @@ public function renderOperand(Operand $operand): ?array "type" => "", ]; } + if (!$operand instanceof Operand\Literal) { return null; } return [ "kind" => "LITERAL", - "type" => $operand->type ? "<{$operand->type}>" : "", - "value" => var_export($operand->value, true), + "type" => $operand->type, + "value" => $operand->value, ]; } diff --git a/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php b/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php index d0f43d5..fd69991 100644 --- a/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php +++ b/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php @@ -44,11 +44,12 @@ public function renderOperand(Operand $operand): ?array if (!$operand instanceof Operand\Temporary) { return null; } + return [ "kind" => "TEMP", - "type" => $operand->type ? "<{$operand->type}>" : "", - "id" => "#" . $this->getVarId($operand), - "original" => $operand->original ? "<" . $this->printer->renderOperand($operand->original) . ">" : "", + "type" => $operand->type, + "id" => $this->getVarId($operand), + "original" => $operand->original ? $this->printer->renderOperand($operand->original) : null, ]; } diff --git a/lib/PHPCfg/Printer/Renderer/Operand/Variable.php b/lib/PHPCfg/Printer/Renderer/Operand/Variable.php index 073e091..b8c2807 100644 --- a/lib/PHPCfg/Printer/Renderer/Operand/Variable.php +++ b/lib/PHPCfg/Printer/Renderer/Operand/Variable.php @@ -40,24 +40,26 @@ public function renderOperand(Operand $operand): ?array } assert($operand->name instanceof Operand\Literal); - $prefix = "$"; + $reference = false; + $scope = ""; if ($operand instanceof Operand\BoundVariable) { if ($operand->byRef) { - $prefix = '&$'; + $reference = true; } + switch ($operand->scope) { case Operand\BoundVariable::SCOPE_GLOBAL: - $prefix = "global $prefix"; + $scope = "global"; break; case Operand\BoundVariable::SCOPE_LOCAL: - $prefix = "local $prefix"; + $scope = "local"; break; case Operand\BoundVariable::SCOPE_OBJECT: - $prefix = "this $prefix"; + $scope = "this"; break; case Operand\BoundVariable::SCOPE_FUNCTION: - $prefix = "static $prefix"; + $scope = "static"; break; default: throw new LogicException('Unknown bound variable scope'); @@ -66,9 +68,10 @@ public function renderOperand(Operand $operand): ?array return [ "kind" => "VARIABLE", - "type" => $operand->type ? "<{$operand->type}>" : "", - "name" => $prefix . $operand->name->value, + "type" => $operand->type, + "name" => $operand->name->value, + "scope" => $scope, + "reference" => $reference, ]; } - } diff --git a/lib/PHPCfg/Printer/Text.php b/lib/PHPCfg/Printer/Text.php index 2e74773..8923cb7 100755 --- a/lib/PHPCfg/Printer/Text.php +++ b/lib/PHPCfg/Printer/Text.php @@ -11,6 +11,8 @@ namespace PHPCfg\Printer; +use LogicException; +use PHPCfg\Operand; use PHPCfg\Func; use PHPCfg\Script; @@ -87,4 +89,76 @@ public function printVars(Func $func): string return $output; } + + public function renderOperand(Operand $var): string + { + foreach ($this->renderers as $renderer) { + $result = $renderer->renderOperand($var); + if ($result !== null) { + $kind = $result['kind']; + $type = $result['type'] ? "<{$result['type']}>" : ""; + + if($kind == "TEMP" ) { + $result['id'] = "#" . $result['id']; + if(isset($result['original']) && $result['original']) { + $result['original'] = "<" . $result['original'] . ">"; + } + } + else if($kind == "VARIABLE") { + $result['name'] = $result['reference'] ? "&$" . $result['name'] : "$" . $result['name']; + + if($result['scope']) { + $result['name'] = $result['scope'] ." ". $result['name']; + } + + unset($result['scope'], $result['reference']); + } else if($kind == "LITERAL"){ + $result['value'] = var_export($result['value'], true); + } + + unset($result['kind'], $result['type']); + return strtoupper($kind) . $type . '(' . trim(implode(" ", $result)) . ')'; + } + } + + throw new LogicException("Unknown operand rendering: " . get_class($var)); + } + + public function renderOpLabelValue(array | string $value, string $prefix): string + { + $result = ''; + if (is_array($value)) { + foreach ($value as $k => $v) { + $newprefix = is_string($k) ? "{$prefix}['{$k}']" : "{$prefix}[{$k}]"; + if (is_array($v)) { + $result .= $this->renderOpLabelValue($v, $newprefix); + } else { + $result .= $this->indent("{$newprefix}: {$v}"); + } + } + } else { + $result .= $this->indent("{$prefix}: {$value}"); + } + + return $result; + } + + public function renderOpLabel(array $desc): string + { + $result = "{$desc['kind']}"; + unset($desc['kind'], $desc['childblocks']); + + foreach ($desc as $name => $val) { + if (is_array($val)) { + foreach ($val as $k => $v) { + $prefix = "\n{$k}"; + $result .= $this->renderOpLabelValue($v, $prefix); + } + } else { + $result .= $this->indent("\n{$name}: {$val}"); + } + } + + return $result; + } } diff --git a/test/CodeTest.php b/test/CodeTest.php index aabf85d..564b7a1 100755 --- a/test/CodeTest.php +++ b/test/CodeTest.php @@ -42,8 +42,8 @@ public function testParseAndDump($code, $expectedDump) } $this->assertEquals( - $this->canonicalize($expectedDump), - $this->canonicalize($result), + CodeTest::canonicalize($expectedDump), + CodeTest::canonicalize($result), ); } @@ -65,7 +65,7 @@ public static function provideTestParseAndDump() } } - private function canonicalize($str) + public static function canonicalize($str) { // trim from both sides $str = trim($str); diff --git a/test/code/and.test b/test/code/and.test index 9f8877d..62721e9 100755 --- a/test/code/and.test +++ b/test/code/and.test @@ -25,9 +25,12 @@ Block#2 Block#3 Parent: Block#2 Parent: Block#1 - TEMP(#4) = Phi(LITERAL(false), TEMP(#3)) + Phi + vars[0]: LITERAL(false) + vars[1]: TEMP(#3) + result: TEMP(#4) Expr_Assign var: TEMP(#5 ) expr: TEMP(#4) result: TEMP(#6) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/anonymous_class.test b/test/code/anonymous_class.test index 465fc6c..7af7a80 100644 --- a/test/code/anonymous_class.test +++ b/test/code/anonymous_class.test @@ -19,11 +19,9 @@ Block#1 expr: TEMP(#1) result: TEMP(#3) Stmt_Class + attrGroup[0][0]['name']: LITERAL('Attr') + attrGroup[0][0]['arg'][0]: LITERAL('foo') name: {anonymousClass}#2 - attrGroup[0]: - attr[0]: - name: LITERAL('Attr') - args[0]: LITERAL('foo') stmts: Block#3 Expr_New class: LITERAL('{anonymousClass}#2') diff --git a/test/code/arrayList.test b/test/code/arrayList.test index 33308d5..0466c56 100755 --- a/test/code/arrayList.test +++ b/test/code/arrayList.test @@ -31,4 +31,4 @@ Block#1 var: TEMP(#10 ) expr: TEMP(#9) result: TEMP(#11) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/arrow_fn.test b/test/code/arrow_fn.test index a9e2476..5ad2152 100644 --- a/test/code/arrow_fn.test +++ b/test/code/arrow_fn.test @@ -46,4 +46,4 @@ Block#1 right: TEMP(#1 ) result: TEMP(#6) Terminal_Return - expr: TEMP(#6) \ No newline at end of file + expr: TEMP(#6) diff --git a/test/code/assign_coalesce.test b/test/code/assign_coalesce.test index 24d29d2..8e25a28 100644 --- a/test/code/assign_coalesce.test +++ b/test/code/assign_coalesce.test @@ -14,4 +14,4 @@ Block#1 var: TEMP(#4 ) expr: TEMP(#3) result: TEMP(#5) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/block.test b/test/code/block.test index e37c6f0..3d3a4cf 100644 --- a/test/code/block.test +++ b/test/code/block.test @@ -3,10 +3,10 @@ echo "a"; { $aaaa = 1; -} +} + +{ -{ - } ----- Block#1 diff --git a/test/code/cast.test b/test/code/cast.test index b902665..84f574f 100644 --- a/test/code/cast.test +++ b/test/code/cast.test @@ -1,7 +1,6 @@ ) - attrGroup[0]: - attr[0]: - name: LITERAL('FooParamAttrib') - args[0]: LITERAL('Foo1') - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/class_this.test b/test/code/class_this.test index 4b33043..684a87f 100755 --- a/test/code/class_this.test +++ b/test/code/class_this.test @@ -25,4 +25,4 @@ Block#1 result: TEMP(#1) Terminal_Echo expr: TEMP(#1) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/class_typed_property.test b/test/code/class_typed_property.test index 02e020c..66586de 100755 --- a/test/code/class_typed_property.test +++ b/test/code/class_typed_property.test @@ -1,25 +1,25 @@ -) - expr: TEMP(#1) - result: TEMP(#3) - Terminal_Return - -Block#2 - Stmt_Property - declaredType: ?NS\NameOfClass - flags: public - name: LITERAL('self') \ No newline at end of file +) + expr: TEMP(#1) + result: TEMP(#3) + Terminal_Return + +Block#2 + Stmt_Property + declaredType: ?NS\NameOfClass + flags: public + name: LITERAL('self') diff --git a/test/code/closure.test b/test/code/closure.test index 79ed5b4..e64444a 100755 --- a/test/code/closure.test +++ b/test/code/closure.test @@ -54,4 +54,4 @@ Block#1 var: TEMP(#6 ) expr: TEMP(#5) result: TEMP(#7) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/closure_empty.test b/test/code/closure_empty.test index fbb1b95..ce7e9a0 100755 --- a/test/code/closure_empty.test +++ b/test/code/closure_empty.test @@ -17,4 +17,4 @@ Block#1 declaredType: mixed name: LITERAL('a') result: TEMP(#1 ) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/constDecl.test b/test/code/constDecl.test index 599ff10..baafa8f 100755 --- a/test/code/constDecl.test +++ b/test/code/constDecl.test @@ -55,4 +55,4 @@ Block#6 Expr_BinaryOp_Plus left: LITERAL(4) right: LITERAL(4) - result: TEMP(#5) \ No newline at end of file + result: TEMP(#5) diff --git a/test/code/constFetch.test b/test/code/constFetch.test index 6714550..a2693b1 100755 --- a/test/code/constFetch.test +++ b/test/code/constFetch.test @@ -26,6 +26,6 @@ Block#1 result: TEMP(#4) Expr_FuncCall name: LITERAL('var_dump') - args[0]: LITERAL(NULL) + args[0]: NULL() result: TEMP(#5) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/duplicate_label.test b/test/code/duplicate_label.test index c9e3f51..8784c16 100644 --- a/test/code/duplicate_label.test +++ b/test/code/duplicate_label.test @@ -2,4 +2,4 @@ foo: foo: ----- -Label 'foo' already defined \ No newline at end of file +Label 'foo' already defined diff --git a/test/code/empty.test b/test/code/empty.test index 8d3e21e..00469b5 100755 --- a/test/code/empty.test +++ b/test/code/empty.test @@ -22,4 +22,4 @@ Block#1 name: LITERAL('var_dump') args[0]: TEMP(#5) result: TEMP(#6) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/error_supress.test b/test/code/error_supress.test index 62c6be5..6d1c96a 100755 --- a/test/code/error_supress.test +++ b/test/code/error_supress.test @@ -20,4 +20,4 @@ Block#2 result: TEMP(#3) Terminal_Echo expr: TEMP(#1 ) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/exprFuncCall.test b/test/code/exprFuncCall.test index 4ccd4aa..5f62c0d 100755 --- a/test/code/exprFuncCall.test +++ b/test/code/exprFuncCall.test @@ -12,4 +12,4 @@ Block#1 name: TEMP(#1 ) args[0]: LITERAL('some string') result: TEMP(#3) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/foreach.test b/test/code/foreach.test index d5949f4..489b698 100755 --- a/test/code/foreach.test +++ b/test/code/foreach.test @@ -43,4 +43,4 @@ Block#3 Block#4 Parent: Block#2 - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/function.test b/test/code/function.test index bd4c3ec..b137f11 100755 --- a/test/code/function.test +++ b/test/code/function.test @@ -15,4 +15,4 @@ Block#1 name: LITERAL('a') result: TEMP(#1 ) Terminal_Return - expr: TEMP(#1 ) \ No newline at end of file + expr: TEMP(#1 ) diff --git a/test/code/function_attributes.test b/test/code/function_attributes.test index 27e3919..238547e 100644 --- a/test/code/function_attributes.test +++ b/test/code/function_attributes.test @@ -11,24 +11,18 @@ function foo_func(#[FooParamAttrib('Foo1')] $foo) {} ----- Block#1 Stmt_Function + attrGroup[0][0]['name']: LITERAL('ExampleAttribute') + attrGroup[0][0]['arg'][0]: LITERAL('foo') + attrGroup[0][0]['arg'][1]: LITERAL('bar') name: foo2 - attrGroup[0]: - attr[0]: - name: LITERAL('ExampleAttribute') - args[0]: LITERAL('foo') - args[1]: LITERAL('bar') Expr_ConstFetch name: LITERAL('null') result: TEMP(#1) Stmt_Function + attrGroup[0][0]['name']: LITERAL('ConstAttr') + attrGroup[1][0]['name']: LITERAL('FooAttribute') + attrGroup[1][0]['arg'][0]: TEMP(#1) name: foo5 - attrGroup[0]: - attr[0]: - name: LITERAL('ConstAttr') - attrGroup[1]: - attr[0]: - name: LITERAL('FooAttribute') - args[0]: TEMP(#1) Stmt_Function name: foo_func Terminal_Return @@ -44,11 +38,9 @@ Block#1 Function 'foo_func': mixed Block#1 Expr_Param + attrGroup[0][0]['name']: LITERAL('FooParamAttrib') + attrGroup[0][0]['arg'][0]: LITERAL('Foo1') declaredType: mixed name: LITERAL('foo') result: TEMP(#1 ) - attrGroup[0]: - attr[0]: - name: LITERAL('FooParamAttrib') - args[0]: LITERAL('Foo1') - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/function_empty.test b/test/code/function_empty.test index 579ed54..b0a8a03 100755 --- a/test/code/function_empty.test +++ b/test/code/function_empty.test @@ -12,4 +12,4 @@ Block#1 declaredType: mixed name: LITERAL('a') result: TEMP(#1 ) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/function_namespace.test b/test/code/function_namespace.test index 8098e77..56f2ae3 100755 --- a/test/code/function_namespace.test +++ b/test/code/function_namespace.test @@ -16,4 +16,4 @@ Block#1 name: LITERAL('a') result: TEMP(#1 ) Terminal_Return - expr: TEMP(#1 ) \ No newline at end of file + expr: TEMP(#1 ) diff --git a/test/code/function_return_type.test b/test/code/function_return_type.test index 7698b91..760a9a8 100755 --- a/test/code/function_return_type.test +++ b/test/code/function_return_type.test @@ -1,18 +1,18 @@ -) - Terminal_Return - expr: TEMP(#1 ) \ No newline at end of file +) + Terminal_Return + expr: TEMP(#1 ) diff --git a/test/code/goto_forever.test b/test/code/goto_forever.test index adc63a9..83a9188 100644 --- a/test/code/goto_forever.test +++ b/test/code/goto_forever.test @@ -10,4 +10,4 @@ Block#2 Parent: Block#1 Parent: Block#2 Stmt_Jump - target: Block#2 \ No newline at end of file + target: Block#2 diff --git a/test/code/goto_undefined.test b/test/code/goto_undefined.test index 61a0e32..ad05b7d 100644 --- a/test/code/goto_undefined.test +++ b/test/code/goto_undefined.test @@ -2,4 +2,4 @@ goto nowhere; echo "a\n"; ----- -'goto' to undefined label 'nowhere' \ No newline at end of file +'goto' to undefined label 'nowhere' diff --git a/test/code/if_else.test b/test/code/if_else.test index d0d4557..7e1e043 100755 --- a/test/code/if_else.test +++ b/test/code/if_else.test @@ -32,4 +32,4 @@ Block#4 Parent: Block#3 Terminal_Echo expr: LITERAL('c') - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/if_else_if_else.test b/test/code/if_else_if_else.test index b7f0a39..3866e0b 100755 --- a/test/code/if_else_if_else.test +++ b/test/code/if_else_if_else.test @@ -49,4 +49,4 @@ Block#6 Terminal_Echo expr: LITERAL('c') Stmt_Jump - target: Block#4 \ No newline at end of file + target: Block#4 diff --git a/test/code/if_elseif_else.test b/test/code/if_elseif_else.test index a8478b0..af09408 100755 --- a/test/code/if_elseif_else.test +++ b/test/code/if_elseif_else.test @@ -49,4 +49,4 @@ Block#6 Terminal_Echo expr: LITERAL('c') Stmt_Jump - target: Block#4 \ No newline at end of file + target: Block#4 diff --git a/test/code/include.test b/test/code/include.test index 289e33a..f231c0f 100755 --- a/test/code/include.test +++ b/test/code/include.test @@ -22,5 +22,3 @@ Block#1 result: TEMP(#5) type: require_once Terminal_Return - - diff --git a/test/code/interface.test b/test/code/interface.test index 2d1cf94..fa4b138 100755 --- a/test/code/interface.test +++ b/test/code/interface.test @@ -15,4 +15,4 @@ Block#2 name: method flags: public -Function 'Test::method': mixed \ No newline at end of file +Function 'Test::method': mixed diff --git a/test/code/intersection_type.test b/test/code/intersection_type.test index e46f732..8f0066f 100644 --- a/test/code/intersection_type.test +++ b/test/code/intersection_type.test @@ -15,4 +15,3 @@ Block#1 name: LITERAL('string') result: TEMP(#1 ) Terminal_Return - diff --git a/test/code/isset.test b/test/code/isset.test index c1eb133..784f9ed 100755 --- a/test/code/isset.test +++ b/test/code/isset.test @@ -26,4 +26,4 @@ Block#2 Block#3 Parent: Block#2 Parent: Block#1 - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/list.test b/test/code/list.test index 93fca93..ac885d7 100755 --- a/test/code/list.test +++ b/test/code/list.test @@ -82,4 +82,4 @@ Block#3 Block#4 Parent: Block#2 - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/listKeys.test b/test/code/listKeys.test index e9e4289..664a0f5 100755 --- a/test/code/listKeys.test +++ b/test/code/listKeys.test @@ -24,4 +24,4 @@ Block#1 var: TEMP(#8 ) expr: TEMP(#7) result: TEMP(#9) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/literal.test b/test/code/literal.test index 1f92ac6..6be9625 100644 --- a/test/code/literal.test +++ b/test/code/literal.test @@ -22,4 +22,4 @@ Block#1 var: TEMP(#7 ) expr: LITERAL('aaaa\'\')') result: TEMP(#8) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/match.test b/test/code/match.test index 64d83d5..dfe18f6 100644 --- a/test/code/match.test +++ b/test/code/match.test @@ -31,7 +31,7 @@ Block#3 expr: LITERAL('bar') result: TEMP(#4) Stmt_Jump - target: Block#5 + target: Block#5 Block#4 Parent: Block#1 @@ -46,9 +46,11 @@ Block#5 Parent: Block#2 Parent: Block#3 Parent: Block#4 - TEMP(#6) = Phi(TEMP(#1), TEMP(#3), TEMP(#5)) + Phi + vars[0]: TEMP(#1) + vars[1]: TEMP(#3) + vars[2]: TEMP(#5) + result: TEMP(#6) Terminal_Echo expr: TEMP(#6) Terminal_Return - - diff --git a/test/code/match2.test b/test/code/match2.test index 4cf8aa0..251de24 100644 --- a/test/code/match2.test +++ b/test/code/match2.test @@ -39,15 +39,19 @@ Block#4 Parent: Block#2 Parent: Block#5 Parent: Block#7 - TEMP(#5) = Phi(TEMP(#2), TEMP(#6), TEMP(#7)) + Phi + vars[0]: TEMP(#2) + vars[1]: TEMP(#5) + vars[2]: TEMP(#6) + result: TEMP(#7) Terminal_Echo - expr: TEMP(#5) + expr: TEMP(#7) Terminal_Return Block#5 Parent: Block#3 Expr_Assign - var: TEMP(#6) + var: TEMP(#5) expr: LITERAL('bar') result: TEMP(#8) Stmt_Jump @@ -73,7 +77,7 @@ Block#7 Expr_BinaryOp_Concat left: LITERAL('baz') right: LITERAL('buz') - result: TEMP(#7) + result: TEMP(#6) Stmt_Jump target: Block#4 diff --git a/test/code/namespaced_conditionals.test b/test/code/namespaced_conditionals.test index 21d49c0..cc1cc6e 100755 --- a/test/code/namespaced_conditionals.test +++ b/test/code/namespaced_conditionals.test @@ -43,4 +43,4 @@ Block#4 Block#5 Parent: Block#4 Parent: Block#3 - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/nested_phi.test b/test/code/nested_phi.test index d6e5edf..d61f8f2 100755 --- a/test/code/nested_phi.test +++ b/test/code/nested_phi.test @@ -7,7 +7,6 @@ foreach ([1, 2, 3] as $b) { } } echo $a; - ----- Block#1 Expr_Assign @@ -31,7 +30,10 @@ Block#2 Parent: Block#1 Parent: Block#3 Parent: Block#5 - TEMP(#4 ) = Phi(TEMP(#1 ), TEMP(#5 )) + Phi + vars[0]: TEMP(#1 ) + vars[1]: TEMP(#4 ) + result: TEMP(#5 ) Iterator_Valid var: TEMP(#3) result: TEMP(#6) @@ -50,7 +52,7 @@ Block#3 expr: TEMP(#7) result: TEMP(#9) Expr_BinaryOp_Greater - left: TEMP(#4 ) + left: TEMP(#5 ) right: LITERAL(0) result: TEMP(#10) Stmt_JumpIf @@ -61,18 +63,18 @@ Block#3 Block#4 Parent: Block#2 Terminal_Echo - expr: TEMP(#4 ) + expr: TEMP(#5 ) Terminal_Return Block#5 Parent: Block#3 Expr_BinaryOp_Plus - left: TEMP(#4 ) + left: TEMP(#5 ) right: TEMP(#8 ) result: TEMP(#11) Expr_Assign - var: TEMP(#5 ) + var: TEMP(#4 ) expr: TEMP(#11) result: TEMP(#12) Stmt_Jump - target: Block#2 \ No newline at end of file + target: Block#2 diff --git a/test/code/nop.test b/test/code/nop.test index 522e670..d1f512a 100755 --- a/test/code/nop.test +++ b/test/code/nop.test @@ -11,4 +11,4 @@ Block#1 result: TEMP(#2) Terminal_Echo expr: TEMP(#1 ) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/nsFuncCall.test b/test/code/nsFuncCall.test index 5006170..d51753c 100755 --- a/test/code/nsFuncCall.test +++ b/test/code/nsFuncCall.test @@ -8,4 +8,4 @@ Block#1 nsName: LITERAL('Foo\\call') name: LITERAL('call') result: TEMP(#1) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/or.test b/test/code/or.test index 8d4ec80..f2a956f 100755 --- a/test/code/or.test +++ b/test/code/or.test @@ -14,10 +14,13 @@ Block#1 Block#2 Parent: Block#3 Parent: Block#1 - TEMP(#2) = Phi(LITERAL(true), TEMP(#3)) + Phi + vars[0]: LITERAL(true) + vars[1]: TEMP(#2) + result: TEMP(#3) Expr_Assign var: TEMP(#4 ) - expr: TEMP(#2) + expr: TEMP(#3) result: TEMP(#5) Terminal_Return @@ -28,6 +31,6 @@ Block#3 result: TEMP(#6) Expr_Cast_Bool expr: TEMP(#6) - result: TEMP(#3) + result: TEMP(#2) Stmt_Jump - target: Block#2 \ No newline at end of file + target: Block#2 diff --git a/test/code/property.test b/test/code/property.test index 54b2559..3581b62 100755 --- a/test/code/property.test +++ b/test/code/property.test @@ -7,7 +7,7 @@ class A { private readonly static $prop5; static $prop6; protected $prop7; - + #[ConstAttr] #[FooAttribute(null)] private string $foo5; @@ -59,16 +59,12 @@ Block#2 name: LITERAL('null') result: TEMP(#2) Stmt_Property + attrGroup[0][0]['name']: LITERAL('ConstAttr') + attrGroup[1][0]['name']: LITERAL('FooAttribute') + attrGroup[1][0]['arg'][0]: TEMP(#2) declaredType: string flags: private name: LITERAL('foo5') - attrGroup[0]: - attr[0]: - name: LITERAL('ConstAttr') - attrGroup[1]: - attr[0]: - name: LITERAL('FooAttribute') - args[0]: TEMP(#2) Terminal_Const name: LITERAL('FOO') value: LITERAL('foo') diff --git a/test/code/shellExec.test b/test/code/shellExec.test index 80cb58e..216447d 100755 --- a/test/code/shellExec.test +++ b/test/code/shellExec.test @@ -11,4 +11,4 @@ Block#1 name: LITERAL('shell_exec') args[0]: TEMP(#2) result: TEMP(#3) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/switch.test b/test/code/switch.test index d90c58a..52a6d5a 100755 --- a/test/code/switch.test +++ b/test/code/switch.test @@ -50,4 +50,4 @@ Block#5 Parent: Block#2 Parent: Block#3 Parent: Block#4 - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/switch2.test b/test/code/switch2.test index 5aa06e5..5c8a406 100755 --- a/test/code/switch2.test +++ b/test/code/switch2.test @@ -84,4 +84,4 @@ Block#8 Terminal_Echo expr: LITERAL('C') Stmt_Jump - target: Block#6 \ No newline at end of file + target: Block#6 diff --git a/test/code/ternary.test b/test/code/ternary.test index debaa27..670dbe6 100755 --- a/test/code/ternary.test +++ b/test/code/ternary.test @@ -29,9 +29,12 @@ Block#3 Block#4 Parent: Block#2 Parent: Block#3 - TEMP(#8) = Phi(TEMP(#2), TEMP(#5)) + Phi + vars[0]: TEMP(#2) + vars[1]: TEMP(#5) + result: TEMP(#8) Expr_Assign var: TEMP(#9 ) expr: TEMP(#8) result: TEMP(#10) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/ternary2.test b/test/code/ternary2.test index 5ca3bb7..6580474 100755 --- a/test/code/ternary2.test +++ b/test/code/ternary2.test @@ -27,10 +27,13 @@ Block#3 Block#4 Parent: Block#2 Parent: Block#7 - TEMP(#4) = Phi(TEMP(#2), TEMP(#5)) + Phi + vars[0]: TEMP(#2) + vars[1]: TEMP(#4) + result: TEMP(#5) Expr_Assign var: TEMP(#6 ) - expr: TEMP(#4) + expr: TEMP(#5) result: TEMP(#7) Terminal_Return @@ -55,10 +58,13 @@ Block#6 Block#7 Parent: Block#5 Parent: Block#6 - TEMP(#13) = Phi(TEMP(#8), TEMP(#10)) + Phi + vars[0]: TEMP(#8) + vars[1]: TEMP(#10) + result: TEMP(#13) Expr_Assign - var: TEMP(#5) + var: TEMP(#4) expr: TEMP(#13) result: TEMP(#14) Stmt_Jump - target: Block#4 \ No newline at end of file + target: Block#4 diff --git a/test/code/throw.test b/test/code/throw.test index fa695cd..1e2cef8 100644 --- a/test/code/throw.test +++ b/test/code/throw.test @@ -11,7 +11,10 @@ Block#1 Block#2 Parent: Block#1 - TEMP(#2) = Phi(LITERAL(true), TEMP(#3)) + Phi + vars[0]: LITERAL(true) + vars[1]: TEMP(#2) + result: TEMP(#3) Expr_New class: LITERAL('InvalidArgumentException') args[0]: LITERAL('foo') diff --git a/test/code/traitUse.test b/test/code/traitUse.test index d9e3317..2b97b31 100644 --- a/test/code/traitUse.test +++ b/test/code/traitUse.test @@ -67,32 +67,27 @@ Block#4 Stmt_TraitUse use[0]: LITERAL('\\A') use[1]: LITERAL('\\B') - adaptation[0]: Insteadof - trait: LITERAL('\\B') - method: LITERAL('smallTalk') - insteadof[0]: LITERAL('\\A') - adaptation[1]: Insteadof - trait: LITERAL('\\A') - method: LITERAL('bigTalk') - insteadof[0]: LITERAL('\\B') + adaptation[0]['Insteadof']['trait']: LITERAL('\\B') + adaptation[0]['Insteadof']['method']: LITERAL('smallTalk') + adaptation[0]['Insteadof']['insteadof'][0]: LITERAL('\\A') + adaptation[1]['Insteadof']['trait']: LITERAL('\\A') + adaptation[1]['Insteadof']['method']: LITERAL('bigTalk') + adaptation[1]['Insteadof']['insteadof'][0]: LITERAL('\\B') Block#5 Stmt_TraitUse use[0]: LITERAL('\\A') use[1]: LITERAL('\\B') - adaptation[0]: Insteadof - trait: LITERAL('\\B') - method: LITERAL('smallTalk') - insteadof[0]: LITERAL('\\A') - adaptation[1]: Insteadof - trait: LITERAL('\\A') - method: LITERAL('bigTalk') - insteadof[0]: LITERAL('\\B') - adaptation[2]: Alias - trait: LITERAL('\\B') - method: LITERAL('bigTalk') - newName: LITERAL('talk') - newModifier: private + adaptation[0]['Insteadof']['trait']: LITERAL('\\B') + adaptation[0]['Insteadof']['method']: LITERAL('smallTalk') + adaptation[0]['Insteadof']['insteadof'][0]: LITERAL('\\A') + adaptation[1]['Insteadof']['trait']: LITERAL('\\A') + adaptation[1]['Insteadof']['method']: LITERAL('bigTalk') + adaptation[1]['Insteadof']['insteadof'][0]: LITERAL('\\B') + adaptation[2]['alias']['trait']: LITERAL('\\B') + adaptation[2]['alias']['method']: LITERAL('bigTalk') + adaptation[2]['alias']['newName']: LITERAL('talk') + adaptation[2]['alias']['newModifier']: private Function 'A::smallTalk': mixed Block#1 @@ -116,4 +111,4 @@ Function 'B::bigTalk': mixed Block#1 Terminal_Echo expr: LITERAL('B') - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/traitUse2.test b/test/code/traitUse2.test index 05de201..37ba2b6 100644 --- a/test/code/traitUse2.test +++ b/test/code/traitUse2.test @@ -33,20 +33,18 @@ Block#2 Block#3 Stmt_TraitUse use[0]: LITERAL('\\HelloWorld') - adaptation[0]: Alias - method: LITERAL('sayHello') - newModifier: protected + adaptation[0]['alias']['method']: LITERAL('sayHello') + adaptation[0]['alias']['newModifier']: protected Block#4 Stmt_TraitUse use[0]: LITERAL('\\HelloWorld') - adaptation[0]: Alias - method: LITERAL('sayHello') - newName: LITERAL('myPrivateHello') - newModifier: private + adaptation[0]['alias']['method']: LITERAL('sayHello') + adaptation[0]['alias']['newName']: LITERAL('myPrivateHello') + adaptation[0]['alias']['newModifier']: private Function 'HelloWorld::sayHello': mixed Block#1 Terminal_Echo expr: LITERAL('Hello World!') - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/try.test b/test/code/try.test index 0c6fd0d..8799be4 100644 --- a/test/code/try.test +++ b/test/code/try.test @@ -53,4 +53,4 @@ Block#5 Parent: Block#1 Parent: Block#3 Parent: Block#4 - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/try_bodyblocks.test b/test/code/try_bodyblocks.test index dd1449b..9af262a 100644 --- a/test/code/try_bodyblocks.test +++ b/test/code/try_bodyblocks.test @@ -42,9 +42,13 @@ Block#3 Parent: Block#7 Parent: Block#8 finallyTarget: Block#4 - TEMP(#3 ) = Phi(TEMP(#1 ), TEMP(#4 ), TEMP(#5 )) + Phi + vars[0]: TEMP(#1 ) + vars[1]: TEMP(#3 ) + vars[2]: TEMP(#4 ) + result: TEMP(#5 ) Terminal_Return - expr: TEMP(#3 ) + expr: TEMP(#5 ) Block#4 Parent: Block#2 @@ -106,4 +110,4 @@ Block#9 catchTarget(TEMP(#1 )): Block#3 finallyTarget: Block#4 Stmt_Jump - target: Block#4 \ No newline at end of file + target: Block#4 diff --git a/test/code/try_bodyblocks2.test b/test/code/try_bodyblocks2.test index 21e7ab5..782709f 100644 --- a/test/code/try_bodyblocks2.test +++ b/test/code/try_bodyblocks2.test @@ -44,9 +44,13 @@ Block#3 Parent: Block#8 Parent: Block#9 finallyTarget: Block#4 - TEMP(#3 ) = Phi(TEMP(#1 ), TEMP(#4 ), TEMP(#5 )) + Phi + vars[0]: TEMP(#1 ) + vars[1]: TEMP(#3 ) + vars[2]: TEMP(#4 ) + result: TEMP(#5 ) Terminal_Return - expr: TEMP(#3 ) + expr: TEMP(#5 ) Block#4 Parent: Block#2 @@ -116,4 +120,4 @@ Block#10 catchTarget(TEMP(#1 )): Block#3 finallyTarget: Block#4 Stmt_Jump - target: Block#4 \ No newline at end of file + target: Block#4 diff --git a/test/code/try_finally.test b/test/code/try_finally.test index 59ce932..0e155ba 100644 --- a/test/code/try_finally.test +++ b/test/code/try_finally.test @@ -37,4 +37,4 @@ Block#4 Parent: Block#2 Parent: Block#3 Terminal_Return - expr: LITERAL('finally') \ No newline at end of file + expr: LITERAL('finally') diff --git a/test/code/try_nested.test b/test/code/try_nested.test index dcf61a6..a5fb7d2 100644 --- a/test/code/try_nested.test +++ b/test/code/try_nested.test @@ -3,7 +3,7 @@ try { try { echo "nested try"; - } + } catch(Exception1 $e1) { echo $e1; } @@ -39,9 +39,12 @@ Block#3 Parent: Block#2 Parent: Block#7 finallyTarget: Block#4 - TEMP(#3 ) = Phi(TEMP(#1 ), TEMP(#4 )) + Phi + vars[0]: TEMP(#1 ) + vars[1]: TEMP(#3 ) + result: TEMP(#4 ) Terminal_Echo - expr: TEMP(#3 ) + expr: TEMP(#4 ) Stmt_Jump target: Block#4 @@ -81,4 +84,4 @@ Block#7 name: LITERAL('true') result: TEMP(#6) Terminal_Return - expr: TEMP(#6) \ No newline at end of file + expr: TEMP(#6) diff --git a/test/code/type_assert.test b/test/code/type_assert.test index 4517799..873b8bd 100755 --- a/test/code/type_assert.test +++ b/test/code/type_assert.test @@ -29,7 +29,7 @@ Block#3 Expr_Assertion expr: TEMP(#1 ) result: TEMP(#4 ) - assert: not(LITERAL('int')) + assert['not']: LITERAL('int') Expr_FuncCall name: LITERAL('is_float') args[0]: TEMP(#4 ) @@ -43,8 +43,14 @@ Block#3 Block#4 Parent: Block#3 Parent: Block#2 - TEMP(#7) = Phi(LITERAL(true), TEMP(#6)) - TEMP(#8 ) = Phi(TEMP(#4 ), TEMP(#3 )) + Phi + vars[0]: LITERAL(true) + vars[1]: TEMP(#6) + result: TEMP(#7) + Phi + vars[0]: TEMP(#4 ) + vars[1]: TEMP(#3 ) + result: TEMP(#8 ) Stmt_JumpIf cond: TEMP(#7) if: Block#5 @@ -55,7 +61,8 @@ Block#5 Expr_Assertion expr: TEMP(#8 ) result: TEMP(#9 ) - assert: LITERAL('int')|LITERAL('float') + assert['|'][0]: LITERAL('int') + assert['|'][1]: LITERAL('float') Terminal_Echo expr: TEMP(#9 ) Stmt_Jump @@ -66,16 +73,20 @@ Block#6 Expr_Assertion expr: TEMP(#8 ) result: TEMP(#10 ) - assert: not(LITERAL('int')|LITERAL('float')) + assert['not']['|'][0]: LITERAL('int') + assert['not']['|'][1]: LITERAL('float') Stmt_Jump target: Block#7 Block#7 Parent: Block#5 Parent: Block#6 - TEMP(#11 ) = Phi(TEMP(#9 ), TEMP(#10 )) + Phi + vars[0]: TEMP(#9 ) + vars[1]: TEMP(#10 ) + result: TEMP(#11 ) Expr_FuncCall name: LITERAL('var_dump') args[0]: TEMP(#11 ) result: TEMP(#12) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/unary.test b/test/code/unary.test index 4a2d323..b4d2b91 100644 --- a/test/code/unary.test +++ b/test/code/unary.test @@ -3,7 +3,6 @@ $a = +1; $b = -2; $c = ~3; - ----- Block#1 Expr_UnaryPlus @@ -27,4 +26,4 @@ Block#1 var: TEMP(#8 ) expr: TEMP(#7) result: TEMP(#9) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/unionType.test b/test/code/unionType.test index 4a53472..6acc6c6 100644 --- a/test/code/unionType.test +++ b/test/code/unionType.test @@ -15,4 +15,3 @@ Block#1 name: LITERAL('string') result: TEMP(#1 ) Terminal_Return - diff --git a/test/code/variablevariable.test b/test/code/variablevariable.test index a43200b..ff270b9 100755 --- a/test/code/variablevariable.test +++ b/test/code/variablevariable.test @@ -2,7 +2,7 @@ ${$foo} = "bar"; ${$foo1."plus".$foo2} = "bar"; -$$foo = "bar"; +$$foo = "bar"; $$$$$$$a = "b"; echo $foo->{$baz[1]}; @@ -102,4 +102,4 @@ Block#1 result: TEMP(#31) Terminal_Echo expr: TEMP(#31) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/while.test b/test/code/while.test index f7c0b0a..3c7128a 100644 --- a/test/code/while.test +++ b/test/code/while.test @@ -4,7 +4,6 @@ while(true) { echo 1; } echo 2; - ----- Block#1 Stmt_Jump @@ -32,4 +31,4 @@ Block#4 Parent: Block#2 Terminal_Echo expr: LITERAL(2) - Terminal_Return \ No newline at end of file + Terminal_Return diff --git a/test/code/yeild_from.test b/test/code/yeild_from.test index a52b7d8..67a3008 100644 --- a/test/code/yeild_from.test +++ b/test/code/yeild_from.test @@ -30,9 +30,12 @@ Block#1 Block#2 Parent: Block#1 Parent: Block#5 - TEMP(#3 ) = Phi(TEMP(#1 ), TEMP(#4 )) + Phi + vars[0]: TEMP(#1 ) + vars[1]: TEMP(#3 ) + result: TEMP(#4 ) Expr_BinaryOp_SmallerOrEqual - left: TEMP(#3 ) + left: TEMP(#4 ) right: LITERAL(3) result: TEMP(#5) Stmt_JumpIf @@ -43,7 +46,7 @@ Block#2 Block#3 Parent: Block#2 Expr_Yield - key: TEMP(#3 ) + key: TEMP(#4 ) result: TEMP(#6) Stmt_Jump target: Block#5 @@ -55,11 +58,11 @@ Block#4 Block#5 Parent: Block#3 Expr_BinaryOp_Plus - left: TEMP(#3 ) + left: TEMP(#4 ) right: LITERAL(1) result: TEMP(#7) Expr_Assign - var: TEMP(#4 ) + var: TEMP(#3 ) expr: TEMP(#7) result: TEMP(#8) Stmt_Jump diff --git a/test/code/yield.test b/test/code/yield.test index f9eebf2..11127f1 100644 --- a/test/code/yield.test +++ b/test/code/yield.test @@ -71,9 +71,12 @@ Block#1 Block#2 Parent: Block#1 Parent: Block#5 - TEMP(#3 ) = Phi(TEMP(#1 ), TEMP(#4 )) + Phi + vars[0]: TEMP(#1 ) + vars[1]: TEMP(#3 ) + result: TEMP(#4 ) Expr_BinaryOp_SmallerOrEqual - left: TEMP(#3 ) + left: TEMP(#4 ) right: LITERAL(3) result: TEMP(#5) Stmt_JumpIf @@ -84,7 +87,7 @@ Block#2 Block#3 Parent: Block#2 Expr_Yield - key: TEMP(#3 ) + key: TEMP(#4 ) result: TEMP(#6) Stmt_Jump target: Block#5 @@ -96,12 +99,12 @@ Block#4 Block#5 Parent: Block#3 Expr_BinaryOp_Plus - left: TEMP(#3 ) + left: TEMP(#4 ) right: LITERAL(1) result: TEMP(#7) Expr_Assign - var: TEMP(#4 ) + var: TEMP(#3 ) expr: TEMP(#7) result: TEMP(#8) Stmt_Jump - target: Block#2 \ No newline at end of file + target: Block#2 diff --git a/test/integration/ParserAttributesTest.php b/test/integration/ParserAttributesTest.php index 0eb27f2..713b696 100755 --- a/test/integration/ParserAttributesTest.php +++ b/test/integration/ParserAttributesTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\Attributes\CoversNothing; use PHPUnit\Framework\TestCase; use RuntimeException; +use PHPCfg\CodeTest; #[CoversNothing] class ParserAttributesTest extends TestCase @@ -57,7 +58,7 @@ function foo(\$a) { $result = $e->getMessage(); } - $this->assertEquals($this->canonicalize($expected), $this->canonicalize($result)); + $this->assertEquals(CodeTest::canonicalize($expected), CodeTest::canonicalize($result)); } public function testAttributes() @@ -77,7 +78,6 @@ function foowithattribute(\$a) { $expected = <<<'EOF' Block#1 Stmt_Function - name: foo attribute['filename']: foo.php attribute['startLine']: 2 attribute['startTokenPos']: 1 @@ -85,8 +85,8 @@ function foowithattribute(\$a) { attribute['endLine']: 4 attribute['endTokenPos']: 15 attribute['endFilePos']: 40 + name: foo Stmt_Function - name: foowithattribute attribute['filename']: foo.php attribute['startLine']: 6 attribute['startTokenPos']: 17 @@ -94,31 +94,27 @@ function foowithattribute(\$a) { attribute['endLine']: 9 attribute['endTokenPos']: 35 attribute['endFilePos']: 98 - attrGroup[0]: - attribute['filename']: foo.php - attribute['startLine']: 6 - attribute['startTokenPos']: 17 - attribute['startFilePos']: 43 - attribute['endLine']: 6 - attribute['endTokenPos']: 19 - attribute['endFilePos']: 49 - attr[0]: - attribute['filename']: foo.php - attribute['startLine']: 6 - attribute['startTokenPos']: 18 - attribute['startFilePos']: 45 - attribute['endLine']: 6 - attribute['endTokenPos']: 18 - attribute['endFilePos']: 48 - name: LITERAL('Attr') + attrGroup[0]['attribute']['filename']: foo.php + attrGroup[0]['attribute']['startLine']: 6 + attrGroup[0]['attribute']['startTokenPos']: 17 + attrGroup[0]['attribute']['startFilePos']: 43 + attrGroup[0]['attribute']['endLine']: 6 + attrGroup[0]['attribute']['endTokenPos']: 19 + attrGroup[0]['attribute']['endFilePos']: 49 + attrGroup[0][0]['attribute']['filename']: foo.php + attrGroup[0][0]['attribute']['startLine']: 6 + attrGroup[0][0]['attribute']['startTokenPos']: 18 + attrGroup[0][0]['attribute']['startFilePos']: 45 + attrGroup[0][0]['attribute']['endLine']: 6 + attrGroup[0][0]['attribute']['endTokenPos']: 18 + attrGroup[0][0]['attribute']['endFilePos']: 48 + attrGroup[0][0]['name']: LITERAL('Attr') + name: foowithattribute Terminal_Return Function 'foo': mixed Block#1 Expr_Param - declaredType: mixed - name: LITERAL('a') - result: TEMP(#1 ) attribute['filename']: foo.php attribute['startLine']: 2 attribute['startTokenPos']: 5 @@ -126,8 +122,10 @@ function foowithattribute(\$a) { attribute['endLine']: 2 attribute['endTokenPos']: 5 attribute['endFilePos']: 20 + declaredType: mixed + name: LITERAL('a') + result: TEMP(#1 ) Terminal_Return - expr: TEMP(#1 ) attribute['filename']: foo.php attribute['startLine']: 3 attribute['startTokenPos']: 10 @@ -135,13 +133,11 @@ function foowithattribute(\$a) { attribute['endLine']: 3 attribute['endTokenPos']: 13 attribute['endFilePos']: 38 + expr: TEMP(#1 ) Function 'foowithattribute': mixed Block#1 Expr_Param - declaredType: mixed - name: LITERAL('a') - result: TEMP(#1 ) attribute['filename']: foo.php attribute['startLine']: 7 attribute['startTokenPos']: 25 @@ -149,8 +145,10 @@ function foowithattribute(\$a) { attribute['endLine']: 7 attribute['endTokenPos']: 25 attribute['endFilePos']: 78 + declaredType: mixed + name: LITERAL('a') + result: TEMP(#1 ) Terminal_Return - expr: TEMP(#1 ) attribute['filename']: foo.php attribute['startLine']: 8 attribute['startTokenPos']: 30 @@ -158,6 +156,7 @@ function foowithattribute(\$a) { attribute['endLine']: 8 attribute['endTokenPos']: 33 attribute['endFilePos']: 96 + expr: TEMP(#1 ) EOF; $parser = new Parser((new ParserFactory())->createForNewestSupportedVersion(), null); @@ -173,18 +172,6 @@ function foowithattribute(\$a) { $result = $e->getMessage(); } - $this->assertEquals($this->canonicalize($expected), $this->canonicalize($result)); - } - - private function canonicalize($str) - { - // trim from both sides - $str = trim($str); - - // normalize EOL to \n - $str = str_replace(["\r\n", "\r"], "\n", $str); - - // trim right side of all lines - return implode("\n", array_map('rtrim', explode("\n", $str))); + $this->assertEquals(CodeTest::canonicalize($expected), CodeTest::canonicalize($result)); } } diff --git a/test/integration/PrinterProtobufTest.php b/test/integration/PrinterProtobufTest.php new file mode 100644 index 0000000..034d94b --- /dev/null +++ b/test/integration/PrinterProtobufTest.php @@ -0,0 +1,80 @@ +addVisitor(new PhpParser\NodeVisitor\NameResolver()); + $parser = new Parser((new ParserFactory())->createForNewestSupportedVersion(), $astTraverser); + $traverser = new Traverser(); + $traverser->addVisitor(new Visitor\Simplifier()); + $printer = new Printer\Protobuf(Printer\Printer::MODE_RENDER_ATTRIBUTES); + + try { + $script = $parser->parse($code, 'foo.php'); + $traverser->traverse($script); + + $result = $printer->printScript($script); + } catch (RuntimeException $e) { + $result = $e->getMessage(); + } + + $jsonResult = json_encode(json_decode($result->serializeToJsonString()), JSON_PRETTY_PRINT); + + $this->assertEquals( + CodeTest::canonicalize($expectedDump), + CodeTest::canonicalize($jsonResult), + ); + } + + public static function constructRenderedFromProtobuf(): Script + { + $script = new Script(); + $script->main = $main; + $script->functions = $functions; + + return $script; + } + + public static function provideTestParseAndDump() + { + $dir = __DIR__ . '/protobuf'; + $iter = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($dir), + RecursiveIteratorIterator::LEAVES_ONLY, + ); + + foreach ($iter as $file) { + if (! $file->isFile()) { + continue; + } + + $contents = file_get_contents($file->getPathname()); + yield $file->getBasename() => explode('-----', $contents); + } + } +} diff --git a/test/integration/protobuf/class_attributes.test b/test/integration/protobuf/class_attributes.test new file mode 100644 index 0000000..4361a27 --- /dev/null +++ b/test/integration/protobuf/class_attributes.test @@ -0,0 +1,2135 @@ + Date: Sun, 26 Oct 2025 13:31:44 +0100 Subject: [PATCH 2/4] args rendering for attribute --- lib/PHPCfg/Printer/Renderer/GenericOp.php | 2 +- test/code/anonymous_class.test | 2 +- test/code/class_attributes.test | 14 +++++++------- test/code/function_attributes.test | 8 ++++---- test/code/property.test | 2 +- test/integration/protobuf/class_attributes.test | 10 +++++----- 6 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/PHPCfg/Printer/Renderer/GenericOp.php b/lib/PHPCfg/Printer/Renderer/GenericOp.php index 9a66090..eecda15 100644 --- a/lib/PHPCfg/Printer/Renderer/GenericOp.php +++ b/lib/PHPCfg/Printer/Renderer/GenericOp.php @@ -135,7 +135,7 @@ protected function renderAttrGroups(Op\AttributableOp $op): array } $result['attrGroup'][$indexGroup][$indexAttr]['name'] = $this->printer->renderOperand($attr->name); foreach ($attr->args as $indexArg => $arg) { - $result['attrGroup'][$indexGroup][$indexAttr]['arg'][$indexArg] = $this->printer->renderOperand($arg); + $result['attrGroup'][$indexGroup][$indexAttr]['args'][$indexArg] = $this->printer->renderOperand($arg); } } } diff --git a/test/code/anonymous_class.test b/test/code/anonymous_class.test index 7af7a80..4623b3b 100644 --- a/test/code/anonymous_class.test +++ b/test/code/anonymous_class.test @@ -20,7 +20,7 @@ Block#1 result: TEMP(#3) Stmt_Class attrGroup[0][0]['name']: LITERAL('Attr') - attrGroup[0][0]['arg'][0]: LITERAL('foo') + attrGroup[0][0]['args'][0]: LITERAL('foo') name: {anonymousClass}#2 stmts: Block#3 Expr_New diff --git a/test/code/class_attributes.test b/test/code/class_attributes.test index 7f3b214..414757f 100644 --- a/test/code/class_attributes.test +++ b/test/code/class_attributes.test @@ -36,8 +36,8 @@ Block#1 stmts: Block#2 Stmt_Class attrGroup[0][0]['name']: LITERAL('ExampleAttribute') - attrGroup[0][0]['arg'][0]: LITERAL('foo') - attrGroup[0][0]['arg'][1]: LITERAL('bar') + attrGroup[0][0]['args'][0]: LITERAL('foo') + attrGroup[0][0]['args'][1]: LITERAL('bar') name: NameOfClass2 stmts: Block#3 Stmt_Class @@ -64,7 +64,7 @@ Block#1 result: TEMP(#3) Stmt_Class attrGroup[0][0]['name']: LITERAL('Attribute') - attrGroup[0][0]['arg'][0]: TEMP(#3) + attrGroup[0][0]['args'][0]: TEMP(#3) name: NameOfClass5 stmts: Block#6 Expr_ConstFetch @@ -73,7 +73,7 @@ Block#1 Stmt_Class attrGroup[0][0]['name']: LITERAL('ConstAttr') attrGroup[1][0]['name']: LITERAL('FooAttribute') - attrGroup[1][0]['arg'][0]: TEMP(#4) + attrGroup[1][0]['args'][0]: TEMP(#4) name: NameOfClass6 stmts: Block#7 Terminal_Return @@ -81,8 +81,8 @@ Block#1 Block#2 Stmt_ClassMethod attrGroup[0][0]['name']: LITERAL('ExampleAttributeMethod') - attrGroup[0][0]['arg'][0]: LITERAL('foo') - attrGroup[0][0]['arg'][1]: LITERAL('bar') + attrGroup[0][0]['args'][0]: LITERAL('foo') + attrGroup[0][0]['args'][1]: LITERAL('bar') name: method1 flags: private @@ -100,7 +100,7 @@ Function 'NameOfClass1::method1': mixed Block#1 Expr_Param attrGroup[0][0]['name']: LITERAL('FooParamAttrib') - attrGroup[0][0]['arg'][0]: LITERAL('Foo1') + attrGroup[0][0]['args'][0]: LITERAL('Foo1') declaredType: mixed name: LITERAL('foo') result: TEMP(#1 ) diff --git a/test/code/function_attributes.test b/test/code/function_attributes.test index 238547e..ff89dcc 100644 --- a/test/code/function_attributes.test +++ b/test/code/function_attributes.test @@ -12,8 +12,8 @@ function foo_func(#[FooParamAttrib('Foo1')] $foo) {} Block#1 Stmt_Function attrGroup[0][0]['name']: LITERAL('ExampleAttribute') - attrGroup[0][0]['arg'][0]: LITERAL('foo') - attrGroup[0][0]['arg'][1]: LITERAL('bar') + attrGroup[0][0]['args'][0]: LITERAL('foo') + attrGroup[0][0]['args'][1]: LITERAL('bar') name: foo2 Expr_ConstFetch name: LITERAL('null') @@ -21,7 +21,7 @@ Block#1 Stmt_Function attrGroup[0][0]['name']: LITERAL('ConstAttr') attrGroup[1][0]['name']: LITERAL('FooAttribute') - attrGroup[1][0]['arg'][0]: TEMP(#1) + attrGroup[1][0]['args'][0]: TEMP(#1) name: foo5 Stmt_Function name: foo_func @@ -39,7 +39,7 @@ Function 'foo_func': mixed Block#1 Expr_Param attrGroup[0][0]['name']: LITERAL('FooParamAttrib') - attrGroup[0][0]['arg'][0]: LITERAL('Foo1') + attrGroup[0][0]['args'][0]: LITERAL('Foo1') declaredType: mixed name: LITERAL('foo') result: TEMP(#1 ) diff --git a/test/code/property.test b/test/code/property.test index 3581b62..bb0b4c2 100755 --- a/test/code/property.test +++ b/test/code/property.test @@ -61,7 +61,7 @@ Block#2 Stmt_Property attrGroup[0][0]['name']: LITERAL('ConstAttr') attrGroup[1][0]['name']: LITERAL('FooAttribute') - attrGroup[1][0]['arg'][0]: TEMP(#2) + attrGroup[1][0]['args'][0]: TEMP(#2) declaredType: string flags: private name: LITERAL('foo5') diff --git a/test/integration/protobuf/class_attributes.test b/test/integration/protobuf/class_attributes.test index 4361a27..0878cad 100644 --- a/test/integration/protobuf/class_attributes.test +++ b/test/integration/protobuf/class_attributes.test @@ -351,7 +351,7 @@ class NameOfClass6 { } } }, - "arg": { + "args": { "map": { "value": { "0": { @@ -1277,7 +1277,7 @@ class NameOfClass6 { } } }, - "arg": { + "args": { "map": { "value": { "0": { @@ -1633,7 +1633,7 @@ class NameOfClass6 { } } }, - "arg": { + "args": { "map": { "value": { "0": { @@ -1834,7 +1834,7 @@ class NameOfClass6 { } } }, - "arg": { + "args": { "map": { "value": { "0": { @@ -2055,7 +2055,7 @@ class NameOfClass6 { } } }, - "arg": { + "args": { "map": { "value": { "0": { From 96f1b1d8b0d8a95310aeca83e34306060edf29c3 Mon Sep 17 00:00:00 2001 From: eric-therond Date: Mon, 27 Oct 2025 15:47:47 +0100 Subject: [PATCH 3/4] fix loadRenderers --- lib/PHPCfg/Parser.php | 6 +++--- lib/PHPCfg/Printer/Printer.php | 7 +++++-- .../Printer/Renderer/{ => Specific}/Op/Assertion.php | 2 +- lib/PHPCfg/Printer/Renderer/{ => Specific}/Op/Include_.php | 2 +- lib/PHPCfg/Printer/Renderer/{ => Specific}/Op/TraitUse.php | 2 +- .../Printer/Renderer/{ => Specific}/Operand/Literal.php | 2 +- .../Printer/Renderer/{ => Specific}/Operand/Temporary.php | 2 +- .../Printer/Renderer/{ => Specific}/Operand/Variable.php | 2 +- 8 files changed, 14 insertions(+), 11 deletions(-) rename lib/PHPCfg/Printer/Renderer/{ => Specific}/Op/Assertion.php (96%) rename lib/PHPCfg/Printer/Renderer/{ => Specific}/Op/Include_.php (95%) rename lib/PHPCfg/Printer/Renderer/{ => Specific}/Op/TraitUse.php (98%) rename lib/PHPCfg/Printer/Renderer/{ => Specific}/Operand/Literal.php (95%) rename lib/PHPCfg/Printer/Renderer/{ => Specific}/Operand/Temporary.php (96%) rename lib/PHPCfg/Printer/Renderer/{ => Specific}/Operand/Variable.php (97%) diff --git a/lib/PHPCfg/Parser.php b/lib/PHPCfg/Parser.php index 34be63c..aa46349 100755 --- a/lib/PHPCfg/Parser.php +++ b/lib/PHPCfg/Parser.php @@ -91,9 +91,9 @@ protected function loadHandlers(): void { $it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( - __DIR__ . '/ParserHandler/', - RecursiveIteratorIterator::LEAVES_ONLY - ) + __DIR__ . '/ParserHandler/' + ), + RecursiveIteratorIterator::LEAVES_ONLY ); $handlers = []; foreach ($it as $file) { diff --git a/lib/PHPCfg/Printer/Printer.php b/lib/PHPCfg/Printer/Printer.php index 8ae8a1e..dba69a2 100755 --- a/lib/PHPCfg/Printer/Printer.php +++ b/lib/PHPCfg/Printer/Printer.php @@ -17,6 +17,7 @@ use PHPCfg\Op; use PHPCfg\Operand; use PHPCfg\Script; +use FilesystemIterator; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use SplObjectStorage; @@ -59,9 +60,11 @@ protected function loadRenderers(): void $it = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( __DIR__ . '/Renderer/', - RecursiveIteratorIterator::LEAVES_ONLY - ) + FilesystemIterator::SKIP_DOTS + ), + RecursiveIteratorIterator::CHILD_FIRST ); + $handlers = []; foreach ($it as $file) { if (!$file->isFile() || $file->getExtension() !== 'php') { diff --git a/lib/PHPCfg/Printer/Renderer/Op/Assertion.php b/lib/PHPCfg/Printer/Renderer/Specific/Op/Assertion.php similarity index 96% rename from lib/PHPCfg/Printer/Renderer/Op/Assertion.php rename to lib/PHPCfg/Printer/Renderer/Specific/Op/Assertion.php index 379aeaf..8c60b67 100644 --- a/lib/PHPCfg/Printer/Renderer/Op/Assertion.php +++ b/lib/PHPCfg/Printer/Renderer/Specific/Op/Assertion.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Op; +namespace PHPCfg\Printer\Renderer\Specific\Op; use PHPCfg\Assertion as CoreAssertion; use PHPCfg\Op; diff --git a/lib/PHPCfg/Printer/Renderer/Op/Include_.php b/lib/PHPCfg/Printer/Renderer/Specific/Op/Include_.php similarity index 95% rename from lib/PHPCfg/Printer/Renderer/Op/Include_.php rename to lib/PHPCfg/Printer/Renderer/Specific/Op/Include_.php index 1c5f07d..ecda687 100644 --- a/lib/PHPCfg/Printer/Renderer/Op/Include_.php +++ b/lib/PHPCfg/Printer/Renderer/Specific/Op/Include_.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Op; +namespace PHPCfg\Printer\Renderer\Specific\Op; use PHPCfg\Op; use PHPCfg\Printer\Renderer\GenericOp; diff --git a/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php b/lib/PHPCfg/Printer/Renderer/Specific/Op/TraitUse.php similarity index 98% rename from lib/PHPCfg/Printer/Renderer/Op/TraitUse.php rename to lib/PHPCfg/Printer/Renderer/Specific/Op/TraitUse.php index b93fd92..332f89a 100644 --- a/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php +++ b/lib/PHPCfg/Printer/Renderer/Specific/Op/TraitUse.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Op; +namespace PHPCfg\Printer\Renderer\Specific\Op; use PHPCfg\Op; use PHPCfg\Printer\Renderer\GenericOp; diff --git a/lib/PHPCfg/Printer/Renderer/Operand/Literal.php b/lib/PHPCfg/Printer/Renderer/Specific/Operand/Literal.php similarity index 95% rename from lib/PHPCfg/Printer/Renderer/Operand/Literal.php rename to lib/PHPCfg/Printer/Renderer/Specific/Operand/Literal.php index e0010bc..b5e2695 100644 --- a/lib/PHPCfg/Printer/Renderer/Operand/Literal.php +++ b/lib/PHPCfg/Printer/Renderer/Specific/Operand/Literal.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Operand; +namespace PHPCfg\Printer\Renderer\Specific\Operand; use PHPCfg\Op; use PHPCfg\Operand; diff --git a/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php b/lib/PHPCfg/Printer/Renderer/Specific/Operand/Temporary.php similarity index 96% rename from lib/PHPCfg/Printer/Renderer/Operand/Temporary.php rename to lib/PHPCfg/Printer/Renderer/Specific/Operand/Temporary.php index fd69991..615a535 100644 --- a/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php +++ b/lib/PHPCfg/Printer/Renderer/Specific/Operand/Temporary.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Operand; +namespace PHPCfg\Printer\Renderer\Specific\Operand; use PHPCfg\Op; use PHPCfg\Operand; diff --git a/lib/PHPCfg/Printer/Renderer/Operand/Variable.php b/lib/PHPCfg/Printer/Renderer/Specific/Operand/Variable.php similarity index 97% rename from lib/PHPCfg/Printer/Renderer/Operand/Variable.php rename to lib/PHPCfg/Printer/Renderer/Specific/Operand/Variable.php index b8c2807..ccb05b6 100644 --- a/lib/PHPCfg/Printer/Renderer/Operand/Variable.php +++ b/lib/PHPCfg/Printer/Renderer/Specific/Operand/Variable.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Operand; +namespace PHPCfg\Printer\Renderer\Specific\Operand; use LogicException; use PHPCfg\Op; From 45611624648cd09a818c4508366540f3770912f3 Mon Sep 17 00:00:00 2001 From: eric-therond Date: Mon, 27 Oct 2025 16:29:53 +0100 Subject: [PATCH 4/4] fix loadRenderers --- lib/PHPCfg/Printer/Printer.php | 17 ++++++++++++++++- .../Renderer/{Specific => }/Op/Assertion.php | 2 +- .../Renderer/{Specific => }/Op/Include_.php | 2 +- .../Renderer/{Specific => }/Op/TraitUse.php | 2 +- .../Renderer/{Specific => }/Operand/Literal.php | 2 +- .../{Specific => }/Operand/Temporary.php | 2 +- .../{Specific => }/Operand/Variable.php | 2 +- 7 files changed, 22 insertions(+), 7 deletions(-) rename lib/PHPCfg/Printer/Renderer/{Specific => }/Op/Assertion.php (96%) rename lib/PHPCfg/Printer/Renderer/{Specific => }/Op/Include_.php (95%) rename lib/PHPCfg/Printer/Renderer/{Specific => }/Op/TraitUse.php (98%) rename lib/PHPCfg/Printer/Renderer/{Specific => }/Operand/Literal.php (95%) rename lib/PHPCfg/Printer/Renderer/{Specific => }/Operand/Temporary.php (96%) rename lib/PHPCfg/Printer/Renderer/{Specific => }/Operand/Variable.php (97%) diff --git a/lib/PHPCfg/Printer/Printer.php b/lib/PHPCfg/Printer/Printer.php index dba69a2..38e24d2 100755 --- a/lib/PHPCfg/Printer/Printer.php +++ b/lib/PHPCfg/Printer/Printer.php @@ -62,10 +62,11 @@ protected function loadRenderers(): void __DIR__ . '/Renderer/', FilesystemIterator::SKIP_DOTS ), - RecursiveIteratorIterator::CHILD_FIRST + RecursiveIteratorIterator::LEAVES_ONLY ); $handlers = []; + $classes = []; foreach ($it as $file) { if (!$file->isFile() || $file->getExtension() !== 'php') { continue; @@ -78,6 +79,20 @@ protected function loadRenderers(): void continue; } + $classes[] = $class; + } + + usort($classes, function ($a, $b) { + $aParts = substr_count($a, '\\'); + $bParts = substr_count($b, '\\'); + + if ($aParts == $bParts) { + return 0; + } + return ($aParts < $bParts) ? 1 : -1; + }); + + foreach ($classes as $class) { $obj = new $class($this); $this->addRenderer($obj); } diff --git a/lib/PHPCfg/Printer/Renderer/Specific/Op/Assertion.php b/lib/PHPCfg/Printer/Renderer/Op/Assertion.php similarity index 96% rename from lib/PHPCfg/Printer/Renderer/Specific/Op/Assertion.php rename to lib/PHPCfg/Printer/Renderer/Op/Assertion.php index 8c60b67..379aeaf 100644 --- a/lib/PHPCfg/Printer/Renderer/Specific/Op/Assertion.php +++ b/lib/PHPCfg/Printer/Renderer/Op/Assertion.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Specific\Op; +namespace PHPCfg\Printer\Renderer\Op; use PHPCfg\Assertion as CoreAssertion; use PHPCfg\Op; diff --git a/lib/PHPCfg/Printer/Renderer/Specific/Op/Include_.php b/lib/PHPCfg/Printer/Renderer/Op/Include_.php similarity index 95% rename from lib/PHPCfg/Printer/Renderer/Specific/Op/Include_.php rename to lib/PHPCfg/Printer/Renderer/Op/Include_.php index ecda687..1c5f07d 100644 --- a/lib/PHPCfg/Printer/Renderer/Specific/Op/Include_.php +++ b/lib/PHPCfg/Printer/Renderer/Op/Include_.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Specific\Op; +namespace PHPCfg\Printer\Renderer\Op; use PHPCfg\Op; use PHPCfg\Printer\Renderer\GenericOp; diff --git a/lib/PHPCfg/Printer/Renderer/Specific/Op/TraitUse.php b/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php similarity index 98% rename from lib/PHPCfg/Printer/Renderer/Specific/Op/TraitUse.php rename to lib/PHPCfg/Printer/Renderer/Op/TraitUse.php index 332f89a..b93fd92 100644 --- a/lib/PHPCfg/Printer/Renderer/Specific/Op/TraitUse.php +++ b/lib/PHPCfg/Printer/Renderer/Op/TraitUse.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Specific\Op; +namespace PHPCfg\Printer\Renderer\Op; use PHPCfg\Op; use PHPCfg\Printer\Renderer\GenericOp; diff --git a/lib/PHPCfg/Printer/Renderer/Specific/Operand/Literal.php b/lib/PHPCfg/Printer/Renderer/Operand/Literal.php similarity index 95% rename from lib/PHPCfg/Printer/Renderer/Specific/Operand/Literal.php rename to lib/PHPCfg/Printer/Renderer/Operand/Literal.php index b5e2695..e0010bc 100644 --- a/lib/PHPCfg/Printer/Renderer/Specific/Operand/Literal.php +++ b/lib/PHPCfg/Printer/Renderer/Operand/Literal.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Specific\Operand; +namespace PHPCfg\Printer\Renderer\Operand; use PHPCfg\Op; use PHPCfg\Operand; diff --git a/lib/PHPCfg/Printer/Renderer/Specific/Operand/Temporary.php b/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php similarity index 96% rename from lib/PHPCfg/Printer/Renderer/Specific/Operand/Temporary.php rename to lib/PHPCfg/Printer/Renderer/Operand/Temporary.php index 615a535..fd69991 100644 --- a/lib/PHPCfg/Printer/Renderer/Specific/Operand/Temporary.php +++ b/lib/PHPCfg/Printer/Renderer/Operand/Temporary.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Specific\Operand; +namespace PHPCfg\Printer\Renderer\Operand; use PHPCfg\Op; use PHPCfg\Operand; diff --git a/lib/PHPCfg/Printer/Renderer/Specific/Operand/Variable.php b/lib/PHPCfg/Printer/Renderer/Operand/Variable.php similarity index 97% rename from lib/PHPCfg/Printer/Renderer/Specific/Operand/Variable.php rename to lib/PHPCfg/Printer/Renderer/Operand/Variable.php index ccb05b6..b8c2807 100644 --- a/lib/PHPCfg/Printer/Renderer/Specific/Operand/Variable.php +++ b/lib/PHPCfg/Printer/Renderer/Operand/Variable.php @@ -9,7 +9,7 @@ * @license MIT See LICENSE at the root of the project for more info */ -namespace PHPCfg\Printer\Renderer\Specific\Operand; +namespace PHPCfg\Printer\Renderer\Operand; use LogicException; use PHPCfg\Op;