From 883a4a41ebea889c341e6ae17cd6deb2b0872737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 26 Sep 2023 14:06:49 +0200 Subject: [PATCH] Add Expression interfaces --- generator/composer.json | 1 + generator/config/pipeline-operators.yaml | 6 ++++++ generator/config/query-operators.yaml | 2 ++ generator/config/stages.yaml | 3 --- generator/src/AbstractGenerator.php | 9 ++++----- .../src/Definition/OperatorDefinition.php | 1 + generator/src/ValueClassGenerator.php | 20 +++++++++++++++++-- .../Expression/ResolvesToArrayExpression.php | 8 ++++++++ .../Expression/ResolvesToBoolExpression.php | 8 ++++++++ .../Expression/ResolvesToExpression.php | 8 ++++++++ .../Expression/ResolvesToMatchExpression.php | 8 ++++++++ .../Expression/ResolvesToNumberExpression.php | 8 ++++++++ .../Expression/ResolvesToQueryOperator.php | 8 ++++++++ .../ResolvesToSortSpecification.php | 8 ++++++++ 14 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 src/Builder/Expression/ResolvesToArrayExpression.php create mode 100644 src/Builder/Expression/ResolvesToBoolExpression.php create mode 100644 src/Builder/Expression/ResolvesToExpression.php create mode 100644 src/Builder/Expression/ResolvesToMatchExpression.php create mode 100644 src/Builder/Expression/ResolvesToNumberExpression.php create mode 100644 src/Builder/Expression/ResolvesToQueryOperator.php create mode 100644 src/Builder/Expression/ResolvesToSortSpecification.php diff --git a/generator/composer.json b/generator/composer.json index 213ba130d..faa365acf 100644 --- a/generator/composer.json +++ b/generator/composer.json @@ -15,6 +15,7 @@ "require": { "php": ">=8.2", "ext-mongodb": "*", + "mongodb/mongodb": "@dev", "nette/php-generator": "^4", "symfony/console": "^6.3", "symfony/yaml": "^6.3" diff --git a/generator/config/pipeline-operators.yaml b/generator/config/pipeline-operators.yaml index 5555b533c..43a01c731 100644 --- a/generator/config/pipeline-operators.yaml +++ b/generator/config/pipeline-operators.yaml @@ -1,33 +1,39 @@ - name: and + type: resolvesToBoolExpression args: - name: expressions type: resolvesToExpression isVariadic: true - name: eq + type: resolvesToBoolExpression args: - name: expression1 type: resolvesToExpression - name: expression2 type: resolvesToExpression - name: gt + type: resolvesToBoolExpression args: - name: expression1 type: resolvesToExpression - name: expression2 type: resolvesToExpression - name: lt + type: resolvesToBoolExpression args: - name: expression1 type: resolvesToExpression - name: expression2 type: resolvesToExpression - name: ne + type: resolvesToBoolExpression args: - name: expression1 type: resolvesToExpression - name: expression2 type: resolvesToExpression - name: filter + type: resolvesToArrayExpression usesNamedArgs: true args: - name: input diff --git a/generator/config/query-operators.yaml b/generator/config/query-operators.yaml index 2af65db56..c217b7a77 100644 --- a/generator/config/query-operators.yaml +++ b/generator/config/query-operators.yaml @@ -1,9 +1,11 @@ - name: and + type: resolvesToBoolExpression args: - name: query type: resolvesToQueryOperator isVariadic: true - name: expr + type: resolvesToExpression args: - name: expression type: resolvesToExpression diff --git a/generator/config/stages.yaml b/generator/config/stages.yaml index 901abe6dc..7c438f567 100644 --- a/generator/config/stages.yaml +++ b/generator/config/stages.yaml @@ -1,15 +1,12 @@ ---- - name: match args: - name: matchExpr type: resolvesToMatchExpression isVariadic: true - - name: sort args: - name: sortSpecification type: resolvesToSortSpecification - - name: limit args: - name: limit diff --git a/generator/src/AbstractGenerator.php b/generator/src/AbstractGenerator.php index 1b5cd7c7d..2da0f70d9 100644 --- a/generator/src/AbstractGenerator.php +++ b/generator/src/AbstractGenerator.php @@ -16,10 +16,10 @@ use function file_put_contents; use function implode; use function in_array; +use function interface_exists; use function is_dir; use function mkdir; use function sort; -use function str_starts_with; use function ucfirst; /** @internal */ @@ -32,7 +32,7 @@ abstract class AbstractGenerator 'resolvesToBoolExpression' => [Expression\ResolvesToBoolExpression::class, 'array', 'object', 'string', 'bool'], 'resolvesToMatchExpression' => ['array', 'object', Expression\ResolvesToMatchExpression::class], 'resolvesToNumberExpression' => [Expression\ResolvesToBoolExpression::class, 'array', 'object', 'string', 'int', 'float'], - 'resolvesToQueryOperator' => ['array', 'object', Expression\ResolvesToQuery::class], + 'resolvesToQueryOperator' => ['array', 'object', Expression\ResolvesToQueryOperator::class], 'resolvesToSortSpecification' => ['array', 'object', Expression\ResolvesToSortSpecification::class], ]; @@ -72,11 +72,10 @@ final protected function generateTypeString(ArgumentDefinition $arg): array $docTypes = $nativeTypes; foreach ($nativeTypes as $key => $typeName) { - // @todo replace with class_exists - if (str_starts_with($typeName, 'MongoDB\\')) { + if (interface_exists($typeName)) { $nativeTypes[$key] = $docTypes[$key] = '\\' . $typeName; - // A union cannot contain both object and a class type, which is redundant and causes a PHP error + // @todo replace "object" with "stdClass" and force any class object to implement the proper interface if (in_array('object', $nativeTypes, true)) { unset($nativeTypes[$key]); } diff --git a/generator/src/Definition/OperatorDefinition.php b/generator/src/Definition/OperatorDefinition.php index 74f174050..f9537ab0e 100644 --- a/generator/src/Definition/OperatorDefinition.php +++ b/generator/src/Definition/OperatorDefinition.php @@ -12,6 +12,7 @@ public function __construct( public string $name, + public ?string $type = null, public bool $usesNamedArgs = false, array $args = [], ) { diff --git a/generator/src/ValueClassGenerator.php b/generator/src/ValueClassGenerator.php index cfa0ec559..4412f6263 100644 --- a/generator/src/ValueClassGenerator.php +++ b/generator/src/ValueClassGenerator.php @@ -5,10 +5,11 @@ use MongoDB\CodeGenerator\Definition\OperatorDefinition; use Nette\PhpGenerator\ClassType; +use RuntimeException; use function assert; - -use const PHP_EOL; +use function interface_exists; +use function ucfirst; /** * Generates a value object class for stages and operators. @@ -20,6 +21,7 @@ public function createClassForObject(object $object): ClassType assert($object instanceof OperatorDefinition); $class = new ClassType($this->getClassName($object)); + $class->setImplements($this->getInterfaces($object)); $constuctor = $class->addMethod('__construct'); @@ -51,4 +53,18 @@ public function createClassForObject(object $object): ClassType return $class; } + + private function getInterfaces(OperatorDefinition $definition): array + { + if ($definition->type === null) { + return []; + } + + $interface = 'MongoDB\\Builder\\Expression\\' . ucfirst($definition->type); + if (! interface_exists($interface)) { + throw new RuntimeException('Interface ' . $interface . ' does not exist'); + } + + return [$interface]; + } } diff --git a/src/Builder/Expression/ResolvesToArrayExpression.php b/src/Builder/Expression/ResolvesToArrayExpression.php new file mode 100644 index 000000000..eccb127bd --- /dev/null +++ b/src/Builder/Expression/ResolvesToArrayExpression.php @@ -0,0 +1,8 @@ +