From 2a8b28d42a06ed60d87f786b5a95da5bea21a741 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Thu, 7 Nov 2024 15:23:34 +0100 Subject: [PATCH] add support for phpstan/phpdoc-parser 2 --- composer-require-checker.json | 3 +- composer.json | 2 +- composer.lock | 2 +- phpstan.neon | 28 ++++++++++++++++ psalm.xml | 7 ++++ .../Tags/Factory/AbstractPHPStanFactory.php | 33 +++++++++++++------ .../Tags/Factory/TagFactoryTestCase.php | 17 +++++++--- 7 files changed, 75 insertions(+), 17 deletions(-) diff --git a/composer-require-checker.json b/composer-require-checker.json index 19eee4ff..b81a5784 100644 --- a/composer-require-checker.json +++ b/composer-require-checker.json @@ -2,7 +2,8 @@ "symbol-whitelist" : [ "null", "true", "false", "static", "self", "parent", - "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "XSLTProcessor" + "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", "XSLTProcessor", + "PHPStan\\PhpDocParser\\ParserConfig" ], "php-core-extensions" : [ "Core", diff --git a/composer.json b/composer.json index 9cd35ed1..8105049b 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "webmozart/assert": "^1.9.1", "phpdocumentor/reflection-common": "^2.2", "ext-filter": "*", - "phpstan/phpdoc-parser": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "doctrine/deprecations": "^1.1" }, "require-dev": { diff --git a/composer.lock b/composer.lock index dd6fdbd7..f01fe622 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8d0008447edbcdb6139a9c64654e5931", + "content-hash": "7980f2ec05f5b526fd14283b3ff34b2a", "packages": [ { "name": "doctrine/deprecations", diff --git a/phpstan.neon b/phpstan.neon index c2365775..9ca87a24 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -3,5 +3,33 @@ parameters: ignoreErrors: - '#Method phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::createTag\(\) should return phpDocumentor\\Reflection\\DocBlock\\Tag but returns mixed#' - '#Offset 2 on array\{string, 28, int\} on left side of \?\? always exists and is not nullable\.#' + - + message: "#^Parameter \\#1 \\$constExprParser of class PHPStan\\\\PhpDocParser\\\\Parser\\\\TypeParser constructor expects PHPStan\\\\PhpDocParser\\\\Parser\\\\ConstExprParser\\|null, PHPStan\\\\PhpDocParser\\\\ParserConfig given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php + - + message: "#^Parameter \\#1 \\$parseDoctrineAnnotations of class PHPStan\\\\PhpDocParser\\\\Lexer\\\\Lexer constructor expects bool, PHPStan\\\\PhpDocParser\\\\ParserConfig given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php + - + message: "#^Parameter \\#1 \\$typeParser of class PHPStan\\\\PhpDocParser\\\\Parser\\\\PhpDocParser constructor expects PHPStan\\\\PhpDocParser\\\\Parser\\\\TypeParser, PHPStan\\\\PhpDocParser\\\\ParserConfig given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php + - + message: "#^Parameter \\#1 \\$unescapeStrings of class PHPStan\\\\PhpDocParser\\\\Parser\\\\ConstExprParser constructor expects bool, PHPStan\\\\PhpDocParser\\\\ParserConfig given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php + - + message: "#^Parameter \\#2 \\$constantExprParser of class PHPStan\\\\PhpDocParser\\\\Parser\\\\PhpDocParser constructor expects PHPStan\\\\PhpDocParser\\\\Parser\\\\ConstExprParser, PHPStan\\\\PhpDocParser\\\\Parser\\\\TypeParser given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php + - + message: "#^Parameter \\#2 \\$quoteAwareConstExprString of class PHPStan\\\\PhpDocParser\\\\Parser\\\\TypeParser constructor expects bool, PHPStan\\\\PhpDocParser\\\\Parser\\\\ConstExprParser given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php + - + message: "#^Parameter \\#3 \\$requireWhitespaceBeforeDescription of class PHPStan\\\\PhpDocParser\\\\Parser\\\\PhpDocParser constructor expects bool, PHPStan\\\\PhpDocParser\\\\Parser\\\\ConstExprParser given\\.$#" + count: 1 + path: src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php paths: - src diff --git a/psalm.xml b/psalm.xml index 6d8fd6b9..30c08adb 100644 --- a/psalm.xml +++ b/psalm.xml @@ -68,5 +68,12 @@ + + + + + + + diff --git a/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php index 240e79d9..8d3370b8 100644 --- a/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php +++ b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php @@ -21,8 +21,10 @@ use PHPStan\PhpDocParser\Parser\PhpDocParser; use PHPStan\PhpDocParser\Parser\TokenIterator; use PHPStan\PhpDocParser\Parser\TypeParser; +use PHPStan\PhpDocParser\ParserConfig; use RuntimeException; +use function class_exists; use function ltrim; use function property_exists; use function rtrim; @@ -44,16 +46,27 @@ class AbstractPHPStanFactory implements Factory public function __construct(PHPStanFactory ...$factories) { - $this->lexer = new Lexer(true); - $constParser = new ConstExprParser(true, true, ['lines' => true, 'indexes' => true]); - $this->parser = new PhpDocParser( - new TypeParser($constParser, true, ['lines' => true, 'indexes' => true]), - $constParser, - true, - true, - ['lines' => true, 'indexes' => true], - true - ); + if (class_exists(ParserConfig::class)) { + $config = new ParserConfig(['indexes' => true, 'lines' => true]); + $this->lexer = new Lexer($config); + $constParser = new ConstExprParser($config); + $this->parser = new PhpDocParser( + $config, + new TypeParser($config, $constParser), + $constParser + ); + } else { + $this->lexer = new Lexer(true); + $constParser = new ConstExprParser(true, true, ['lines' => true, 'indexes' => true]); + $this->parser = new PhpDocParser( + new TypeParser($constParser, true, ['lines' => true, 'indexes' => true]), + $constParser, + true, + true, + ['lines' => true, 'indexes' => true], + true + ); + } $this->factories = $factories; } diff --git a/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php index d97c7f1d..429254d4 100644 --- a/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php +++ b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php @@ -24,19 +24,28 @@ use PHPStan\PhpDocParser\Parser\PhpDocParser; use PHPStan\PhpDocParser\Parser\TokenIterator; use PHPStan\PhpDocParser\Parser\TypeParser; +use PHPStan\PhpDocParser\ParserConfig; use PHPUnit\Framework\TestCase; +use function class_exists; use function property_exists; abstract class TagFactoryTestCase extends TestCase { public function parseTag(string $tag): PhpDocTagNode { - $lexer = new Lexer(); - $tokens = $lexer->tokenize($tag); - $constParser = new ConstExprParser(); + if (class_exists(ParserConfig::class)) { + $config = new ParserConfig([]); + $lexer = new Lexer($config); + $constParser = new ConstExprParser($config); + $phpDocParser = new PhpDocParser($config, new TypeParser($config, $constParser), $constParser); + } else { + $lexer = new Lexer(); + $constParser = new ConstExprParser(); + $phpDocParser = new PhpDocParser(new TypeParser($constParser), $constParser); + } - $tagNode = (new PhpDocParser(new TypeParser($constParser), $constParser))->parseTag(new TokenIterator($tokens)); + $tagNode = ($phpDocParser)->parseTag(new TokenIterator($lexer->tokenize($tag))); if (property_exists($tagNode->value, 'description') === true) { $tagNode->value->setAttribute('description', $tagNode->value->description); }