diff --git a/lib/Doctrine/Common/Annotations/DocParser.php b/lib/Doctrine/Common/Annotations/DocParser.php index 21c5bf345..80b5d07b2 100644 --- a/lib/Doctrine/Common/Annotations/DocParser.php +++ b/lib/Doctrine/Common/Annotations/DocParser.php @@ -15,8 +15,10 @@ use function array_keys; use function array_map; +use function array_values; use function class_exists; use function constant; +use function count; use function defined; use function explode; use function gettype; @@ -863,18 +865,34 @@ private function Annotation() ); } - $defaultProperty = 'value'; - // Change the default property only if the @NamedArgumentConstructor - // tag and the default_property are set + $arguments = $this->MethodCall(); + + $positionalArguments = $arguments['positional_arguments'] ?? []; + $namedArguments = $arguments['named_arguments'] ?? []; + if ( self::$annotationMetadata[$name]['has_named_argument_constructor'] && self::$annotationMetadata[$name]['default_property'] !== null ) { - $defaultProperty = self::$annotationMetadata[$name]['default_property']; + $values = $namedArguments; + foreach (self::$annotationMetadata[$name]['constructor_args'] as $property => $parameter) { + $position = $parameter['position']; + if (! isset($values[$property]) && isset($positionalArguments[$position])) { + $values[$property] = $positionalArguments[$position]; + } + } + } else { + $values = $namedArguments; + if (! empty($positionalArguments) && ! isset($values['value'])) { + if (count($positionalArguments) === 1) { + $value = $positionalArguments[0]; + } else { + $value = array_values($positionalArguments); + } + $values['value'] = $value; + } } - $values = $this->MethodCall($defaultProperty); - if (isset(self::$annotationMetadata[$name]['enum'])) { // checks all declared attributes foreach (self::$annotationMetadata[$name]['enum'] as $property => $enum) { @@ -1027,7 +1045,7 @@ private function Annotation() * @throws AnnotationException * @throws ReflectionException */ - private function MethodCall(string $defaultProperty): array + private function MethodCall(): array { $values = []; @@ -1038,7 +1056,7 @@ private function MethodCall(string $defaultProperty): array $this->match(DocLexer::T_OPEN_PARENTHESIS); if (! $this->lexer->isNextToken(DocLexer::T_CLOSE_PARENTHESIS)) { - $values = $this->Values($defaultProperty); + $values = $this->Values(); } $this->match(DocLexer::T_CLOSE_PARENTHESIS); @@ -1054,7 +1072,7 @@ private function MethodCall(string $defaultProperty): array * @throws AnnotationException * @throws ReflectionException */ - private function Values(string $defaultProperty): array + private function Values(): array { $values = [$this->Value()]; @@ -1075,23 +1093,17 @@ private function Values(string $defaultProperty): array $values[] = $value; } + $namedArguments = []; + $positionalArguments = []; foreach ($values as $k => $value) { if (is_object($value) && $value instanceof stdClass) { - $values[$value->name] = $value->value; - } elseif (! isset($values[$defaultProperty])) { - $values[$defaultProperty] = $value; + $namedArguments[$value->name] = $value->value; } else { - if (! is_array($values[$defaultProperty])) { - $values[$defaultProperty] = [$values[$defaultProperty]]; - } - - $values[$defaultProperty][] = $value; + $positionalArguments[$k] = $value; } - - unset($values[$k]); } - return $values; + return ['named_arguments' => $namedArguments, 'positional_arguments' => $positionalArguments]; } /**