phpstan/phpdoc-parser now requires PHP 7.4 or newer to run.
Instead of different arrays and boolean values passed into class constructors during setup, parser classes now share a common ParserConfig object.
Before:
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
$usedAttributes = ['lines' => true, 'indexes' => true];
$lexer = new Lexer();
$constExprParser = new ConstExprParser(true, true, $usedAttributes);
$typeParser = new TypeParser($constExprParser, true, $usedAttributes);
$phpDocParser = new PhpDocParser($typeParser, $constExprParser, true, true, $usedAttributes);After:
use PHPStan\PhpDocParser\Lexer\Lexer;
use PHPStan\PhpDocParser\ParserConfig;
use PHPStan\PhpDocParser\Parser\ConstExprParser;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\Parser\PhpDocParser;
$config = new ParserConfig(usedAttributes: ['lines' => true, 'indexes' => true]);
$lexer = new Lexer($config);
$constExprParser = new ConstExprParser($config);
$typeParser = new TypeParser($config, $constExprParser);
$phpDocParser = new PhpDocParser($config, $typeParser, $constExprParser);The point of ParserConfig is that over the course of phpstan/phpdoc-parser 2.x development series it's most likely going to gain new optional parameters akin to PHPStan's bleeding edge. These parameters will allow opting in to new behaviour which will become the default in 3.0.
With ParserConfig object, it's now going to be impossible to configure parser classes inconsistently. Which happened to users when they were separate boolean values.
This parser now supports parsing Doctrine Annotations. The AST nodes representing Doctrine Annotations live in the PHPStan\PhpDocParser\Ast\PhpDoc\Doctrine namespace.
phpdoc-parser 1.x sometimes silently consumed invalid part of a PHPDoc type as description:
/** @return \Closure(...int, string): string */This became IdentifierTypeNode of \Closure and with (...int, string): string as description. (Valid callable syntax is: \Closure(int ...$u, string): string.)
Another example:
/** @return array{foo: int}} */The extra } also became description.
Both of these examples are now InvalidTagValueNode.
If these parts are supposed to be PHPDoc descriptions, you need to put whitespace between the type and the description text:
/** @return \Closure (...int, string): string */
/** @return array{foo: int} } */In phpdoc-parser 1.x, invalid type alias syntax was represented as InvalidTagValueNode, losing information about a type alias being present.
/**
* @phpstan-type TypeAlias
*/This @phpstan-type is missing the actual type to alias. In phpdoc-parser 2.0 this is now represented as TypeAliasTagValueNode (instead of InvalidTagValueNode) with InvalidTypeNode in place of the type.
The class QuoteAwareConstExprStringNode has been removed.
Instead, ConstExprStringNode gained information about the kind of quotes being used.
ConstExprStringNode::$value now contains unescaped values without surrounding '' or "" quotes.
Use ConstExprStringNode::__toString() or Printer to get the escaped value along with surrounding quotes.
Multi-line descriptions between tags were previously represented as separate PhpDocTextNode:
/**
* @param Foo $foo 1st multi world description
* some text in the middle
* @param Bar $bar 2nd multi world description
*/The line with some text in the middle in phpdoc-parser 2.0 is now part of the description of the first @param tag.
ArrayShapeNode constructor made private, added public static methods createSealed() and createUnsealed().
- Constructor parameter
$isEqualityinAssertTag*ValueNodemade required - Constructor parameter
$templateTypesinMethodTagValueNodemade required - Constructor parameter
$isReferenceinParamTagValueNodemade required - Constructor parameter
$isReferenceinTypelessParamTagValueNodemade required - Constructor parameter
$templateTypesinCallableTypeNodemade required - Constructor parameters
$expectedTokenValueand$currentTokenLineinParserExceptionmade required ArrayShapeItemNodeandObjectShapeItemNodeare not standalone TypeNode, just Node