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..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) {
@@ -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..38e24d2 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,10 +60,13 @@ protected function loadRenderers(): void
$it = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
__DIR__ . '/Renderer/',
- RecursiveIteratorIterator::LEAVES_ONLY
- )
+ FilesystemIterator::SKIP_DOTS
+ ),
+ RecursiveIteratorIterator::LEAVES_ONLY
);
+
$handlers = [];
+ $classes = [];
foreach ($it as $file) {
if (!$file->isFile() || $file->getExtension() !== 'php') {
continue;
@@ -75,14 +79,32 @@ 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);
}
}
- abstract public function printScript(Script $script): string;
+ abstract public function printScript(Script $script): mixed;
+
+ abstract public function printFunc(Func $func): mixed;
- abstract public function printFunc(Func $func): string;
+ abstract public function renderOperand(Operand $var): mixed;
+
+ abstract public function renderOpLabel(array $desc): mixed;
protected function reset(): void
{
@@ -98,20 +120,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 +135,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 +167,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 +219,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..eecda15 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]['args'][$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..4623b3b 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]['args'][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..ff89dcc 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]['args'][0]: LITERAL('foo')
+ attrGroup[0][0]['args'][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]['args'][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]['args'][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..bb0b4c2 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]['args'][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..0878cad
--- /dev/null
+++ b/test/integration/protobuf/class_attributes.test
@@ -0,0 +1,2135 @@
+