diff --git a/src/Analyser/ArgumentsHandler.php b/src/Analyser/ArgumentsHandler.php index 905cc628f9b..44b6037a185 100644 --- a/src/Analyser/ArgumentsHandler.php +++ b/src/Analyser/ArgumentsHandler.php @@ -370,18 +370,14 @@ public function processArgs( if ($arg->value instanceof Expr\Closure) { $storedClosureArgResult = null; - if ($nodeScopeResolver->isReturningStoredExpressionResults() || $nodeScopeResolver->isConsumingStoredExpressionResults()) { + if ($nodeScopeResolver->isReturningStoredExpressionResults()) { // an on-demand re-walk of the enclosing call must not re-run the // closure's whole by-ref convergence: consume the main walk's // stored result, or (when the body release already dropped it) // price the closure through getClosureType's per-node cache - // a single body walk on miss, none on repeat asks $storedClosureArgResult = $storage->findExpressionResult($arg->value); - // consume mode alone (the nullsafe call's plain-twin walk) is the - // FIRST and only walk of these arguments - nothing stored them, so - // a miss means "walk it", not "price it silently": pricing skips - // the body walk and never fires the closure's node callbacks - if ($storedClosureArgResult === null && $nodeScopeResolver->isReturningStoredExpressionResults()) { + if ($storedClosureArgResult === null) { $storedClosureArgResult = $this->expressionResultFactory->create( $scopeToPass, beforeScope: $scopeToPass, @@ -528,12 +524,10 @@ public function processArgs( } elseif ($arg->value instanceof Expr\ArrowFunction) { $storedClosureArgResult = null; - if ($nodeScopeResolver->isReturningStoredExpressionResults() || $nodeScopeResolver->isConsumingStoredExpressionResults()) { + if ($nodeScopeResolver->isReturningStoredExpressionResults()) { // see the Closure branch above - consume or price via the cache $storedClosureArgResult = $storage->findExpressionResult($arg->value); - // consume mode alone (the nullsafe call's plain-twin walk) is the - // first and only walk of the argument - a miss means walk it - if ($storedClosureArgResult === null && $nodeScopeResolver->isReturningStoredExpressionResults()) { + if ($storedClosureArgResult === null) { $storedClosureArgResult = $this->expressionResultFactory->create( $scopeToPass, beforeScope: $scopeToPass, diff --git a/src/Analyser/ExprHandler/NullsafeMethodCallHandler.php b/src/Analyser/ExprHandler/NullsafeMethodCallHandler.php index af8d00eaac2..ebbc5946959 100644 --- a/src/Analyser/ExprHandler/NullsafeMethodCallHandler.php +++ b/src/Analyser/ExprHandler/NullsafeMethodCallHandler.php @@ -92,6 +92,7 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex $exprResult = $nodeScopeResolver->processExprNodeConsumingStored( $stmt, $methodCall, + $expr->var, $nonNullabilityResult->getScope(), $storage, $nodeCallback, diff --git a/src/Analyser/ExprHandler/NullsafePropertyFetchHandler.php b/src/Analyser/ExprHandler/NullsafePropertyFetchHandler.php index a2966a59ce2..b54f05529d5 100644 --- a/src/Analyser/ExprHandler/NullsafePropertyFetchHandler.php +++ b/src/Analyser/ExprHandler/NullsafePropertyFetchHandler.php @@ -85,7 +85,7 @@ public function processExpr(NodeScopeResolver $nodeScopeResolver, Stmt $stmt, Ex $expr->name, $attributes, ); - $exprResult = $nodeScopeResolver->processExprNodeConsumingStored($stmt, $propertyFetch, $nonNullabilityResult->getScope(), $storage, $nodeCallback, $context); + $exprResult = $nodeScopeResolver->processExprNodeConsumingStored($stmt, $propertyFetch, $expr->var, $nonNullabilityResult->getScope(), $storage, $nodeCallback, $context); $scope = $this->nonNullabilityHelper->revertNonNullability($exprResult->getScope(), $nonNullabilityResult->getSpecifiedExpressions()); // The `?->`'s own type on the asking scope. $receiverType is the receiver's diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 6d43f10e951..3c917bbb589 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -80,10 +80,13 @@ class NodeScopeResolver /** * Consume-stored mode: a walk that deliberately re-enters an * already-walked subtree (the nullsafe plain twin re-walking its - * receiver) consumes stored results unconditionally instead of - * re-processing - node callbacks fired during the original walk. + * receiver) consumes this node's stored result unconditionally instead + * of re-processing it - node callbacks fired during the original walk. + * Only this exact node is consumed: the rest of the twin (arguments, + * a dynamic name) is walked normally, even when the storage was seeded + * with results of an earlier loop convergence pass. */ - private bool $consumeStoredExpressionResults = false; + private ?Expr $consumeStoredExpression = null; private ?NonNullabilityHelper $nonNullabilityHelper = null; @@ -493,12 +496,6 @@ public function isReturningStoredExpressionResults(): bool return $this->returnStoredExpressionResults; } - /** Whether the walk consumes stored results unconditionally (see processExprNodeConsumingStored()). */ - public function isConsumingStoredExpressionResults(): bool - { - return $this->consumeStoredExpressionResults; - } - public function lookForSetAllowedUndefinedExpressions(MutatingScope $scope, Expr $expr): MutatingScope { return $this->lookForExpressionCallback($scope, $expr, static fn (MutatingScope $scope, Expr $expr): MutatingScope => $scope->setAllowedUndefinedExpression($expr)); @@ -544,22 +541,22 @@ private function lookForExpressionCallback(MutatingScope $scope, Expr $expr, Clo * are stored into the given storage - pass a duplicate to keep them isolated. */ /** - * Processes an expression whose already-walked subtrees must be CONSUMED - * from their stored results instead of re-walked: the nullsafe handlers + * Processes an expression whose already-walked receiver must be CONSUMED + * from its stored result instead of re-walked: the nullsafe handlers * process the receiver once (real callbacks) and then walk the plain twin, - * whose receiver subtree answers from storage, re-anchored to the twin's + * whose receiver answers from storage, re-anchored to the twin's * (ensured) scope. * * @param callable(Node $node, Scope $scope): void $nodeCallback */ - public function processExprNodeConsumingStored(Node\Stmt $stmt, Expr $expr, MutatingScope $scope, ExpressionResultStorage $storage, callable $nodeCallback, ExpressionContext $context): ExpressionResult + public function processExprNodeConsumingStored(Node\Stmt $stmt, Expr $expr, Expr $consumedExpr, MutatingScope $scope, ExpressionResultStorage $storage, callable $nodeCallback, ExpressionContext $context): ExpressionResult { - $previous = $this->consumeStoredExpressionResults; - $this->consumeStoredExpressionResults = true; + $previous = $this->consumeStoredExpression; + $this->consumeStoredExpression = $consumedExpr; try { return $this->processExprNode($stmt, $expr, $scope, $storage, $nodeCallback, $context); } finally { - $this->consumeStoredExpressionResults = $previous; + $this->consumeStoredExpression = $previous; } } @@ -775,7 +772,8 @@ public function processExprNode( ExpressionContext $context, ): ExpressionResult { - if ($this->returnStoredExpressionResults || $this->consumeStoredExpressionResults) { + $consume = $this->consumeStoredExpression === $expr; + if ($this->returnStoredExpressionResults || $consume) { $storedResult = $storage->findExpressionResult($expr); // a stored result only answers when the current scope agrees with its // evaluation position on the variables the expression reads - a @@ -784,7 +782,7 @@ public function processExprNode( // re-processes the node on its own scope instead. In CONSUME mode the // divergence is intentional (an ensured-non-null device) and the // stored result is consumed unconditionally, re-anchored below. - if ($storedResult !== null && ($this->consumeStoredExpressionResults || $storedResult->askScopeVariableStateMatches($scope, $scope->nativeTypesPromoted))) { + if ($storedResult !== null && ($consume || $storedResult->askScopeVariableStateMatches($scope, $scope->nativeTypesPromoted))) { // a foreign-position answer must not thread its original walk // scopes into THIS walk - re-anchor it to the asking position so // subsequent operands keep evaluating on the asking scope @@ -793,7 +791,7 @@ public function processExprNode( } $reanchored = $storedResult->atAskPosition($scope); - if ($this->consumeStoredExpressionResults) { + if ($consume) { // the re-anchored view IS this walk's result for the node // (the nullsafe twin's receiver at the ensured position) - // store it so later asks (rules' storage reads) see the same diff --git a/tests/PHPStan/Analyser/AnalyserIntegrationTest.php b/tests/PHPStan/Analyser/AnalyserIntegrationTest.php index eb6149da32e..ac5201a9242 100644 --- a/tests/PHPStan/Analyser/AnalyserIntegrationTest.php +++ b/tests/PHPStan/Analyser/AnalyserIntegrationTest.php @@ -16,6 +16,7 @@ use function array_map; use function array_unique; use function array_values; +use function count; use function extension_loaded; use function sprintf; use const PHP_VERSION_ID; @@ -1807,6 +1808,31 @@ public function testBug15331(): void $this->assertNoErrors($errors); } + #[RequiresPhp('>= 8.0.0')] + public function testBug15520(): void + { + $errors = $this->runAnalyse(__DIR__ . '/data/bug-15520.php'); + $expected = [ + ['Access to an undefined property Bug15520\\Presenter::$undefinedProperty.', 20], + ['Binary operation "+" between 1 and \'x\' results in an error.', 20], + ['Call to an undefined method Bug15520\\Presenter::undefinedMethod().', 20], + ['Method Bug15520\\Category::imageFor() invoked with 2 parameters, 1 required.', 20], + ['Call to an undefined method Bug15520\\Presenter::undefinedWhile().', 33], + ['Call to an undefined method Bug15520\\Presenter::undefinedDoWhile().', 46], + ['Call to an undefined method Bug15520\\Presenter::undefinedFor().', 59], + ['Call to an undefined method Bug15520\\Presenter::undefinedInClosure().', 74], + ['Call to an undefined method Bug15520\\Presenter::undefinedInArrowFunction().', 76], + ['Call to an undefined method Bug15520\\Presenter::undefinedInPropertyName().', 90], + ['Call to an undefined method Bug15520\\Presenter::undefinedInNested().', 104], + ['Call to an undefined method Bug15520\\Presenter::undefinedInMethodName().', 105], + ]; + $this->assertCount(count($expected), $errors); + foreach ($expected as $i => [$message, $line]) { + $this->assertSame($message, $errors[$i]->getMessage()); + $this->assertSame($line, $errors[$i]->getLine()); + } + } + /** * @param string[]|null $allAnalysedFiles * @return list diff --git a/tests/PHPStan/Analyser/data/bug-15520.php b/tests/PHPStan/Analyser/data/bug-15520.php new file mode 100644 index 00000000000..6830301043d --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-15520.php @@ -0,0 +1,110 @@ + $categories + * @return list + */ + public function images(array $categories): array + { + $images = []; + foreach ($categories as $category) { + $images[] = $category?->imageFor($this->undefinedMethod($this->undefinedProperty), 1 + 'x'); + } + + return $images; + } + + /** + * @return list + */ + public function whileLoop(?Category $category): array + { + $images = []; + while (count($images) < 10) { + $images[] = $category?->imageFor($this->undefinedWhile()); + } + + return $images; + } + + /** + * @return list + */ + public function doWhileLoop(?Category $category): array + { + $images = []; + do { + $images[] = $category?->imageFor($this->undefinedDoWhile()); + } while (count($images) < 10); + + return $images; + } + + /** + * @return list + */ + public function forLoop(?Category $category): array + { + $images = []; + for ($i = 0; $i < 10; $i++) { + $images[] = $category?->imageFor($this->undefinedFor()); + } + + return $images; + } + + /** + * @param list $categories + * @return list + */ + public function closureArgument(array $categories): array + { + $images = []; + foreach ($categories as $category) { + $images[] = $category?->imageFor((function (): string { + return $this->undefinedInClosure(); + })()); + $images[] = $category?->imageFor((fn (): string => $this->undefinedInArrowFunction())()); + } + + return $images; + } + + /** + * @param list $objects + * @return list + */ + public function nullsafePropertyFetch(array $objects, string $name): array + { + $values = []; + foreach ($objects as $object) { + $values[] = $object?->{$name . $this->undefinedInPropertyName()}; + } + + return $values; + } + + /** + * @param list $categories + * @return list + */ + public function nestedAndChained(array $categories, string $method): array + { + $images = []; + foreach ($categories as $category) { + $images[] = $category?->imageFor($category?->imageFor($this->undefinedInNested()) ?? ''); + $images[] = $category?->{$method . $this->undefinedInMethodName()}(); + } + + return $images; + } +} diff --git a/tests/PHPStan/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php b/tests/PHPStan/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php index 0bbef747ba9..b49feb428af 100644 --- a/tests/PHPStan/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php +++ b/tests/PHPStan/Rules/DeadCode/UnusedPrivatePropertyRuleTest.php @@ -475,6 +475,15 @@ public function testBug14703(): void $this->analyse([__DIR__ . '/data/bug-14703.php'], []); } + #[RequiresPhp('>= 8.0.0')] + public function testBug15520(): void + { + $this->alwaysWrittenTags = []; + $this->alwaysReadTags = []; + + $this->analyse([__DIR__ . '/data/bug-15520.php'], []); + } + public function testBug14880(): void { $this->alwaysWrittenTags = []; diff --git a/tests/PHPStan/Rules/DeadCode/data/bug-15520.php b/tests/PHPStan/Rules/DeadCode/data/bug-15520.php new file mode 100644 index 00000000000..1ef33529620 --- /dev/null +++ b/tests/PHPStan/Rules/DeadCode/data/bug-15520.php @@ -0,0 +1,81 @@ += 8.0 + +namespace Bug15520Property; + +interface SeasonResolver +{ + public function current(): string; +} + +interface Category +{ + public function imageFor(string $season): ?string; +} + +final class Presenter +{ + public function __construct( + private SeasonResolver $seasonResolver, + ) + { + } + + /** + * @param list $categories + * @return list + */ + public function images(array $categories): array + { + $images = []; + foreach ($categories as $category) { + $images[] = $category?->imageFor($this->seasonResolver->current()); + } + + return $images; + } +} + +final class WhilePresenter +{ + public function __construct( + private SeasonResolver $seasonResolver, + ) + { + } + + /** + * @return list + */ + public function images(?Category $category): array + { + $images = []; + while (count($images) < 10) { + $images[] = $category?->imageFor($this->seasonResolver->current()); + } + + return $images; + } +} + +final class PropertyNamePresenter +{ + public function __construct( + private string $name, + ) + { + } + + /** + * @param list $objects + * @return list + */ + public function values(array $objects): array + { + $values = []; + foreach ($objects as $object) { + $values[] = $object?->{$this->name}; + } + + return $values; + } +} diff --git a/turbo-ext/src/ArgumentsHandler.cpp b/turbo-ext/src/ArgumentsHandler.cpp index f6dcb74d7fa..38f71d9d63d 100644 --- a/turbo-ext/src/ArgumentsHandler.cpp +++ b/turbo-ext/src/ArgumentsHandler.cpp @@ -339,11 +339,6 @@ inline bool nsrIsReturningStoredExpressionResults(zval *nodeScopeResolver, bool return pt_node_scope_resolver_is_returning_stored_expression_results(nodeScopeResolver, out); } -inline bool nsrIsConsumingStoredExpressionResults(zval *nodeScopeResolver, bool &out) -{ - return pt_node_scope_resolver_is_consuming_stored_expression_results(nodeScopeResolver, out); -} - inline bool nsrStoreExpressionResult(zval *nodeScopeResolver, zval *storage, zval *expr, zval *result) { return pt_node_scope_resolver_store_expression_result(nodeScopeResolver, storage, expr, result); @@ -1746,11 +1741,10 @@ class ArgumentsHandler zend_never_inline zv::Val storedClosureArgResult(Walk &w, zval *value, zval *scopeToPass, bool &failed) const { failed = true; - bool returning = false, consuming = false; + bool returning = false; if (UNEXPECTED(!nsrIsReturningStoredExpressionResults(w.nodeScopeResolver, returning))) return zv::Val(); - if (!returning && UNEXPECTED(!nsrIsConsumingStoredExpressionResults(w.nodeScopeResolver, consuming))) return zv::Val(); failed = false; - if (!returning && !consuming) return zv::Val(); + if (!returning) return zv::Val(); failed = true; zv::Val stored = pt_expression_result_storage_find(w.storage, value); @@ -1759,12 +1753,6 @@ class ArgumentsHandler failed = false; return stored; } - bool returningAgain = false; - if (UNEXPECTED(!nsrIsReturningStoredExpressionResults(w.nodeScopeResolver, returningAgain))) return zv::Val(); - if (!returningAgain) { - failed = false; - return zv::Val(); - } zval *closureTypeResolver = slot(slots::closureTypeResolver); zv::Val type = closureTypeResolverGetClosureType(closureTypeResolver, scopeToPass, value, false, w.storage); if (UNEXPECTED(type.isUndef())) return zv::Val(); diff --git a/turbo-ext/src/NodeScopeResolver.cpp b/turbo-ext/src/NodeScopeResolver.cpp index 4cadeb7f040..a43af8a662b 100644 --- a/turbo-ext/src/NodeScopeResolver.cpp +++ b/turbo-ext/src/NodeScopeResolver.cpp @@ -714,8 +714,6 @@ class NodeScopeResolver bool isReturningStoredExpressionResults() const { return flag(slots::returnStoredExpressionResults); } - bool isConsumingStoredExpressionResults() const { return flag(slots::consumeStoredExpressionResults); } - /* Mirrors lookForSetAllowedUndefinedExpressions() / * lookForUnsetAllowedUndefinedExpressions() over the private * lookForExpressionCallback() */ @@ -730,12 +728,12 @@ class NodeScopeResolver } /* Mirrors processExprNodeConsumingStored(). */ - zv::Val processExprNodeConsumingStored(zval *stmt, zval *expr, zval *scope, zval *storage, zval *nodeCallback, zval *context) + zv::Val processExprNodeConsumingStored(zval *stmt, zval *expr, zval *consumedExpr, zval *scope, zval *storage, zval *nodeCallback, zval *context) { - bool previous = flag(slots::consumeStoredExpressionResults); - setFlag(slots::consumeStoredExpressionResults, true); + zv::Val previous = zv::Val::copyOf(slot(slots::consumeStoredExpression).deref()); + slot(slots::consumeStoredExpression).deref().assign(zv::Val::copyOf(zv::Ref(consumedExpr))); zv::Val result = thisProcessExprNode(stmt, expr, scope, storage, nodeCallback, context); - pt_finally([&]() { setFlag(slots::consumeStoredExpressionResults, previous); }); + pt_finally([&]() { slot(slots::consumeStoredExpression).deref().assign(std::move(previous)); }); if (UNEXPECTED(EG(exception))) return zv::Val(); return result; } @@ -1951,11 +1949,13 @@ class NodeScopeResolver zv::Val processExprNodeBody(zval *stmt, zval *expr, zval *scope, zval *storage, zval *nodeCallback, zval *context) { - if (flag(slots::returnStoredExpressionResults) || flag(slots::consumeStoredExpressionResults)) { + zv::Ref consumedExpr = slot(slots::consumeStoredExpression).deref(); + bool consume = consumedExpr.isObject() && consumedExpr.asObject() == Z_OBJ_P(expr); + if (flag(slots::returnStoredExpressionResults) || consume) { zv::Val storedResult = pt_expression_result_storage_find(storage, expr); if (UNEXPECTED(storedResult.isUndef())) return zv::Val(); if (!storedResult.isNull()) { - bool answers = flag(slots::consumeStoredExpressionResults); + bool answers = consume; if (!answers) { bool promoted; if (UNEXPECTED(!pt_mutating_scope_native_types_promoted(Z_OBJ_P(scope), promoted))) return zv::Val(); @@ -1968,7 +1968,7 @@ class NodeScopeResolver zv::Val reanchored = pt_expression_result_at_ask_position(storedResult.raw(), scope); if (UNEXPECTED(reanchored.isUndef())) return zv::Val(); - if (flag(slots::consumeStoredExpressionResults) && UNEXPECTED(!thisStoreExpressionResult(storage, expr, reanchored.raw()))) return zv::Val(); + if (consume && UNEXPECTED(!thisStoreExpressionResult(storage, expr, reanchored.raw()))) return zv::Val(); return reanchored; } } @@ -2381,24 +2381,12 @@ bool pt_node_scope_resolver_is_returning_stored_expression_results(zval *nodeSco return true; } -bool pt_node_scope_resolver_is_consuming_stored_expression_results(zval *nodeScopeResolver, bool &out) -{ - if (isNativeResolver(nodeScopeResolver)) { - out = NodeScopeResolver(Z_OBJ_P(nodeScopeResolver)).isConsumingStoredExpressionResults(); - return true; - } - zv::Val result = pt_type_call(Z_OBJ_P(nodeScopeResolver), PT_LC("isconsumingstoredexpressionresults"), 0, NULL); - if (UNEXPECTED(result.isUndef())) return false; - out = zend_is_true(result.raw()); - return true; -} - /* the fetch handlers' (NullsafePropertyFetchHandler.cpp) */ -zv::Val pt_node_scope_resolver_process_expr_node_consuming_stored(zval *nodeScopeResolver, zval *stmt, zval *expr, zval *scope, zval *storage, zval *nodeCallback, zval *context) +zv::Val pt_node_scope_resolver_process_expr_node_consuming_stored(zval *nodeScopeResolver, zval *stmt, zval *expr, zval *consumedExpr, zval *scope, zval *storage, zval *nodeCallback, zval *context) { - if (isNativeResolver(nodeScopeResolver)) return NodeScopeResolver(Z_OBJ_P(nodeScopeResolver)).processExprNodeConsumingStored(stmt, expr, scope, storage, nodeCallback, context); - zv::Args argv{stmt, expr, scope, storage, nodeCallback, context}; - return pt_type_call(Z_OBJ_P(nodeScopeResolver), PT_LC("processexprnodeconsumingstored"), 6, argv); + if (isNativeResolver(nodeScopeResolver)) return NodeScopeResolver(Z_OBJ_P(nodeScopeResolver)).processExprNodeConsumingStored(stmt, expr, consumedExpr, scope, storage, nodeCallback, context); + zv::Args argv{stmt, expr, consumedExpr, scope, storage, nodeCallback, context}; + return pt_type_call(Z_OBJ_P(nodeScopeResolver), PT_LC("processexprnodeconsumingstored"), 7, argv); } /* the closure walk's (ClosureProcessor.cpp) */ @@ -2626,11 +2614,6 @@ PT_MINIT_REGISTRATION(pt_register_node_scope_resolver) RETURN_BOOL(PT_NSR_THIS.isReturningStoredExpressionResults()); }); - cls.method(sigs::isConsumingStoredExpressionResults, [](INTERNAL_FUNCTION_PARAMETERS) { - ZEND_PARSE_PARAMETERS_NONE(); - RETURN_BOOL(PT_NSR_THIS.isConsumingStoredExpressionResults()); - }); - cls.method(sigs::lookForSetAllowedUndefinedExpressions, [](INTERNAL_FUNCTION_PARAMETERS) { zval *scope, *expr; ZEND_PARSE_PARAMETERS_START(2, 2) @@ -2650,16 +2633,17 @@ PT_MINIT_REGISTRATION(pt_register_node_scope_resolver) }); cls.method(sigs::processExprNodeConsumingStored, [](INTERNAL_FUNCTION_PARAMETERS) { - zval *stmt, *expr, *scope, *storage, *nodeCallback, *context; - ZEND_PARSE_PARAMETERS_START(6, 6) + zval *stmt, *expr, *consumedExpr, *scope, *storage, *nodeCallback, *context; + ZEND_PARSE_PARAMETERS_START(7, 7) Z_PARAM_OBJECT(stmt) Z_PARAM_OBJECT(expr) + Z_PARAM_OBJECT(consumedExpr) Z_PARAM_OBJECT(scope) Z_PARAM_OBJECT(storage) Z_PARAM_ZVAL(nodeCallback) Z_PARAM_OBJECT(context) ZEND_PARSE_PARAMETERS_END(); - PT_RETURN_VAL(PT_NSR_THIS.processExprNodeConsumingStored(stmt, expr, scope, storage, nodeCallback, context)); + PT_RETURN_VAL(PT_NSR_THIS.processExprNodeConsumingStored(stmt, expr, consumedExpr, scope, storage, nodeCallback, context)); }); cls.method(sigs::processExprOnDemand, [](INTERNAL_FUNCTION_PARAMETERS) { diff --git a/turbo-ext/src/NullsafeMethodCallHandler.cpp b/turbo-ext/src/NullsafeMethodCallHandler.cpp index 7f223020416..e1ec35da861 100644 --- a/turbo-ext/src/NullsafeMethodCallHandler.cpp +++ b/turbo-ext/src/NullsafeMethodCallHandler.cpp @@ -229,7 +229,7 @@ class NullsafeMethodCallHandler { zv::Val ensuredScope = ensuredResultScope(nonNullabilityResult.raw()); if (UNEXPECTED(ensuredScope.isUndef())) return zv::Val(); - exprResult = pt_node_scope_resolver_process_expr_node_consuming_stored(nodeScopeResolver, stmt, methodCall.raw(), ensuredScope.raw(), storage, nodeCallback, context); + exprResult = pt_node_scope_resolver_process_expr_node_consuming_stored(nodeScopeResolver, stmt, methodCall.raw(), var, ensuredScope.raw(), storage, nodeCallback, context); if (UNEXPECTED(exprResult.isUndef())) return zv::Val(); } { diff --git a/turbo-ext/src/NullsafePropertyFetchHandler.cpp b/turbo-ext/src/NullsafePropertyFetchHandler.cpp index 73bb77d4647..484f20acfd1 100644 --- a/turbo-ext/src/NullsafePropertyFetchHandler.cpp +++ b/turbo-ext/src/NullsafePropertyFetchHandler.cpp @@ -222,7 +222,7 @@ class NullsafePropertyFetchHandler { zv::Val ensuredScope = ensuredResultScope(nonNullabilityResult.raw()); if (UNEXPECTED(ensuredScope.isUndef())) return zv::Val(); - exprResult = pt_node_scope_resolver_process_expr_node_consuming_stored(nodeScopeResolver, stmt, propertyFetch.raw(), ensuredScope.raw(), storage, nodeCallback, context); + exprResult = pt_node_scope_resolver_process_expr_node_consuming_stored(nodeScopeResolver, stmt, propertyFetch.raw(), var, ensuredScope.raw(), storage, nodeCallback, context); if (UNEXPECTED(exprResult.isUndef())) return zv::Val(); } { diff --git a/turbo-ext/src/generated/NodeScopeResolver.h b/turbo-ext/src/generated/NodeScopeResolver.h index 754c18e3fcb..f2094138355 100644 --- a/turbo-ext/src/generated/NodeScopeResolver.h +++ b/turbo-ext/src/generated/NodeScopeResolver.h @@ -12,7 +12,7 @@ namespace ptdecl::NodeScopeResolver { namespace slot { inline constexpr uint32_t analysedFiles = 0; inline constexpr uint32_t returnStoredExpressionResults = 1; -inline constexpr uint32_t consumeStoredExpressionResults = 2; +inline constexpr uint32_t consumeStoredExpression = 2; inline constexpr uint32_t nonNullabilityHelper = 3; inline constexpr uint32_t nodeGatherers = 4; inline constexpr uint32_t container = 5; @@ -33,7 +33,7 @@ inline void declareProperties(reg::Class &cls) { cls.property("analysedFiles", ZEND_ACC_PRIVATE, reg::PropertyKind::TypedEmptyArray, MAY_BE_ARRAY); cls.property("returnStoredExpressionResults", ZEND_ACC_PROTECTED, reg::PropertyKind::TypedBool, 0); - cls.property("consumeStoredExpressionResults", ZEND_ACC_PRIVATE, reg::PropertyKind::TypedBool, 0); + cls.property("consumeStoredExpression", ZEND_ACC_PRIVATE, reg::PropertyKind::TypedNull, MAY_BE_NULL, "PhpParser\\Node\\Expr"); cls.property("nonNullabilityHelper", ZEND_ACC_PRIVATE, reg::PropertyKind::TypedNull, MAY_BE_NULL, "PHPStan\\Analyser\\ExprHandler\\Helper\\NonNullabilityHelper"); cls.property("nodeGatherers", ZEND_ACC_PRIVATE, reg::PropertyKind::TypedEmptyArray, MAY_BE_ARRAY); cls.property("guardNewWorld", ZEND_ACC_PUBLIC | ZEND_ACC_STATIC, reg::PropertyKind::TypedBool, 0); @@ -105,65 +105,65 @@ inline constexpr char strings[] = "fileName\0" /* 1131 */ "isAnalysedFile\0" /* 1140 */ "isReturningStoredExpressionResults\0" /* 1155 */ - "isConsumingStoredExpressionResults\0" /* 1190 */ - "lookForSetAllowedUndefinedExpressions\0" /* 1225 */ - "lookForUnsetAllowedUndefinedExpressions\0" /* 1263 */ - "callback\0" /* 1303 */ - "Closure\0" /* 1312 */ - "lookForExpressionCallback\0" /* 1320 */ - "PHPStan\\Analyser\\ExpressionContext\0" /* 1346 */ - "processExprNodeConsumingStored\0" /* 1381 */ - "processExprOnDemand\0" /* 1412 */ - "readStoredResult\0" /* 1432 */ - "PHPStan\\Type\\Type\0" /* 1449 */ - "readTypeOfMaybeStored\0" /* 1467 */ - "findScopeStateType\0" /* 1489 */ - "readScopeStateOrSyntheticType\0" /* 1508 */ - "requireScopeStateType\0" /* 1538 */ - "caller\0" /* 1560 */ - "guardAgainstUnprocessedRealNode\0" /* 1567 */ - "processSyntheticOnDemand\0" /* 1599 */ - "processExprNode\0" /* 1624 */ - "processExprNodeInternal\0" /* 1640 */ - "propertyFetch\0" /* 1664 */ - "PhpParser\\Node\\Expr\\PropertyFetch\0" /* 1678 */ - "propertyReflection\0" /* 1712 */ - "PHPStan\\Reflection\\Php\\PhpPropertyReflection\0" /* 1731 */ - "hookName\0" /* 1776 */ - "getImpurePointsFromPropertyHook\0" /* 1785 */ - "isPropertyHookBackingValueAccess\0" /* 1817 */ - "getAssignedVariables\0" /* 1850 */ - "loopNode\0" /* 1871 */ - "bodyStmts\0" /* 1880 */ - "isReplayableConvergenceBody\0" /* 1890 */ - "isContextSensitiveStatement\0" /* 1918 */ - "node\0" /* 1946 */ - "hasContextSensitiveConstruct\0" /* 1951 */ - "gatherer\0" /* 1980 */ - "pushNodeGatherer\0" /* 1989 */ - "popNodeGatherer\0" /* 2006 */ - "suspendNodeGatherers\0" /* 2022 */ - "gatherers\0" /* 2043 */ - "restoreNodeGatherers\0" /* 2053 */ - "recording\0" /* 2074 */ - "PHPStan\\Analyser\\RecordingNodeCallback\0" /* 2084 */ - "replayRecording\0" /* 2123 */ - "from\0" /* 2139 */ - "to\0" /* 2144 */ - "replayRecordingRange\0" /* 2147 */ - "callNodeCallbackWithExpression\0" /* 2168 */ - "callNodeCallback\0" /* 2199 */ - "PHPStan\\Analyser\\Generics\\TemplateArgumentFrame\0" /* 2216 */ - "observingTemplateArgumentFrame\0" /* 2264 */ - "returnedResult\0" /* 2295 */ - "PHPStan\\Analyser\\Generics\\TemplateArgumentConstraints\0" /* 2310 */ - "collectReturnSend\0" /* 2364 */ - "keyType\0" /* 2382 */ - "valueType\0" /* 2390 */ - "collectYieldSend\0" /* 2400 */ - "delegatedType\0" /* 2417 */ - "collectYieldFromSend\0" /* 2431 */ - "getDeclaredReturnType"; /* 2452 */ + "lookForSetAllowedUndefinedExpressions\0" /* 1190 */ + "lookForUnsetAllowedUndefinedExpressions\0" /* 1228 */ + "callback\0" /* 1268 */ + "Closure\0" /* 1277 */ + "lookForExpressionCallback\0" /* 1285 */ + "consumedExpr\0" /* 1311 */ + "PHPStan\\Analyser\\ExpressionContext\0" /* 1324 */ + "processExprNodeConsumingStored\0" /* 1359 */ + "processExprOnDemand\0" /* 1390 */ + "readStoredResult\0" /* 1410 */ + "PHPStan\\Type\\Type\0" /* 1427 */ + "readTypeOfMaybeStored\0" /* 1445 */ + "findScopeStateType\0" /* 1467 */ + "readScopeStateOrSyntheticType\0" /* 1486 */ + "requireScopeStateType\0" /* 1516 */ + "caller\0" /* 1538 */ + "guardAgainstUnprocessedRealNode\0" /* 1545 */ + "processSyntheticOnDemand\0" /* 1577 */ + "processExprNode\0" /* 1602 */ + "processExprNodeInternal\0" /* 1618 */ + "propertyFetch\0" /* 1642 */ + "PhpParser\\Node\\Expr\\PropertyFetch\0" /* 1656 */ + "propertyReflection\0" /* 1690 */ + "PHPStan\\Reflection\\Php\\PhpPropertyReflection\0" /* 1709 */ + "hookName\0" /* 1754 */ + "getImpurePointsFromPropertyHook\0" /* 1763 */ + "isPropertyHookBackingValueAccess\0" /* 1795 */ + "getAssignedVariables\0" /* 1828 */ + "loopNode\0" /* 1849 */ + "bodyStmts\0" /* 1858 */ + "isReplayableConvergenceBody\0" /* 1868 */ + "isContextSensitiveStatement\0" /* 1896 */ + "node\0" /* 1924 */ + "hasContextSensitiveConstruct\0" /* 1929 */ + "gatherer\0" /* 1958 */ + "pushNodeGatherer\0" /* 1967 */ + "popNodeGatherer\0" /* 1984 */ + "suspendNodeGatherers\0" /* 2000 */ + "gatherers\0" /* 2021 */ + "restoreNodeGatherers\0" /* 2031 */ + "recording\0" /* 2052 */ + "PHPStan\\Analyser\\RecordingNodeCallback\0" /* 2062 */ + "replayRecording\0" /* 2101 */ + "from\0" /* 2117 */ + "to\0" /* 2122 */ + "replayRecordingRange\0" /* 2125 */ + "callNodeCallbackWithExpression\0" /* 2146 */ + "callNodeCallback\0" /* 2177 */ + "PHPStan\\Analyser\\Generics\\TemplateArgumentFrame\0" /* 2194 */ + "observingTemplateArgumentFrame\0" /* 2242 */ + "returnedResult\0" /* 2273 */ + "PHPStan\\Analyser\\Generics\\TemplateArgumentConstraints\0" /* 2288 */ + "collectReturnSend\0" /* 2342 */ + "keyType\0" /* 2360 */ + "valueType\0" /* 2368 */ + "collectYieldSend\0" /* 2378 */ + "delegatedType\0" /* 2395 */ + "collectYieldFromSend\0" /* 2409 */ + "getDeclaredReturnType"; /* 2430 */ inline constexpr reg::PackedArg args[] = { reg::packed(0, 0, 10), /* __construct $container */ reg::packed(48, 0, 73), /* __construct $templateArgumentObserver */ @@ -230,7 +230,6 @@ inline constexpr reg::PackedArg args[] = { reg::packed(1131, MAY_BE_STRING), /* isAnalysedFile $fileName */ reg::packed(371, MAY_BE_BOOL), /* isAnalysedFile return */ reg::packed(371, MAY_BE_BOOL), /* isReturningStoredExpressionResults return */ - reg::packed(371, MAY_BE_BOOL), /* isConsumingStoredExpressionResults return */ reg::packed(502, 0, 508), /* lookForSetAllowedUndefinedExpressions $scope */ reg::packed(663, 0, 668), /* lookForSetAllowedUndefinedExpressions $expr */ reg::packed(371, 0, 508), /* lookForSetAllowedUndefinedExpressions return */ @@ -239,14 +238,15 @@ inline constexpr reg::PackedArg args[] = { reg::packed(371, 0, 508), /* lookForUnsetAllowedUndefinedExpressions return */ reg::packed(502, 0, 508), /* lookForExpressionCallback $scope */ reg::packed(663, 0, 668), /* lookForExpressionCallback $expr */ - reg::packed(1303, 0, 1312), /* lookForExpressionCallback $callback */ + reg::packed(1268, 0, 1277), /* lookForExpressionCallback $callback */ reg::packed(371, 0, 508), /* lookForExpressionCallback return */ reg::packed(1090, 0, 1095), /* processExprNodeConsumingStored $stmt */ reg::packed(663, 0, 668), /* processExprNodeConsumingStored $expr */ + reg::packed(1311, 0, 668), /* processExprNodeConsumingStored $consumedExpr */ reg::packed(502, 0, 508), /* processExprNodeConsumingStored $scope */ reg::packed(614, 0, 622), /* processExprNodeConsumingStored $storage */ reg::packed(539, MAY_BE_CALLABLE), /* processExprNodeConsumingStored $nodeCallback */ - reg::packed(761, 0, 1346), /* processExprNodeConsumingStored $context */ + reg::packed(761, 0, 1324), /* processExprNodeConsumingStored $context */ reg::packed(371, 0, 705), /* processExprNodeConsumingStored return */ reg::packed(663, 0, 668), /* processExprOnDemand $expr */ reg::packed(502, 0, 508), /* processExprOnDemand $scope */ @@ -257,18 +257,18 @@ inline constexpr reg::PackedArg args[] = { reg::packed(371, 0, 705), /* readStoredResult return */ reg::packed(663, 0, 668), /* readTypeOfMaybeStored $expr */ reg::packed(502, 0, 508), /* readTypeOfMaybeStored $scope */ - reg::packed(371, 0, 1449), /* readTypeOfMaybeStored return */ + reg::packed(371, 0, 1427), /* readTypeOfMaybeStored return */ reg::packed(663, 0, 668), /* findScopeStateType $expr */ reg::packed(502, 0, 508), /* findScopeStateType $scope */ - reg::packed(371, MAY_BE_NULL, 1449), /* findScopeStateType return */ + reg::packed(371, MAY_BE_NULL, 1427), /* findScopeStateType return */ reg::packed(663, 0, 668), /* readScopeStateOrSyntheticType $expr */ reg::packed(502, 0, 508), /* readScopeStateOrSyntheticType $scope */ - reg::packed(371, 0, 1449), /* readScopeStateOrSyntheticType return */ + reg::packed(371, 0, 1427), /* readScopeStateOrSyntheticType return */ reg::packed(663, 0, 668), /* requireScopeStateType $expr */ reg::packed(502, 0, 508), /* requireScopeStateType $scope */ - reg::packed(371, 0, 1449), /* requireScopeStateType return */ + reg::packed(371, 0, 1427), /* requireScopeStateType return */ reg::packed(663, 0, 668), /* guardAgainstUnprocessedRealNode $expr */ - reg::packed(1560, MAY_BE_STRING), /* guardAgainstUnprocessedRealNode $caller */ + reg::packed(1538, MAY_BE_STRING), /* guardAgainstUnprocessedRealNode $caller */ reg::packed(371, MAY_BE_VOID), /* guardAgainstUnprocessedRealNode return */ reg::packed(663, 0, 668), /* processSyntheticOnDemand $expr */ reg::packed(502, 0, 508), /* processSyntheticOnDemand $scope */ @@ -278,46 +278,46 @@ inline constexpr reg::PackedArg args[] = { reg::packed(502, 0, 508), /* processExprNode $scope */ reg::packed(614, 0, 622), /* processExprNode $storage */ reg::packed(539, MAY_BE_CALLABLE), /* processExprNode $nodeCallback */ - reg::packed(761, 0, 1346), /* processExprNode $context */ + reg::packed(761, 0, 1324), /* processExprNode $context */ reg::packed(371, 0, 705), /* processExprNode return */ reg::packed(1090, 0, 1095), /* processExprNodeInternal $stmt */ reg::packed(663, 0, 668), /* processExprNodeInternal $expr */ reg::packed(502, 0, 508), /* processExprNodeInternal $scope */ reg::packed(614, 0, 622), /* processExprNodeInternal $storage */ reg::packed(539, MAY_BE_CALLABLE), /* processExprNodeInternal $nodeCallback */ - reg::packed(761, 0, 1346), /* processExprNodeInternal $context */ + reg::packed(761, 0, 1324), /* processExprNodeInternal $context */ reg::packed(371, 0, 705), /* processExprNodeInternal return */ reg::packed(502, 0, 508), /* getImpurePointsFromPropertyHook $scope */ - reg::packed(1664, 0, 1678), /* getImpurePointsFromPropertyHook $propertyFetch */ - reg::packed(1712, 0, 1731), /* getImpurePointsFromPropertyHook $propertyReflection */ - reg::packed(1776, MAY_BE_STRING), /* getImpurePointsFromPropertyHook $hookName */ + reg::packed(1642, 0, 1656), /* getImpurePointsFromPropertyHook $propertyFetch */ + reg::packed(1690, 0, 1709), /* getImpurePointsFromPropertyHook $propertyReflection */ + reg::packed(1754, MAY_BE_STRING), /* getImpurePointsFromPropertyHook $hookName */ reg::packed(371, MAY_BE_ARRAY), /* getImpurePointsFromPropertyHook return */ reg::packed(502, 0, 508), /* isPropertyHookBackingValueAccess $scope */ - reg::packed(1664, 0, 1678), /* isPropertyHookBackingValueAccess $propertyFetch */ + reg::packed(1642, 0, 1656), /* isPropertyHookBackingValueAccess $propertyFetch */ reg::packed(371, MAY_BE_BOOL), /* isPropertyHookBackingValueAccess return */ reg::packed(663, 0, 668), /* getAssignedVariables $expr */ reg::packed(371, MAY_BE_ARRAY), /* getAssignedVariables return */ - reg::packed(1871, 0, 843), /* isReplayableConvergenceBody $loopNode */ - reg::packed(1880, MAY_BE_ARRAY), /* isReplayableConvergenceBody $bodyStmts */ + reg::packed(1849, 0, 843), /* isReplayableConvergenceBody $loopNode */ + reg::packed(1858, MAY_BE_ARRAY), /* isReplayableConvergenceBody $bodyStmts */ reg::packed(371, MAY_BE_BOOL), /* isReplayableConvergenceBody return */ reg::packed(1090, 0, 1095), /* isContextSensitiveStatement $stmt */ reg::packed(371, MAY_BE_BOOL), /* isContextSensitiveStatement return */ - reg::packed(1946, 0, 843), /* hasContextSensitiveConstruct $node */ + reg::packed(1924, 0, 843), /* hasContextSensitiveConstruct $node */ reg::packed(371, MAY_BE_BOOL), /* hasContextSensitiveConstruct return */ - reg::packed(1980, MAY_BE_CALLABLE), /* pushNodeGatherer $gatherer */ + reg::packed(1958, MAY_BE_CALLABLE), /* pushNodeGatherer $gatherer */ reg::packed(371, MAY_BE_VOID), /* pushNodeGatherer return */ reg::packed(371, MAY_BE_VOID), /* popNodeGatherer return */ reg::packed(371, MAY_BE_ARRAY), /* suspendNodeGatherers return */ - reg::packed(2043, MAY_BE_ARRAY), /* restoreNodeGatherers $gatherers */ + reg::packed(2021, MAY_BE_ARRAY), /* restoreNodeGatherers $gatherers */ reg::packed(371, MAY_BE_VOID), /* restoreNodeGatherers return */ - reg::packed(2074, 0, 2084), /* replayRecording $recording */ + reg::packed(2052, 0, 2062), /* replayRecording $recording */ reg::packed(539, MAY_BE_CALLABLE), /* replayRecording $nodeCallback */ reg::packed(614, 0, 622), /* replayRecording $storage */ reg::packed(502, 0, 508), /* replayRecording $scope */ reg::packed(371, MAY_BE_VOID), /* replayRecording return */ - reg::packed(2074, 0, 2084), /* replayRecordingRange $recording */ - reg::packed(2139, MAY_BE_LONG), /* replayRecordingRange $from */ - reg::packed(2144, MAY_BE_LONG), /* replayRecordingRange $to */ + reg::packed(2052, 0, 2062), /* replayRecordingRange $recording */ + reg::packed(2117, MAY_BE_LONG), /* replayRecordingRange $from */ + reg::packed(2122, MAY_BE_LONG), /* replayRecordingRange $to */ reg::packed(539, MAY_BE_CALLABLE), /* replayRecordingRange $nodeCallback */ reg::packed(614, 0, 622), /* replayRecordingRange $storage */ reg::packed(502, 0, 508), /* replayRecordingRange $scope */ @@ -326,27 +326,27 @@ inline constexpr reg::PackedArg args[] = { reg::packed(663, 0, 843), /* callNodeCallbackWithExpression $expr */ reg::packed(502, 0, 508), /* callNodeCallbackWithExpression $scope */ reg::packed(614, 0, 622), /* callNodeCallbackWithExpression $storage */ - reg::packed(761, 0, 1346), /* callNodeCallbackWithExpression $context */ + reg::packed(761, 0, 1324), /* callNodeCallbackWithExpression $context */ reg::packed(371, MAY_BE_VOID), /* callNodeCallbackWithExpression return */ reg::packed(539, MAY_BE_CALLABLE), /* callNodeCallback $nodeCallback */ - reg::packed(1946, 0, 843), /* callNodeCallback $node */ + reg::packed(1924, 0, 843), /* callNodeCallback $node */ reg::packed(502, 0, 508), /* callNodeCallback $scope */ reg::packed(614, 0, 622), /* callNodeCallback $storage */ reg::packed(371, MAY_BE_VOID), /* callNodeCallback return */ reg::packed(502, 0, 508), /* observingTemplateArgumentFrame $scope */ - reg::packed(371, MAY_BE_NULL, 2216), /* observingTemplateArgumentFrame return */ + reg::packed(371, MAY_BE_NULL, 2194), /* observingTemplateArgumentFrame return */ reg::packed(502, 0, 508), /* collectReturnSend $scope */ - reg::packed(2295, 0, 705), /* collectReturnSend $returnedResult */ - reg::packed(371, 0, 2310), /* collectReturnSend return */ + reg::packed(2273, 0, 705), /* collectReturnSend $returnedResult */ + reg::packed(371, 0, 2288), /* collectReturnSend return */ reg::packed(502, 0, 508), /* collectYieldSend $scope */ - reg::packed(2382, MAY_BE_NULL, 1449), /* collectYieldSend $keyType */ - reg::packed(2390, MAY_BE_NULL, 1449), /* collectYieldSend $valueType */ - reg::packed(371, 0, 2310), /* collectYieldSend return */ + reg::packed(2360, MAY_BE_NULL, 1427), /* collectYieldSend $keyType */ + reg::packed(2368, MAY_BE_NULL, 1427), /* collectYieldSend $valueType */ + reg::packed(371, 0, 2288), /* collectYieldSend return */ reg::packed(502, 0, 508), /* collectYieldFromSend $scope */ - reg::packed(2417, 0, 1449), /* collectYieldFromSend $delegatedType */ - reg::packed(371, 0, 2310), /* collectYieldFromSend return */ + reg::packed(2395, 0, 1427), /* collectYieldFromSend $delegatedType */ + reg::packed(371, 0, 2288), /* collectYieldFromSend return */ reg::packed(502, 0, 508), /* getDeclaredReturnType $scope */ - reg::packed(371, MAY_BE_NULL, 1449), /* getDeclaredReturnType return */ + reg::packed(371, MAY_BE_NULL, 1427), /* getDeclaredReturnType return */ }; using Sig = reg::Sig; } // namespace sigtab @@ -368,40 +368,39 @@ inline constexpr sigtab::Sig processStmtNodesInternal = { { 1065 /* processStmtN inline constexpr sigtab::Sig processStmtNode = { { 1115 /* processStmtNode */, 5, 56, 5, 61, ZEND_ACC_PUBLIC } }; inline constexpr sigtab::Sig isAnalysedFile = { { 1140 /* isAnalysedFile */, 1, 62, 1, 63, ZEND_ACC_PUBLIC } }; inline constexpr sigtab::Sig isReturningStoredExpressionResults = { { 1155 /* isReturningStoredExpressionResults */, 0, 64, 0, 64, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig isConsumingStoredExpressionResults = { { 1190 /* isConsumingStoredExpressionResults */, 0, 65, 0, 65, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig lookForSetAllowedUndefinedExpressions = { { 1225 /* lookForSetAllowedUndefinedExpressions */, 2, 66, 2, 68, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig lookForUnsetAllowedUndefinedExpressions = { { 1263 /* lookForUnsetAllowedUndefinedExpressions */, 2, 69, 2, 71, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig lookForExpressionCallback = { { 1320 /* lookForExpressionCallback */, 3, 72, 3, 75, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processExprNodeConsumingStored = { { 1381 /* processExprNodeConsumingStored */, 6, 76, 6, 82, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig processExprOnDemand = { { 1412 /* processExprOnDemand */, 3, 83, 3, 86, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig readStoredResult = { { 1432 /* readStoredResult */, 2, 87, 2, 89, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig readTypeOfMaybeStored = { { 1467 /* readTypeOfMaybeStored */, 2, 90, 2, 92, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig findScopeStateType = { { 1489 /* findScopeStateType */, 2, 93, 2, 95, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig readScopeStateOrSyntheticType = { { 1508 /* readScopeStateOrSyntheticType */, 2, 96, 2, 98, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig requireScopeStateType = { { 1538 /* requireScopeStateType */, 2, 99, 2, 101, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig guardAgainstUnprocessedRealNode = { { 1567 /* guardAgainstUnprocessedRealNode */, 2, 102, 2, 104, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processSyntheticOnDemand = { { 1599 /* processSyntheticOnDemand */, 2, 105, 2, 107, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig processExprNode = { { 1624 /* processExprNode */, 6, 108, 6, 114, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig processExprNodeInternal = { { 1640 /* processExprNodeInternal */, 6, 115, 6, 121, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig getImpurePointsFromPropertyHook = { { 1785 /* getImpurePointsFromPropertyHook */, 4, 122, 4, 126, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig isPropertyHookBackingValueAccess = { { 1817 /* isPropertyHookBackingValueAccess */, 2, 127, 2, 129, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig getAssignedVariables = { { 1850 /* getAssignedVariables */, 1, 130, 1, 131, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig isReplayableConvergenceBody = { { 1890 /* isReplayableConvergenceBody */, 2, 132, 2, 134, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig isContextSensitiveStatement = { { 1918 /* isContextSensitiveStatement */, 1, 135, 1, 136, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig hasContextSensitiveConstruct = { { 1951 /* hasContextSensitiveConstruct */, 1, 137, 1, 138, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig pushNodeGatherer = { { 1989 /* pushNodeGatherer */, 1, 139, 1, 140, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig popNodeGatherer = { { 2006 /* popNodeGatherer */, 0, 141, 0, 141, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig suspendNodeGatherers = { { 2022 /* suspendNodeGatherers */, 0, 142, 0, 142, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig restoreNodeGatherers = { { 2053 /* restoreNodeGatherers */, 1, 143, 1, 144, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig replayRecording = { { 2123 /* replayRecording */, 4, 145, 4, 149, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig replayRecordingRange = { { 2147 /* replayRecordingRange */, 6, 150, 6, 156, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig callNodeCallbackWithExpression = { { 2168 /* callNodeCallbackWithExpression */, 5, 157, 5, 162, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig callNodeCallback = { { 2199 /* callNodeCallback */, 4, 163, 4, 167, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig observingTemplateArgumentFrame = { { 2264 /* observingTemplateArgumentFrame */, 1, 168, 1, 169, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig collectReturnSend = { { 2364 /* collectReturnSend */, 2, 170, 2, 172, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig collectYieldSend = { { 2400 /* collectYieldSend */, 3, 173, 3, 176, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig collectYieldFromSend = { { 2431 /* collectYieldFromSend */, 2, 177, 2, 179, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig getDeclaredReturnType = { { 2452 /* getDeclaredReturnType */, 1, 180, 1, 181, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; +inline constexpr sigtab::Sig lookForSetAllowedUndefinedExpressions = { { 1190 /* lookForSetAllowedUndefinedExpressions */, 2, 65, 2, 67, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig lookForUnsetAllowedUndefinedExpressions = { { 1228 /* lookForUnsetAllowedUndefinedExpressions */, 2, 68, 2, 70, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig lookForExpressionCallback = { { 1285 /* lookForExpressionCallback */, 3, 71, 3, 74, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processExprNodeConsumingStored = { { 1359 /* processExprNodeConsumingStored */, 7, 75, 7, 82, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig processExprOnDemand = { { 1390 /* processExprOnDemand */, 3, 83, 3, 86, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig readStoredResult = { { 1410 /* readStoredResult */, 2, 87, 2, 89, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig readTypeOfMaybeStored = { { 1445 /* readTypeOfMaybeStored */, 2, 90, 2, 92, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig findScopeStateType = { { 1467 /* findScopeStateType */, 2, 93, 2, 95, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig readScopeStateOrSyntheticType = { { 1486 /* readScopeStateOrSyntheticType */, 2, 96, 2, 98, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig requireScopeStateType = { { 1516 /* requireScopeStateType */, 2, 99, 2, 101, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig guardAgainstUnprocessedRealNode = { { 1545 /* guardAgainstUnprocessedRealNode */, 2, 102, 2, 104, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processSyntheticOnDemand = { { 1577 /* processSyntheticOnDemand */, 2, 105, 2, 107, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig processExprNode = { { 1602 /* processExprNode */, 6, 108, 6, 114, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig processExprNodeInternal = { { 1618 /* processExprNodeInternal */, 6, 115, 6, 121, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig getImpurePointsFromPropertyHook = { { 1763 /* getImpurePointsFromPropertyHook */, 4, 122, 4, 126, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig isPropertyHookBackingValueAccess = { { 1795 /* isPropertyHookBackingValueAccess */, 2, 127, 2, 129, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig getAssignedVariables = { { 1828 /* getAssignedVariables */, 1, 130, 1, 131, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig isReplayableConvergenceBody = { { 1868 /* isReplayableConvergenceBody */, 2, 132, 2, 134, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig isContextSensitiveStatement = { { 1896 /* isContextSensitiveStatement */, 1, 135, 1, 136, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig hasContextSensitiveConstruct = { { 1929 /* hasContextSensitiveConstruct */, 1, 137, 1, 138, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig pushNodeGatherer = { { 1967 /* pushNodeGatherer */, 1, 139, 1, 140, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig popNodeGatherer = { { 1984 /* popNodeGatherer */, 0, 141, 0, 141, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig suspendNodeGatherers = { { 2000 /* suspendNodeGatherers */, 0, 142, 0, 142, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig restoreNodeGatherers = { { 2031 /* restoreNodeGatherers */, 1, 143, 1, 144, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig replayRecording = { { 2101 /* replayRecording */, 4, 145, 4, 149, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig replayRecordingRange = { { 2125 /* replayRecordingRange */, 6, 150, 6, 156, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig callNodeCallbackWithExpression = { { 2146 /* callNodeCallbackWithExpression */, 5, 157, 5, 162, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig callNodeCallback = { { 2177 /* callNodeCallback */, 4, 163, 4, 167, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig observingTemplateArgumentFrame = { { 2242 /* observingTemplateArgumentFrame */, 1, 168, 1, 169, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig collectReturnSend = { { 2342 /* collectReturnSend */, 2, 170, 2, 172, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig collectYieldSend = { { 2378 /* collectYieldSend */, 3, 173, 3, 176, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig collectYieldFromSend = { { 2409 /* collectYieldFromSend */, 2, 177, 2, 179, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig getDeclaredReturnType = { { 2430 /* getDeclaredReturnType */, 1, 180, 1, 181, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; } // namespace sig } // namespace ptdecl::NodeScopeResolver diff --git a/turbo-ext/src/support.h b/turbo-ext/src/support.h index 049d366fd46..b8606239ab0 100644 --- a/turbo-ext/src/support.h +++ b/turbo-ext/src/support.h @@ -2964,12 +2964,10 @@ zv::Val pt_arguments_handler_process_args(zval *handler, zval *nodeScopeResolver * pending exception */ [[nodiscard]] bool pt_arguments_handler_process_dropped_args(zval *handler, zval *nodeScopeResolver, zval *stmt, zval *originalCall, zval *normalizedCall, zval *scope, zval *storage, zval *context); /* NodeScopeResolver.cpp — $nodeScopeResolver->lookForUnsetAllowedUndefinedExpressions($scope, - * $expr) / ->isReturningStoredExpressionResults() / - * ->isConsumingStoredExpressionResults(): the native body for the native + * $expr) / ->isReturningStoredExpressionResults(): the native body for the native * class, the method otherwise; UNDEF / false = pending exception */ zv::Val pt_node_scope_resolver_look_for_unset_allowed_undefined_expressions(zval *nodeScopeResolver, zval *scope, zval *expr); [[nodiscard]] bool pt_node_scope_resolver_is_returning_stored_expression_results(zval *nodeScopeResolver, bool &out); -[[nodiscard]] bool pt_node_scope_resolver_is_consuming_stored_expression_results(zval *nodeScopeResolver, bool &out); /* MutatingScope.cpp — $scope->pushInFunctionCall($reflection, $parameter, * $rememberTypes) ($reflection / $parameter IS_NULL for null) / * ->popInFunctionCall() / ->withClosureBindScopeClasses($classes) / @@ -3135,7 +3133,7 @@ zv::Val pt_non_nullability_helper_revert_non_nullability(zval *helper, zval *sco /* NodeScopeResolver.cpp — $nodeScopeResolver->processExprNodeConsumingStored(...): * the native body for exactly the native class, the method otherwise; UNDEF = * pending exception */ -zv::Val pt_node_scope_resolver_process_expr_node_consuming_stored(zval *nodeScopeResolver, zval *stmt, zval *expr, zval *scope, zval *storage, zval *nodeCallback, zval *context); +zv::Val pt_node_scope_resolver_process_expr_node_consuming_stored(zval *nodeScopeResolver, zval *stmt, zval *expr, zval *consumedExpr, zval *scope, zval *storage, zval *nodeCallback, zval *context); /* }}} */