From 634cea72974d79cda1c33f7675511e6db78c2a55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Thu, 28 Nov 2024 15:02:12 +0100 Subject: [PATCH] Rename noName to mergeObject --- generator/README.md | 4 +- generator/config/query/geoIntersects.yaml | 2 +- generator/config/query/geoWithin.yaml | 2 +- generator/config/query/near.yaml | 2 +- generator/config/query/nearSphere.yaml | 2 +- generator/config/schema.json | 4 +- generator/config/stage/group.yaml | 2 +- .../src/Definition/ArgumentDefinition.php | 5 +- generator/src/OperatorClassGenerator.php | 46 +++++++++---------- generator/src/OperatorFactoryGenerator.php | 11 ++--- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/generator/README.md b/generator/README.md index a14037604..92ba1cd96 100644 --- a/generator/README.md +++ b/generator/README.md @@ -20,7 +20,7 @@ The `generator/config/*.yaml` files contains the list of operators and stages th ### Arguments | Field | Type | Description | -| `name` | `string` | The name of the argument. It can start with `$`. | +| `name` | `string` | The name of the argument. It can start with `$` when the aggregation operator needs it, but it will be trimmed from the class property name. | | `type` | list of `string` | The list of accepted types | | `description` | `string` | The description of the argument from MongoDB's documentation. | | `optional` | `boolean` | Whether the argument is optional or not. | @@ -29,7 +29,7 @@ The `generator/config/*.yaml` files contains the list of operators and stages th | `variadic` | `string` | If sent, the argument is variadic. Defines the format `array` for a list or `object` for a map | | `variadicMin` | `integer` | The minimum number of arguments for a variadic parameter. | | `default` | `scalar` or `array` | The default value for the argument. | -| `noName` | `bool` | Default `false`. If `true`, the value must be an object and the properties of the value object are merged into the parent operator. `$group` stage uses it for the fields. | +| `mergeObject` | `bool` | Default `false`. If `true`, the value must be an object and the properties of the value object are merged into the parent operator. `$group` stage uses it for the fields. | ### Test pipelines diff --git a/generator/config/query/geoIntersects.yaml b/generator/config/query/geoIntersects.yaml index 6a675e3b5..4df3a43de 100644 --- a/generator/config/query/geoIntersects.yaml +++ b/generator/config/query/geoIntersects.yaml @@ -9,7 +9,7 @@ description: | arguments: - name: geometry - noName: true + mergeObject: true type: - geometry tests: diff --git a/generator/config/query/geoWithin.yaml b/generator/config/query/geoWithin.yaml index ae19744fd..f9f6204d0 100644 --- a/generator/config/query/geoWithin.yaml +++ b/generator/config/query/geoWithin.yaml @@ -9,7 +9,7 @@ description: | arguments: - name: geometry - noName: true + mergeObject: true type: - geometry tests: diff --git a/generator/config/query/near.yaml b/generator/config/query/near.yaml index 010911f54..89d7f511f 100644 --- a/generator/config/query/near.yaml +++ b/generator/config/query/near.yaml @@ -9,7 +9,7 @@ description: | arguments: - name: geometry - noName: true + mergeObject: true type: - geometry - diff --git a/generator/config/query/nearSphere.yaml b/generator/config/query/nearSphere.yaml index 1a9e4f205..72e8e18e9 100644 --- a/generator/config/query/nearSphere.yaml +++ b/generator/config/query/nearSphere.yaml @@ -9,7 +9,7 @@ description: | arguments: - name: geometry - noName: true + mergeObject: true type: - geometry - diff --git a/generator/config/schema.json b/generator/config/schema.json index 17d4b32a9..61846e3e7 100644 --- a/generator/config/schema.json +++ b/generator/config/schema.json @@ -168,8 +168,8 @@ "$comment": "The default value for the argument.", "type": ["array", "boolean", "number", "string"] }, - "noName": { - "$comment": "Skip the name in object encoding and merge the value object", + "mergeObject": { + "$comment": "Skip the name in object encoding and merge the properties of the value into the operator", "type": "boolean", "default": false } diff --git a/generator/config/stage/group.yaml b/generator/config/stage/group.yaml index 0f0cc6ca3..a4bae60c2 100644 --- a/generator/config/stage/group.yaml +++ b/generator/config/stage/group.yaml @@ -15,7 +15,7 @@ arguments: The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents. - name: field - noName: true + mergeObject: true type: - accumulator variadic: object diff --git a/generator/src/Definition/ArgumentDefinition.php b/generator/src/Definition/ArgumentDefinition.php index 2a94a9cdc..53cb88768 100644 --- a/generator/src/Definition/ArgumentDefinition.php +++ b/generator/src/Definition/ArgumentDefinition.php @@ -13,6 +13,7 @@ final class ArgumentDefinition { + public string $propertyName; public VariadicType|null $variadic; public int|null $variadicMin; @@ -25,7 +26,7 @@ public function __construct( string|null $variadic = null, int|null $variadicMin = null, public mixed $default = null, - public bool $noName = false, + public bool $mergeObject = false, ) { assert($this->optional === false || $this->default === null, 'Optional arguments cannot have a default value'); if (is_array($type)) { @@ -35,6 +36,8 @@ public function __construct( } } + $this->propertyName = ltrim($this->name, '$'); + if ($variadic) { $this->variadic = VariadicType::from($variadic); if ($variadicMin === null) { diff --git a/generator/src/OperatorClassGenerator.php b/generator/src/OperatorClassGenerator.php index 565631e3d..3a8705ce3 100644 --- a/generator/src/OperatorClassGenerator.php +++ b/generator/src/OperatorClassGenerator.php @@ -65,29 +65,27 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition $encodeNames = []; $constructor = $class->addMethod('__construct'); foreach ($operator->arguments as $argument) { - // Remove the leading $ from the argument name - $argName = ltrim($argument->name, '$'); - $encodeNames[$argName] = $argument->noName ? null : $argument->name; + $encodeNames[$argument->propertyName] = $argument->mergeObject ? null : $argument->name; $type = $this->getAcceptedTypes($argument); foreach ($type->use as $use) { $namespace->addUse($use); } - $property = $class->addProperty($argName); + $property = $class->addProperty($argument->propertyName); $property->setReadOnly(); - $constructorParam = $constructor->addParameter($argName); + $constructorParam = $constructor->addParameter($argument->propertyName); $constructorParam->setType($type->native); if ($argument->variadic) { $constructor->setVariadic(); - $constructor->addComment('@param ' . $type->doc . ' ...$' . $argName . rtrim(' ' . $argument->description)); + $constructor->addComment('@param ' . $type->doc . ' ...$' . $argument->propertyName . rtrim(' ' . $argument->description)); if ($argument->variadicMin > 0) { $namespace->addUse(InvalidArgumentException::class); $constructor->addBody(<<variadicMin}) { - throw new InvalidArgumentException(\sprintf('Expected at least %d values for \${$argName}, got %d.', {$argument->variadicMin}, \count(\${$argName}))); + if (\count(\${$argument->propertyName}) < {$argument->variadicMin}) { + throw new InvalidArgumentException(\sprintf('Expected at least %d values for \${$argument->propertyName}, got %d.', {$argument->variadicMin}, \count(\${$argument->propertyName}))); } PHP); @@ -95,39 +93,39 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition if ($argument->variadic === VariadicType::Array) { $property->setType('array'); - $property->addComment('@var list<' . $type->doc . '> $' . $argName . rtrim(' ' . $argument->description)); + $property->addComment('@var list<' . $type->doc . '> $' . $argument->propertyName . rtrim(' ' . $argument->description)); // Warn that named arguments are not supported // @see https://psalm.dev/docs/running_psalm/issues/NamedArgumentNotAllowed/ $constructor->addComment('@no-named-arguments'); $namespace->addUseFunction('array_is_list'); $namespace->addUse(InvalidArgumentException::class); $constructor->addBody(<<propertyName})) { + throw new InvalidArgumentException('Expected \${$argument->propertyName} arguments to be a list (array), named arguments are not supported'); } PHP); } elseif ($argument->variadic === VariadicType::Object) { $namespace->addUse(stdClass::class); $property->setType(stdClass::class); - $property->addComment('@var stdClass<' . $type->doc . '> $' . $argName . rtrim(' ' . $argument->description)); + $property->addComment('@var stdClass<' . $type->doc . '> $' . $argument->propertyName . rtrim(' ' . $argument->description)); $namespace->addUseFunction('is_string'); $namespace->addUse(InvalidArgumentException::class); $constructor->addBody(<< \$value) { + foreach(\${$argument->propertyName} as \$key => \$value) { if (! is_string(\$key)) { - throw new InvalidArgumentException('Expected \${$argName} arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); + throw new InvalidArgumentException('Expected \${$argument->propertyName} arguments to be a map (object), named arguments (:) or array unpacking ...[\'\' => ] must be used'); } } - \${$argName} = (object) \${$argName}; + \${$argument->propertyName} = (object) \${$argument->propertyName}; PHP); } } else { // Non-variadic arguments - $property->addComment('@var ' . $type->doc . ' $' . $argName . rtrim(' ' . $argument->description)); + $property->addComment('@var ' . $type->doc . ' $' . $argument->propertyName . rtrim(' ' . $argument->description)); $property->setType($type->native); - $constructor->addComment('@param ' . $type->doc . ' $' . $argName . rtrim(' ' . $argument->description)); + $constructor->addComment('@param ' . $type->doc . ' $' . $argument->propertyName . rtrim(' ' . $argument->description)); if ($argument->optional) { // We use a special Optional::Undefined type to differentiate between null and undefined @@ -142,8 +140,8 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition $namespace->addUseFunction('array_is_list'); $namespace->addUse(InvalidArgumentException::class); $constructor->addBody(<<propertyName}) && ! array_is_list(\${$argument->propertyName})) { + throw new InvalidArgumentException('Expected \${$argument->propertyName} argument to be a list, got an associative array.'); } PHP); @@ -153,8 +151,8 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition $namespace->addUseFunction('is_array'); $namespace->addUse(QueryObject::class); $constructor->addBody(<<propertyName})) { + \${$argument->propertyName} = QueryObject::create(\${$argument->propertyName}); } PHP); @@ -164,8 +162,8 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition $namespace->addUseFunction('is_string'); $namespace->addUse(Javascript::class); $constructor->addBody(<<propertyName})) { + \${$argument->propertyName} = new Javascript(\${$argument->propertyName}); } PHP); @@ -173,7 +171,7 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition } // Set property from constructor argument - $constructor->addBody('$this->' . $argName . ' = $' . $argName . ';'); + $constructor->addBody('$this->' . $argument->propertyName . ' = $' . $argument->propertyName . ';'); } if ($encodeNames !== []) { diff --git a/generator/src/OperatorFactoryGenerator.php b/generator/src/OperatorFactoryGenerator.php index d2be1ebdd..e60804ad8 100644 --- a/generator/src/OperatorFactoryGenerator.php +++ b/generator/src/OperatorFactoryGenerator.php @@ -60,13 +60,12 @@ private function addMethod(GeneratorDefinition $definition, OperatorDefinition $ $method->addComment('@see ' . $operator->link); $args = []; foreach ($operator->arguments as $argument) { - $argName = ltrim($argument->name, '$'); $type = $this->getAcceptedTypes($argument); foreach ($type->use as $use) { $namespace->addUse($use); } - $parameter = $method->addParameter($argName); + $parameter = $method->addParameter($argument->propertyName); $parameter->setType($type->native); if ($argument->variadic) { if ($argument->variadic === VariadicType::Array) { @@ -76,8 +75,8 @@ private function addMethod(GeneratorDefinition $definition, OperatorDefinition $ } $method->setVariadic(); - $method->addComment('@param ' . $type->doc . ' ...$' . $argName . rtrim(' ' . $argument->description)); - $args[] = '...$' . $argName; + $method->addComment('@param ' . $type->doc . ' ...$' . $argument->propertyName . rtrim(' ' . $argument->description)); + $args[] = '...$' . $argument->propertyName; } else { if ($argument->optional) { $parameter->setDefaultValue(new Literal('Optional::Undefined')); @@ -85,8 +84,8 @@ private function addMethod(GeneratorDefinition $definition, OperatorDefinition $ $parameter->setDefaultValue($argument->default); } - $method->addComment('@param ' . $type->doc . ' $' . $argName . rtrim(' ' . $argument->description)); - $args[] = '$' . $argName; + $method->addComment('@param ' . $type->doc . ' $' . $argument->propertyName . rtrim(' ' . $argument->description)); + $args[] = '$' . $argument->propertyName; } }