diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a3cd8f..5ac6294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Yii Framework 2 apidoc extension Change Log - Bug #313: Fix deprecation error `Method deprecated, use ::getParameters()` (mspirkov) - Bug #317: Fix `trim` deprecation errors `Passing null to parameter #1 ($string) of type string is deprecated` (mspirkov) - Bug #318: Fix deprecation errors `mb_convert_encoding(): Handling HTML entities via mbstring is deprecated` (mspirkov) +- Enh #319: Determining types by type hints for properties, methods and params (mspirkov) 3.0.7 February 13, 2025 diff --git a/models/BaseDoc.php b/models/BaseDoc.php index 91c838e..216b9fb 100644 --- a/models/BaseDoc.php +++ b/models/BaseDoc.php @@ -25,6 +25,8 @@ */ class BaseDoc extends BaseObject { + private const INHERITDOC_TAG_NAME = 'inheritdoc'; + /** * @var \phpDocumentor\Reflection\Types\Context */ @@ -210,11 +212,16 @@ public function __construct($reflector = null, $context = null, $config = []) if (in_array($this->shortDescription, ['{@inheritdoc}', '{@inheritDoc}', '@inheritdoc', '@inheritDoc'], true)) { // Mock up parsing of '{@inheritdoc}' (in brackets) tag, which is not yet supported at "phpdocumentor/reflection-docblock" 2.x // todo consider removal in case of "phpdocumentor/reflection-docblock" upgrade - $this->tags[] = new Generic('inheritdoc'); + $this->tags[] = new Generic(self::INHERITDOC_TAG_NAME); $this->shortDescription = ''; } } + protected function isInheritdocTag(Tag $tag): bool + { + return $tag instanceof Generic && $tag->getName() === self::INHERITDOC_TAG_NAME; + } + /** * Converts inline links to unified format. * @see ApiMarkdownTrait::parseApiLinks() diff --git a/models/FunctionDoc.php b/models/FunctionDoc.php index 70765f5..4cba57d 100644 --- a/models/FunctionDoc.php +++ b/models/FunctionDoc.php @@ -7,6 +7,7 @@ namespace yii\apidoc\models; +use phpDocumentor\Reflection\DocBlock\Tags\Generic; use phpDocumentor\Reflection\DocBlock\Tags\Param; use phpDocumentor\Reflection\DocBlock\Tags\Return_; use phpDocumentor\Reflection\DocBlock\Tags\Throws; @@ -27,7 +28,13 @@ class FunctionDoc extends BaseDoc public $params = []; public $exceptions = []; public $return; + /** + * @var string|null + */ public $returnType; + /** + * @var string[]|null + */ public $returnTypes; public $isReturnByReference; @@ -52,6 +59,8 @@ public function __construct($reflector = null, $context = null, $config = []) $this->params[$arg->name] = $arg; } + $hasInheritdoc = false; + foreach ($this->tags as $i => $tag) { if ($tag instanceof Throws) { $this->exceptions[implode($this->splitTypes($tag->getType()))] = $tag->getDescription(); @@ -75,7 +84,14 @@ public function __construct($reflector = null, $context = null, $config = []) $this->returnTypes = $this->splitTypes($tag->getType()); $this->return = StringHelper::mb_ucfirst($tag->getDescription()); unset($this->tags[$i]); + } elseif ($this->isInheritdocTag($tag)) { + $hasInheritdoc = true; } } + + if (!$hasInheritdoc && $this->returnType === null) { + $this->returnType = (string) $reflector->getReturnType(); + $this->returnTypes = [$this->returnType]; + } } } diff --git a/models/ParamDoc.php b/models/ParamDoc.php index 7316d13..a101029 100644 --- a/models/ParamDoc.php +++ b/models/ParamDoc.php @@ -25,7 +25,13 @@ class ParamDoc extends BaseObject public $isPassedByReference; // will be set by creating class public $description; + /** + * @var string|null + */ public $type; + /** + * @var string[]|null + */ public $types; public $sourceFile; @@ -42,6 +48,8 @@ public function __construct($reflector = null, $context = null, $config = []) if ($reflector !== null) { $this->name = $reflector->getName(); $this->typeHint = (string) $reflector->getType(); + $this->type = $this->typeHint; + $this->types = [$this->type]; $this->defaultValue = $reflector->getDefault(); $this->isOptional = $this->defaultValue !== null; $this->isPassedByReference = $reflector->isByReference(); diff --git a/models/PropertyDoc.php b/models/PropertyDoc.php index ccf629b..c082875 100644 --- a/models/PropertyDoc.php +++ b/models/PropertyDoc.php @@ -70,17 +70,17 @@ public function __construct($reflector = null, $context = null, $config = []) $hasInheritdoc = false; foreach ($this->tags as $tag) { - if ($tag->getName() === 'inheritdoc') { - $hasInheritdoc = true; - } if ($tag instanceof Var_) { $this->type = (string) $tag->getType(); $this->types = $this->splitTypes($tag->getType()); $this->description = StringHelper::mb_ucfirst($tag->getDescription()); $this->shortDescription = BaseDoc::extractFirstSentence($this->description); + } elseif ($this->isInheritdocTag($tag)) { + $hasInheritdoc = true; } } + if (empty($this->shortDescription) && $context !== null && !$hasInheritdoc) { $context->warnings[] = [ 'line' => $this->startLine, @@ -88,5 +88,10 @@ public function __construct($reflector = null, $context = null, $config = []) 'message' => "No short description for element '{$this->name}'", ]; } + + if (!$hasInheritdoc && $this->type === null) { + $this->type = (string) $reflector->getType(); + $this->types = [$this->type]; + } } } diff --git a/templates/html/ApiRenderer.php b/templates/html/ApiRenderer.php index abe93fd..00513fb 100644 --- a/templates/html/ApiRenderer.php +++ b/templates/html/ApiRenderer.php @@ -292,7 +292,7 @@ public function renderMethodSignature($method, $context = null) return '' . implode(' ', $definition) . ' ' . '' . ($method->isReturnByReference ? '&' : '') - . ($method->returnType === null ? 'void' : $this->createTypeLink($method->returnTypes, $context)) . ' ' + . $this->createTypeLink($method->returnTypes, $context) . ' ' . '' . $this->createSubjectLink($method, $method->name) . '' . str_replace(' ', ' ', ' ( ' . implode(', ', $params) . ' )'); } diff --git a/tests/commands/__snapshots__/ApiControllerTest__testGenerateBootstrap__1.html b/tests/commands/__snapshots__/ApiControllerTest__testGenerateBootstrap__1.html index 6e963d9..febfd20 100644 --- a/tests/commands/__snapshots__/ApiControllerTest__testGenerateBootstrap__1.html +++ b/tests/commands/__snapshots__/ApiControllerTest__testGenerateBootstrap__1.html @@ -120,6 +120,18 @@
+
| +public self setBirthDate ( integer $birthDate ) | ||
| $birthDate | +integer | ++ | +
+ + Source code + +
+
+ public function setBirthDate(int $birthDate): self
+{
+ $this->birthDate = $birthDate;
+ return $this;
+}
+
+
+ +
| +public mixed methodWithoutDocAndTypeHints ( ) |
+ + Source code + +
+
+ public function methodWithoutDocAndTypeHints()
+{
+ return '';
+}
+ Defined in: + yiiunit\apidoc\data\api\animal\Animal::setBirthDate()
+ ++
| +public self setBirthDate ( integer $birthDate ) | ||
| $birthDate | +integer | ++ | +
+ + Source code + +
+
+ public function setBirthDate(int $birthDate): self
+{
+ $this->birthDate = $birthDate;
+ return $this;
+}
+ Defined in: + yiiunit\apidoc\data\api\animal\Animal::setBirthDate()
+ ++
| +public self setBirthDate ( integer $birthDate ) | ||
| $birthDate | +integer | ++ | +
+ + Source code + +
+
+ public function setBirthDate(int $birthDate): self
+{
+ $this->birthDate = $birthDate;
+ return $this;
+}