Skip to content

Commit cc83891

Browse files
committed
Always call processStmtNodes on property hook body thanks to getStmts()
1 parent 01ade6e commit cc83891

File tree

2 files changed

+80
-44
lines changed

2 files changed

+80
-44
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
use PHPStan\Parser\ArrowFunctionArgVisitor;
125125
use PHPStan\Parser\ClosureArgVisitor;
126126
use PHPStan\Parser\ImmediatelyInvokedClosureVisitor;
127+
use PHPStan\Parser\LineAttributesVisitor;
127128
use PHPStan\Parser\Parser;
128129
use PHPStan\Parser\PropertyHookNameVisitor;
129130
use PHPStan\Php\PhpVersion;
@@ -4830,54 +4831,61 @@ private function processPropertyHooks(
48304831
$hook,
48314832
), $hookScope);
48324833

4834+
$stmts = $hook->getStmts();
4835+
if ($stmts === null) {
4836+
return;
4837+
}
4838+
48334839
if ($hook->body instanceof Expr) {
4834-
$this->processExprNode($stmt, $hook->body, $hookScope, $nodeCallback, ExpressionContext::createTopLevel());
4835-
$nodeCallback(new PropertyAssignNode(new PropertyFetch(new Variable('this'), $propertyName, $hook->body->getAttributes()), $hook->body, false), $hookScope);
4836-
} elseif (is_array($hook->body)) {
4837-
$gatheredReturnStatements = [];
4838-
$executionEnds = [];
4839-
$methodImpurePoints = [];
4840-
$statementResult = $this->processStmtNodes(new PropertyHookStatementNode($hook), $hook->body, $hookScope, static function (Node $node, Scope $scope) use ($nodeCallback, $hookScope, &$gatheredReturnStatements, &$executionEnds, &$hookImpurePoints): void {
4841-
$nodeCallback($node, $scope);
4842-
if ($scope->getFunction() !== $hookScope->getFunction()) {
4843-
return;
4844-
}
4845-
if ($scope->isInAnonymousFunction()) {
4846-
return;
4847-
}
4848-
if ($node instanceof PropertyAssignNode) {
4849-
$hookImpurePoints[] = new ImpurePoint(
4850-
$scope,
4851-
$node,
4852-
'propertyAssign',
4853-
'property assignment',
4854-
true,
4855-
);
4856-
return;
4857-
}
4858-
if ($node instanceof ExecutionEndNode) {
4859-
$executionEnds[] = $node;
4860-
return;
4861-
}
4862-
if (!$node instanceof Return_) {
4863-
return;
4864-
}
4840+
// enrich attributes of nodes in short hook body statements
4841+
$traverser = new NodeTraverser(
4842+
new LineAttributesVisitor($hook->body->getStartLine(), $hook->body->getEndLine()),
4843+
);
4844+
$traverser->traverse($stmts);
4845+
}
48654846

4866-
$gatheredReturnStatements[] = new ReturnStatement($scope, $node);
4867-
}, StatementContext::createTopLevel());
4847+
$gatheredReturnStatements = [];
4848+
$executionEnds = [];
4849+
$methodImpurePoints = [];
4850+
$statementResult = $this->processStmtNodes(new PropertyHookStatementNode($hook), $stmts, $hookScope, static function (Node $node, Scope $scope) use ($nodeCallback, $hookScope, &$gatheredReturnStatements, &$executionEnds, &$hookImpurePoints): void {
4851+
$nodeCallback($node, $scope);
4852+
if ($scope->getFunction() !== $hookScope->getFunction()) {
4853+
return;
4854+
}
4855+
if ($scope->isInAnonymousFunction()) {
4856+
return;
4857+
}
4858+
if ($node instanceof PropertyAssignNode) {
4859+
$hookImpurePoints[] = new ImpurePoint(
4860+
$scope,
4861+
$node,
4862+
'propertyAssign',
4863+
'property assignment',
4864+
true,
4865+
);
4866+
return;
4867+
}
4868+
if ($node instanceof ExecutionEndNode) {
4869+
$executionEnds[] = $node;
4870+
return;
4871+
}
4872+
if (!$node instanceof Return_) {
4873+
return;
4874+
}
48684875

4869-
$nodeCallback(new PropertyHookReturnStatementsNode(
4870-
$hook,
4871-
$gatheredReturnStatements,
4872-
$statementResult,
4873-
$executionEnds,
4874-
array_merge($statementResult->getImpurePoints(), $methodImpurePoints),
4875-
$classReflection,
4876-
$hookReflection,
4877-
$propertyReflection,
4878-
), $hookScope);
4879-
}
4876+
$gatheredReturnStatements[] = new ReturnStatement($scope, $node);
4877+
}, StatementContext::createTopLevel());
48804878

4879+
$nodeCallback(new PropertyHookReturnStatementsNode(
4880+
$hook,
4881+
$gatheredReturnStatements,
4882+
$statementResult,
4883+
$executionEnds,
4884+
array_merge($statementResult->getImpurePoints(), $methodImpurePoints),
4885+
$classReflection,
4886+
$hookReflection,
4887+
$propertyReflection,
4888+
), $hookScope);
48814889
}
48824890
}
48834891

src/Parser/LineAttributesVisitor.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Parser;
4+
5+
use PhpParser\Node;
6+
use PhpParser\NodeVisitorAbstract;
7+
8+
final class LineAttributesVisitor extends NodeVisitorAbstract
9+
{
10+
11+
public function __construct(private ?int $startLine, private ?int $endLine)
12+
{
13+
}
14+
15+
public function enterNode(Node $node): Node
16+
{
17+
if ($node->getStartLine() === -1) {
18+
$node->setAttribute('startLine', $this->startLine);
19+
}
20+
21+
if ($node->getEndLine() === -1) {
22+
$node->setAttribute('endLine', $this->endLine);
23+
}
24+
25+
return $node;
26+
}
27+
28+
}

0 commit comments

Comments
 (0)