Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update nikic/php-parser to 5.0 #10567

Merged
merged 17 commits into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,12 @@
"felixfbecker/language-server-protocol": "^1.5.2",
"fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0",
"netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
"nikic/php-parser": "^4.16",
"nikic/php-parser": "^5.0.0",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a dependency that Psalm shares with other tools like PHPUnit. In order to allow downstream projects to upgrade their dependencies gracefully, Psalm should produce a release first that is compatible with both major versions.

Suggested change
"nikic/php-parser": "^5.0.0",
"nikic/php-parser": "^4.18 || ^5.0",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm open to trying to create a version of this PR that would land on the 5.x branch that would work with both parser v4 and v5. I think the main thing would be going back to the deprecated node names (eg Encapsed vs Interpolated), which are still supported in v5 via class aliases.

The thing I'd worry about is additional complexity, maintenance, and testing involved in supporting two versions. The differences are non-trivial, as evidenced by this PR. PHPStan also looks like it's planning to jump to parser v5 on its 2.0 release, with its 1.x releases only supporting parser v4.

I'd like feedback from the maintainers before making any major changes to this PR or creating a new one.

"sebastian/diff": "^4.0 || ^5.0",
"spatie/array-to-xml": "^2.17.0 || ^3.0",
"symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0",
"symfony/filesystem": "^5.4 || ^6.0 || ^7.0"
},
"conflict": {
"nikic/php-parser": "4.17.0"
},
"provide": {
"psalm/psalm": "self.version"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/plugins/SafeArrayKeyChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Psalm\Example\Plugin;

use PhpParser\Node\Expr\ArrayItem;
use PhpParser\Node\ArrayItem;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\AddRemoveTaintsEvent;
use Psalm\Plugin\EventHandler\RemoveTaintsInterface;
Expand Down
10 changes: 0 additions & 10 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@950293c6e74c6e9db842f537c5722755b1594313">
<file src="vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php">
<PossiblyUndefinedStringArrayOffset>
<code><![CDATA[$subNodes['expr']]]></code>
</PossiblyUndefinedStringArrayOffset>
</file>
<file src="examples/TemplateChecker.php">
<PossiblyUndefinedIntArrayOffset>
<code><![CDATA[$comment_block->tags['variablesfrom'][0]]]></code>
Expand Down Expand Up @@ -2351,9 +2346,4 @@
<code>$return_type</code>
</RiskyTruthyFalsyComparison>
</file>
<file src="vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php">
<PossiblyUndefinedStringArrayOffset>
<code><![CDATA[$subNodes['expr']]]></code>
</PossiblyUndefinedStringArrayOffset>
</file>
</files>
21 changes: 21 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,31 @@
</errorLevel>
</PropertyTypeCoercion>

<InvalidArrayOffset>
<errorLevel type="suppress">
<file name="vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php" />
<file name="vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php" />
</errorLevel>
</InvalidArrayOffset>

<InvalidPropertyAssignmentValue>
<errorLevel type="suppress">
<file name="vendor/nikic/php-parser/lib/PhpParser/Node/MatchArm.php" />
</errorLevel>
</InvalidPropertyAssignmentValue>

<MixedAssignment>
<errorLevel type="suppress">
<directory name="vendor/nikic/php-parser" />
</errorLevel>
</MixedAssignment>

<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<referencedProperty name="PhpParser\Node\Const_::$namespacedName" />
<referencedProperty name="PhpParser\Node\Stmt\ClassLike::$namespacedName" />
<referencedProperty name="PhpParser\Node\Stmt\Function_::$namespacedName" />
</errorLevel>
</PropertyNotSetInConstructor>
</issueHandlers>
</psalm>
4 changes: 2 additions & 2 deletions src/Psalm/CodeLocation/ParseErrorLocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public function __construct(
string $file_path,
string $file_name,
) {
/** @psalm-suppress PossiblyUndefinedStringArrayOffset, ImpureMethodCall */
/** @psalm-suppress PossiblyUndefinedStringArrayOffset */
$this->file_start = (int)$error->getAttributes()['startFilePos'];
/** @psalm-suppress PossiblyUndefinedStringArrayOffset, ImpureMethodCall */
/** @psalm-suppress PossiblyUndefinedStringArrayOffset */
$this->file_end = (int)$error->getAttributes()['endFilePos'];
$this->raw_file_start = $this->file_start;
$this->raw_file_end = $this->file_end;
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/ClassAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1195,7 +1195,7 @@ static function (FunctionLikeParameter $param): PhpParser\Node\Arg {
$fake_stmt = new VirtualClassMethod(
new VirtualIdentifier('__construct'),
[
'flags' => PhpParser\Node\Stmt\Class_::MODIFIER_PUBLIC,
'flags' => PhpParser\Modifiers::PUBLIC,
'params' => $fake_constructor_params,
'stmts' => $fake_constructor_stmts,
],
Expand Down
11 changes: 3 additions & 8 deletions src/Psalm/Internal/Analyzer/FunctionLike/ReturnTypeCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public static function getReturnTypes(
$yield_types = array_merge($yield_types, self::getYieldTypeFromExpression($stmt->expr, $nodes));
} elseif ($stmt->expr instanceof PhpParser\Node\Scalar\String_) {
$return_types[] = Type::getString();
} elseif ($stmt->expr instanceof PhpParser\Node\Scalar\LNumber) {
} elseif ($stmt->expr instanceof PhpParser\Node\Scalar\Int_) {
$return_types[] = Type::getInt();
} elseif ($stmt->expr instanceof PhpParser\Node\Expr\ConstFetch) {
if ((string)$stmt->expr->name === 'true') {
Expand All @@ -77,14 +77,9 @@ public static function getReturnTypes(
break;
}

if ($stmt instanceof PhpParser\Node\Stmt\Throw_) {
$return_types[] = Type::getNever();

break;
}

if ($stmt instanceof PhpParser\Node\Stmt\Expression) {
if ($stmt->expr instanceof PhpParser\Node\Expr\Exit_) {
if ($stmt->expr instanceof PhpParser\Node\Expr\Exit_
|| $stmt->expr instanceof PhpParser\Node\Expr\Throw_) {
$return_types[] = Type::getNever();

break;
Expand Down
3 changes: 1 addition & 2 deletions src/Psalm/Internal/Analyzer/ProjectAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1186,8 +1186,7 @@ public function setPhpVersion(string $version, string $source): void
$analysis_php_version_id = $php_major_version * 10_000 + $php_minor_version * 100;

if ($this->codebase->analysis_php_version_id !== $analysis_php_version_id) {
// reset lexer and parser when php version changes
StatementsProvider::clearLexer();
// reset parser when php version changes
StatementsProvider::clearParser();
}

Expand Down
17 changes: 9 additions & 8 deletions src/Psalm/Internal/Analyzer/ScopeAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ public static function getControlActions(

foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Return_ ||
$stmt instanceof PhpParser\Node\Stmt\Throw_ ||
($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Exit_)
($stmt instanceof PhpParser\Node\Stmt\Expression
&& ($stmt->expr instanceof PhpParser\Node\Expr\Exit_
|| $stmt->expr instanceof PhpParser\Node\Expr\Throw_))
) {
if (!$return_is_exit && $stmt instanceof PhpParser\Node\Stmt\Return_) {
$stmt_return_type = null;
Expand Down Expand Up @@ -85,7 +86,7 @@ public static function getControlActions(
if ($stmt instanceof PhpParser\Node\Stmt\Continue_) {
$count = !$stmt->num
? 1
: ($stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : null);
: ($stmt->num instanceof PhpParser\Node\Scalar\Int_ ? $stmt->num->value : null);

if ($break_types && $count !== null && count($break_types) >= $count) {
/** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
Expand All @@ -102,7 +103,7 @@ public static function getControlActions(
if ($stmt instanceof PhpParser\Node\Stmt\Break_) {
$count = !$stmt->num
? 1
: ($stmt->num instanceof PhpParser\Node\Scalar\LNumber ? $stmt->num->value : null);
: ($stmt->num instanceof PhpParser\Node\Scalar\Int_ ? $stmt->num->value : null);

if ($break_types && $count !== null && count($break_types) >= $count) {
/** @psalm-suppress InvalidArrayOffset Some int-range improvements are needed */
Expand Down Expand Up @@ -408,9 +409,9 @@ public static function onlyThrowsOrExits(NodeTypeProvider $type_provider, array
for ($i = count($stmts) - 1; $i >= 0; --$i) {
$stmt = $stmts[$i];

if ($stmt instanceof PhpParser\Node\Stmt\Throw_
|| ($stmt instanceof PhpParser\Node\Stmt\Expression
&& $stmt->expr instanceof PhpParser\Node\Expr\Exit_)
if ($stmt instanceof PhpParser\Node\Stmt\Expression
&& ($stmt->expr instanceof PhpParser\Node\Expr\Exit_
|| $stmt->expr instanceof PhpParser\Node\Expr\Throw_)
) {
return true;
}
Expand Down Expand Up @@ -438,7 +439,7 @@ public static function onlyThrows(array $stmts): bool
}

foreach ($stmts as $stmt) {
if ($stmt instanceof PhpParser\Node\Stmt\Throw_) {
if ($stmt instanceof PhpParser\Node\Stmt\Expression && $stmt->expr instanceof PhpParser\Node\Expr\Throw_) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@
use Psalm\Node\Expr\BinaryOp\VirtualEqual;
use Psalm\Node\Expr\BinaryOp\VirtualIdentical;
use Psalm\Node\Expr\VirtualArray;
use Psalm\Node\Expr\VirtualArrayItem;
use Psalm\Node\Expr\VirtualBooleanNot;
use Psalm\Node\Expr\VirtualConstFetch;
use Psalm\Node\Expr\VirtualFuncCall;
use Psalm\Node\Expr\VirtualVariable;
use Psalm\Node\Name\VirtualFullyQualified;
use Psalm\Node\Scalar\VirtualLNumber;
use Psalm\Node\Scalar\VirtualInt;
use Psalm\Node\Stmt\VirtualIf;
use Psalm\Node\VirtualArg;
use Psalm\Node\VirtualArrayItem;
use Psalm\Node\VirtualName;
use Psalm\Type;
use Psalm\Type\Atomic\TDependentGetClass;
Expand Down Expand Up @@ -249,8 +249,8 @@ public static function analyze(
$case_equality_expr = new VirtualFuncCall(
new VirtualFullyQualified(['rand']),
[
new VirtualArg(new VirtualLNumber(0)),
new VirtualArg(new VirtualLNumber(1)),
new VirtualArg(new VirtualInt(0)),
new VirtualArg(new VirtualInt(1)),
],
$case->getAttributes(),
);
Expand Down Expand Up @@ -294,8 +294,8 @@ public static function analyze(
$case_or_default_equality_expr = new VirtualFuncCall(
new VirtualFullyQualified(['rand']),
[
new VirtualArg(new VirtualLNumber(0)),
new VirtualArg(new VirtualLNumber(1)),
new VirtualArg(new VirtualInt(0)),
new VirtualArg(new VirtualInt(1)),
],
$case->getAttributes(),
);
Expand Down Expand Up @@ -690,8 +690,8 @@ private static function simplifyCaseEqualityExpression(
}

/**
* @param array<PhpParser\Node\Expr\ArrayItem> $in_array_values
* @return ?array<PhpParser\Node\Expr\ArrayItem>
* @param array<PhpParser\Node\ArrayItem> $in_array_values
* @return ?array<PhpParser\Node\ArrayItem>
*/
private static function getOptionsFromNestedOr(
PhpParser\Node\Expr $case_equality_expr,
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Internal/Analyzer/Statements/BreakAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static function analyze(
if ($loop_scope) {
if ($context->break_types
&& end($context->break_types) === 'switch'
&& (!$stmt->num instanceof PhpParser\Node\Scalar\LNumber || $stmt->num->value < 2)
&& (!$stmt->num instanceof PhpParser\Node\Scalar\Int_ || $stmt->num->value < 2)
) {
$loop_scope->final_actions[] = ScopeAnalyzer::ACTION_LEAVE_SWITCH;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static function analyze(
PhpParser\Node\Stmt\Continue_ $stmt,
Context $context,
): void {
$count = $stmt->num instanceof PhpParser\Node\Scalar\LNumber? $stmt->num->value : 1;
$count = $stmt->num instanceof PhpParser\Node\Scalar\Int_? $stmt->num->value : 1;

$loop_scope = $context->loop_scope;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ private static function analyzeArrayItem(
StatementsAnalyzer $statements_analyzer,
Context $context,
ArrayCreationInfo $array_creation_info,
PhpParser\Node\Expr\ArrayItem $item,
PhpParser\Node\ArrayItem $item,
Codebase $codebase,
): void {
if ($item->unpack) {
Expand Down Expand Up @@ -519,7 +519,7 @@ private static function analyzeArrayItem(
private static function handleUnpackedArray(
StatementsAnalyzer $statements_analyzer,
ArrayCreationInfo $array_creation_info,
PhpParser\Node\Expr\ArrayItem $item,
PhpParser\Node\ArrayItem $item,
Union $unpacked_array_type,
Codebase $codebase,
): void {
Expand Down
Loading
Loading