From 434928f417a086d5ebfcb0abe129b612e4f4ba30 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 1 Sep 2020 13:53:03 +0200 Subject: [PATCH] Polyfill instanceof --- src/Plugin/NestedExpressionFixer.php | 41 +++++++++- src/Target/Php70/CompoundAccess.php | 109 --------------------------- test/exprGen.php | 21 ++++-- 3 files changed, 54 insertions(+), 117 deletions(-) delete mode 100644 src/Target/Php70/CompoundAccess.php diff --git a/src/Plugin/NestedExpressionFixer.php b/src/Plugin/NestedExpressionFixer.php index 2543261..3f79f5e 100644 --- a/src/Plugin/NestedExpressionFixer.php +++ b/src/Plugin/NestedExpressionFixer.php @@ -4,6 +4,7 @@ namespace Phabel\Plugin; use Phabel\Context; use Phabel\Plugin; +use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\Assign; @@ -21,6 +22,20 @@ use PhpParser\Node\Scalar\LNumber; class NestedExpressionFixer extends Plugin { + /** + * Recursively extract bottom ArrayDimFetch + * + * @param Node $var + * @return Node + */ + private static function &extractWorkVar(Expr &$var): Expr + { + if ($var instanceof ArrayDimFetch && $var->var instanceof ArrayDimFetch) { + return self::extractWorkVar($var->var); + } + return $var; + } + public function leave(Expr $expr, Context $context): ?Expr { /** @var array, true>> */ @@ -32,24 +47,31 @@ class NestedExpressionFixer extends Plugin /** @var Expr $value */ $value = &$expr->{$key}; if (!isset($types[\get_class($value)])) { - continue; + $workVar = $this->extractWorkVar($value); + if (!isset($types[\get_class($workVar)])) { + continue; + } } switch ($class) { case ArrayDimFetch::class: case PropertyFetch::class: case MethodCall::class: - case New_::class: case Instanceof_::class: + if ($expr instanceof Instanceof_ && $key === 'class') { + return self::callPoly('instanceOf', $expr->expr, $expr->class); + } $value = self::callPoly('returnMe', $value); break; + case New_::class: case ClassConstFetch::class: // For all the following expressions, wrapping in a ternary breaks return-by-ref case StaticCall::class: case StaticPropertyFetch::class: case FuncCall::class: + $valueCopy = $value; return new Ternary( new BooleanOr( - new Assign($value = $context->getVariable(), $value), + new Assign($value = $context->getVariable(), $valueCopy), new LNumber(1) ), $expr, @@ -76,4 +98,17 @@ class NestedExpressionFixer extends Plugin { return $data; } + + /** + * Check if a is instance of b + * + * @param class-string|object $a + * @param class-string|object $b + * + * @return boolean + */ + public static function instanceOf($a, $b): bool + { + return $a instanceof $b; + } } diff --git a/src/Target/Php70/CompoundAccess.php b/src/Target/Php70/CompoundAccess.php deleted file mode 100644 index 9dbe718..0000000 --- a/src/Target/Php70/CompoundAccess.php +++ /dev/null @@ -1,109 +0,0 @@ -vars as &$var) { - if ($var instanceof ArrayDimFetch - && $var->var instanceof Expr - && !($var->var instanceof Variable || $var->var instanceof FuncCall) { - $var->var = self::callPoly('returnMe', $var->var); - } - } - } - /** - * Fix yield array access. - * - * @param ArrayDimFetch $node Node - * - * @return void - */ - public function enterArrayYield(ArrayDimFetch $node): void - { - if (!$node->var instanceof Node\Expr\Yield_) { - return; - } - $node->var = self::callPoly('returnMe', $node->var); - } - /** - * Fix yield array access. - * - * @param Yield_ $node Yield - * - * @return void - */ - public function enterYield(Yield_ $node): void - { - $value = &$node->value; - if ($value instanceof Node\Expr\Variable && $value->name !== "this") { - return; - } - if ($value instanceof Node\Expr\FuncCall || - $value instanceof Node\Expr\MethodCall || - $value instanceof Node\Expr\StaticCall || - $value instanceof Node\Scalar - ) { - return; - } - $value = self::callPoly('returnMe', $value); - } - /** - * Replace method call on yielded|cloned|closure object. - * - * @param MethodCall $node Method call - * - * @return void - */ - public function enterMethodCall(MethodCall $node): void - { - $value = &$node->var; - if (!$value instanceof Node\Expr\Clone_ && - !$value instanceof Node\Expr\Yield_ && - !$value instanceof Node\Expr\Closure - ) { - return; - } - $value = self::callPoly('returnMe', $value); - } - /** - * Returns the data provided. - * - * @param mixed $data Data - * - * @return mixed - * - * @template T - * - * @psalm-param T $data data - * - * @psalm-return T - */ - public static function returnMe($data) - { - return $data; - } -} diff --git a/test/exprGen.php b/test/exprGen.php index ee078a5..017369e 100644 --- a/test/exprGen.php +++ b/test/exprGen.php @@ -93,7 +93,7 @@ function checkSyntax(string $code, int $startFrom = 56): int /** @var ReflectionClass[] */ $expressions = []; -foreach ($allClasses = ClassFinder::getClassesInNamespace('PhpParser', ClassFinder::RECURSIVE_MODE) as $class) { +foreach (ClassFinder::getClassesInNamespace('PhpParser', ClassFinder::RECURSIVE_MODE) as $class) { $class = new ReflectionClass($class); if ($class->isSubclassOf(Expr::class) && !$class->isAbstract() && $class->getName() !== PrintableNewAnonClassNode::class @@ -264,12 +264,23 @@ foreach ($instanceArgTypes as $class => $argTypes) { } $keys = []; - foreach ($result['main'] as $version) { - $keys = array_merge_recursive($keys, $version); - } +foreach ($result['main'] as $version) { + $keys = array_merge_recursive($keys, $version); +} foreach ($keys as &$values) { $values = array_keys($values); } var_dump($keys); - \file_put_contents('result.php', ' $a->getname(), $expressions), true); +foreach ($result as &$type) { + foreach ($type as &$version) { + foreach ($version as &$class) { + foreach ($class as &$arguments) { + $arguments = array_diff_key($ckeys, $arguments); + } + } + } +} +\file_put_contents('resultReverse.php', '