mirror of
https://github.com/rectorphp/rector.git
synced 2025-03-13 20:12:07 +01:00
Updated Rector to commit e0e88ed2dd5573bde7197d40c770f8b8504646cc
e0e88ed2dd
Bump phpdoc-parser 2.0.2 and regenerate preload.php (#6744)
This commit is contained in:
parent
29938fc39c
commit
d3d583f3ac
@ -264,6 +264,7 @@ require_once __DIR__ . '/vendor/nikic/php-parser/lib/PhpParser/compatibility_tok
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Node.php';
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/NodeVisitor.php';
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php';
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/Comment.php';
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/NodeAttributes.php';
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.php';
|
||||
require_once __DIR__ . '/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php';
|
||||
|
@ -19,12 +19,12 @@ final class VersionResolver
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const PACKAGE_VERSION = 'd4af0ff3eb3ac59534a699a2c3c05e317a10b4d4';
|
||||
public const PACKAGE_VERSION = 'e0e88ed2dd5573bde7197d40c770f8b8504646cc';
|
||||
/**
|
||||
* @api
|
||||
* @var string
|
||||
*/
|
||||
public const RELEASE_DATE = '2025-02-19 18:18:05';
|
||||
public const RELEASE_DATE = '2025-02-19 22:27:43';
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
|
@ -11,8 +11,6 @@ use PHPStan\Analyser\NodeScopeResolver;
|
||||
use PHPStan\Analyser\ScopeFactory;
|
||||
use PHPStan\Parser\Parser;
|
||||
use PHPStan\PhpDoc\TypeNodeResolver;
|
||||
use PHPStan\PhpDocParser\Parser\ConstExprParser;
|
||||
use PHPStan\PhpDocParser\Parser\TypeParser;
|
||||
use PHPStan\PhpDocParser\ParserConfig;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\Application\ChangedNodeScopeRefresher;
|
||||
@ -267,9 +265,6 @@ final class LazyContainerFactory
|
||||
$rectorConfig->when(OnlyRuleResolver::class)->needs('$rectors')->giveTagged(RectorInterface::class);
|
||||
$rectorConfig->singleton(FileProcessor::class);
|
||||
$rectorConfig->singleton(PostFileProcessor::class);
|
||||
// phpdoc-parser
|
||||
$rectorConfig->when(TypeParser::class)->needs('$usedAttributes')->give(['lines' => \true, 'indexes' => \true]);
|
||||
$rectorConfig->when(ConstExprParser::class)->needs('$usedAttributes')->give(['lines' => \true, 'indexes' => \true]);
|
||||
$rectorConfig->when(RectorNodeTraverser::class)->needs('$rectors')->giveTagged(RectorInterface::class);
|
||||
$rectorConfig->when(ConfigInitializer::class)->needs('$rectors')->giveTagged(RectorInterface::class);
|
||||
$rectorConfig->when(ClassNameImportSkipper::class)->needs('$classNameImportSkipVoters')->giveTagged(ClassNameImportSkipVoterInterface::class);
|
||||
@ -357,7 +352,8 @@ final class LazyContainerFactory
|
||||
$this->registerTagged($rectorConfig, self::SCOPE_RESOLVER_NODE_VISITOR_CLASSES, ScopeResolverNodeVisitorInterface::class);
|
||||
$this->createPHPStanServices($rectorConfig);
|
||||
$rectorConfig->when(PhpDocNodeMapper::class)->needs('$phpDocNodeVisitors')->giveTagged(BasePhpDocNodeVisitorInterface::class);
|
||||
$rectorConfig->singleton(ParserConfig::class, static fn(Container $container): ParserConfig => new ParserConfig(['lines' => \true, 'indexes' => \true]));
|
||||
// phpdoc-parser
|
||||
$rectorConfig->singleton(ParserConfig::class, static fn(Container $container): ParserConfig => new ParserConfig(['lines' => \true, 'indexes' => \true, 'comments' => \true]));
|
||||
return $rectorConfig;
|
||||
}
|
||||
/**
|
||||
|
2
vendor/autoload.php
vendored
2
vendor/autoload.php
vendored
@ -22,4 +22,4 @@ if (PHP_VERSION_ID < 50600) {
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23::getLoader();
|
||||
return ComposerAutoloaderInit30bd5d3b9b1d532a1d3e11eb20f91e28::getLoader();
|
||||
|
1
vendor/composer/autoload_classmap.php
vendored
1
vendor/composer/autoload_classmap.php
vendored
@ -9,6 +9,7 @@ return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\AbstractNodeVisitor' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/AbstractNodeVisitor.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\Attribute' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/Attribute.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\Comment' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/Comment.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprArrayItemNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprArrayNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprFalseNode' => $vendorDir . '/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php',
|
||||
|
10
vendor/composer/autoload_real.php
vendored
10
vendor/composer/autoload_real.php
vendored
@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23
|
||||
class ComposerAutoloaderInit30bd5d3b9b1d532a1d3e11eb20f91e28
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
@ -22,17 +22,17 @@ class ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23', 'loadClassLoader'), true, true);
|
||||
spl_autoload_register(array('ComposerAutoloaderInit30bd5d3b9b1d532a1d3e11eb20f91e28', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23', 'loadClassLoader'));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit30bd5d3b9b1d532a1d3e11eb20f91e28', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23::getInitializer($loader));
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit30bd5d3b9b1d532a1d3e11eb20f91e28::getInitializer($loader));
|
||||
|
||||
$loader->setClassMapAuthoritative(true);
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23::$files;
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit30bd5d3b9b1d532a1d3e11eb20f91e28::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
9
vendor/composer/autoload_static.php
vendored
9
vendor/composer/autoload_static.php
vendored
@ -4,7 +4,7 @@
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23
|
||||
class ComposerStaticInit30bd5d3b9b1d532a1d3e11eb20f91e28
|
||||
{
|
||||
public static $files = array (
|
||||
'ad155f8f1cf0d418fe49e248db8c661b' => __DIR__ . '/..' . '/react/promise/src/functions_include.php',
|
||||
@ -228,6 +228,7 @@ class ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\AbstractNodeVisitor' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/AbstractNodeVisitor.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\Attribute' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/Attribute.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\Comment' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/Comment.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprArrayItemNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprArrayNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php',
|
||||
'PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprFalseNode' => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php',
|
||||
@ -2864,9 +2865,9 @@ class ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInita9ca9624b9ec3b7183135fb9d7d95d23::$classMap;
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit30bd5d3b9b1d532a1d3e11eb20f91e28::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit30bd5d3b9b1d532a1d3e11eb20f91e28::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit30bd5d3b9b1d532a1d3e11eb20f91e28::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
|
14
vendor/composer/installed.json
vendored
14
vendor/composer/installed.json
vendored
@ -869,17 +869,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phpstan\/phpdoc-parser",
|
||||
"version": "2.0.2",
|
||||
"version_normalized": "2.0.2.0",
|
||||
"version": "2.1.0",
|
||||
"version_normalized": "2.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https:\/\/github.com\/phpstan\/phpdoc-parser.git",
|
||||
"reference": "51087f87dcce2663e1fed4dfd4e56eccd580297e"
|
||||
"reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpdoc-parser\/zipball\/51087f87dcce2663e1fed4dfd4e56eccd580297e",
|
||||
"reference": "51087f87dcce2663e1fed4dfd4e56eccd580297e",
|
||||
"url": "https:\/\/api.github.com\/repos\/phpstan\/phpdoc-parser\/zipball\/9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
|
||||
"reference": "9b30d6fd026b2c132b3985ce6b23bec09ab3aa68",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -896,7 +896,7 @@
|
||||
"phpunit\/phpunit": "^9.6",
|
||||
"symfony\/process": "^5.2"
|
||||
},
|
||||
"time": "2025-02-17T20:25:51+00:00",
|
||||
"time": "2025-02-19T13:28:12+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
@ -913,7 +913,7 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https:\/\/github.com\/phpstan\/phpdoc-parser\/issues",
|
||||
"source": "https:\/\/github.com\/phpstan\/phpdoc-parser\/tree\/2.0.2"
|
||||
"source": "https:\/\/github.com\/phpstan\/phpdoc-parser\/tree\/2.1.0"
|
||||
},
|
||||
"install-path": "..\/phpstan\/phpdoc-parser"
|
||||
},
|
||||
|
2
vendor/composer/installed.php
vendored
2
vendor/composer/installed.php
vendored
File diff suppressed because one or more lines are too long
6
vendor/phpstan/phpdoc-parser/README.md
vendored
6
vendor/phpstan/phpdoc-parser/README.md
vendored
@ -13,9 +13,9 @@ For the complete list of supported PHPDoc features check out PHPStan documentati
|
||||
|
||||
* [PHPDoc Basics](https://phpstan.org/writing-php-code/phpdocs-basics) (list of PHPDoc tags)
|
||||
* [PHPDoc Types](https://phpstan.org/writing-php-code/phpdoc-types) (list of PHPDoc types)
|
||||
* [phpdoc-parser API Reference](https://phpstan.github.io/phpdoc-parser/2.0.x/namespace-PHPStan.PhpDocParser.html) with all the AST node types etc.
|
||||
* [phpdoc-parser API Reference](https://phpstan.github.io/phpdoc-parser/2.1.x/namespace-PHPStan.PhpDocParser.html) with all the AST node types etc.
|
||||
|
||||
This parser also supports parsing [Doctrine Annotations](https://github.com/doctrine/annotations). The AST nodes live in the [PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine namespace](https://phpstan.github.io/phpdoc-parser/2.0.x/namespace-PHPStan.PhpDocParser.Ast.PhpDoc.Doctrine.html).
|
||||
This parser also supports parsing [Doctrine Annotations](https://github.com/doctrine/annotations). The AST nodes live in the [PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine namespace](https://phpstan.github.io/phpdoc-parser/2.1.x/namespace-PHPStan.PhpDocParser.Ast.PhpDoc.Doctrine.html).
|
||||
|
||||
## Installation
|
||||
|
||||
@ -83,7 +83,7 @@ use PHPStan\PhpDocParser\Printer\Printer;
|
||||
|
||||
// basic setup with enabled required lexer attributes
|
||||
|
||||
$config = new ParserConfig(usedAttributes: ['lines' => true, 'indexes' => true]);
|
||||
$config = new ParserConfig(usedAttributes: ['lines' => true, 'indexes' => true, 'comments' => true]);
|
||||
$lexer = new Lexer($config);
|
||||
$constExprParser = new ConstExprParser($config);
|
||||
$typeParser = new TypeParser($config, $constExprParser);
|
||||
|
@ -10,4 +10,5 @@ final class Attribute
|
||||
public const START_INDEX = 'startIndex';
|
||||
public const END_INDEX = 'endIndex';
|
||||
public const ORIGINAL_NODE = 'originalNode';
|
||||
public const COMMENTS = 'comments';
|
||||
}
|
||||
|
22
vendor/phpstan/phpdoc-parser/src/Ast/Comment.php
vendored
Normal file
22
vendor/phpstan/phpdoc-parser/src/Ast/Comment.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare (strict_types=1);
|
||||
namespace PHPStan\PhpDocParser\Ast;
|
||||
|
||||
use function trim;
|
||||
class Comment
|
||||
{
|
||||
public string $text;
|
||||
public int $startLine;
|
||||
public int $startIndex;
|
||||
public function __construct(string $text, int $startLine = -1, int $startIndex = -1)
|
||||
{
|
||||
$this->text = $text;
|
||||
$this->startLine = $startLine;
|
||||
$this->startIndex = $startIndex;
|
||||
}
|
||||
public function getReformattedText() : string
|
||||
{
|
||||
return trim($this->text);
|
||||
}
|
||||
}
|
@ -13,6 +13,10 @@ trait NodeAttributes
|
||||
*/
|
||||
public function setAttribute(string $key, $value) : void
|
||||
{
|
||||
if ($value === null) {
|
||||
unset($this->attributes[$key]);
|
||||
return;
|
||||
}
|
||||
$this->attributes[$key] = $value;
|
||||
}
|
||||
public function hasAttribute(string $key) : bool
|
||||
|
@ -49,7 +49,8 @@ class Lexer
|
||||
public const TOKEN_CLOSE_CURLY_BRACKET = 34;
|
||||
public const TOKEN_NEGATED = 35;
|
||||
public const TOKEN_ARROW = 36;
|
||||
public const TOKEN_LABELS = [self::TOKEN_REFERENCE => '\'&\'', self::TOKEN_UNION => '\'|\'', self::TOKEN_INTERSECTION => '\'&\'', self::TOKEN_NULLABLE => '\'?\'', self::TOKEN_NEGATED => '\'!\'', self::TOKEN_OPEN_PARENTHESES => '\'(\'', self::TOKEN_CLOSE_PARENTHESES => '\')\'', self::TOKEN_OPEN_ANGLE_BRACKET => '\'<\'', self::TOKEN_CLOSE_ANGLE_BRACKET => '\'>\'', self::TOKEN_OPEN_SQUARE_BRACKET => '\'[\'', self::TOKEN_CLOSE_SQUARE_BRACKET => '\']\'', self::TOKEN_OPEN_CURLY_BRACKET => '\'{\'', self::TOKEN_CLOSE_CURLY_BRACKET => '\'}\'', self::TOKEN_COMMA => '\',\'', self::TOKEN_COLON => '\':\'', self::TOKEN_VARIADIC => '\'...\'', self::TOKEN_DOUBLE_COLON => '\'::\'', self::TOKEN_DOUBLE_ARROW => '\'=>\'', self::TOKEN_ARROW => '\'->\'', self::TOKEN_EQUAL => '\'=\'', self::TOKEN_OPEN_PHPDOC => '\'/**\'', self::TOKEN_CLOSE_PHPDOC => '\'*/\'', self::TOKEN_PHPDOC_TAG => 'TOKEN_PHPDOC_TAG', self::TOKEN_DOCTRINE_TAG => 'TOKEN_DOCTRINE_TAG', self::TOKEN_PHPDOC_EOL => 'TOKEN_PHPDOC_EOL', self::TOKEN_FLOAT => 'TOKEN_FLOAT', self::TOKEN_INTEGER => 'TOKEN_INTEGER', self::TOKEN_SINGLE_QUOTED_STRING => 'TOKEN_SINGLE_QUOTED_STRING', self::TOKEN_DOUBLE_QUOTED_STRING => 'TOKEN_DOUBLE_QUOTED_STRING', self::TOKEN_DOCTRINE_ANNOTATION_STRING => 'TOKEN_DOCTRINE_ANNOTATION_STRING', self::TOKEN_IDENTIFIER => 'type', self::TOKEN_THIS_VARIABLE => '\'$this\'', self::TOKEN_VARIABLE => 'variable', self::TOKEN_HORIZONTAL_WS => 'TOKEN_HORIZONTAL_WS', self::TOKEN_OTHER => 'TOKEN_OTHER', self::TOKEN_END => 'TOKEN_END', self::TOKEN_WILDCARD => '*'];
|
||||
public const TOKEN_COMMENT = 37;
|
||||
public const TOKEN_LABELS = [self::TOKEN_REFERENCE => '\'&\'', self::TOKEN_UNION => '\'|\'', self::TOKEN_INTERSECTION => '\'&\'', self::TOKEN_NULLABLE => '\'?\'', self::TOKEN_NEGATED => '\'!\'', self::TOKEN_OPEN_PARENTHESES => '\'(\'', self::TOKEN_CLOSE_PARENTHESES => '\')\'', self::TOKEN_OPEN_ANGLE_BRACKET => '\'<\'', self::TOKEN_CLOSE_ANGLE_BRACKET => '\'>\'', self::TOKEN_OPEN_SQUARE_BRACKET => '\'[\'', self::TOKEN_CLOSE_SQUARE_BRACKET => '\']\'', self::TOKEN_OPEN_CURLY_BRACKET => '\'{\'', self::TOKEN_CLOSE_CURLY_BRACKET => '\'}\'', self::TOKEN_COMMA => '\',\'', self::TOKEN_COMMENT => '\'//\'', self::TOKEN_COLON => '\':\'', self::TOKEN_VARIADIC => '\'...\'', self::TOKEN_DOUBLE_COLON => '\'::\'', self::TOKEN_DOUBLE_ARROW => '\'=>\'', self::TOKEN_ARROW => '\'->\'', self::TOKEN_EQUAL => '\'=\'', self::TOKEN_OPEN_PHPDOC => '\'/**\'', self::TOKEN_CLOSE_PHPDOC => '\'*/\'', self::TOKEN_PHPDOC_TAG => 'TOKEN_PHPDOC_TAG', self::TOKEN_DOCTRINE_TAG => 'TOKEN_DOCTRINE_TAG', self::TOKEN_PHPDOC_EOL => 'TOKEN_PHPDOC_EOL', self::TOKEN_FLOAT => 'TOKEN_FLOAT', self::TOKEN_INTEGER => 'TOKEN_INTEGER', self::TOKEN_SINGLE_QUOTED_STRING => 'TOKEN_SINGLE_QUOTED_STRING', self::TOKEN_DOUBLE_QUOTED_STRING => 'TOKEN_DOUBLE_QUOTED_STRING', self::TOKEN_DOCTRINE_ANNOTATION_STRING => 'TOKEN_DOCTRINE_ANNOTATION_STRING', self::TOKEN_IDENTIFIER => 'type', self::TOKEN_THIS_VARIABLE => '\'$this\'', self::TOKEN_VARIABLE => 'variable', self::TOKEN_HORIZONTAL_WS => 'TOKEN_HORIZONTAL_WS', self::TOKEN_OTHER => 'TOKEN_OTHER', self::TOKEN_END => 'TOKEN_END', self::TOKEN_WILDCARD => '*'];
|
||||
public const VALUE_OFFSET = 0;
|
||||
public const TYPE_OFFSET = 1;
|
||||
public const LINE_OFFSET = 2;
|
||||
@ -104,6 +105,7 @@ class Lexer
|
||||
self::TOKEN_OPEN_CURLY_BRACKET => '\\{',
|
||||
self::TOKEN_CLOSE_CURLY_BRACKET => '\\}',
|
||||
self::TOKEN_COMMA => ',',
|
||||
self::TOKEN_COMMENT => '\\/\\/[^\\r\\n]*(?=\\n|\\r|\\*/)',
|
||||
self::TOKEN_VARIADIC => '\\.\\.\\.',
|
||||
self::TOKEN_DOUBLE_COLON => '::',
|
||||
self::TOKEN_DOUBLE_ARROW => '=>',
|
||||
|
@ -79,8 +79,16 @@ class PhpDocParser
|
||||
}
|
||||
$tag = new Ast\PhpDoc\PhpDocTagNode($name, $this->enrichWithAttributes($tokens, new Ast\PhpDoc\InvalidTagValueNode($e->getMessage(), $e), $startLine, $startIndex));
|
||||
$tokens->forwardToTheEnd();
|
||||
$comments = $tokens->flushComments();
|
||||
if ($comments !== []) {
|
||||
throw new LogicException('Comments should already be flushed');
|
||||
}
|
||||
return $this->enrichWithAttributes($tokens, new Ast\PhpDoc\PhpDocNode([$this->enrichWithAttributes($tokens, $tag, $startLine, $startIndex)]), 1, 0);
|
||||
}
|
||||
$comments = $tokens->flushComments();
|
||||
if ($comments !== []) {
|
||||
throw new LogicException('Comments should already be flushed');
|
||||
}
|
||||
return $this->enrichWithAttributes($tokens, new Ast\PhpDoc\PhpDocNode($children), 1, 0);
|
||||
}
|
||||
/** @phpstan-impure */
|
||||
|
@ -4,6 +4,7 @@ declare (strict_types=1);
|
||||
namespace PHPStan\PhpDocParser\Parser;
|
||||
|
||||
use LogicException;
|
||||
use PHPStan\PhpDocParser\Ast\Comment;
|
||||
use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use function array_pop;
|
||||
use function assert;
|
||||
@ -16,7 +17,9 @@ class TokenIterator
|
||||
/** @var list<array{string, int, int}> */
|
||||
private array $tokens;
|
||||
private int $index;
|
||||
/** @var int[] */
|
||||
/** @var list<Comment> */
|
||||
private array $comments = [];
|
||||
/** @var list<array{int, list<Comment>}> */
|
||||
private array $savePoints = [];
|
||||
/** @var list<int> */
|
||||
private array $skippedTokenTypes = [Lexer::TOKEN_HORIZONTAL_WS];
|
||||
@ -113,8 +116,7 @@ class TokenIterator
|
||||
$this->detectNewline();
|
||||
}
|
||||
}
|
||||
$this->index++;
|
||||
$this->skipIrrelevantTokens();
|
||||
$this->next();
|
||||
}
|
||||
/**
|
||||
* @throws ParserException
|
||||
@ -124,8 +126,7 @@ class TokenIterator
|
||||
if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType || $this->tokens[$this->index][Lexer::VALUE_OFFSET] !== $tokenValue) {
|
||||
$this->throwError($tokenType, $tokenValue);
|
||||
}
|
||||
$this->index++;
|
||||
$this->skipIrrelevantTokens();
|
||||
$this->next();
|
||||
}
|
||||
/** @phpstan-impure */
|
||||
public function tryConsumeTokenValue(string $tokenValue) : bool
|
||||
@ -133,10 +134,18 @@ class TokenIterator
|
||||
if ($this->tokens[$this->index][Lexer::VALUE_OFFSET] !== $tokenValue) {
|
||||
return \false;
|
||||
}
|
||||
$this->index++;
|
||||
$this->skipIrrelevantTokens();
|
||||
$this->next();
|
||||
return \true;
|
||||
}
|
||||
/**
|
||||
* @return list<Comment>
|
||||
*/
|
||||
public function flushComments() : array
|
||||
{
|
||||
$res = $this->comments;
|
||||
$this->comments = [];
|
||||
return $res;
|
||||
}
|
||||
/** @phpstan-impure */
|
||||
public function tryConsumeTokenType(int $tokenType) : bool
|
||||
{
|
||||
@ -148,11 +157,12 @@ class TokenIterator
|
||||
$this->detectNewline();
|
||||
}
|
||||
}
|
||||
$this->index++;
|
||||
$this->skipIrrelevantTokens();
|
||||
$this->next();
|
||||
return \true;
|
||||
}
|
||||
/** @phpstan-impure */
|
||||
/**
|
||||
* @deprecated Use skipNewLineTokensAndConsumeComments instead (when parsing a type)
|
||||
*/
|
||||
public function skipNewLineTokens() : void
|
||||
{
|
||||
if (!$this->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
|
||||
@ -162,6 +172,24 @@ class TokenIterator
|
||||
$foundNewLine = $this->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
} while ($foundNewLine === \true);
|
||||
}
|
||||
public function skipNewLineTokensAndConsumeComments() : void
|
||||
{
|
||||
if ($this->currentTokenType() === Lexer::TOKEN_COMMENT) {
|
||||
$this->comments[] = new Comment($this->currentTokenValue(), $this->currentTokenLine(), $this->currentTokenIndex());
|
||||
$this->next();
|
||||
}
|
||||
if (!$this->isCurrentTokenType(Lexer::TOKEN_PHPDOC_EOL)) {
|
||||
return;
|
||||
}
|
||||
do {
|
||||
$foundNewLine = $this->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
|
||||
if ($this->currentTokenType() !== Lexer::TOKEN_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
$this->comments[] = new Comment($this->currentTokenValue(), $this->currentTokenLine(), $this->currentTokenIndex());
|
||||
$this->next();
|
||||
} while ($foundNewLine === \true);
|
||||
}
|
||||
private function detectNewline() : void
|
||||
{
|
||||
$value = $this->currentTokenValue();
|
||||
@ -220,7 +248,7 @@ class TokenIterator
|
||||
}
|
||||
public function pushSavePoint() : void
|
||||
{
|
||||
$this->savePoints[] = $this->index;
|
||||
$this->savePoints[] = [$this->index, $this->comments];
|
||||
}
|
||||
public function dropSavePoint() : void
|
||||
{
|
||||
@ -228,9 +256,9 @@ class TokenIterator
|
||||
}
|
||||
public function rollback() : void
|
||||
{
|
||||
$index = array_pop($this->savePoints);
|
||||
assert($index !== null);
|
||||
$this->index = $index;
|
||||
$savepoint = array_pop($this->savePoints);
|
||||
assert($savepoint !== null);
|
||||
[$this->index, $this->comments] = $savepoint;
|
||||
}
|
||||
/**
|
||||
* @throws ParserException
|
||||
|
@ -32,7 +32,7 @@ class TypeParser
|
||||
} else {
|
||||
$type = $this->parseAtomic($tokens);
|
||||
$tokens->pushSavePoint();
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
try {
|
||||
$enrichedType = $this->enrichTypeOnUnionOrIntersection($tokens, $type);
|
||||
} catch (\PHPStan\PhpDocParser\Parser\ParserException $parserException) {
|
||||
@ -71,6 +71,10 @@ class TypeParser
|
||||
$type->setAttribute(Ast\Attribute::START_LINE, $startLine);
|
||||
$type->setAttribute(Ast\Attribute::END_LINE, $tokens->currentTokenLine());
|
||||
}
|
||||
$comments = $tokens->flushComments();
|
||||
if ($this->config->useCommentsAttributes) {
|
||||
$type->setAttribute(Ast\Attribute::COMMENTS, $comments);
|
||||
}
|
||||
if ($this->config->useIndexAttributes) {
|
||||
$type->setAttribute(Ast\Attribute::START_INDEX, $startIndex);
|
||||
$type->setAttribute(Ast\Attribute::END_INDEX, $tokens->endIndexOfLastRelevantToken());
|
||||
@ -91,7 +95,7 @@ class TypeParser
|
||||
if ($tokens->isCurrentTokenValue('is')) {
|
||||
$type = $this->parseConditional($tokens, $type);
|
||||
} else {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) {
|
||||
$type = $this->subParseUnion($tokens, $type);
|
||||
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
@ -107,9 +111,9 @@ class TypeParser
|
||||
$startLine = $tokens->currentTokenLine();
|
||||
$startIndex = $tokens->currentTokenIndex();
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$type = $this->subParse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
|
||||
$type = $this->tryParseArrayOrOffsetAccess($tokens, $type);
|
||||
@ -194,7 +198,7 @@ class TypeParser
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) {
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
$tokens->pushSavePoint();
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) {
|
||||
$tokens->rollback();
|
||||
break;
|
||||
@ -208,9 +212,9 @@ class TypeParser
|
||||
{
|
||||
$types = [$type];
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
return new Ast\Type\UnionTypeNode($types);
|
||||
}
|
||||
@ -221,7 +225,7 @@ class TypeParser
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
$tokens->pushSavePoint();
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$tokens->rollback();
|
||||
break;
|
||||
@ -235,9 +239,9 @@ class TypeParser
|
||||
{
|
||||
$types = [$type];
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$types[] = $this->parseAtomic($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
return new Ast\Type\IntersectionTypeNode($types);
|
||||
}
|
||||
@ -251,13 +255,13 @@ class TypeParser
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
$targetType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$ifType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$elseType = $this->subParse($tokens);
|
||||
return new Ast\Type\ConditionalTypeNode($subjectType, $targetType, $ifType, $elseType, $negated);
|
||||
}
|
||||
@ -272,13 +276,13 @@ class TypeParser
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
|
||||
}
|
||||
$targetType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$ifType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$elseType = $this->subParse($tokens);
|
||||
return new Ast\Type\ConditionalTypeForParameterNode($parameterName, $targetType, $ifType, $elseType, $negated);
|
||||
}
|
||||
@ -315,20 +319,21 @@ class TypeParser
|
||||
public function parseGeneric(\PHPStan\PhpDocParser\Parser\TokenIterator $tokens, Ast\Type\IdentifierTypeNode $baseType) : Ast\Type\GenericTypeNode
|
||||
{
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET);
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$startLine = $baseType->getAttribute(Ast\Attribute::START_LINE);
|
||||
$startIndex = $baseType->getAttribute(Ast\Attribute::START_INDEX);
|
||||
$genericTypes = [];
|
||||
$variances = [];
|
||||
$isFirst = \true;
|
||||
while ($isFirst || $tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
// trailing comma case
|
||||
if (!$isFirst && $tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) {
|
||||
break;
|
||||
}
|
||||
$isFirst = \false;
|
||||
[$genericTypes[], $variances[]] = $this->parseGenericTypeArgument($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
$type = new Ast\Type\GenericTypeNode($baseType, $genericTypes, $variances);
|
||||
if ($startLine !== null && $startIndex !== null) {
|
||||
@ -393,18 +398,18 @@ class TypeParser
|
||||
{
|
||||
$templates = $hasTemplate ? $this->parseCallableTemplates($tokens) : [];
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$parameters = [];
|
||||
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
|
||||
$parameters[] = $this->parseCallableParameter($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
|
||||
break;
|
||||
}
|
||||
$parameters[] = $this->parseCallableParameter($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
}
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES);
|
||||
@ -425,14 +430,14 @@ class TypeParser
|
||||
$templates = [];
|
||||
$isFirst = \true;
|
||||
while ($isFirst || $tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
// trailing comma case
|
||||
if (!$isFirst && $tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET)) {
|
||||
break;
|
||||
}
|
||||
$isFirst = \false;
|
||||
$templates[] = $this->parseCallableTemplateArgument($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET);
|
||||
return $templates;
|
||||
@ -587,29 +592,37 @@ class TypeParser
|
||||
$items = [];
|
||||
$sealed = \true;
|
||||
$unsealedType = null;
|
||||
$done = \false;
|
||||
do {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
||||
return Ast\Type\ArrayShapeNode::createSealed($items, $kind);
|
||||
}
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC)) {
|
||||
$sealed = \false;
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
|
||||
if ($kind === Ast\Type\ArrayShapeNode::KIND_ARRAY) {
|
||||
$unsealedType = $this->parseArrayShapeUnsealedType($tokens);
|
||||
} else {
|
||||
$unsealedType = $this->parseListShapeUnsealedType($tokens);
|
||||
}
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
$tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA);
|
||||
break;
|
||||
}
|
||||
$items[] = $this->parseArrayShapeItem($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA));
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if (!$tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$done = \true;
|
||||
}
|
||||
if ($tokens->currentTokenType() !== Lexer::TOKEN_COMMENT) {
|
||||
continue;
|
||||
}
|
||||
$tokens->next();
|
||||
} while (!$done);
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET);
|
||||
if ($sealed) {
|
||||
return Ast\Type\ArrayShapeNode::createSealed($items, $kind);
|
||||
@ -621,6 +634,8 @@ class TypeParser
|
||||
{
|
||||
$startLine = $tokens->currentTokenLine();
|
||||
$startIndex = $tokens->currentTokenIndex();
|
||||
// parse any comments above the item
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
try {
|
||||
$tokens->pushSavePoint();
|
||||
$key = $this->parseArrayShapeKey($tokens);
|
||||
@ -666,15 +681,15 @@ class TypeParser
|
||||
$startLine = $tokens->currentTokenLine();
|
||||
$startIndex = $tokens->currentTokenIndex();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$valueType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$keyType = null;
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$keyType = $valueType;
|
||||
$valueType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
}
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET);
|
||||
return $this->enrichWithAttributes($tokens, new Ast\Type\ArrayShapeUnsealedTypeNode($valueType, $keyType), $startLine, $startIndex);
|
||||
@ -687,9 +702,9 @@ class TypeParser
|
||||
$startLine = $tokens->currentTokenLine();
|
||||
$startIndex = $tokens->currentTokenIndex();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$valueType = $this->parse($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET);
|
||||
return $this->enrichWithAttributes($tokens, new Ast\Type\ArrayShapeUnsealedTypeNode($valueType, null), $startLine, $startIndex);
|
||||
}
|
||||
@ -701,14 +716,14 @@ class TypeParser
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET);
|
||||
$items = [];
|
||||
do {
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
|
||||
return new Ast\Type\ObjectShapeNode($items);
|
||||
}
|
||||
$items[] = $this->parseObjectShapeItem($tokens);
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
} while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA));
|
||||
$tokens->skipNewLineTokens();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET);
|
||||
return new Ast\Type\ObjectShapeNode($items);
|
||||
}
|
||||
@ -717,6 +732,7 @@ class TypeParser
|
||||
{
|
||||
$startLine = $tokens->currentTokenLine();
|
||||
$startIndex = $tokens->currentTokenIndex();
|
||||
$tokens->skipNewLineTokensAndConsumeComments();
|
||||
$key = $this->parseObjectShapeKey($tokens);
|
||||
$optional = $tokens->tryConsumeTokenType(Lexer::TOKEN_NULLABLE);
|
||||
$tokens->consumeTokenType(Lexer::TOKEN_COLON);
|
||||
|
@ -7,12 +7,14 @@ class ParserConfig
|
||||
{
|
||||
public bool $useLinesAttributes;
|
||||
public bool $useIndexAttributes;
|
||||
public bool $useCommentsAttributes;
|
||||
/**
|
||||
* @param array{lines?: bool, indexes?: bool} $usedAttributes
|
||||
* @param array{lines?: bool, indexes?: bool, comments?: bool} $usedAttributes
|
||||
*/
|
||||
public function __construct(array $usedAttributes)
|
||||
{
|
||||
$this->useLinesAttributes = $usedAttributes['lines'] ?? \false;
|
||||
$this->useIndexAttributes = $usedAttributes['indexes'] ?? \false;
|
||||
$this->useCommentsAttributes = $usedAttributes['comments'] ?? \false;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace PHPStan\PhpDocParser\Printer;
|
||||
|
||||
use LogicException;
|
||||
use PHPStan\PhpDocParser\Ast\Attribute;
|
||||
use PHPStan\PhpDocParser\Ast\Comment;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprArrayNode;
|
||||
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNode;
|
||||
use PHPStan\PhpDocParser\Ast\Node;
|
||||
@ -67,6 +68,7 @@ use PHPStan\PhpDocParser\Lexer\Lexer;
|
||||
use PHPStan\PhpDocParser\Parser\TokenIterator;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function get_class;
|
||||
use function get_object_vars;
|
||||
@ -75,6 +77,7 @@ use function in_array;
|
||||
use function is_array;
|
||||
use function preg_match_all;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
use function strlen;
|
||||
use function strpos;
|
||||
use function trim;
|
||||
@ -415,20 +418,24 @@ final class Printer
|
||||
}
|
||||
foreach ($diff as $i => $diffElem) {
|
||||
$diffType = $diffElem->type;
|
||||
$newNode = $diffElem->new;
|
||||
$originalNode = $diffElem->old;
|
||||
$arrItem = $diffElem->new;
|
||||
$origArrayItem = $diffElem->old;
|
||||
if ($diffType === \PHPStan\PhpDocParser\Printer\DiffElem::TYPE_KEEP || $diffType === \PHPStan\PhpDocParser\Printer\DiffElem::TYPE_REPLACE) {
|
||||
$beforeFirstKeepOrReplace = \false;
|
||||
if (!$newNode instanceof Node || !$originalNode instanceof Node) {
|
||||
if (!$arrItem instanceof Node || !$origArrayItem instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
/** @var int $itemStartPos */
|
||||
$itemStartPos = $originalNode->getAttribute(Attribute::START_INDEX);
|
||||
$itemStartPos = $origArrayItem->getAttribute(Attribute::START_INDEX);
|
||||
/** @var int $itemEndPos */
|
||||
$itemEndPos = $originalNode->getAttribute(Attribute::END_INDEX);
|
||||
$itemEndPos = $origArrayItem->getAttribute(Attribute::END_INDEX);
|
||||
if ($itemStartPos < 0 || $itemEndPos < 0 || $itemStartPos < $tokenIndex) {
|
||||
throw new LogicException();
|
||||
}
|
||||
$comments = $arrItem->getAttribute(Attribute::COMMENTS) ?? [];
|
||||
$origComments = $origArrayItem->getAttribute(Attribute::COMMENTS) ?? [];
|
||||
$commentStartPos = count($origComments) > 0 ? $origComments[0]->startIndex : $itemStartPos;
|
||||
assert($commentStartPos >= 0);
|
||||
$result .= $originalTokens->getContentBetween($tokenIndex, $itemStartPos);
|
||||
if (count($delayedAdd) > 0) {
|
||||
foreach ($delayedAdd as $delayedAddNode) {
|
||||
@ -436,6 +443,13 @@ final class Printer
|
||||
if ($parenthesesNeeded) {
|
||||
$result .= '(';
|
||||
}
|
||||
if ($insertNewline) {
|
||||
$delayedAddComments = $delayedAddNode->getAttribute(Attribute::COMMENTS) ?? [];
|
||||
if (count($delayedAddComments) > 0) {
|
||||
$result .= $this->printComments($delayedAddComments, $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
$result .= sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
}
|
||||
}
|
||||
$result .= $this->printNodeFormatPreserving($delayedAddNode, $originalTokens);
|
||||
if ($parenthesesNeeded) {
|
||||
$result .= ')';
|
||||
@ -448,12 +462,18 @@ final class Printer
|
||||
}
|
||||
$delayedAdd = [];
|
||||
}
|
||||
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($newNode), $this->parenthesesListMap[$mapKey], \true) && !in_array(get_class($originalNode), $this->parenthesesListMap[$mapKey], \true);
|
||||
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($arrItem), $this->parenthesesListMap[$mapKey], \true) && !in_array(get_class($origArrayItem), $this->parenthesesListMap[$mapKey], \true);
|
||||
$addParentheses = $parenthesesNeeded && !$originalTokens->hasParentheses($itemStartPos, $itemEndPos);
|
||||
if ($addParentheses) {
|
||||
$result .= '(';
|
||||
}
|
||||
$result .= $this->printNodeFormatPreserving($newNode, $originalTokens);
|
||||
if ($comments !== $origComments) {
|
||||
if (count($comments) > 0) {
|
||||
$result .= $this->printComments($comments, $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
$result .= sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
}
|
||||
}
|
||||
$result .= $this->printNodeFormatPreserving($arrItem, $originalTokens);
|
||||
if ($addParentheses) {
|
||||
$result .= ')';
|
||||
}
|
||||
@ -462,42 +482,48 @@ final class Printer
|
||||
if ($insertStr === null) {
|
||||
return null;
|
||||
}
|
||||
if (!$newNode instanceof Node) {
|
||||
if (!$arrItem instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
if ($insertStr === ', ' && $isMultiline) {
|
||||
if ($insertStr === ', ' && $isMultiline || count($arrItem->getAttribute(Attribute::COMMENTS) ?? []) > 0) {
|
||||
$insertStr = ',';
|
||||
$insertNewline = \true;
|
||||
}
|
||||
if ($beforeFirstKeepOrReplace) {
|
||||
// Will be inserted at the next "replace" or "keep" element
|
||||
$delayedAdd[] = $newNode;
|
||||
$delayedAdd[] = $arrItem;
|
||||
continue;
|
||||
}
|
||||
/** @var int $itemEndPos */
|
||||
$itemEndPos = $tokenIndex - 1;
|
||||
if ($insertNewline) {
|
||||
$result .= $insertStr . sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
$comments = $arrItem->getAttribute(Attribute::COMMENTS) ?? [];
|
||||
$result .= $insertStr;
|
||||
if (count($comments) > 0) {
|
||||
$result .= sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
$result .= $this->printComments($comments, $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
}
|
||||
$result .= sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
|
||||
} else {
|
||||
$result .= $insertStr;
|
||||
}
|
||||
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($newNode), $this->parenthesesListMap[$mapKey], \true);
|
||||
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($arrItem), $this->parenthesesListMap[$mapKey], \true);
|
||||
if ($parenthesesNeeded) {
|
||||
$result .= '(';
|
||||
}
|
||||
$result .= $this->printNodeFormatPreserving($newNode, $originalTokens);
|
||||
$result .= $this->printNodeFormatPreserving($arrItem, $originalTokens);
|
||||
if ($parenthesesNeeded) {
|
||||
$result .= ')';
|
||||
}
|
||||
$tokenIndex = $itemEndPos + 1;
|
||||
} elseif ($diffType === \PHPStan\PhpDocParser\Printer\DiffElem::TYPE_REMOVE) {
|
||||
if (!$originalNode instanceof Node) {
|
||||
if (!$origArrayItem instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
/** @var int $itemStartPos */
|
||||
$itemStartPos = $originalNode->getAttribute(Attribute::START_INDEX);
|
||||
$itemStartPos = $origArrayItem->getAttribute(Attribute::START_INDEX);
|
||||
/** @var int $itemEndPos */
|
||||
$itemEndPos = $originalNode->getAttribute(Attribute::END_INDEX);
|
||||
$itemEndPos = $origArrayItem->getAttribute(Attribute::END_INDEX);
|
||||
if ($itemStartPos < 0 || $itemEndPos < 0) {
|
||||
throw new LogicException();
|
||||
}
|
||||
@ -547,6 +573,17 @@ final class Printer
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* @param list<Comment> $comments
|
||||
*/
|
||||
private function printComments(array $comments, string $beforeAsteriskIndent, string $afterAsteriskIndent) : string
|
||||
{
|
||||
$formattedComments = [];
|
||||
foreach ($comments as $comment) {
|
||||
$formattedComments[] = str_replace("\n", "\n" . $beforeAsteriskIndent . '*' . $afterAsteriskIndent, $comment->getReformattedText());
|
||||
}
|
||||
return implode("\n{$beforeAsteriskIndent}*{$afterAsteriskIndent}", $formattedComments);
|
||||
}
|
||||
/**
|
||||
* @param array<Node|null> $nodes
|
||||
* @return array{bool, string, string}
|
||||
@ -574,7 +611,7 @@ final class Printer
|
||||
}
|
||||
$c = preg_match_all('~\\n(?<before>[\\x09\\x20]*)\\*(?<after>\\x20*)~', $allText, $matches, PREG_SET_ORDER);
|
||||
if ($c === 0) {
|
||||
return [$isMultiline, '', ''];
|
||||
return [$isMultiline, ' ', ' '];
|
||||
}
|
||||
$before = '';
|
||||
$after = '';
|
||||
@ -587,6 +624,8 @@ final class Printer
|
||||
}
|
||||
$after = $match['after'];
|
||||
}
|
||||
$before = strlen($before) === 0 ? ' ' : $before;
|
||||
$after = strlen($after) === 0 ? ' ' : $after;
|
||||
return [$isMultiline, $before, $after];
|
||||
}
|
||||
private function printNodeFormatPreserving(Node $node, TokenIterator $originalTokens) : string
|
||||
|
2
vendor/scoper-autoload.php
vendored
2
vendor/scoper-autoload.php
vendored
@ -30,7 +30,7 @@ if (!function_exists('humbug_phpscoper_expose_class')) {
|
||||
}
|
||||
}
|
||||
humbug_phpscoper_expose_class('AutoloadIncluder', 'RectorPrefix202502\AutoloadIncluder');
|
||||
humbug_phpscoper_expose_class('ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23', 'RectorPrefix202502\ComposerAutoloaderInita9ca9624b9ec3b7183135fb9d7d95d23');
|
||||
humbug_phpscoper_expose_class('ComposerAutoloaderInit30bd5d3b9b1d532a1d3e11eb20f91e28', 'RectorPrefix202502\ComposerAutoloaderInit30bd5d3b9b1d532a1d3e11eb20f91e28');
|
||||
humbug_phpscoper_expose_class('Product', 'RectorPrefix202502\Product');
|
||||
humbug_phpscoper_expose_class('SomeTest', 'RectorPrefix202502\SomeTest');
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user