diff --git a/composer.json b/composer.json index 9f79b3be..fc193a79 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ }, "require-dev": { "nette/tester": "^2.4", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "tracy/tracy": "^2.8", "phpstan/phpstan": "^1.0" }, diff --git a/src/PhpGenerator/Helpers.php b/src/PhpGenerator/Helpers.php index 71e7de6f..e49db879 100644 --- a/src/PhpGenerator/Helpers.php +++ b/src/PhpGenerator/Helpers.php @@ -174,10 +174,14 @@ public static function validateType(?string $type, bool &$nullable): ?string return null; } - if (!preg_match('#(?: - \?[\w\\\\]+| - [\w\\\\]+ (?: (&[\w\\\\]+)* | (\|[\w\\\\]+)* ) - )()$#xAD', $type)) { + if (!preg_match(<<<'XX' + ~(?n) + ( + \?? (? [\w\\]+)| + (? (?&type) (& (?&type))+ )| + (? (?&type) | \( (?&intersection) \) ) (\| (?&upart) )+ + )$~xAD + XX, $type)) { throw new Nette\InvalidArgumentException("Value '$type' is not valid type."); } diff --git a/tests/PhpGenerator/ClassType.phpt b/tests/PhpGenerator/ClassType.phpt index cc6c2a4f..86fc78ef 100644 --- a/tests/PhpGenerator/ClassType.phpt +++ b/tests/PhpGenerator/ClassType.phpt @@ -131,8 +131,8 @@ $method->addParameter('res', null) ->setType(Type::union(Type::Array, 'null')); $method->addParameter('bar', null) - ->setType('stdClass|string') - ->setNullable(true); + ->setNullable(true) + ->setType('stdClass|string'); $class->addTrait('foo'); $class->removeTrait('foo'); diff --git a/tests/PhpGenerator/Helpers.validateType.phpt b/tests/PhpGenerator/Helpers.validateType.phpt new file mode 100644 index 00000000..1277ca8f --- /dev/null +++ b/tests/PhpGenerator/Helpers.validateType.phpt @@ -0,0 +1,43 @@ + Helpers::validateType('-', $foo), + Nette\InvalidArgumentException::class, +); + +Assert::exception( + fn() => Helpers::validateType('?Foo|Bar', $foo), + Nette\InvalidArgumentException::class, +); + +Assert::exception( + fn() => Helpers::validateType('(Foo)', $foo), + Nette\InvalidArgumentException::class, +); + +Assert::exception( + fn() => Helpers::validateType('(Foo&Bar)', $foo), + Nette\InvalidArgumentException::class, +); diff --git a/tests/PhpGenerator/expected/ClassType.from.82.expect b/tests/PhpGenerator/expected/ClassType.from.82.expect index 4c03d053..6ea6378a 100644 --- a/tests/PhpGenerator/expected/ClassType.from.82.expect +++ b/tests/PhpGenerator/expected/ClassType.from.82.expect @@ -1,5 +1,8 @@ readonly class Class13 { + public function func(C|(X&D)|null $foo): (A&B)|null + { + } } trait Trait13 diff --git a/tests/PhpGenerator/expected/Extractor.classes.82.expect b/tests/PhpGenerator/expected/Extractor.classes.82.expect index c7de3d7e..54f5c525 100644 --- a/tests/PhpGenerator/expected/Extractor.classes.82.expect +++ b/tests/PhpGenerator/expected/Extractor.classes.82.expect @@ -6,6 +6,9 @@ namespace Abc; readonly class Class13 { + public function func(C|(X&D)|null $foo): (A&B)|null + { + } } trait Trait13 diff --git a/tests/PhpGenerator/fixtures/classes.82.php b/tests/PhpGenerator/fixtures/classes.82.php index 95e594ff..ae22c11e 100644 --- a/tests/PhpGenerator/fixtures/classes.82.php +++ b/tests/PhpGenerator/fixtures/classes.82.php @@ -6,6 +6,9 @@ readonly class Class13 { + public function func(C|(X&D)|null $foo): (A&B)|null + { + } }