diff --git a/Annotations/AnnotationGenerator.php b/Annotations/AnnotationGenerator.php index f4e8f89..4e045e4 100644 --- a/Annotations/AnnotationGenerator.php +++ b/Annotations/AnnotationGenerator.php @@ -11,6 +11,9 @@ namespace Piwik\Plugins\OpenApiDocs\Annotations; +use Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\DocBlock\Tags\Param; +use Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\DocBlock\Tags\TagWithType; +use Matomo\Dependencies\OpenApiDocs\phpDocumentor\Reflection\DocBlockFactory; use Piwik\API\DocumentationGenerator; use Piwik\API\NoDefaultValue; use Piwik\API\Proxy; @@ -24,11 +27,6 @@ use Piwik\UrlHelper; use Piwik\Validators\BaseValidator; use Piwik\Validators\NotEmpty; -use PHPStan\PhpDocParser\Lexer\Lexer; -use PHPStan\PhpDocParser\Parser\PhpDocParser; -use PHPStan\PhpDocParser\Parser\TypeParser; -use PHPStan\PhpDocParser\Parser\ConstExprParser; -use PHPStan\PhpDocParser\Parser\TokenIterator; class AnnotationGenerator { @@ -282,21 +280,21 @@ protected function buildAnnotationForMethod(array $rules, string $pluginName, \R */ public function getParamInfoFromDocBlock(string $docBlock): array { - $lexer = new Lexer(); - $tokens = $lexer->tokenize($docBlock); - $expressionParser = new ConstExprParser(); - $parser = new PhpDocParser(new TypeParser($expressionParser), $expressionParser); - $node = $parser->parse(new TokenIterator($tokens)); + $factory = DocBlockFactory::createInstance(); + $docBlockObject = $factory->create($docBlock); $params = []; - foreach ($node->getParamTagValues() as $param) { - $name = ltrim($param->parameterName, '$'); + foreach ($docBlockObject->getTagsByName('param') as $param) { + if (!($param instanceof Param)) { + continue; + } + $name = ltrim($param->getVariableName(), '$'); $params[$name] = [ - 'type' => (string)$param->type, + 'type' => (string) $param->getType(), // Normalise the description. E.g. remove linebreaks and indentation - 'description' => trim(preg_replace(['/^\h+/m', '/\R+/u',], ['', ' '], $param->description)), - 'byRef' => $param->isReference, - 'variadic' => $param->isVariadic, + 'description' => trim(preg_replace(['/^\h+/m', '/\R+/u',], ['', ' '], (string) $param->getDescription())), + 'byRef' => $param->isReference(), + 'variadic' => $param->isVariadic(), ]; } return $params; @@ -313,27 +311,24 @@ public function getParamInfoFromDocBlock(string $docBlock): array */ public function getResponseInfoFromDocBlock(string $docBlock): array { - $lexer = new Lexer(); - $tokens = $lexer->tokenize($docBlock); - $expressionParser = new ConstExprParser(); - $parser = new PhpDocParser(new TypeParser($expressionParser), $expressionParser); - $node = $parser->parse(new TokenIterator($tokens)); + $factory = DocBlockFactory::createInstance(); + $docBlockObject = $factory->create($docBlock); $responseInfo = ['type' => null]; - $returnTags = $node->getReturnTagValues(); - if (empty($returnTags)) { + $returnTags = $docBlockObject->getTagsByName('return'); + if (empty($returnTags) || !($returnTags[0] instanceof TagWithType)) { return $responseInfo; } $returnTag = $returnTags[0]; - $tagValue = strval($returnTag->type); + $tagValue = strval($returnTag->getType()); $responseInfo['type'] = $this->getOpenApiTypeFromPhpType($tagValue); if ($responseInfo['type'] === 'string' && !empty($tagValue) && strtolower($tagValue) !== 'string') { $responseInfo['type'] = ''; $responseInfo['description'] = 'Response of unknown type'; } - if (!empty($returnTag->description)) { - $responseInfo['description'] = $returnTag->description; + if (!empty($returnTag->getDescription())) { + $responseInfo['description'] = $returnTag->getDescription(); } return $responseInfo; diff --git a/Commands/GenerateAnnotations.php b/Commands/GenerateAnnotations.php index 1c147df..d5faa45 100644 --- a/Commands/GenerateAnnotations.php +++ b/Commands/GenerateAnnotations.php @@ -72,11 +72,6 @@ protected function doExecute(): int $input = $this->getInput(); $output = $this->getOutput(); - if (!class_exists('PHPStan\PhpDocParser\Parser\PhpDocParser')) { - $output->writeln("This command requires phpstan/phpdoc-parser. It should be available while running Matomo in development mode."); - return self::FAILURE; - } - $plugin = $input->getOption('plugin'); if (empty($plugin)) { throw new \RuntimeException('Please specify a plugin name.'); diff --git a/phpstan-bootstrap.php b/phpstan-bootstrap.php new file mode 100644 index 0000000..bdf349e --- /dev/null +++ b/phpstan-bootstrap.php @@ -0,0 +1,4 @@ + 'array', + 'description' => 'Some test description for the return annotation.', ]; $this->assertEquals($expected, $this->annotationGenerator->getResponseInfoFromDocBlock(self::EXAMPLE_API_METHOD_DOC_BLOCK1)); }