From faafa3535c11c05e17f05f21a541b96a837a55a2 Mon Sep 17 00:00:00 2001 From: Martin Rademacher Date: Thu, 23 Dec 2021 14:28:48 +1300 Subject: [PATCH] Rationalise attribute parameters for types that inherit from Schema (#1037) Also clean up a few things we've missed during the annotation/attribute split. --- composer.json | 3 +- src/Annotations/JsonContent.php | 6 -- src/Annotations/Parameter.php | 47 +---------- src/Annotations/Property.php | 7 -- src/Attributes/AdditionalProperties.php | 54 ++++++++++++- src/Attributes/Contact.php | 19 ++--- src/Attributes/Discriminator.php | 15 ++-- src/Attributes/Examples.php | 25 +++--- src/Attributes/ExternalDocumentation.php | 9 ++- src/Attributes/Flow.php | 17 ++-- src/Attributes/Header.php | 1 + src/Attributes/Info.php | 17 ++-- src/Attributes/Items.php | 62 +++++++++++---- src/Attributes/JsonContent.php | 63 ++++++++++++--- src/Attributes/License.php | 13 ++-- src/Attributes/Link.php | 13 ++-- src/Attributes/MediaType.php | 13 ++-- src/Attributes/OpenApi.php | 1 + src/Attributes/OperationTrait.php | 17 ++-- src/Attributes/ParameterTrait.php | 22 +++--- src/Attributes/PathItem.php | 1 + src/Attributes/Property.php | 78 ++++++++++++------- src/Attributes/RequestBody.php | 7 +- src/Attributes/Response.php | 11 +-- src/Attributes/Schema.php | 66 +++++++++++----- src/Attributes/SecurityScheme.php | 37 ++++----- src/Attributes/Server.php | 9 ++- src/Attributes/ServerVariable.php | 13 ++-- src/Attributes/Tag.php | 9 ++- src/Attributes/Xml.php | 13 ++-- src/Attributes/XmlContent.php | 63 ++++++++++++--- tests/Analysers/ReflectionAnalyserTest.php | 2 +- tests/Analysers/TokenScannerTest.php | 2 +- tests/Annotations/AttachableTest.php | 5 +- .../Annotations/CustomAttachable.php | 2 +- tests/Fixtures/Apis/Attributes/basic.php | 50 ++++++++++-- tests/Fixtures/Apis/DocBlocks/basic.php | 32 +++++++- tests/Fixtures/Apis/Mixed/basic.php | 21 ++++- tests/Fixtures/Apis/basic.yaml | 18 +++++ .../Attributes/CustomAttachable.php | 2 +- 40 files changed, 576 insertions(+), 289 deletions(-) rename tests/{ => Fixtures}/Annotations/CustomAttachable.php (91%) rename tests/{ => Fixtures}/Attributes/CustomAttachable.php (93%) diff --git a/composer.json b/composer.json index c68392101..ee8a6829b 100644 --- a/composer.json +++ b/composer.json @@ -61,7 +61,8 @@ "autoload-dev": { "psr-4": { "OpenApi\\Tests\\": "tests/", - "AnotherNamespace\\": "tests/Fixtures/AnotherNamespace" + "AnotherNamespace\\": "tests/Fixtures/AnotherNamespace", + "OpenApi\\Tests\\Fixtures\\Annotations\\": "tests/Fixtures/Annotations" } }, "scripts": { diff --git a/src/Annotations/JsonContent.php b/src/Annotations/JsonContent.php index 217207e4b..bb6044672 100644 --- a/src/Annotations/JsonContent.php +++ b/src/Annotations/JsonContent.php @@ -17,12 +17,6 @@ */ class JsonContent extends Schema { - - /** - * @var object - */ - public $example = Generator::UNDEFINED; - /** * @var object */ diff --git a/src/Annotations/Parameter.php b/src/Annotations/Parameter.php index 46bd1f548..c5e0f9d62 100644 --- a/src/Annotations/Parameter.php +++ b/src/Annotations/Parameter.php @@ -17,7 +17,7 @@ * * @Annotation */ -abstract class AbstractParameter extends AbstractAnnotation +class Parameter extends AbstractAnnotation { /** * $ref See https://swagger.io/docs/specification/using-ref/. @@ -264,48 +264,3 @@ public function identity(): string return parent::_identity(['name', 'in']); } } - -if (\PHP_VERSION_ID >= 80100) { - /** - * @Annotation - */ - #[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)] - class Parameter extends AbstractParameter - { - public function __construct( - array $properties = [], - string $parameter = Generator::UNDEFINED, - string $name = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $in = Generator::UNDEFINED, - ?bool $required = null, - string $ref = Generator::UNDEFINED, - ?Schema $schema = null, - ?array $examples = null, - ?array $x = null, - ?array $attachables = null - ) { - parent::__construct($properties + [ - 'parameter' => $parameter, - 'name' => $name, - 'description' => $description, - 'in' => $this->in !== Generator::UNDEFINED ? $this->in : $in, - 'required' => $this->required !== Generator::UNDEFINED ? $this->required : ($required ?? Generator::UNDEFINED), - 'ref' => $ref, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($schema, $examples, $attachables), - ]); - } - } -} else { - /** - * @Annotation - */ - class Parameter extends AbstractParameter - { - public function __construct(array $properties) - { - parent::__construct($properties); - } - } -} diff --git a/src/Annotations/Property.php b/src/Annotations/Property.php index 7532467b4..b707deb9d 100644 --- a/src/Annotations/Property.php +++ b/src/Annotations/Property.php @@ -20,13 +20,6 @@ class Property extends Schema */ public $property = Generator::UNDEFINED; - /** - * Indicates the property is nullable. - * - * @var bool - */ - public $nullable = Generator::UNDEFINED; - /** * @inheritdoc */ diff --git a/src/Attributes/AdditionalProperties.php b/src/Attributes/AdditionalProperties.php index 8dfc182c0..527eaa2bf 100644 --- a/src/Attributes/AdditionalProperties.php +++ b/src/Attributes/AdditionalProperties.php @@ -15,12 +15,60 @@ class AdditionalProperties extends \OpenApi\Annotations\AdditionalProperties { public function __construct( + // schema + string|object|null $ref = null, + ?string $schema = null, + ?string $title = null, + ?string $description = null, + ?array $required = null, + ?array $properties = null, + ?string $type = null, + ?string $format = null, + ?Items $items = null, + ?string $collectionFormat = null, + $default = null, + ?string $pattern = null, + ?array $enum = null, + ?Discriminator $discriminator = null, + ?bool $readOnly = null, + ?bool $writeOnly = null, + ?Xml $xml = null, + ?ExternalDocumentation $externalDocs = null, + $example = null, + ?bool $nullable = null, + ?bool $deprecated = null, + ?array $allOf = null, + ?array $anyOf = null, + ?array $oneOf = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($attachables), - ]); + 'ref' => $ref ?? Generator::UNDEFINED, + 'schema' => $schema ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'required' => $required ?? Generator::UNDEFINED, + 'properties' => $properties ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'format' => $format ?? Generator::UNDEFINED, + 'collectionFormat' => $collectionFormat ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, + 'pattern' => $pattern ?? Generator::UNDEFINED, + 'enum' => $enum ?? Generator::UNDEFINED, + 'readOnly' => $readOnly ?? Generator::UNDEFINED, + 'writeOnly' => $writeOnly ?? Generator::UNDEFINED, + 'xml' => $xml ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'nullable' => $nullable ?? Generator::UNDEFINED, + 'deprecated' => $deprecated ?? Generator::UNDEFINED, + 'allOf' => $allOf ?? Generator::UNDEFINED, + 'anyOf' => $anyOf ?? Generator::UNDEFINED, + 'oneOf' => $oneOf ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + 'attachables' => $attachables ?? Generator::UNDEFINED, + 'value' => $this->combine($items, $discriminator, $externalDocs, $attachables), + ]); } } diff --git a/src/Attributes/Contact.php b/src/Attributes/Contact.php index 2067ba5f4..7572ab60f 100644 --- a/src/Attributes/Contact.php +++ b/src/Attributes/Contact.php @@ -12,18 +12,19 @@ class Contact extends \OpenApi\Annotations\Contact { public function __construct( - string $name = Generator::UNDEFINED, - string $url = Generator::UNDEFINED, - string $email = Generator::UNDEFINED, + ?string $name = null, + ?string $url = null, + ?string $email = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'name' => $name, - 'url' => $url, - 'email' => $email, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($attachables), - ]); + 'name' => $name ?? Generator::UNDEFINED, + 'url' => $url ?? Generator::UNDEFINED, + 'email' => $email ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + 'value' => $this->combine($attachables), + ]); } } diff --git a/src/Attributes/Discriminator.php b/src/Attributes/Discriminator.php index e5859f9d0..d1c508f92 100644 --- a/src/Attributes/Discriminator.php +++ b/src/Attributes/Discriminator.php @@ -12,16 +12,17 @@ class Discriminator extends \OpenApi\Annotations\Discriminator { public function __construct( - string $propertyName = Generator::UNDEFINED, - string $mapping = Generator::UNDEFINED, + ?string $propertyName = null, + ?string $mapping = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'propertyName' => $propertyName, - 'mapping' => $mapping, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($attachables), - ]); + 'propertyName' => $propertyName ?? Generator::UNDEFINED, + 'mapping' => $mapping ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + 'value' => $this->combine($attachables), + ]); } } diff --git a/src/Attributes/Examples.php b/src/Attributes/Examples.php index 542483a20..df1ff2481 100644 --- a/src/Attributes/Examples.php +++ b/src/Attributes/Examples.php @@ -12,22 +12,23 @@ class Examples extends \OpenApi\Annotations\Examples { public function __construct( - string $summary = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $value = Generator::UNDEFINED, - string $externalValue = Generator::UNDEFINED, - string $ref = Generator::UNDEFINED, + ?string $summary = null, + ?string $description = null, + ?string $value = null, + ?string $externalValue = null, + string|object|null $ref = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'summary' => $summary, - 'description' => $description, - 'value' => $value, - 'externalValue' => $externalValue, - 'ref' => $ref, - 'x' => $x ?? Generator::UNDEFINED, - ]); + 'summary' => $summary ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'value' => $value ?? Generator::UNDEFINED, + 'externalValue' => $externalValue ?? Generator::UNDEFINED, + 'ref' => $ref ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + ]); if ($attachables) { $this->merge($attachables); } diff --git a/src/Attributes/ExternalDocumentation.php b/src/Attributes/ExternalDocumentation.php index d962c09f0..15832549d 100644 --- a/src/Attributes/ExternalDocumentation.php +++ b/src/Attributes/ExternalDocumentation.php @@ -12,14 +12,15 @@ class ExternalDocumentation extends \OpenApi\Annotations\ExternalDocumentation { public function __construct( - string $description = Generator::UNDEFINED, - string $url = Generator::UNDEFINED, + ?string $description = null, + ?string $url = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'description' => $description, - 'url' => $url, + 'description' => $description ?? Generator::UNDEFINED, + 'url' => $url ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($attachables), ]); diff --git a/src/Attributes/Flow.php b/src/Attributes/Flow.php index c5576c96c..a9ae03443 100644 --- a/src/Attributes/Flow.php +++ b/src/Attributes/Flow.php @@ -12,19 +12,20 @@ class Flow extends \OpenApi\Annotations\Flow { public function __construct( - string $authorizationUrl = Generator::UNDEFINED, - string $tokenUrl = Generator::UNDEFINED, - string $refreshUrl = Generator::UNDEFINED, - string $flow = Generator::UNDEFINED, + ?string $authorizationUrl = null, + ?string $tokenUrl = null, + ?string $refreshUrl = null, + ?string $flow = null, ?array $scopes = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'authorizationUrl' => $authorizationUrl, - 'tokenUrl' => $tokenUrl, - 'refreshUrl' => $refreshUrl, - 'flow' => $flow, + 'authorizationUrl' => $authorizationUrl ?? Generator::UNDEFINED, + 'tokenUrl' => $tokenUrl ?? Generator::UNDEFINED, + 'refreshUrl' => $refreshUrl ?? Generator::UNDEFINED, + 'flow' => $flow ?? Generator::UNDEFINED, 'scopes' => $scopes ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($attachables), diff --git a/src/Attributes/Header.php b/src/Attributes/Header.php index 0388d6c79..e6d8cd0a6 100644 --- a/src/Attributes/Header.php +++ b/src/Attributes/Header.php @@ -11,6 +11,7 @@ class Header extends \OpenApi\Annotations\Header { public function __construct( + // annotation ?array $x = null, ?array $attachables = null ) { diff --git a/src/Attributes/Info.php b/src/Attributes/Info.php index d4a05b2c3..5767642b2 100644 --- a/src/Attributes/Info.php +++ b/src/Attributes/Info.php @@ -12,20 +12,21 @@ class Info extends \OpenApi\Annotations\Info { public function __construct( - string $version = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $title = Generator::UNDEFINED, - string $termsOfService = Generator::UNDEFINED, + ?string $version = null, + ?string $description = null, + ?string $title = null, + ?string $termsOfService = null, ?Contact $contact = null, ?License $license = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'version' => $version, - 'description' => $description, - 'title' => $title, - 'termsOfService' => $termsOfService, + 'version' => $version ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'termsOfService' => $termsOfService ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($contact, $license, $attachables), ]); diff --git a/src/Attributes/Items.php b/src/Attributes/Items.php index 4126b91bf..2b4646ec4 100644 --- a/src/Attributes/Items.php +++ b/src/Attributes/Items.php @@ -12,26 +12,62 @@ class Items extends \OpenApi\Annotations\Items { public function __construct( - string $type = Generator::UNDEFINED, - string $ref = Generator::UNDEFINED, + // schema + string|object|null $ref = null, + ?string $schema = null, + ?string $title = null, + ?string $description = null, + ?array $required = null, + ?array $properties = null, + ?string $type = null, + ?string $format = null, + ?Items $items = null, + ?string $collectionFormat = null, + $default = null, + ?string $pattern = null, + ?array $enum = null, + ?Discriminator $discriminator = null, + ?bool $readOnly = null, + ?bool $writeOnly = null, + ?Xml $xml = null, + ?ExternalDocumentation $externalDocs = null, + $example = null, + ?bool $nullable = null, ?bool $deprecated = null, ?array $allOf = null, ?array $anyOf = null, ?array $oneOf = null, - ?bool $nullable = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'type' => $type, - 'ref' => $ref, - 'nullable' => $nullable ?? Generator::UNDEFINED, - 'deprecated' => $deprecated ?? Generator::UNDEFINED, - 'allOf' => $allOf ?? Generator::UNDEFINED, - 'anyOf' => $anyOf ?? Generator::UNDEFINED, - 'oneOf' => $oneOf ?? Generator::UNDEFINED, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($attachables), - ]); + // schema + 'ref' => $ref ?? Generator::UNDEFINED, + 'schema' => $schema ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'required' => $required ?? Generator::UNDEFINED, + 'properties' => $properties ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'format' => $format ?? Generator::UNDEFINED, + 'collectionFormat' => $collectionFormat ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, + 'pattern' => $pattern ?? Generator::UNDEFINED, + 'enum' => $enum ?? Generator::UNDEFINED, + 'readOnly' => $readOnly ?? Generator::UNDEFINED, + 'writeOnly' => $writeOnly ?? Generator::UNDEFINED, + 'xml' => $xml ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'nullable' => $nullable ?? Generator::UNDEFINED, + 'deprecated' => $deprecated ?? Generator::UNDEFINED, + 'allOf' => $allOf ?? Generator::UNDEFINED, + 'anyOf' => $anyOf ?? Generator::UNDEFINED, + 'oneOf' => $oneOf ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + // annotation + 'attachables' => $attachables ?? Generator::UNDEFINED, + 'value' => $this->combine($items, $discriminator, $externalDocs, $attachables), + ]); } } diff --git a/src/Attributes/JsonContent.php b/src/Attributes/JsonContent.php index 5e0e508cd..45a386679 100644 --- a/src/Attributes/JsonContent.php +++ b/src/Attributes/JsonContent.php @@ -12,23 +12,64 @@ class JsonContent extends \OpenApi\Annotations\JsonContent { public function __construct( - string $ref = Generator::UNDEFINED, + object $examples = null, + // schema + string|object|null $ref = null, + ?string $schema = null, + ?string $title = null, + ?string $description = null, + ?array $required = null, + ?array $properties = null, + ?string $type = null, + ?string $format = null, + ?Items $items = null, + ?string $collectionFormat = null, + $default = null, + ?string $pattern = null, + ?array $enum = null, + ?Discriminator $discriminator = null, + ?bool $readOnly = null, + ?bool $writeOnly = null, + ?Xml $xml = null, + ?ExternalDocumentation $externalDocs = null, + $example = null, + ?bool $nullable = null, + ?bool $deprecated = null, ?array $allOf = null, ?array $anyOf = null, ?array $oneOf = null, - string $type = Generator::UNDEFINED, - $items = Generator::UNDEFINED, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'ref' => $ref, - 'allOf' => $allOf ?? Generator::UNDEFINED, - 'anyOf' => $anyOf ?? Generator::UNDEFINED, - 'oneOf' => $oneOf ?? Generator::UNDEFINED, - 'type' => $type, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($items, $attachables), - ]); + 'examples' => $examples ?? Generator::UNDEFINED, + // schema + 'ref' => $ref ?? Generator::UNDEFINED, + 'schema' => $schema ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'required' => $required ?? Generator::UNDEFINED, + 'properties' => $properties ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'format' => $format ?? Generator::UNDEFINED, + 'collectionFormat' => $collectionFormat ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, + 'pattern' => $pattern ?? Generator::UNDEFINED, + 'enum' => $enum ?? Generator::UNDEFINED, + 'readOnly' => $readOnly ?? Generator::UNDEFINED, + 'writeOnly' => $writeOnly ?? Generator::UNDEFINED, + 'xml' => $xml ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'nullable' => $nullable ?? Generator::UNDEFINED, + 'deprecated' => $deprecated ?? Generator::UNDEFINED, + 'allOf' => $allOf ?? Generator::UNDEFINED, + 'anyOf' => $anyOf ?? Generator::UNDEFINED, + 'oneOf' => $oneOf ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + // annotation + 'attachables' => $attachables ?? Generator::UNDEFINED, + 'value' => $this->combine($items, $discriminator, $externalDocs, $attachables), + ]); } } diff --git a/src/Attributes/License.php b/src/Attributes/License.php index 7b72ae915..efcbcd440 100644 --- a/src/Attributes/License.php +++ b/src/Attributes/License.php @@ -12,16 +12,17 @@ class License extends \OpenApi\Annotations\License { public function __construct( - string $name = Generator::UNDEFINED, - string $identifier = Generator::UNDEFINED, - string $url = Generator::UNDEFINED, + ?string $name = null, + ?string $identifier = null, + ?string $url = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'name' => $name, - 'identifier' => $identifier, - 'url' => $url, + 'name' => $name ?? Generator::UNDEFINED, + 'identifier' => $identifier ?? Generator::UNDEFINED, + 'url' => $url ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($attachables), ]); diff --git a/src/Attributes/Link.php b/src/Attributes/Link.php index aa759de40..b90ec15a6 100644 --- a/src/Attributes/Link.php +++ b/src/Attributes/Link.php @@ -12,17 +12,18 @@ class Link extends \OpenApi\Annotations\Link { public function __construct( - string $link = Generator::UNDEFINED, - string $ref = Generator::UNDEFINED, - string $operationId = Generator::UNDEFINED, + ?string $link = null, + string|object|null $ref = null, + ?string $operationId = null, ?array $parameters = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'link' => $link, - 'ref' => $ref, - 'operationId' => $operationId, + 'link' => $link ?? Generator::UNDEFINED, + 'ref' => $ref ?? Generator::UNDEFINED, + 'operationId' => $operationId ?? Generator::UNDEFINED, 'parameters' => $parameters ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($attachables), diff --git a/src/Attributes/MediaType.php b/src/Attributes/MediaType.php index 723e64201..a5e9810b0 100644 --- a/src/Attributes/MediaType.php +++ b/src/Attributes/MediaType.php @@ -12,18 +12,19 @@ class MediaType extends \OpenApi\Annotations\MediaType { public function __construct( - string $mediaType = Generator::UNDEFINED, + ?string $mediaType = null, ?Schema $schema = null, - $example = Generator::UNDEFINED, + $example = null, ?array $examples = null, - string $encoding = Generator::UNDEFINED, + ?string $encoding = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'mediaType' => $mediaType, - 'example' => $example, - 'encoding' => $encoding, + 'mediaType' => $mediaType ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'encoding' => $encoding ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($schema, $examples, $attachables), ]); diff --git a/src/Attributes/OpenApi.php b/src/Attributes/OpenApi.php index bf7ab12f2..6d0aff85e 100644 --- a/src/Attributes/OpenApi.php +++ b/src/Attributes/OpenApi.php @@ -17,6 +17,7 @@ public function __construct( ?array $servers = null, ?array $tags = null, ?ExternalDocumentation $externalDocs = null, + // annotation ?array $x = null, ?array $attachables = null ) { diff --git a/src/Attributes/OperationTrait.php b/src/Attributes/OperationTrait.php index 9b4e6436f..02b3c40ba 100644 --- a/src/Attributes/OperationTrait.php +++ b/src/Attributes/OperationTrait.php @@ -11,10 +11,10 @@ trait OperationTrait { public function __construct( - string $path = Generator::UNDEFINED, - string $operationId = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $summary = Generator::UNDEFINED, + ?string $path = null, + ?string $operationId = null, + ?string $description = null, + ?string $summary = null, ?array $security = null, ?array $servers = null, ?RequestBody $requestBody = null, @@ -22,14 +22,15 @@ public function __construct( ?array $parameters = null, ?array $responses = null, ?ExternalDocumentation $externalDocs = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'path' => $path, - 'operationId' => $operationId, - 'description' => $description, - 'summary' => $summary, + 'path' => $path ?? Generator::UNDEFINED, + 'operationId' => $operationId ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'summary' => $summary ?? Generator::UNDEFINED, 'security' => $security ?? Generator::UNDEFINED, 'servers' => $servers ?? Generator::UNDEFINED, 'tags' => $tags ?? Generator::UNDEFINED, diff --git a/src/Attributes/ParameterTrait.php b/src/Attributes/ParameterTrait.php index 64920a1f1..df3f997bf 100644 --- a/src/Attributes/ParameterTrait.php +++ b/src/Attributes/ParameterTrait.php @@ -11,25 +11,25 @@ trait ParameterTrait { public function __construct( - array $properties = [], - string $parameter = Generator::UNDEFINED, - string $name = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $in = Generator::UNDEFINED, + ?string $parameter = null, + ?string $name = null, + ?string $description = null, + ?string $in = null, ?bool $required = null, - string $ref = Generator::UNDEFINED, + string|object|null $ref = null, ?Schema $schema = null, ?array $examples = null, + // annotation ?array $x = null, ?array $attachables = null ) { - parent::__construct($properties + [ - 'parameter' => $parameter, - 'name' => $name, - 'description' => $description, + parent::__construct([ + 'parameter' => $parameter ?? Generator::UNDEFINED, + 'name' => $name ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, 'in' => $this->in !== Generator::UNDEFINED ? $this->in : $in, 'required' => $this->required !== Generator::UNDEFINED ? $this->required : ($required ?? Generator::UNDEFINED), - 'ref' => $ref, + 'ref' => $ref ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($schema, $examples, $attachables), ]); diff --git a/src/Attributes/PathItem.php b/src/Attributes/PathItem.php index adcc65832..9d5c2bb54 100644 --- a/src/Attributes/PathItem.php +++ b/src/Attributes/PathItem.php @@ -12,6 +12,7 @@ class PathItem extends \OpenApi\Annotations\PathItem { public function __construct( + // annotation ?array $x = null, ?array $attachables = null ) { diff --git a/src/Attributes/Property.php b/src/Attributes/Property.php index 85a2e6593..252d9d4cc 100644 --- a/src/Attributes/Property.php +++ b/src/Attributes/Property.php @@ -12,38 +12,64 @@ class Property extends \OpenApi\Annotations\Property { public function __construct( - string $property = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $title = Generator::UNDEFINED, - string $type = Generator::UNDEFINED, - string $format = Generator::UNDEFINED, - string $ref = Generator::UNDEFINED, + ?string $property = null, + // schema + string|object|null $ref = null, + ?string $schema = null, + ?string $title = null, + ?string $description = null, + ?array $required = null, + ?array $properties = null, + ?string $type = null, + ?string $format = null, + ?Items $items = null, + ?string $collectionFormat = null, + $default = null, + ?string $pattern = null, + ?array $enum = null, + ?Discriminator $discriminator = null, + ?bool $readOnly = null, + ?bool $writeOnly = null, + ?Xml $xml = null, + ?ExternalDocumentation $externalDocs = null, + $example = null, + ?bool $nullable = null, + ?bool $deprecated = null, ?array $allOf = null, ?array $anyOf = null, ?array $oneOf = null, - ?bool $nullable = null, - ?Items $items = null, - ?bool $deprecated = null, - $example = Generator::UNDEFINED, - $examples = Generator::UNDEFINED, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'property' => $property, - 'description' => $description, - 'title' => $title, - 'type' => $type, - 'format' => $format, - 'nullable' => $nullable ?? Generator::UNDEFINED, - 'deprecated' => $deprecated ?? Generator::UNDEFINED, - 'example' => $example, - 'ref' => $ref, - 'allOf' => $allOf ?? Generator::UNDEFINED, - 'anyOf' => $anyOf ?? Generator::UNDEFINED, - 'oneOf' => $oneOf ?? Generator::UNDEFINED, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($items, $examples, $attachables), - ]); + 'property' => $property ?? Generator::UNDEFINED, + // schema + 'ref' => $ref ?? Generator::UNDEFINED, + 'schema' => $schema ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'required' => $required ?? Generator::UNDEFINED, + 'properties' => $properties ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'format' => $format ?? Generator::UNDEFINED, + 'collectionFormat' => $collectionFormat ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, + 'pattern' => $pattern ?? Generator::UNDEFINED, + 'enum' => $enum ?? Generator::UNDEFINED, + 'readOnly' => $readOnly ?? Generator::UNDEFINED, + 'writeOnly' => $writeOnly ?? Generator::UNDEFINED, + 'xml' => $xml ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'nullable' => $nullable ?? Generator::UNDEFINED, + 'deprecated' => $deprecated ?? Generator::UNDEFINED, + 'allOf' => $allOf ?? Generator::UNDEFINED, + 'anyOf' => $anyOf ?? Generator::UNDEFINED, + 'oneOf' => $oneOf ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + // annotation + 'attachables' => $attachables ?? Generator::UNDEFINED, + 'value' => $this->combine($items, $discriminator, $externalDocs, $attachables), + ]); } } diff --git a/src/Attributes/RequestBody.php b/src/Attributes/RequestBody.php index 6429e951b..66647a611 100644 --- a/src/Attributes/RequestBody.php +++ b/src/Attributes/RequestBody.php @@ -12,14 +12,15 @@ class RequestBody extends \OpenApi\Annotations\RequestBody { public function __construct( - string $description = Generator::UNDEFINED, + ?string $description = null, ?bool $required = null, - $content = Generator::UNDEFINED, + $content = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'description' => $description, + 'description' => $description ?? Generator::UNDEFINED, 'required' => $required ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($content, $attachables), diff --git a/src/Attributes/Response.php b/src/Attributes/Response.php index 14e64d388..f12d3a6e5 100644 --- a/src/Attributes/Response.php +++ b/src/Attributes/Response.php @@ -12,16 +12,17 @@ class Response extends \OpenApi\Annotations\Response { public function __construct( - $response = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - $content = Generator::UNDEFINED, + $response = null, + ?string $description = null, + $content = null, ?array $links = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'response' => $response, - 'description' => $description, + 'response' => $response ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($content, $links, $attachables), ]); diff --git a/src/Attributes/Schema.php b/src/Attributes/Schema.php index 90a5d0971..465e0692a 100644 --- a/src/Attributes/Schema.php +++ b/src/Attributes/Schema.php @@ -12,30 +12,60 @@ class Schema extends \OpenApi\Annotations\Schema { public function __construct( - string $schema = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $title = Generator::UNDEFINED, - string $type = Generator::UNDEFINED, - string $format = Generator::UNDEFINED, - string $ref = Generator::UNDEFINED, + // schema + string|object|null $ref = null, + ?string $schema = null, + ?string $title = null, + ?string $description = null, + ?array $required = null, + ?array $properties = null, + ?string $type = null, + ?string $format = null, ?Items $items = null, + ?string $collectionFormat = null, + $default = null, + ?string $pattern = null, ?array $enum = null, - ?bool $deprecated = null, + ?Discriminator $discriminator = null, + ?bool $readOnly = null, + ?bool $writeOnly = null, + ?Xml $xml = null, ?ExternalDocumentation $externalDocs = null, + $example = null, + ?bool $nullable = null, + ?bool $deprecated = null, + ?array $allOf = null, + ?array $anyOf = null, + ?array $oneOf = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'schema' => $schema, - 'description' => $description, - 'title' => $title, - 'type' => $type, - 'format' => $format, - 'ref' => $ref, - 'enum' => $enum ?? Generator::UNDEFINED, - 'deprecated' => $deprecated ?? Generator::UNDEFINED, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($externalDocs, $items, $attachables), - ]); + 'ref' => $ref ?? Generator::UNDEFINED, + 'schema' => $schema ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'required' => $required ?? Generator::UNDEFINED, + 'properties' => $properties ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'format' => $format ?? Generator::UNDEFINED, + 'collectionFormat' => $collectionFormat ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, + 'pattern' => $pattern ?? Generator::UNDEFINED, + 'enum' => $enum ?? Generator::UNDEFINED, + 'readOnly' => $readOnly ?? Generator::UNDEFINED, + 'writeOnly' => $writeOnly ?? Generator::UNDEFINED, + 'xml' => $xml ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'nullable' => $nullable ?? Generator::UNDEFINED, + 'deprecated' => $deprecated ?? Generator::UNDEFINED, + 'allOf' => $allOf ?? Generator::UNDEFINED, + 'anyOf' => $anyOf ?? Generator::UNDEFINED, + 'oneOf' => $oneOf ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + 'attachables' => $attachables ?? Generator::UNDEFINED, + 'value' => $this->combine($items, $discriminator, $externalDocs, $attachables), + ]); } } diff --git a/src/Attributes/SecurityScheme.php b/src/Attributes/SecurityScheme.php index 3bf62efac..f86b2b168 100644 --- a/src/Attributes/SecurityScheme.php +++ b/src/Attributes/SecurityScheme.php @@ -12,29 +12,30 @@ class SecurityScheme extends \OpenApi\Annotations\SecurityScheme { public function __construct( - string $ref = Generator::UNDEFINED, - string $securityScheme = Generator::UNDEFINED, - string $type = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $name = Generator::UNDEFINED, - string $in = Generator::UNDEFINED, - string $bearerFormat = Generator::UNDEFINED, - string $scheme = Generator::UNDEFINED, - string $openIdConnectUrl = Generator::UNDEFINED, + string|object|null $ref = null, + ?string $securityScheme = null, + ?string $type = null, + ?string $description = null, + ?string $name = null, + ?string $in = null, + ?string $bearerFormat = null, + ?string $scheme = null, + ?string $openIdConnectUrl = null, ?array $flows = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'ref' => $ref, - 'securityScheme' => $securityScheme, - 'type' => $type, - 'description' => $description, - 'name' => $name, - 'in' => $in, - 'bearerFormat' => $bearerFormat, - 'scheme' => $scheme, - 'openIdConnectUrl' => $openIdConnectUrl, + 'ref' => $ref ?? Generator::UNDEFINED, + 'securityScheme' => $securityScheme ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'name' => $name ?? Generator::UNDEFINED, + 'in' => $in ?? Generator::UNDEFINED, + 'bearerFormat' => $bearerFormat ?? Generator::UNDEFINED, + 'scheme' => $scheme ?? Generator::UNDEFINED, + 'openIdConnectUrl' => $openIdConnectUrl ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($flows, $attachables), ]); diff --git a/src/Attributes/Server.php b/src/Attributes/Server.php index 24fd78224..a28b7fa7d 100644 --- a/src/Attributes/Server.php +++ b/src/Attributes/Server.php @@ -12,15 +12,16 @@ class Server extends \OpenApi\Annotations\Server { public function __construct( - string $url = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, + ?string $url = null, + ?string $description = null, ?array $variables = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'url' => $url, - 'description' => $description, + 'url' => $url ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($variables, $attachables), ]); diff --git a/src/Attributes/ServerVariable.php b/src/Attributes/ServerVariable.php index d4f07cefc..1c2447b50 100644 --- a/src/Attributes/ServerVariable.php +++ b/src/Attributes/ServerVariable.php @@ -12,18 +12,19 @@ class ServerVariable extends \OpenApi\Annotations\ServerVariable { public function __construct( - string $serverVariable = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, - string $default = Generator::UNDEFINED, + ?string $serverVariable = null, + ?string $description = null, + ?string $default = null, ?array $enum = null, ?array $variables = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'serverVariable' => $serverVariable, - 'description' => $description, - 'default' => $default, + 'serverVariable' => $serverVariable ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, 'enum' => $enum ?? Generator::UNDEFINED, 'variables' => $variables ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, diff --git a/src/Attributes/Tag.php b/src/Attributes/Tag.php index 1f85ef481..8564930c1 100644 --- a/src/Attributes/Tag.php +++ b/src/Attributes/Tag.php @@ -12,15 +12,16 @@ class Tag extends \OpenApi\Annotations\Tag { public function __construct( - string $name = Generator::UNDEFINED, - string $description = Generator::UNDEFINED, + ?string $name = null, + ?string $description = null, ?ExternalDocumentation $externalDocs = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'name' => $name, - 'description' => $description, + 'name' => $name ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, 'value' => $this->combine($externalDocs, $attachables), ]); diff --git a/src/Attributes/Xml.php b/src/Attributes/Xml.php index 8bfb9cb25..0cd0c372c 100644 --- a/src/Attributes/Xml.php +++ b/src/Attributes/Xml.php @@ -12,18 +12,19 @@ class Xml extends \OpenApi\Annotations\Xml { public function __construct( - string $name = Generator::UNDEFINED, - string $namespace = Generator::UNDEFINED, - string $prefix = Generator::UNDEFINED, + ?string $name = null, + ?string $namespace = null, + ?string $prefix = null, ?bool $attribute = null, ?bool $wrapped = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'name' => $name, - 'namespace' => $namespace, - 'prefix' => $prefix, + 'name' => $name ?? Generator::UNDEFINED, + 'namespace' => $namespace ?? Generator::UNDEFINED, + 'prefix' => $prefix ?? Generator::UNDEFINED, 'attribute' => $attribute ?? Generator::UNDEFINED, 'wrapped' => $wrapped ?? Generator::UNDEFINED, 'x' => $x ?? Generator::UNDEFINED, diff --git a/src/Attributes/XmlContent.php b/src/Attributes/XmlContent.php index 0cf9441bf..f75855fe9 100644 --- a/src/Attributes/XmlContent.php +++ b/src/Attributes/XmlContent.php @@ -12,23 +12,64 @@ class XmlContent extends \OpenApi\Annotations\XmlContent { public function __construct( - string $ref = Generator::UNDEFINED, + object $examples = null, + // schema + string|object|null $ref = null, + ?string $schema = null, + ?string $title = null, + ?string $description = null, + ?array $required = null, + ?array $properties = null, + ?string $type = null, + ?string $format = null, + ?Items $items = null, + ?string $collectionFormat = null, + $default = null, + ?string $pattern = null, + ?array $enum = null, + ?Discriminator $discriminator = null, + ?bool $readOnly = null, + ?bool $writeOnly = null, + ?Xml $xml = null, + ?ExternalDocumentation $externalDocs = null, + $example = null, + ?bool $nullable = null, + ?bool $deprecated = null, ?array $allOf = null, ?array $anyOf = null, ?array $oneOf = null, - string $type = Generator::UNDEFINED, - ?Items $items = null, + // annotation ?array $x = null, ?array $attachables = null ) { parent::__construct([ - 'ref' => $ref, - 'allOf' => $allOf ?? Generator::UNDEFINED, - 'anyOf' => $anyOf ?? Generator::UNDEFINED, - 'oneOf' => $oneOf ?? Generator::UNDEFINED, - 'type' => $type, - 'x' => $x ?? Generator::UNDEFINED, - 'value' => $this->combine($items, $attachables), - ]); + 'examples' => $examples ?? Generator::UNDEFINED, + // schema + 'ref' => $ref ?? Generator::UNDEFINED, + 'schema' => $schema ?? Generator::UNDEFINED, + 'title' => $title ?? Generator::UNDEFINED, + 'description' => $description ?? Generator::UNDEFINED, + 'required' => $required ?? Generator::UNDEFINED, + 'properties' => $properties ?? Generator::UNDEFINED, + 'type' => $type ?? Generator::UNDEFINED, + 'format' => $format ?? Generator::UNDEFINED, + 'collectionFormat' => $collectionFormat ?? Generator::UNDEFINED, + 'default' => $default ?? Generator::UNDEFINED, + 'pattern' => $pattern ?? Generator::UNDEFINED, + 'enum' => $enum ?? Generator::UNDEFINED, + 'readOnly' => $readOnly ?? Generator::UNDEFINED, + 'writeOnly' => $writeOnly ?? Generator::UNDEFINED, + 'xml' => $xml ?? Generator::UNDEFINED, + 'example' => $example ?? Generator::UNDEFINED, + 'nullable' => $nullable ?? Generator::UNDEFINED, + 'deprecated' => $deprecated ?? Generator::UNDEFINED, + 'allOf' => $allOf ?? Generator::UNDEFINED, + 'anyOf' => $anyOf ?? Generator::UNDEFINED, + 'oneOf' => $oneOf ?? Generator::UNDEFINED, + 'x' => $x ?? Generator::UNDEFINED, + // annotation + 'attachables' => $attachables ?? Generator::UNDEFINED, + 'value' => $this->combine($items, $discriminator, $externalDocs, $attachables), + ]); } } diff --git a/tests/Analysers/ReflectionAnalyserTest.php b/tests/Analysers/ReflectionAnalyserTest.php index 91f3b7ed5..e05eae14a 100644 --- a/tests/Analysers/ReflectionAnalyserTest.php +++ b/tests/Analysers/ReflectionAnalyserTest.php @@ -128,7 +128,7 @@ public function testApiAttributesBasic(AnalyserInterface $analyser) // check CustomAttachable is only attached to @OA\Get /** @var Get[] $gets */ $gets = $analysis->getAnnotationsOfType(Get::class, true); - $this->assertCount(1, $gets); + $this->assertCount(2, $gets); $this->assertTrue(is_array($gets[0]->attachables), 'Attachables not set'); $this->assertCount(1, $gets[0]->attachables); diff --git a/tests/Analysers/TokenScannerTest.php b/tests/Analysers/TokenScannerTest.php index f0aee0c05..9022accaf 100644 --- a/tests/Analysers/TokenScannerTest.php +++ b/tests/Analysers/TokenScannerTest.php @@ -35,7 +35,7 @@ public function scanCases() 'uses' => ['OA' => 'OpenApi\\Annotations'], 'interfaces' => [], 'traits' => [], - 'methods' => ['getProduct', 'addProduct'], + 'methods' => ['getProduct', 'addProduct', 'getAll'], 'properties' => [], ], 'OpenApi\\Tests\\Fixtures\\Apis\\DocBlocks\\ProductInterface' => [ diff --git a/tests/Annotations/AttachableTest.php b/tests/Annotations/AttachableTest.php index 64c26141c..5a353a54f 100644 --- a/tests/Annotations/AttachableTest.php +++ b/tests/Annotations/AttachableTest.php @@ -10,6 +10,7 @@ use OpenApi\Annotations\Attachable; use OpenApi\Annotations\Schema; use OpenApi\Generator; +use OpenApi\Tests\Fixtures\Annotations\CustomAttachable; use OpenApi\Tests\OpenApiTestCase; class AttachableTest extends OpenApiTestCase @@ -28,8 +29,8 @@ public function testCustomAttachableImplementationsAreAttached() { $analysis = new Analysis([], $this->getContext()); (new Generator()) - ->addAlias('oaf', 'OpenApi\\Tests\\Annotations') - ->addNamespace('OpenApi\\Tests\\Annotations\\') + ->addAlias('oaf', 'OpenApi\Tests\Fixtures\Annotations') + ->addNamespace('OpenApi\Tests\Fixtures\Annotations\\') ->generate($this->fixtures(['UsingCustomAttachables.php']), $analysis); $schemas = $analysis->getAnnotationsOfType(Schema::class, true); diff --git a/tests/Annotations/CustomAttachable.php b/tests/Fixtures/Annotations/CustomAttachable.php similarity index 91% rename from tests/Annotations/CustomAttachable.php rename to tests/Fixtures/Annotations/CustomAttachable.php index e9769f1ba..da2ab7c8c 100644 --- a/tests/Annotations/CustomAttachable.php +++ b/tests/Fixtures/Annotations/CustomAttachable.php @@ -1,6 +1,6 @@