From 71254d186e15f88cc7e2ac8982a7ff5b9d12a680 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Thu, 13 Feb 2020 08:49:38 +1100 Subject: [PATCH 1/5] add onlyVar property that only uses var annotation Also fix the invalid property type annotations (int, should be integer) --- tests/AugmentPropertiesTest.php | 21 +++++++++++++++------ tests/Fixtures/TypedProperties.php | 12 +++++++++--- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/tests/AugmentPropertiesTest.php b/tests/AugmentPropertiesTest.php index 093b312df..0fe341678 100644 --- a/tests/AugmentPropertiesTest.php +++ b/tests/AugmentPropertiesTest.php @@ -143,6 +143,7 @@ public function testTypedProperties() $annotationTrumpsAll, $undefined, $onlyAnnotated, + $onlyVar, $staticUndefined, $staticString, $staticNullableString, @@ -182,11 +183,11 @@ public function testTypedProperties() ]); $this->assertName($annotationTrumpsNative, [ self::KEY_PROPERTY => UNDEFINED, - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', ]); $this->assertName($annotationTrumpsAll, [ self::KEY_PROPERTY => UNDEFINED, - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', ]); $this->assertName($undefined, [ self::KEY_PROPERTY => UNDEFINED, @@ -194,7 +195,11 @@ public function testTypedProperties() ]); $this->assertName($onlyAnnotated, [ self::KEY_PROPERTY => UNDEFINED, - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', + ]); + $this->assertName($onlyVar, [ + self::KEY_PROPERTY => UNDEFINED, + self::KEY_TYPE => UNDEFINED, ]); $this->assertName($staticUndefined, [ self::KEY_PROPERTY => UNDEFINED, @@ -245,11 +250,11 @@ public function testTypedProperties() ]); $this->assertName($annotationTrumpsNative, [ self::KEY_PROPERTY => 'annotationTrumpsNative', - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', ]); $this->assertName($annotationTrumpsAll, [ self::KEY_PROPERTY => 'annotationTrumpsAll', - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', ]); $this->assertName($undefined, [ self::KEY_PROPERTY => 'undefined', @@ -257,7 +262,11 @@ public function testTypedProperties() ]); $this->assertName($onlyAnnotated, [ self::KEY_PROPERTY => 'onlyAnnotated', - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', + ]); + $this->assertName($onlyVar, [ + self::KEY_PROPERTY => 'onlyVar', + self::KEY_TYPE => 'integer', ]); $this->assertName($staticUndefined, [ self::KEY_PROPERTY => 'staticUndefined', diff --git a/tests/Fixtures/TypedProperties.php b/tests/Fixtures/TypedProperties.php index 2651f2ce7..de7d5fc57 100644 --- a/tests/Fixtures/TypedProperties.php +++ b/tests/Fixtures/TypedProperties.php @@ -55,7 +55,7 @@ class TypedProperties /** * @var int * @OA\Property( - * type="int", + * type="integer", * ) */ public string $annotationTrumpsNative; @@ -63,7 +63,7 @@ class TypedProperties /** * @var string * @OA\Property( - * type="int", + * type="integer", * ) */ public string $annotationTrumpsAll; @@ -75,11 +75,17 @@ class TypedProperties /** * @OA\Property( - * type="int", + * type="integer", * ) */ public $onlyAnnotated; + /** + * @var int + * @OA\Property() + */ + public $onlyVar; + /** * @OA\Property() */ From a1f10453abfc357e9b2b65916decc8425408345c Mon Sep 17 00:00:00 2001 From: Chris Young Date: Thu, 13 Feb 2020 09:32:05 +1100 Subject: [PATCH 2/5] support type conversion for typed properties --- src/Processors/AugmentProperties.php | 34 ++++++++++++++++++++++++---- tests/AugmentPropertiesTest.php | 14 ++++++++---- tests/Fixtures/TypedProperties.php | 6 ++--- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/Processors/AugmentProperties.php b/src/Processors/AugmentProperties.php index 1c65bdb51..f50d702ba 100644 --- a/src/Processors/AugmentProperties.php +++ b/src/Processors/AugmentProperties.php @@ -59,14 +59,40 @@ public function __invoke(Analysis $analysis) if ($property->property === UNDEFINED) { $property->property = $context->property; } - if ($property->type === UNDEFINED) { - $property->type = $context->type; - } if ($property->ref !== UNDEFINED) { continue; } $comment = str_replace("\r\n", "\n", $context->comment); - if (preg_match('/@var\s+(?[^\s]+)([ \t])?(?.+)?$/im', $comment, $varMatches)) { + if ($property->type === UNDEFINED && $context->type !== UNDEFINED) { + $type = strtolower($context->type); + if (self::$types[$type] ?? false) { + $type = static::$types[strtolower($type)]; + if (is_array($type)) { + if ($property->format === UNDEFINED) { + $property->format = $type[1]; + } + $type = $type[0]; + } + $property->type = $type; + } else { + $key = strtolower($context->fullyQualifiedName($type)); + + if ($property->ref === UNDEFINED && array_key_exists($key, $refs)) { + if ($property->nullable) { + $property->oneOf = [ + new Schema([ + '_context' => $property->_context, + 'ref' => $refs[$key] + ]) + ]; + $property->nullable = true; + } else { + $property->ref = $refs[$key]; + } + continue; + } + } + } else if (preg_match('/@var\s+(?[^\s]+)([ \t])?(?.+)?$/im', $comment, $varMatches)) { if ($property->type === UNDEFINED) { preg_match('/^([^\[]+)(.*$)/', trim($varMatches['type']), $typeMatches); $isNullable = $this->isNullable($typeMatches[1]); diff --git a/tests/AugmentPropertiesTest.php b/tests/AugmentPropertiesTest.php index 0fe341678..65d08e98b 100644 --- a/tests/AugmentPropertiesTest.php +++ b/tests/AugmentPropertiesTest.php @@ -20,8 +20,10 @@ class AugmentPropertiesTest extends OpenApiTestCase { const KEY_PROPERTY = 'property'; + const KEY_REFERENCE = 'ref'; const KEY_EXAMPLE = 'example'; const KEY_DESCRIPTION = 'description'; + const KEY_FORMAT = 'format'; const KEY_TYPE = 'type'; public function testAugmentProperties() @@ -222,7 +224,7 @@ public function testTypedProperties() ]); $this->assertName($intType, [ self::KEY_PROPERTY => 'intType', - self::KEY_TYPE => 'int', + self::KEY_TYPE => 'integer', ]); $this->assertName($nullableString, [ self::KEY_PROPERTY => 'nullableString', @@ -230,19 +232,21 @@ public function testTypedProperties() ]); $this->assertName($dateTime, [ self::KEY_PROPERTY => 'dateTime', - self::KEY_TYPE => 'DateTime', + self::KEY_TYPE => 'string', + self::KEY_FORMAT => 'date-time', ]); $this->assertName($qualified, [ self::KEY_PROPERTY => 'qualified', - self::KEY_TYPE => 'DateTimeInterface', + self::KEY_TYPE => 'string', + self::KEY_FORMAT => 'date-time', ]); $this->assertName($namespace, [ self::KEY_PROPERTY => 'namespace', - self::KEY_TYPE => 'Foo', + self::KEY_REFERENCE => '#/components/schemas/TypedProperties', ]); $this->assertName($importedNamespace, [ self::KEY_PROPERTY => 'importedNamespace', - self::KEY_TYPE => 'Foo', + self::KEY_REFERENCE => '#/components/schemas/TypedProperties', ]); $this->assertName($nativeTrumpsVar, [ self::KEY_PROPERTY => 'nativeTrumpsVar', diff --git a/tests/Fixtures/TypedProperties.php b/tests/Fixtures/TypedProperties.php index de7d5fc57..6fece05d3 100644 --- a/tests/Fixtures/TypedProperties.php +++ b/tests/Fixtures/TypedProperties.php @@ -1,7 +1,7 @@ Date: Thu, 13 Feb 2020 09:32:25 +1100 Subject: [PATCH 3/5] support nullable property for typed properties --- src/Processors/AugmentProperties.php | 1 + src/StaticAnalyser.php | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Processors/AugmentProperties.php b/src/Processors/AugmentProperties.php index f50d702ba..1e3379475 100644 --- a/src/Processors/AugmentProperties.php +++ b/src/Processors/AugmentProperties.php @@ -64,6 +64,7 @@ public function __invoke(Analysis $analysis) } $comment = str_replace("\r\n", "\n", $context->comment); if ($property->type === UNDEFINED && $context->type !== UNDEFINED) { + $property->nullable = $context->nullable; $type = strtolower($context->type); if (self::$types[$type] ?? false) { $type = static::$types[strtolower($type)]; diff --git a/src/StaticAnalyser.php b/src/StaticAnalyser.php index c15b3a620..f5f791a06 100644 --- a/src/StaticAnalyser.php +++ b/src/StaticAnalyser.php @@ -182,12 +182,13 @@ protected function fromTokens($tokens, $parseContext) } if (in_array($token[0], [T_PRIVATE, T_PROTECTED, T_PUBLIC, T_VAR])) { // Scope - [$type, $token] = $this->extractTypeAndNextToken($tokens, $parseContext); + [$type, $nullable, $token] = $this->extractTypeAndNextToken($tokens, $parseContext); if ($token[0] === T_VARIABLE) { // instance property $propertyContext = new Context( [ 'property' => substr($token[1], 1), 'type' => $type, + 'nullable' => $nullable, 'line' => $line, ], $schemaContext @@ -393,6 +394,7 @@ private function parseUseStatement(&$tokens, &$token, $parseContext) private function extractTypeAndNextToken(array &$tokens, Context $parseContext): array { $type = UNDEFINED; + $nullable = false; $token = $this->nextToken($tokens, $parseContext); if ($token[0] === T_STATIC) { @@ -400,6 +402,7 @@ private function extractTypeAndNextToken(array &$tokens, Context $parseContext): } if ($token === '?') { // nullable type + $nullable = true; $token = $this->nextToken($tokens, $parseContext); } @@ -411,6 +414,6 @@ private function extractTypeAndNextToken(array &$tokens, Context $parseContext): $token = $this->nextToken($tokens, $parseContext); } - return [$type, $token]; + return [$type, $nullable, $token]; } } From 26f5d0260e9c2a2d0aa03d2ad4aa61770c5a2e06 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Thu, 13 Feb 2020 09:57:45 +1100 Subject: [PATCH 4/5] only set nullable to true, not false --- src/Processors/AugmentProperties.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Processors/AugmentProperties.php b/src/Processors/AugmentProperties.php index 1e3379475..e43662e6d 100644 --- a/src/Processors/AugmentProperties.php +++ b/src/Processors/AugmentProperties.php @@ -64,7 +64,9 @@ public function __invoke(Analysis $analysis) } $comment = str_replace("\r\n", "\n", $context->comment); if ($property->type === UNDEFINED && $context->type !== UNDEFINED) { - $property->nullable = $context->nullable; + if ($context->nullable === true) { + $property->nullable = true; + } $type = strtolower($context->type); if (self::$types[$type] ?? false) { $type = static::$types[strtolower($type)]; From 72abd735903eb98eddc8731f4d065cdbeaaed214 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Thu, 13 Feb 2020 10:33:05 +1100 Subject: [PATCH 5/5] fix nullable condition --- src/Processors/AugmentProperties.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Processors/AugmentProperties.php b/src/Processors/AugmentProperties.php index e43662e6d..b320eecce 100644 --- a/src/Processors/AugmentProperties.php +++ b/src/Processors/AugmentProperties.php @@ -81,7 +81,7 @@ public function __invoke(Analysis $analysis) $key = strtolower($context->fullyQualifiedName($type)); if ($property->ref === UNDEFINED && array_key_exists($key, $refs)) { - if ($property->nullable) { + if ($property->nullable === true) { $property->oneOf = [ new Schema([ '_context' => $property->_context,