diff --git a/composer.json b/composer.json index 9c2e3570b9..3a722a9282 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "hoa/compiler": "3.17.08.08", "hoa/exception": "^1.0", "hoa/file": "1.17.07.11", - "jetbrains/phpstorm-stubs": "dev-master#bdc8acd7c04c0c87197849c7cdd27e44b67b56c7", + "jetbrains/phpstorm-stubs": "dev-master#5686f9ceebde3d9338bea53b78d70ebde5fb5710", "nette/bootstrap": "^3.0", "nette/di": "^3.1.4", "nette/neon": "3.3.3", diff --git a/composer.lock b/composer.lock index cbfc81e3da..7039f2bc07 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": "b8e13e2eb99acb0933ff8956a498ffe4", + "content-hash": "8d65a8ad1ba3923e57e72376e8dfefed", "packages": [ { "name": "clue/ndjson-react", @@ -1434,19 +1434,19 @@ "source": { "type": "git", "url": "https://github.com/JetBrains/phpstorm-stubs.git", - "reference": "bdc8acd7c04c0c87197849c7cdd27e44b67b56c7" + "reference": "5686f9ceebde3d9338bea53b78d70ebde5fb5710" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/bdc8acd7c04c0c87197849c7cdd27e44b67b56c7", - "reference": "bdc8acd7c04c0c87197849c7cdd27e44b67b56c7", + "url": "https://api.github.com/repos/JetBrains/phpstorm-stubs/zipball/5686f9ceebde3d9338bea53b78d70ebde5fb5710", + "reference": "5686f9ceebde3d9338bea53b78d70ebde5fb5710", "shasum": "" }, "require-dev": { - "friendsofphp/php-cs-fixer": "v3.46.0", - "nikic/php-parser": "v5.0.0", - "phpdocumentor/reflection-docblock": "5.3.0", - "phpunit/phpunit": "10.5.5" + "friendsofphp/php-cs-fixer": "v3.61.1", + "nikic/php-parser": "v5.1.0", + "phpdocumentor/reflection-docblock": "5.4.1", + "phpunit/phpunit": "11.3.0" }, "default-branch": true, "type": "library", @@ -1474,7 +1474,7 @@ "support": { "source": "https://github.com/JetBrains/phpstorm-stubs/tree/master" }, - "time": "2024-07-05T11:52:49+00:00" + "time": "2024-07-24T19:11:43+00:00" }, { "name": "nette/bootstrap", diff --git a/src/Rules/Methods/CallToConstructorStatementWithoutSideEffectsRule.php b/src/Rules/Methods/CallToConstructorStatementWithoutSideEffectsRule.php index 00a2352c99..c50d21d878 100644 --- a/src/Rules/Methods/CallToConstructorStatementWithoutSideEffectsRule.php +++ b/src/Rules/Methods/CallToConstructorStatementWithoutSideEffectsRule.php @@ -4,6 +4,7 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; +use PHPStan\Node\NoopExpressionNode; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -11,7 +12,7 @@ use function sprintf; /** - * @implements Rule + * @implements Rule */ final class CallToConstructorStatementWithoutSideEffectsRule implements Rule { @@ -25,16 +26,16 @@ public function __construct( public function getNodeType(): string { - return Node\Stmt\Expression::class; + return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope): array { - if (!$node->expr instanceof Node\Expr\New_) { + $instantiation = $node->getOriginalExpr(); + if (!$instantiation instanceof Node\Expr\New_) { return []; } - $instantiation = $node->expr; if (!$instantiation->class instanceof Node\Name) { return []; } @@ -59,27 +60,18 @@ public function processNode(Node $node, Scope $scope): array } $constructor = $classReflection->getConstructor(); - if ($constructor->hasSideEffects()->no()) { - $throwsType = $constructor->getThrowType(); - if ($throwsType !== null && !$throwsType->isVoid()->yes()) { - return []; - } - - $methodResult = $scope->getType($instantiation); - if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { - return []; - } - - return [ - RuleErrorBuilder::message(sprintf( - 'Call to %s::%s() on a separate line has no effect.', - $classReflection->getDisplayName(), - $constructor->getName(), - ))->identifier('new.resultUnused')->build(), - ]; + $methodResult = $scope->getType($instantiation); + if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { + return []; } - return []; + return [ + RuleErrorBuilder::message(sprintf( + 'Call to %s::%s() on a separate line has no effect.', + $classReflection->getDisplayName(), + $constructor->getName(), + ))->identifier('new.resultUnused')->build(), + ]; } } diff --git a/src/Rules/Methods/CallToMethodStatementWithoutSideEffectsRule.php b/src/Rules/Methods/CallToMethodStatementWithoutSideEffectsRule.php index ed78c46f17..c8ead1d217 100644 --- a/src/Rules/Methods/CallToMethodStatementWithoutSideEffectsRule.php +++ b/src/Rules/Methods/CallToMethodStatementWithoutSideEffectsRule.php @@ -5,6 +5,7 @@ use PhpParser\Node; use PHPStan\Analyser\NullsafeOperatorHelper; use PHPStan\Analyser\Scope; +use PHPStan\Node\NoopExpressionNode; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; use PHPStan\Rules\RuleLevelHelper; @@ -14,7 +15,7 @@ use function sprintf; /** - * @implements Rule + * @implements Rule */ final class CallToMethodStatementWithoutSideEffectsRule implements Rule { @@ -25,18 +26,18 @@ public function __construct(private RuleLevelHelper $ruleLevelHelper) public function getNodeType(): string { - return Node\Stmt\Expression::class; + return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope): array { - if ($node->expr instanceof Node\Expr\NullsafeMethodCall) { - $scope = $scope->filterByTruthyValue(new Node\Expr\BinaryOp\NotIdentical($node->expr->var, new Node\Expr\ConstFetch(new Node\Name('null')))); - } elseif (!$node->expr instanceof Node\Expr\MethodCall) { + $methodCall = $node->getOriginalExpr(); + if ($methodCall instanceof Node\Expr\NullsafeMethodCall) { + $scope = $scope->filterByTruthyValue(new Node\Expr\BinaryOp\NotIdentical($methodCall->var, new Node\Expr\ConstFetch(new Node\Name('null')))); + } elseif (!$methodCall instanceof Node\Expr\MethodCall) { return []; } - $methodCall = $node->expr; if (!$methodCall->name instanceof Node\Identifier) { return []; } @@ -60,31 +61,21 @@ public function processNode(Node $node, Scope $scope): array return []; } - $method = $calledOnType->getMethod($methodName, $scope); - if ($method->hasSideEffects()->no() || $node->expr->isFirstClassCallable()) { - if (!$node->expr->isFirstClassCallable()) { - $throwsType = $method->getThrowType(); - if ($throwsType !== null && !$throwsType->isVoid()->yes()) { - return []; - } - } - - $methodResult = $scope->getType($methodCall); - if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { - return []; - } - - return [ - RuleErrorBuilder::message(sprintf( - 'Call to %s %s::%s() on a separate line has no effect.', - $method->isStatic() ? 'static method' : 'method', - $method->getDeclaringClass()->getDisplayName(), - $method->getName(), - ))->identifier('method.resultUnused')->build(), - ]; + $methodResult = $scope->getType($methodCall); + if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { + return []; } - return []; + $method = $calledOnType->getMethod($methodName, $scope); + + return [ + RuleErrorBuilder::message(sprintf( + 'Call to %s %s::%s() on a separate line has no effect.', + $method->isStatic() ? 'static method' : 'method', + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + ))->identifier('method.resultUnused')->build(), + ]; } } diff --git a/src/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRule.php b/src/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRule.php index 8f1828cbe4..550ea9e019 100644 --- a/src/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRule.php +++ b/src/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRule.php @@ -5,6 +5,7 @@ use PhpParser\Node; use PHPStan\Analyser\NullsafeOperatorHelper; use PHPStan\Analyser\Scope; +use PHPStan\Node\NoopExpressionNode; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; @@ -17,7 +18,7 @@ use function strtolower; /** - * @implements Rule + * @implements Rule */ final class CallToStaticMethodStatementWithoutSideEffectsRule implements Rule { @@ -31,16 +32,16 @@ public function __construct( public function getNodeType(): string { - return Node\Stmt\Expression::class; + return NoopExpressionNode::class; } public function processNode(Node $node, Scope $scope): array { - if (!$node->expr instanceof Node\Expr\StaticCall) { + $staticCall = $node->getOriginalExpr(); + if (!$staticCall instanceof Node\Expr\StaticCall) { return []; } - $staticCall = $node->expr; if (!$staticCall->name instanceof Node\Identifier) { return []; } @@ -84,30 +85,19 @@ public function processNode(Node $node, Scope $scope): array return []; } - if ($method->hasSideEffects()->no() || $node->expr->isFirstClassCallable()) { - if (!$node->expr->isFirstClassCallable()) { - $throwsType = $method->getThrowType(); - if ($throwsType !== null && !$throwsType->isVoid()->yes()) { - return []; - } - } - - $methodResult = $scope->getType($staticCall); - if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { - return []; - } - - return [ - RuleErrorBuilder::message(sprintf( - 'Call to %s %s::%s() on a separate line has no effect.', - $method->isStatic() ? 'static method' : 'method', - $method->getDeclaringClass()->getDisplayName(), - $method->getName(), - ))->identifier('staticMethod.resultUnused')->build(), - ]; + $methodResult = $scope->getType($staticCall); + if ($methodResult instanceof NeverType && $methodResult->isExplicit()) { + return []; } - return []; + return [ + RuleErrorBuilder::message(sprintf( + 'Call to %s %s::%s() on a separate line has no effect.', + $method->isStatic() ? 'static method' : 'method', + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + ))->identifier('staticMethod.resultUnused')->build(), + ]; } } diff --git a/tests/PHPStan/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRuleTest.php b/tests/PHPStan/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRuleTest.php index 03cbdaa49d..953ca5f982 100644 --- a/tests/PHPStan/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRuleTest.php +++ b/tests/PHPStan/Rules/Methods/CallToStaticMethodStatementWithoutSideEffectsRuleTest.php @@ -28,10 +28,6 @@ public function testRule(): void 'Call to static method DateTimeImmutable::createFromFormat() on a separate line has no effect.', 12, ], - [ - 'Call to static method DateTimeImmutable::createFromFormat() on a separate line has no effect.', - 13, - ], [ 'Call to method DateTime::format() on a separate line has no effect.', 23,