Last active
December 28, 2025 12:12
-
-
Save thekid/773803d84b357799ffd65f855bc0181c to your computer and use it in GitHub Desktop.
Is operator array structure support for ArrayAccess
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| diff --git a/src/main/php/lang/ast/syntax/php/IsOperator.class.php b/src/main/php/lang/ast/syntax/php/IsOperator.class.php | |
| index 30832b5..bb1048e 100755 | |
| --- a/src/main/php/lang/ast/syntax/php/IsOperator.class.php | |
| +++ b/src/main/php/lang/ast/syntax/php/IsOperator.class.php | |
| @@ -250,24 +250,29 @@ class IsOperator implements Extension { | |
| } | |
| return $compound; | |
| } else if ($pattern instanceof IsArrayStructure) { | |
| - $compound= new BinaryExpression( | |
| - new InvokeExpression(new Literal('is_array'), [$init]), | |
| - '&&', | |
| - new BinaryExpression( | |
| - new InvokeExpression(new Literal('sizeof'), [$use]), | |
| - $pattern->rest ? '>=' : '===', | |
| - new Literal((string)sizeof($pattern->patterns)) | |
| - ) | |
| + $size= new BinaryExpression( | |
| + new InvokeExpression(new Literal('sizeof'), [$use]), | |
| + $pattern->rest ? '>=' : '===', | |
| + new Literal((string)sizeof($pattern->patterns)) | |
| ); | |
| + $arrays= new BinaryExpression(new InvokeExpression(new Literal('is_array'), [$init]), '&&', $size); | |
| + $objects= new BinaryExpression(new InstanceOfExpression($init, new IsValue('ArrayAccess')), '&&', $size); | |
| + | |
| foreach ($pattern->patterns as $key => $p) { | |
| $offset= new Literal((string)$key); | |
| - $compound= new BinaryExpression($compound, '&&', new BinaryExpression( | |
| + $apply= $match($codegen, new OffsetExpression($use, $offset), $p); | |
| + $arrays= new BinaryExpression($arrays, '&&', new BinaryExpression( | |
| new InvokeExpression(new Literal('array_key_exists'), [$offset, $use]), | |
| '&&', | |
| - $match($codegen, new OffsetExpression($use, $offset), $p), | |
| + $apply, | |
| + )); | |
| + $objects= new BinaryExpression($objects, '&&', new BinaryExpression( | |
| + new InvokeExpression(new InstanceExpression($use, new Literal('offsetExists')), [$offset]), | |
| + '&&', | |
| + $apply, | |
| )); | |
| } | |
| - return $compound; | |
| + return new Braced(new BinaryExpression($arrays, '||', $objects)); | |
| } | |
| // Should be unreachable | |
| diff --git a/src/test/php/lang/ast/syntax/php/unittest/ArrayStructureTest.class.php b/src/test/php/lang/ast/syntax/php/unittest/ArrayStructureTest.class.php | |
| index 32c1603..2454ebe 100755 | |
| --- a/src/test/php/lang/ast/syntax/php/unittest/ArrayStructureTest.class.php | |
| +++ b/src/test/php/lang/ast/syntax/php/unittest/ArrayStructureTest.class.php | |
| @@ -63,4 +63,24 @@ class ArrayStructureTest extends EmittingTest { | |
| } | |
| }')); | |
| } | |
| + | |
| + #[Test, Values(['$this', 'new ArrayObject([1, 2, 3])'])] | |
| + public function integrates_with_array_access($expr) { | |
| + Assert::equals([1, 2, 3], $this->run('class %T implements ArrayAccess, Countable { | |
| + | |
| + public function count() { return 3; } | |
| + | |
| + public function offsetExists($i) { return true; } | |
| + | |
| + public function offsetGet($i) { return $i + 1; } | |
| + | |
| + public function offsetSet($i, $value) { /* NOOP */ } | |
| + | |
| + public function offsetUnset($i) { /* NOOP */ } | |
| + | |
| + public function run() { | |
| + return '.$expr.' is [$a, $b, $c] ? [$a, $b, $c] : null; | |
| + } | |
| + }')); | |
| + } | |
| } | |
| \ No newline at end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment