diff --git a/src/Analyser/ExprHandler/AssignHandler.php b/src/Analyser/ExprHandler/AssignHandler.php index 62ee67ed27b..61772c884dc 100644 --- a/src/Analyser/ExprHandler/AssignHandler.php +++ b/src/Analyser/ExprHandler/AssignHandler.php @@ -8,7 +8,12 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\Assign; +use PhpParser\Node\Expr\AssignOp; use PhpParser\Node\Expr\AssignRef; +use PhpParser\Node\Expr\BinaryOp\BooleanAnd; +use PhpParser\Node\Expr\BinaryOp\BooleanOr; +use PhpParser\Node\Expr\BinaryOp\LogicalAnd; +use PhpParser\Node\Expr\BinaryOp\LogicalOr; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\List_; @@ -69,6 +74,7 @@ use PHPStan\Node\VariableAssignNode; use PHPStan\Node\VirtualNode; use PHPStan\Php\PhpVersion; +use PHPStan\Reflection\InitializerExprTypeResolver; use PHPStan\Rules\Properties\PropertyReflectionFinder; use PHPStan\ShouldNotHappenException; use PHPStan\TrinaryLogic; @@ -104,11 +110,13 @@ use function array_slice; use function count; use function in_array; +use function is_array; use function is_float; use function is_int; use function is_nan; use function is_string; use function spl_object_id; +use function str_contains; use const PHP_INT_MAX; /** @@ -160,6 +168,7 @@ public function __construct( private PropertyHookThrowPointsResolver $propertyHookThrowPointsResolver, private StatementsHandler $statementsHandler, private ArrayUnpackingHelper $arrayUnpackingHelper, + private InitializerExprTypeResolver $initializerExprTypeResolver, ) { } @@ -1326,6 +1335,29 @@ public function applyWrite( : $this->defaultNarrowingHelper->specifyTypesForNode($scope, $assignedExpr, TypeSpecifierContext::createFalsey()); $conditionalExpressions = $this->processSureTypesForConditionalExpressionsAfterAssign($nodeScopeResolver, $scope, $storage, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType, $impurePoints, $assignedExpr, $storedAssignedExprResult); $conditionalExpressions = $this->processSureNotTypesForConditionalExpressionsAfterAssign($nodeScopeResolver, $scope, $storage, $var->name, $conditionalExpressions, $falseySpecifiedTypes, $falseyType, $impurePoints, $assignedExpr, $storedAssignedExprResult); + + // An assignment inside a short-circuit operand may or may not have run + // (its variable is only maybe-defined after the RHS walk), but a truthy + // && (or falsey ||) guarantees the right operand was evaluated. The + // operand walk's truthy/falsey scope knows exactly which variables it + // defined - record their certainty as a consequence of the assigned + // boolean, e.g. "$bool = $x && ($var = 'foo'); if ($bool) { … $var … }". + if ( + $storedAssignedExprResult !== null + && ( + $assignedExpr instanceof BooleanAnd + || $assignedExpr instanceof BooleanOr + || $assignedExpr instanceof LogicalAnd + || $assignedExpr instanceof LogicalOr + ) + && self::containsVariableAssignment($assignedExpr) + ) { + if ($assignedExpr instanceof BooleanAnd || $assignedExpr instanceof LogicalAnd) { + $conditionalExpressions = $this->processDefinednessForConditionalExpressionsAfterAssign($conditionalExpressions, $var->name, $truthyType, $storedAssignedExprResult->getTruthyScope(), $scope); + } else { + $conditionalExpressions = $this->processDefinednessForConditionalExpressionsAfterAssign($conditionalExpressions, $var->name, $falseyType, $storedAssignedExprResult->getFalseyScope(), $scope); + } + } } foreach ([null, false, 0, 0.0, '', '0', []] as $falseyScalar) { @@ -1375,7 +1407,23 @@ public function applyWrite( } $nodeScopeResolver->callNodeCallback($nodeCallback, new VariableAssignNode($var, $assignedExpr), $scopeBeforeAssignEval, $storage); - + $remappedConditionalExpressions = []; + if ( + // only the concat-assign's own write remaps - an enclosing plain + // assignment of the same variable (`$s = $s .= 'x'`) sees the + // already-remapped holders and would remap them a second time + $isAssignOp + && $assignedExpr instanceof AssignOp\Concat + && $assignedExpr->var instanceof Variable + && $assignedExpr->var->name === $var->name + && $scope->getConditionalExpressions() !== [] + ) { + $remappedConditionalExpressions = $this->remapConditionalExpressionsThroughConcatAssign( + $scope->getConditionalExpressions(), + '$' . $var->name, + $valueResult->getType(), + ); + } $nativeType = $this->readAssignedValueType($nodeScopeResolver, $storedAssignedExprResult, $assignedExpr, $scope->doNotTreatPhpDocTypesAsCertain()); $scope = $scope->assignVariable( $var->name, @@ -1384,6 +1432,9 @@ public function applyWrite( TrinaryLogic::createYes(), [], ); + foreach ($remappedConditionalExpressions as $exprString => $holders) { + $scope = $scope->addConditionalExpressions((string) $exprString, $holders); // @phpstan-ignore cast.useless + } foreach ($conditionalExpressions as $exprString => $holders) { $scope = $scope->addConditionalExpressions((string) $exprString, $holders); } @@ -2142,6 +2193,170 @@ private function processSureNotTypesForConditionalExpressionsAfterAssign(NodeSco return $conditionalExpressions; } + /** + * `$var .= ` keeps the conditional-expression + * holders about $var alive by remapping them through the append instead of + * losing them to the write's invalidation. A consequence type about $var is + * concatenated with the appended constant; a condition on $var is remapped + * only when it is itself a single constant string - appending a fixed + * suffix is injective, so the remapped condition selects exactly the states + * the original condition did. Holders mentioning $var inside a composite + * expression, with a non-Yes certainty about $var, or with a non-constant + * condition on $var are left to the regular invalidation. This keeps e.g. a + * format string built across `if (!empty($target))` correlated with + * $target while further pieces are appended. + * + * @param array $conditionalExpressions + * @return array + */ + private function remapConditionalExpressionsThroughConcatAssign( + array $conditionalExpressions, + string $varExprString, + Type $appendedType, + ): array + { + $appendedConstantStrings = $appendedType->getConstantStrings(); + if (count($appendedConstantStrings) !== 1 || !$appendedType->equals($appendedConstantStrings[0])) { + return []; + } + $appendedConstantString = $appendedConstantStrings[0]; + + $remapped = []; + foreach ($conditionalExpressions as $targetExprString => $holders) { + $targetExprString = (string) $targetExprString; // @phpstan-ignore cast.useless + $targetIsVar = $targetExprString === $varExprString; + if (!$targetIsVar && str_contains($targetExprString, $varExprString)) { + // a composite target containing the variable ($var[0], f($var), ...) + continue; + } + + foreach ($holders as $holder) { + $holderTouchesVar = $targetIsVar; + $remappable = true; + $newConditions = []; + foreach ($holder->getConditionExpressionTypeHolders() as $conditionExprString => $conditionHolder) { + $conditionExprString = (string) $conditionExprString; // @phpstan-ignore cast.useless + if ($conditionExprString === $varExprString) { + $holderTouchesVar = true; + $conditionConstantStrings = $conditionHolder->getType()->getConstantStrings(); + if ( + !$conditionHolder->getCertainty()->yes() + || count($conditionConstantStrings) !== 1 + || !$conditionHolder->getType()->equals($conditionConstantStrings[0]) + ) { + $remappable = false; + break; + } + $newConditions[$conditionExprString] = ExpressionTypeHolder::createYes( + $conditionHolder->getExpr(), + $conditionConstantStrings[0]->append($appendedConstantString), + ); + continue; + } + + if (str_contains($conditionExprString, $varExprString)) { + $remappable = false; + break; + } + + $newConditions[$conditionExprString] = $conditionHolder; + } + if (!$remappable || !$holderTouchesVar) { + continue; + } + + $typeHolder = $holder->getTypeHolder(); + if ($targetIsVar) { + if (!$typeHolder->getCertainty()->yes()) { + // the append leaves the variable defined on every path - + // an undefined/maybe consequence cannot be carried over + continue; + } + $concatType = $this->initializerExprTypeResolver->resolveConcatType($typeHolder->getType(), $appendedType); + if ($concatType instanceof ErrorType) { + continue; + } + $typeHolder = ExpressionTypeHolder::createYes($typeHolder->getExpr(), $concatType); + } + + $newHolder = new ConditionalExpressionHolder($newConditions, $typeHolder); + $remapped[$targetExprString][$newHolder->getKey()] = $newHolder; + } + } + + return $remapped; + } + + /** + * Records "if the assigned variable has $variableType, the target variable is + * certainly defined (with its branch-scope type)" holders for variables whose + * certainty is Yes in the given branch continuation scope of the RHS (the + * truthy scope of a `&&`, the falsey scope of a `||` - the scopes where every + * short-circuit operand was guaranteed evaluated) but only Maybe in the + * merged after-RHS scope. + * + * @param array $conditionalExpressions + * @return array + */ + private function processDefinednessForConditionalExpressionsAfterAssign( + array $conditionalExpressions, + string $variableName, + Type $variableType, + MutatingScope $branchScope, + MutatingScope $mergedScope, + ): array + { + foreach ($branchScope->expressionTypes as $exprString => $holder) { + if (!$holder->getCertainty()->yes()) { + continue; + } + $expr = $holder->getExpr(); + if (!$expr instanceof Variable || !is_string($expr->name) || $expr->name === $variableName) { + continue; + } + $mergedHolder = $mergedScope->expressionTypes[$exprString] ?? null; + if ($mergedHolder === null || !$mergedHolder->getCertainty()->maybe()) { + continue; + } + + $conditionalHolder = new ConditionalExpressionHolder([ + '$' . $variableName => ExpressionTypeHolder::createYes(new Variable($variableName), $variableType), + ], $holder); + $conditionalExpressions[(string) $exprString][$conditionalHolder->getKey()] = $conditionalHolder; // @phpstan-ignore cast.useless + } + + return $conditionalExpressions; + } + + /** + * Whether the expression contains an assignment whose execution short-circuit + * evaluation may have skipped - a cheap AST gate so the truthy/falsey scope + * is only derived for boolean RHS expressions that can define a variable. + */ + private static function containsVariableAssignment(Node $node): bool + { + if ($node instanceof Assign || $node instanceof AssignOp || $node instanceof AssignRef) { + return true; + } + + foreach ($node->getSubNodeNames() as $subNodeName) { + $subNode = $node->$subNodeName; + if ($subNode instanceof Node) { + if (self::containsVariableAssignment($subNode)) { + return true; + } + } elseif (is_array($subNode)) { + foreach ($subNode as $subNodeItem) { + if ($subNodeItem instanceof Node && self::containsVariableAssignment($subNodeItem)) { + return true; + } + } + } + } + + return false; + } + /** * Current type of a conditional-holder expression, used to refine the holder's * projected type. Prefers the tracked scope state over the stored result, diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 85867200a20..b9277f0f8f3 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -4040,12 +4040,37 @@ public function applySpecifiedTypes(SpecifiedTypes $specifiedTypes): self $expr = $issetExpr->getExpr(); if ($typeSpecification['sure']) { + $innerExprString = $scope->getNodeKey($expr); $scope = $scope->setExpressionCertaintyKeepingType( $expr, TrinaryLogic::createMaybe(), ); + $specifiedExpressions[$innerExprString] = ExpressionTypeHolder::createMaybe( + $expr, + $scope->expressionTypes[$innerExprString]->getType(), + ); } else { + $innerExprString = $scope->getNodeKey($expr); + // Holders conditioned on this expression being undefined (a + // certainty-No condition) wait for exactly the specification + // applied here, but unsetExpression()'s invalidation would drop + // them before the conditional-expressions matcher below could + // fire them - carve them out and re-add them afterwards. + $rescuedHolders = []; + foreach ($scope->conditionalExpressions as $targetExprString => $targetHolders) { + foreach ($targetHolders as $holderKey => $conditionalHolder) { + $conditionHolder = $conditionalHolder->getConditionExpressionTypeHolders()[$innerExprString] ?? null; + if ($conditionHolder === null || !$conditionHolder->getCertainty()->no()) { + continue; + } + $rescuedHolders[$targetExprString][$holderKey] = $conditionalHolder; + } + } $scope = $scope->unsetExpression($expr); + foreach ($rescuedHolders as $targetExprString => $targetHolders) { + $scope = $scope->addConditionalExpressions((string) $targetExprString, $targetHolders); // @phpstan-ignore cast.useless + } + $specifiedExpressions[$innerExprString] = new ExpressionTypeHolder($expr, new ErrorType(), TrinaryLogic::createNo()); } $scopeIsWorkingCopy = false; diff --git a/src/Analyser/StmtHandler/TryCatchHandler.php b/src/Analyser/StmtHandler/TryCatchHandler.php index c41c2168982..b703a1e0015 100644 --- a/src/Analyser/StmtHandler/TryCatchHandler.php +++ b/src/Analyser/StmtHandler/TryCatchHandler.php @@ -6,9 +6,12 @@ use Exception; use PhpParser\Node; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\Variable; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\TryCatch; +use PHPStan\Analyser\ConditionalExpressionHolder; use PHPStan\Analyser\ExpressionResultStorage; +use PHPStan\Analyser\ExpressionTypeHolder; use PHPStan\Analyser\InternalStatementExitPoint; use PHPStan\Analyser\InternalStatementResult; use PHPStan\Analyser\InternalThrowPoint; @@ -28,8 +31,11 @@ use PHPStan\Node\Variable\VariableWrite; use PHPStan\Node\VariableAssignNode; use PHPStan\ShouldNotHappenException; +use PHPStan\TrinaryLogic; use PHPStan\Turbo\ShadowedByTurboExtension; +use PHPStan\Type\ErrorType; use PHPStan\Type\NeverType; +use PHPStan\Type\NullType; use PHPStan\Type\ObjectType; use PHPStan\Type\TypeCombinator; use Throwable; @@ -272,7 +278,13 @@ public function processStmt( $blockScopes[] = $catchScopeForFinally; $catchFlows[] = [$originalCatchType, VariableFlow::sequence($catchNode->var !== null ? VariableFlowBuilder::targetWrite($catchNode->var, VariableWrite::KIND_CATCH, $catchScopeForFinally, $storage) : null, $catchScopeResult->getVariableFlow())]; - $finalScope = $catchScopeResult->isAlwaysTerminating() ? $finalScope : $catchScopeResult->getScope()->mergeWith($finalScope); + if (!$catchScopeResult->isAlwaysTerminating()) { + $mergedScope = $catchScopeResult->getScope()->mergeWith($finalScope); + if ($variableName !== null && $finalScope !== null) { + $mergedScope = $this->addCatchVariableDefinednessConditionals($mergedScope, $finalScope, $catchScopeResult->getScope(), $variableName); + } + $finalScope = $mergedScope; + } $alwaysTerminating = $alwaysTerminating && $catchScopeResult->isAlwaysTerminating(); $hasYield = $hasYield || $catchScopeResult->hasYield(); $catchThrowPoints = $catchScopeResult->getThrowPoints(); @@ -362,4 +374,70 @@ public function processStmt( return new InternalStatementResult($finalScope, hasYield: $hasYield, isAlwaysTerminating: $alwaysTerminating, exitPoints: $exitPoints, throwPoints: array_merge($throwPoints, $throwPointsForLater), impurePoints: $impurePoints, variableFlow: VariableFlow::tryCatch($branchScopeResult->getVariableFlow(), $catchFlows, $finallyFlow), dependencies: Dependencies::merge(...$dependencies)); } + /** + * The catch variable's definedness after the try/catch tells the two joined + * paths apart: when it is untracked on the non-catch path and certainly + * defined at the end of the catch body, "the catch variable is undefined" + * later implies the non-catch path ran. Record that as conditional + * expression holders with a certainty-No condition on the catch variable, + * restoring the non-catch certainty (and type) of variables the join + * demoted to maybe-defined - e.g. `isset($e) || $var instanceof \DateTime` + * evaluates `$var` only where `$e` is narrowed away. + */ + private function addCatchVariableDefinednessConditionals( + MutatingScope $mergedScope, + MutatingScope $nonCatchScope, + MutatingScope $catchEndScope, + string $variableName, + ): MutatingScope + { + $variableExprString = '$' . $variableName; + if (isset($nonCatchScope->expressionTypes[$variableExprString])) { + return $mergedScope; + } + + $catchVariableHolder = $catchEndScope->expressionTypes[$variableExprString] ?? null; + if ($catchVariableHolder === null || !$catchVariableHolder->getCertainty()->yes()) { + return $mergedScope; + } + + $conditions = [ + [ + $variableExprString => new ExpressionTypeHolder(new Variable($variableName), new ErrorType(), TrinaryLogic::createNo()), + ], + ]; + if ($catchVariableHolder->getType()->isNull()->no()) { + // In a scope where any variable can exist (e.g. the top level), the + // isset() machinery models "!isset($e)" on a maybe-defined variable as + // "maybe defined, null when defined" instead of unsetting it. That + // state excludes the catch path just the same - it guarantees a + // defined, non-null catch variable. + $conditions[] = [ + $variableExprString => ExpressionTypeHolder::createMaybe(new Variable($variableName), new NullType()), + ]; + } + foreach ($nonCatchScope->expressionTypes as $exprString => $holder) { + if (!$holder->getCertainty()->yes()) { + continue; + } + $expr = $holder->getExpr(); + if (!$expr instanceof Variable || !is_string($expr->name)) { + continue; + } + $mergedHolder = $mergedScope->expressionTypes[$exprString] ?? null; + if ($mergedHolder === null || !$mergedHolder->getCertainty()->maybe()) { + continue; + } + + $conditionalHolders = []; + foreach ($conditions as $condition) { + $conditionalHolder = new ConditionalExpressionHolder($condition, $holder); + $conditionalHolders[$conditionalHolder->getKey()] = $conditionalHolder; + } + $mergedScope = $mergedScope->addConditionalExpressions((string) $exprString, $conditionalHolders); // @phpstan-ignore cast.useless + } + + return $mergedScope; + } + } diff --git a/tests/PHPStan/Analyser/nsrt/bug-11109.php b/tests/PHPStan/Analyser/nsrt/bug-11109.php new file mode 100644 index 00000000000..9693317ec2b --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-11109.php @@ -0,0 +1,40 @@ +%s'; + +if (empty($target)) { + assertType('\'%s\'', $htmlLinkStructure); + return sprintf($htmlLinkStructure, $url, $linkText); +} + +assertType('\'%s\'', $htmlLinkStructure); +return sprintf($htmlLinkStructure, $url, $target, $linkText); diff --git a/tests/PHPStan/Rules/Functions/PrintfParametersRuleTest.php b/tests/PHPStan/Rules/Functions/PrintfParametersRuleTest.php index f09b273cf9b..bc42cfee18f 100644 --- a/tests/PHPStan/Rules/Functions/PrintfParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/PrintfParametersRuleTest.php @@ -194,4 +194,9 @@ public function testFormatParser(): void ]); } + public function testBug9854(): void + { + $this->analyse([__DIR__ . '/data/bug-9854.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Functions/data/bug-9854.php b/tests/PHPStan/Rules/Functions/data/bug-9854.php new file mode 100644 index 00000000000..1f1e308c505 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-9854.php @@ -0,0 +1,16 @@ +%s'; + +if (empty($target)) { + return sprintf($htmlLinkStructure, $url, $linkText); +} + +return sprintf($htmlLinkStructure, $url, $target, $linkText); diff --git a/tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php b/tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php index 99f580819af..96599f7fa00 100644 --- a/tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php +++ b/tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php @@ -539,4 +539,18 @@ public function testDeadCatch(): void ]); } + public function testBug11109(): void + { + $this->cliArgumentsVariablesRegistered = true; + $this->checkMaybeUndefinedVariables = true; + $this->analyse([__DIR__ . '/data/bug-11109.php'], []); + } + + public function testBug6608(): void + { + $this->cliArgumentsVariablesRegistered = true; + $this->checkMaybeUndefinedVariables = true; + $this->analyse([__DIR__ . '/data/bug-6608.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Variables/data/bug-11109.php b/tests/PHPStan/Rules/Variables/data/bug-11109.php new file mode 100644 index 00000000000..e97dcc67072 --- /dev/null +++ b/tests/PHPStan/Rules/Variables/data/bug-11109.php @@ -0,0 +1,16 @@ + 0) { + AH_VALB(appendedType, pt_expression_result_get_type(valueResult)); + zv::Str varExprString = zv::Str::adopt(zend_string_concat2(PT_LC("$"), ZSTR_VAL(varName), ZSTR_LEN(varName))); + AH_SETB(remappedConditionalExpressions, remapConditionalExpressionsThroughConcatAssign(scopeConditionalExpressions.raw(), varExprString.get(), appendedType.raw())); + } + } + } AH_VALB(nativeScope, pt_mutating_scope_do_not_treat_phpdoc_types_as_certain(Z_OBJ_P(scope.raw()))); AH_VALB(nativeType, readAssignedValueType(nsr, stored, assignedExpr.raw(), nativeScope.raw())); AH_SETB(scope, pt_mutating_scope_assign_variable(Z_OBJ_P(scope.raw()), varName, type.raw(), nativeType.raw(), ahTrinary(PT_TRI_YES))); + for (auto entry : zv::TableRef(Z_ARRVAL_P(remappedConditionalExpressions.raw()))) { + zval *holders = entry.value().raw(); + zend_string *exprString = entry.stringKeyOrNull(); + if (exprString != NULL) { + AH_SETB(scope, pt_mutating_scope_add_conditional_expressions(Z_OBJ_P(scope.raw()), exprString, Z_ARRVAL_P(holders))); + } else { + zv::Str key = zv::Str::adopt(zend_long_to_str((zend_long) entry.indexKey())); + AH_SETB(scope, pt_mutating_scope_add_conditional_expressions(Z_OBJ_P(scope.raw()), key.get(), Z_ARRVAL_P(holders))); + } + } for (auto entry : zv::TableRef(Z_ARRVAL_P(conditionalExpressions.raw()))) { zval *holders = entry.value().raw(); zend_string *exprString = entry.stringKeyOrNull(); @@ -2466,6 +2510,195 @@ class AssignHandler return true; } + static bool strContains(zend_string *haystack, zend_string *needle) + { + return zend_memnstr(ZSTR_VAL(haystack), ZSTR_VAL(needle), ZSTR_LEN(needle), ZSTR_VAL(haystack) + ZSTR_LEN(haystack)) != NULL; + } + + /* the single constant string a type is exactly (count(getConstantStrings()) + * === 1 and equals() it), UNDEF = pending exception, PHP null = none */ + static zv::Val singleConstantString(zval *type) + { + AH_VAL(constantStrings, ahCall(type, PT_LC("getconstantstrings"), 0, NULL)); + if (Z_TYPE_P(constantStrings.raw()) != IS_ARRAY || zend_hash_num_elements(Z_ARRVAL_P(constantStrings.raw())) != 1) return zv::Val::null(); + zval *constantString = zend_hash_index_find(Z_ARRVAL_P(constantStrings.raw()), 0); + if (UNEXPECTED(constantString == NULL)) { + pt_throw_should_not_happen(); + return zv::Val(); + } + ZVAL_DEREF(constantString); + bool equal; + AH_OK(ahEquals(type, constantString, equal)); + if (!equal) return zv::Val::null(); + return zv::Val::copyOf(zv::Ref(constantString)); + } + + /* $holder->getConditionExpressionTypeHolders() / ->getTypeHolder() of a ConditionalExpressionHolder */ + static zv::Val conditionalHolderPart(zval *holder, bool conditions) + { + if (EXPECTED(Z_TYPE_P(holder) == IS_OBJECT && Z_OBJCE_P(holder) == pt_ce_cond_expr_holder)) { + return zv::Val::copyOf(zv::ObjRef(Z_OBJ_P(holder)).propAt(conditions ? PT_CEH_PROP_CONDS : PT_CEH_PROP_TYPEHOLDER).deref()); + } + return conditions ? ahCall(holder, PT_LC("getconditionexpressiontypeholders"), 0, NULL) : ahCall(holder, PT_LC("gettypeholder"), 0, NULL); + } + + /* (twin remapConditionalExpressionsThroughConcatAssign) `$var .= ` keeps the conditional-expression holders about $var + * alive by remapping them through the append instead of losing them to + * the write's invalidation; see the PHP twin for the rules. */ + zv::Val remapConditionalExpressionsThroughConcatAssign(zval *conditionalExpressions, zend_string *varExprString, zval *appendedType) + { + AH_VAL(appendedConstantString, singleConstantString(appendedType)); + if (appendedConstantString.isNull()) return ahEmptyArray(); + + zv::Val remapped = ahEmptyArray(); + for (auto targetEntry : zv::TableRef(Z_ARRVAL_P(conditionalExpressions))) { + zv::Str targetExprString = targetEntry.stringKeyOrNull() != NULL ? zv::Str::copyOf(targetEntry.stringKey()) : zv::Str::adopt(zend_long_to_str((zend_long) targetEntry.indexKey())); + bool targetIsVar = zend_string_equals(targetExprString.get(), varExprString); + if (!targetIsVar && strContains(targetExprString.get(), varExprString)) { + // a composite target containing the variable ($var[0], f($var), ...) + continue; + } + + zval *holders = targetEntry.value().deref().raw(); + if (UNEXPECTED(Z_TYPE_P(holders) != IS_ARRAY)) continue; + for (auto holderEntry : zv::TableRef(Z_ARRVAL_P(holders))) { + zval *holder = holderEntry.value().deref().raw(); + bool holderTouchesVar = targetIsVar; + bool remappable = true; + zv::Val newConditions = ahEmptyArray(); + AH_VAL(conditions, conditionalHolderPart(holder, true)); + if (UNEXPECTED(Z_TYPE_P(conditions.raw()) != IS_ARRAY)) continue; + for (auto conditionEntry : zv::TableRef(Z_ARRVAL_P(conditions.raw()))) { + zv::Str conditionExprString = conditionEntry.stringKeyOrNull() != NULL ? zv::Str::copyOf(conditionEntry.stringKey()) : zv::Str::adopt(zend_long_to_str((zend_long) conditionEntry.indexKey())); + zval *conditionHolder = conditionEntry.value().deref().raw(); + if (zend_string_equals(conditionExprString.get(), varExprString)) { + holderTouchesVar = true; + if (pt_holder_certainty_value(Z_OBJ_P(conditionHolder)) != PT_TRI_YES) { + remappable = false; + break; + } + zval *conditionType = OBJ_PROP_NUM(Z_OBJ_P(conditionHolder), PT_ETH_PROP_TYPE); + ZVAL_DEREF(conditionType); + AH_VAL(conditionConstantString, singleConstantString(conditionType)); + if (conditionConstantString.isNull()) { + remappable = false; + break; + } + zval appendArg; + ZVAL_COPY_VALUE(&appendArg, appendedConstantString.raw()); + AH_VAL(appended, ahCall(conditionConstantString.raw(), PT_LC("append"), 1, &appendArg)); + zval *conditionExpr = OBJ_PROP_NUM(Z_OBJ_P(conditionHolder), PT_ETH_PROP_EXPR); + ZVAL_DEREF(conditionExpr); + AH_VAL(newConditionHolder, newExpressionTypeHolder(conditionExpr, appended.raw(), PT_TRI_YES)); + ahSetKey(newConditions, conditionExprString.get(), newConditionHolder.raw()); + continue; + } + + if (strContains(conditionExprString.get(), varExprString)) { + remappable = false; + break; + } + + ahSetKey(newConditions, conditionExprString.get(), conditionHolder); + } + if (!remappable || !holderTouchesVar) continue; + + AH_VAL(typeHolder, conditionalHolderPart(holder, false)); + if (targetIsVar) { + if (pt_holder_certainty_value(Z_OBJ_P(typeHolder.raw())) != PT_TRI_YES) { + // the append leaves the variable defined on every path - + // an undefined/maybe consequence cannot be carried over + continue; + } + zval *holderType = OBJ_PROP_NUM(Z_OBJ_P(typeHolder.raw()), PT_ETH_PROP_TYPE); + ZVAL_DEREF(holderType); + zv::Args concatArgs{holderType, appendedType}; + AH_VAL(concatType, ahCall(prop(slots::initializerExprTypeResolver), PT_LC("resolveconcattype"), 2, concatArgs)); + if (Z_TYPE_P(concatType.raw()) == IS_OBJECT && instanceof_function(Z_OBJCE_P(concatType.raw()), pt_ce_error_type)) continue; + zval *holderExpr = OBJ_PROP_NUM(Z_OBJ_P(typeHolder.raw()), PT_ETH_PROP_EXPR); + ZVAL_DEREF(holderExpr); + AH_SET(typeHolder, newExpressionTypeHolder(holderExpr, concatType.raw(), PT_TRI_YES)); + } + + AH_VAL(newHolder, newConditionalExpressionHolder(newConditions.raw(), typeHolder.raw())); + zv::Str newHolderKey = zv::Str::adopt(conditionalHolderKey(newHolder.raw())); + AH_OK(!newHolderKey.isNull()); + nestedSet(remapped, targetExprString.get(), newHolderKey.get(), newHolder.raw()); + } + } + + return remapped; + } + + /* Records "if the assigned variable has $variableType, the target variable is + * certainly defined (with its branch-scope type)" holders for variables whose + * certainty is Yes in the given branch continuation scope of the RHS (the + * truthy scope of a `&&`, the falsey scope of a `||`) but only Maybe in the + * merged after-RHS scope. */ + [[nodiscard]] static bool processDefinednessForConditionalExpressionsAfterAssign(zv::Val &conditionalExpressions, zend_string *variableName, zval *variableType, zval *branchScope, zval *mergedScope) + { + zval *branchTypes = OBJ_PROP_NUM(Z_OBJ_P(branchScope), msSlots::expressionTypes); + zval *mergedTypes = OBJ_PROP_NUM(Z_OBJ_P(mergedScope), msSlots::expressionTypes); + ZVAL_DEREF(branchTypes); + ZVAL_DEREF(mergedTypes); + if (UNEXPECTED(Z_TYPE_P(branchTypes) != IS_ARRAY || Z_TYPE_P(mergedTypes) != IS_ARRAY)) { + pt_throw_should_not_happen(); + return false; + } + + for (auto entry : zv::TableRef(Z_ARRVAL_P(branchTypes))) { + zval *holder = entry.value().deref().raw(); + if (pt_holder_certainty_value(Z_OBJ_P(holder)) != PT_TRI_YES) continue; + zval *expr = OBJ_PROP_NUM(Z_OBJ_P(holder), PT_ETH_PROP_EXPR); + ZVAL_DEREF(expr); + zend_string *name = ahStringVariableName(expr); + if (name == NULL || zend_string_equals(name, variableName)) continue; + + zend_string *stringKey = entry.stringKeyOrNull(); + zval *mergedHolder = stringKey != NULL ? zend_hash_find(Z_ARRVAL_P(mergedTypes), stringKey) : zend_hash_index_find(Z_ARRVAL_P(mergedTypes), entry.indexKey()); + if (mergedHolder == NULL) continue; + ZVAL_DEREF(mergedHolder); + if (pt_holder_certainty_value(Z_OBJ_P(mergedHolder)) != PT_TRI_MAYBE) continue; + + AH_VALB(variable, newVariable(variableName)); + AH_VALB(conditionHolder, newExpressionTypeHolder(variable.raw(), variableType, PT_TRI_YES)); + zv::Str conditionKey = zv::Str::adopt(zend_string_concat2(PT_LC("$"), ZSTR_VAL(variableName), ZSTR_LEN(variableName))); + zv::Val conditions = ahEmptyArray(); + ahSetKey(conditions, conditionKey.get(), conditionHolder.raw()); + AH_VALB(conditionalHolder, newConditionalExpressionHolder(conditions.raw(), holder)); + zv::Str holderKey = zv::Str::adopt(conditionalHolderKey(conditionalHolder.raw())); + AH_OKB(!holderKey.isNull()); + zv::Str exprString = stringKey != NULL ? zv::Str::copyOf(stringKey) : zv::Str::adopt(zend_long_to_str((zend_long) entry.indexKey())); + nestedSet(conditionalExpressions, exprString.get(), holderKey.get(), conditionalHolder.raw()); + } + + return true; + } + + /* matcher for containsVariableAssignment() */ + static bool variableAssignmentMatcher(zend_object *node, void *ctx) + { + zend_class_entry *assignCe = pt_class(PT_CLASS_ASSIGN_EXPR); + zend_class_entry *assignOpCe = pt_class(PT_CLASS_ASSIGN_OP_EXPR); + zend_class_entry *assignRefCe = pt_class(PT_CLASS_ASSIGN_REF_EXPR); + if (UNEXPECTED(assignCe == NULL || assignOpCe == NULL || assignRefCe == NULL)) { + static_cast(ctx)->failed = true; + return false; + } + return instanceof_function(node->ce, assignCe) || instanceof_function(node->ce, assignOpCe) || instanceof_function(node->ce, assignRefCe); + } + + /* Whether the expression contains an assignment whose execution short-circuit + * evaluation may have skipped - a cheap AST gate so the truthy/falsey scope + * is only derived for boolean RHS expressions that can define a variable. */ + [[nodiscard]] static bool containsVariableAssignment(zval *node, bool &contains) + { + pt_find_ctx ctx = {}; + contains = pt_find_first_recursive(Z_OBJ_P(node), variableAssignmentMatcher, &ctx) != NULL; + return !ctx.failed; + } + /* (twin 2081) */ static zv::Val currentTypeForConditionalHolder(zval *nsr, zval *scope, zval *storage, zval *expr, zval *assignedExpr, zval *assignedValueResult) { @@ -4873,7 +5106,7 @@ PT_MINIT_REGISTRATION(pt_register_assign_handler) cls.method(sigs::__construct, [](INTERNAL_FUNCTION_PARAMETERS) { zval *argv; uint32_t argc; - ZEND_PARSE_PARAMETERS_START(20, 20) + ZEND_PARSE_PARAMETERS_START(21, 21) Z_PARAM_VARIADIC('+', argv, argc) ZEND_PARSE_PARAMETERS_END(); for (uint32_t i = 0; i < argc; i++) { diff --git a/turbo-ext/src/MutatingScope.cpp b/turbo-ext/src/MutatingScope.cpp index 1138b46ed9a..c0bf17beec2 100644 --- a/turbo-ext/src/MutatingScope.cpp +++ b/turbo-ext/src/MutatingScope.cpp @@ -7713,20 +7713,104 @@ class MutatingScope zend_throw_error(NULL, "phpstan_turbo: IssetExpr::getExpr() did not answer with an object"); return zv::Val(); } + zv::Val innerKey = otherPrivate(scopeObject, PT_LC("getnodekey"), 1, inner.raw(), [&](MutatingScope &other) { + return other.getNodeKey(Z_OBJ_P(inner.raw())); + }); + if (UNEXPECTED(innerKey.isUndef())) return zv::Val(); + zend_string *innerExprString = keyString(innerKey); + if (UNEXPECTED(innerExprString == NULL)) return zv::Val(); zv::Val next; if (specification.sure) { zv::Args args{inner.raw(), pt_trinary_singleton(PT_TRI_MAYBE)}; next = otherPrivate(scopeObject, PT_LC("setexpressioncertaintykeepingtype"), 2, args, [&](MutatingScope &other) { return other.setExpressionCertaintyKeepingType(Z_OBJ_P(inner.raw()), &args[1]); }); + if (UNEXPECTED(next.isUndef())) return zv::Val(); + zend_object *nextObject = requireObject(next, "applySpecifiedTypes"); + if (UNEXPECTED(nextObject == NULL)) return zv::Val(); + HashTable *table = otherTable(nextObject, PT_MS_PROP_EXPRESSION_TYPES, PT_LC("expressionTypes")); + if (UNEXPECTED(table == NULL)) return zv::Val(); + zval *innerHolder = zend_symtable_find(table, innerExprString); + if (UNEXPECTED(innerHolder == NULL)) { + zend_throw_error(NULL, "Call to a member function getType() on null"); + return zv::Val(); + } + zv::Val innerType = holderType(zv::Ref(innerHolder)); + if (UNEXPECTED(innerType.isUndef())) return zv::Val(); + zval holder; + pt_holder_create(&holder, inner.raw(), innerType.raw(), PT_TRI_MAYBE); + specifiedExpressions.set(innerExprString, zv::Val::adopt(holder)); } else { + /* Holders conditioned on this expression being undefined (a + * certainty-No condition) wait for exactly the specification + * applied here, but unsetExpression()'s invalidation would + * drop them before the conditional-expressions matcher below + * could fire them - carve them out and re-add them afterwards. */ + HashTable *conditionalTable = otherTable(scopeObject, PT_MS_PROP_CONDITIONAL_EXPRESSIONS, PT_LC("conditionalExpressions")); + if (UNEXPECTED(conditionalTable == NULL)) return zv::Val(); + zv::Arr rescuedHolders = zv::Arr::create(0); + for (auto targetEntry : zv::TableRef(conditionalTable)) { + zval *targetHolders = targetEntry.value().deref().raw(); + if (UNEXPECTED(Z_TYPE_P(targetHolders) != IS_ARRAY)) continue; + zv::Arr rescuedForTarget = zv::Arr::create(0); + for (auto holderEntry : zv::TableRef(Z_ARRVAL_P(targetHolders))) { + zval *conditionalHolder = holderEntry.value().deref().raw(); + zv::Val conditions; + if (EXPECTED(Z_TYPE_P(conditionalHolder) == IS_OBJECT && Z_OBJCE_P(conditionalHolder) == pt_ce_cond_expr_holder)) { + conditions = zv::Val::copyOf(zv::ObjRef(Z_OBJ_P(conditionalHolder)).propAt(PT_CEH_PROP_CONDS)); + } else { + if (UNEXPECTED(Z_TYPE_P(conditionalHolder) != IS_OBJECT)) { + zend_throw_error(NULL, "Call to a member function getConditionExpressionTypeHolders() on %s", zend_zval_value_name(conditionalHolder)); + return zv::Val(); + } + conditions = pt_type_call(Z_OBJ_P(conditionalHolder), PT_LC("getconditionexpressiontypeholders"), 0, NULL); + if (UNEXPECTED(conditions.isUndef())) return zv::Val(); + } + zval *conditionsZv = conditions.raw(); + ZVAL_DEREF(conditionsZv); + if (UNEXPECTED(Z_TYPE_P(conditionsZv) != IS_ARRAY)) continue; + zval *conditionHolder = zend_symtable_find(Z_ARRVAL_P(conditionsZv), innerExprString); + if (conditionHolder == NULL) continue; + zend_long certainty = holderCertainty(zv::Ref(conditionHolder)); + if (UNEXPECTED(certainty < 0)) return zv::Val(); + if (certainty != PT_TRI_NO) continue; + Z_TRY_ADDREF_P(conditionalHolder); + if (holderEntry.stringKeyOrNull() != NULL) { + zend_hash_update(rescuedForTarget.table(), holderEntry.stringKey(), conditionalHolder); + } else { + zend_hash_index_update(rescuedForTarget.table(), holderEntry.indexKey(), conditionalHolder); + } + } + if (zend_hash_num_elements(rescuedForTarget.table()) == 0) continue; + zval rescuedZv = rescuedForTarget.take(); + if (targetEntry.stringKeyOrNull() != NULL) { + zend_hash_update(rescuedHolders.table(), targetEntry.stringKey(), &rescuedZv); + } else { + zend_hash_index_update(rescuedHolders.table(), targetEntry.indexKey(), &rescuedZv); + } + } + zval arg; ZVAL_COPY_VALUE(&arg, inner.raw()); next = otherPrivate(scopeObject, PT_LC("unsetexpression"), 1, &arg, [&](MutatingScope &other) { return other.unsetExpression(Z_OBJ_P(inner.raw())); }); + if (UNEXPECTED(next.isUndef())) return zv::Val(); + for (auto rescuedEntry : zv::TableRef(rescuedHolders.table())) { + zend_object *nextObject = requireObject(next, "applySpecifiedTypes"); + if (UNEXPECTED(nextObject == NULL)) return zv::Val(); + zv::Str targetExprString = rescuedEntry.stringKeyOrNull() != NULL ? zv::Str::copyOf(rescuedEntry.stringKey()) : zv::Str::adopt(zend_long_to_str((zend_long) rescuedEntry.indexKey())); + zv::Val added = pt_mutating_scope_add_conditional_expressions(nextObject, targetExprString.get(), Z_ARRVAL_P(rescuedEntry.value().deref().raw())); + if (UNEXPECTED(added.isUndef())) return zv::Val(); + next = std::move(added); + } + zval errorType; + if (UNEXPECTED(!pt_error_type_new(&errorType))) return zv::Val(); + zv::Val errorTypeHold = zv::Val::adopt(errorType); + zval holder; + pt_holder_create(&holder, inner.raw(), errorTypeHold.raw(), PT_TRI_NO); + specifiedExpressions.set(innerExprString, zv::Val::adopt(holder)); } - if (UNEXPECTED(next.isUndef())) return zv::Val(); zend_object *nextObject = requireObject(next, "applySpecifiedTypes"); if (UNEXPECTED(nextObject == NULL)) return zv::Val(); scope = std::move(next); diff --git a/turbo-ext/src/TryCatchHandler.cpp b/turbo-ext/src/TryCatchHandler.cpp index 78819f6485a..1ffb976d097 100644 --- a/turbo-ext/src/TryCatchHandler.cpp +++ b/turbo-ext/src/TryCatchHandler.cpp @@ -18,9 +18,11 @@ #include "support.h" #include "generated/TryCatchHandler.h" +#include "generated/MutatingScope.h" namespace slots = ptdecl::TryCatchHandler::slot; namespace sigs = ptdecl::TryCatchHandler::sig; +namespace msSlots = ptdecl::MutatingScope::slot; #include "zv.h" #include "TypeTraits.h" #include "TypeOps.h" @@ -53,6 +55,124 @@ zend_string *pt_tch_throwable_class = nullptr; zend_string *pt_tch_exception_class = nullptr; zend_string *pt_tch_error_class = nullptr; +/* the expressionTypes table of a scope; NULL = pending exception */ +HashTable *scopeExpressionTypes(zval *scope) +{ + zval *table = OBJ_PROP_NUM(Z_OBJ_P(scope), msSlots::expressionTypes); + ZVAL_DEREF(table); + if (UNEXPECTED(Z_TYPE_P(table) != IS_ARRAY)) { + pt_throw_should_not_happen(); + return NULL; + } + return Z_ARRVAL_P(table); +} + +/* new ExpressionTypeHolder(new Variable($name), $type, $certainty) */ +zv::Val variableHolder(zend_string *name, zval *type, zend_long certainty) +{ + zv::Args variableArgv{name}; + zv::Val variable = pt_type_new(PT_CLASS_VARIABLE, 1, variableArgv); + if (UNEXPECTED(variable.isUndef())) return zv::Val(); + zval holder; + pt_holder_create(&holder, variable.raw(), type, certainty); + return zv::Val::adopt(holder); +} + +/* The catch variable's definedness after the try/catch tells the two joined + * paths apart: when it is untracked on the non-catch path and certainly + * defined at the end of the catch body, "the catch variable is undefined" + * later implies the non-catch path ran. Record that as conditional + * expression holders with a certainty-No condition on the catch variable, + * restoring the non-catch certainty (and type) of variables the join + * demoted to maybe-defined. Mirrors addCatchVariableDefinednessConditionals(); + * false = pending exception. */ +[[nodiscard]] bool addCatchVariableDefinednessConditionals(zv::Val &mergedScope, zval *nonCatchScope, zval *catchEndScope, zend_string *variableName) +{ + zv::Str variableExprString = zv::Str::adopt(zend_string_concat2(PT_LC("$"), ZSTR_VAL(variableName), ZSTR_LEN(variableName))); + HashTable *nonCatchTypes = scopeExpressionTypes(nonCatchScope); + if (UNEXPECTED(nonCatchTypes == NULL)) return false; + zval *nonCatchVariable = zend_symtable_find(nonCatchTypes, variableExprString.get()); + if (nonCatchVariable != NULL && Z_TYPE_P(nonCatchVariable) != IS_NULL) return true; + + HashTable *catchEndTypes = scopeExpressionTypes(catchEndScope); + if (UNEXPECTED(catchEndTypes == NULL)) return false; + zval *catchVariableHolder = zend_symtable_find(catchEndTypes, variableExprString.get()); + if (catchVariableHolder == NULL) return true; + ZVAL_DEREF(catchVariableHolder); + if (pt_holder_certainty_value(Z_OBJ_P(catchVariableHolder)) != PT_TRI_YES) return true; + + zv::Arr conditions = zv::Arr::create(2); + { + zval errorType; + if (UNEXPECTED(!pt_error_type_new(&errorType))) return false; + zv::Val errorTypeHold = zv::Val::adopt(errorType); + zv::Val holder = variableHolder(variableName, errorTypeHold.raw(), PT_TRI_NO); + if (UNEXPECTED(holder.isUndef())) return false; + zv::Arr condition = zv::Arr::create(1); + condition.set(variableExprString.get(), std::move(holder)); + conditions.push(zv::Val(std::move(condition))); + } + zval *catchVariableType = OBJ_PROP_NUM(Z_OBJ_P(catchVariableHolder), PT_ETH_PROP_TYPE); + ZVAL_DEREF(catchVariableType); + zend_long isNull = pt_type_call_trinary(Z_OBJ_P(catchVariableType), PT_LC("isnull"), 0, NULL); + if (UNEXPECTED(isNull < 0)) return false; + if (isNull == PT_TRI_NO) { + /* In a scope where any variable can exist (e.g. the top level), the + * isset() machinery models "!isset($e)" on a maybe-defined variable + * as "maybe defined, null when defined" instead of unsetting it. That + * state excludes the catch path just the same. */ + zval nullType; + if (UNEXPECTED(!pt_null_type_new(&nullType))) return false; + zv::Val nullTypeHold = zv::Val::adopt(nullType); + zv::Val holder = variableHolder(variableName, nullTypeHold.raw(), PT_TRI_MAYBE); + if (UNEXPECTED(holder.isUndef())) return false; + zv::Arr condition = zv::Arr::create(1); + condition.set(variableExprString.get(), std::move(holder)); + conditions.push(zv::Val(std::move(condition))); + } + + for (auto entry : zv::TableRef(nonCatchTypes)) { + zval *holder = entry.value().deref().raw(); + if (pt_holder_certainty_value(Z_OBJ_P(holder)) != PT_TRI_YES) continue; + zval *expr = OBJ_PROP_NUM(Z_OBJ_P(holder), PT_ETH_PROP_EXPR); + ZVAL_DEREF(expr); + bool instanceError = false; + bool isVariable = ptsh::isInstanceOf(expr, PT_CLASS_VARIABLE, instanceError); + if (UNEXPECTED(instanceError)) return false; + if (!isVariable) continue; + zval *name = ptsh::readNodeProperty(pt_tch_variable_name_site, expr, PT_LC("name")); + if (UNEXPECTED(name == NULL)) return false; + if (Z_TYPE_P(name) != IS_STRING) continue; + + HashTable *mergedTypes = scopeExpressionTypes(mergedScope.raw()); + if (UNEXPECTED(mergedTypes == NULL)) return false; + zend_string *stringKey = entry.stringKeyOrNull(); + zval *mergedHolder = stringKey != NULL ? zend_hash_find(mergedTypes, stringKey) : zend_hash_index_find(mergedTypes, entry.indexKey()); + if (mergedHolder == NULL) continue; + ZVAL_DEREF(mergedHolder); + if (pt_holder_certainty_value(Z_OBJ_P(mergedHolder)) != PT_TRI_MAYBE) continue; + + zv::Arr conditionalHolders = zv::Arr::create(2); + for (auto condition : zv::ArrRef(conditions.raw())) { + zval raw; + object_init_ex(&raw, pt_ce_cond_expr_holder); + zv::Val conditionalHolder = zv::Val::adopt(raw); + zv::ObjRef object(conditionalHolder.ref().asObject()); + object.propAtWrite(PT_CEH_PROP_CONDS, zv::Val::copyOf(condition.value())); + object.propAtWrite(PT_CEH_PROP_TYPEHOLDER, zv::Val::copyOf(zv::Ref(holder))); + zv::Str key = zv::Str::adopt(pt_ceh_key_build(Z_ARRVAL_P(condition.value().deref().raw()), holder)); + if (UNEXPECTED(key.isNull())) return false; + conditionalHolders.set(key.get(), std::move(conditionalHolder)); + } + zv::Str exprString = stringKey != NULL ? zv::Str::copyOf(stringKey) : zv::Str::adopt(zend_long_to_str((zend_long) entry.indexKey())); + zv::Val added = pt_mutating_scope_add_conditional_expressions(Z_OBJ_P(mergedScope.raw()), exprString.get(), conditionalHolders.table()); + if (UNEXPECTED(added.isUndef())) return false; + mergedScope = std::move(added); + } + + return true; +} + /* $name->toString() */ zv::Val nameToString(zval *name) { @@ -617,7 +737,11 @@ class TryCatchHandler zv::Val hold; zval *resultScope = pt_internal_statement_result_scope(catchResult, hold); if (UNEXPECTED(resultScope == NULL)) return zv::Val(); + zv::Val nonCatchScope = zv::Val::copyOf(finalScope.ref()); if (UNEXPECTED(!ptlh::otherMergeWith(resultScope, finalScope))) return zv::Val(); + if (variableName != NULL && !nonCatchScope.isNull()) { + if (UNEXPECTED(!addCatchVariableDefinednessConditionals(finalScope, nonCatchScope.raw(), resultScope, Z_STR_P(variableNameHold.raw())))) return zv::Val(); + } } alwaysTerminating = alwaysTerminating && catchAlwaysTerminating; if (!hasYield) { diff --git a/turbo-ext/src/generated/AssignHandler.h b/turbo-ext/src/generated/AssignHandler.h index 5edaadc5cbe..4171fa1edfe 100644 --- a/turbo-ext/src/generated/AssignHandler.h +++ b/turbo-ext/src/generated/AssignHandler.h @@ -30,6 +30,7 @@ inline constexpr uint32_t methodThrowPointHelper = 16; inline constexpr uint32_t propertyHookThrowPointsResolver = 17; inline constexpr uint32_t statementsHandler = 18; inline constexpr uint32_t arrayUnpackingHelper = 19; +inline constexpr uint32_t initializerExprTypeResolver = 20; } // namespace slot inline void declareClass(reg::Class &cls) @@ -61,6 +62,7 @@ inline void declareProperties(reg::Class &cls) cls.property("propertyHookThrowPointsResolver", ZEND_ACC_PRIVATE, reg::PropertyKind::Typed, 0, "PHPStan\\Analyser\\PropertyHookThrowPointsResolver"); cls.property("statementsHandler", ZEND_ACC_PRIVATE, reg::PropertyKind::Typed, 0, "PHPStan\\Analyser\\StatementsHandler"); cls.property("arrayUnpackingHelper", ZEND_ACC_PRIVATE, reg::PropertyKind::Typed, 0, "PHPStan\\Type\\ArrayUnpackingHelper"); + cls.property("initializerExprTypeResolver", ZEND_ACC_PRIVATE, reg::PropertyKind::Typed, 0, "PHPStan\\Reflection\\InitializerExprTypeResolver"); } /* the string and parameter tables the signatures below index into (see reg::Sig) */ @@ -106,128 +108,139 @@ inline constexpr char strings[] = "PHPStan\\Analyser\\StatementsHandler\0" /* 1269 */ "arrayUnpackingHelper\0" /* 1304 */ "PHPStan\\Type\\ArrayUnpackingHelper\0" /* 1325 */ - "__construct\0" /* 1359 */ - "expr\0" /* 1371 */ - "PhpParser\\Node\\Expr\0" /* 1376 */ - "\0" /* 1396 */ - "supports\0" /* 1397 */ - "nodeScopeResolver\0" /* 1406 */ - "PHPStan\\Analyser\\NodeScopeResolver\0" /* 1424 */ - "stmt\0" /* 1459 */ - "PhpParser\\Node\\Stmt\0" /* 1464 */ - "scope\0" /* 1484 */ - "PHPStan\\Analyser\\MutatingScope\0" /* 1490 */ - "storage\0" /* 1521 */ - "PHPStan\\Analyser\\ExpressionResultStorage\0" /* 1529 */ - "nodeCallback\0" /* 1570 */ - "context\0" /* 1583 */ - "PHPStan\\Analyser\\ExpressionContext\0" /* 1591 */ - "PHPStan\\Analyser\\ExpressionResult\0" /* 1626 */ - "processExpr\0" /* 1660 */ - "assignedExpr\0" /* 1672 */ - "captureAssignedCallArgResults\0" /* 1685 */ - "PhpParser\\Node\\Expr\\Assign\0" /* 1715 */ - "assignedExprResult\0" /* 1742 */ - "beforeScope\0" /* 1761 */ - "Closure\0" /* 1773 */ - "createCreateTypesCallback\0" /* 1781 */ - "createSpecifyTypesCallback\0" /* 1807 */ - "var\0" /* 1834 */ - "null\0" /* 1838 */ - "processVirtualAssign\0" /* 1843 */ - "mode\0" /* 1864 */ - "PHPStan\\Analyser\\AssignTargetWalkMode\0" /* 1869 */ - "PHPStan\\Analyser\\PreparedAssignTarget\0" /* 1907 */ - "prepareTarget\0" /* 1945 */ - "doPrepareTarget\0" /* 1959 */ - "target\0" /* 1975 */ - "valueResult\0" /* 1982 */ - "assignedValueResult\0" /* 1994 */ - "applyWrite\0" /* 2014 */ - "receiverType\0" /* 2025 */ - "PHPStan\\Type\\Type\0" /* 2038 */ - "keyType\0" /* 2056 */ - "valueType\0" /* 2064 */ - "PHPStan\\Analyser\\Generics\\TemplateArgumentConstraints\0" /* 2074 */ - "collectOffsetSetUsage\0" /* 2128 */ - "keyVar\0" /* 2150 */ - "PhpParser\\Node\\Expr\\Variable\0" /* 2157 */ - "arrayArg\0" /* 2186 */ - "narrowedKeyType\0" /* 2195 */ - "dimFetchType\0" /* 2211 */ - "PHPStan\\Analyser\\SpecifiedTypes\0" /* 2224 */ - "createArrayDimFetchConditionalExpressionHolder\0" /* 2256 */ - "readAssignedValueType\0" /* 2303 */ - "varResult\0" /* 2325 */ - "postEvalScope\0" /* 2335 */ - "preEvalScope\0" /* 2349 */ - "resolveContainerTypesAfterAssignedExprEval\0" /* 2362 */ - "nameResult\0" /* 2405 */ - "nativeValueType\0" /* 2416 */ - "assignDynamicVariable\0" /* 2432 */ - "unwrapAssign\0" /* 2454 */ - "variableName\0" /* 2467 */ - "conditionalExpressions\0" /* 2480 */ - "specifiedTypes\0" /* 2503 */ - "variableType\0" /* 2518 */ - "rhsImpurePoints\0" /* 2531 */ - "processSureTypesForConditionalExpressionsAfterAssign\0" /* 2547 */ - "processSureNotTypesForConditionalExpressionsAfterAssign\0" /* 2600 */ - "currentTypeForConditionalHolder\0" /* 2656 */ - "armScope\0" /* 2688 */ - "armExpr\0" /* 2697 */ - "remainderType\0" /* 2705 */ - "otherArmType\0" /* 2719 */ - "processTernaryArmValueImpliedTypesAfterAssign\0" /* 2732 */ - "holderExpr\0" /* 2778 */ - "holderExprString\0" /* 2789 */ - "holderType\0" /* 2806 */ - "holderCertainty\0" /* 2817 */ - "PHPStan\\TrinaryLogic\0" /* 2833 */ - "addConditionalExpressionHolder\0" /* 2854 */ - "newConditionalExpressions\0" /* 2885 */ - "mergeConditionalExpressions\0" /* 2911 */ - "PhpParser\\Node\\Expr\\Match_\0" /* 2939 */ - "processMatchForConditionalExpressionsAfterAssign\0" /* 2966 */ - "assignedType\0" /* 3015 */ - "processDerivedConditionalExpressionsAfterAssign\0" /* 3028 */ - "PhpParser\\Node\\Expr\\FuncCall\0" /* 3076 */ - "processInArrayForConditionalExpressionsAfterAssign\0" /* 3105 */ - "isExprSafeToProjectThroughVariable\0" /* 3156 */ - "dimFetchStack\0" /* 3191 */ - "PHPStan\\Analyser\\Scope\0" /* 3205 */ - "isImplicitArrayCreation\0" /* 3228 */ - "rootVarName\0" /* 3252 */ - "arrayExpr\0" /* 3264 */ - "PhpParser\\Node\\Expr\\Array_\0" /* 3274 */ - "parentExpr\0" /* 3301 */ - "processArrayByRefItems\0" /* 3312 */ - "implicitIndex\0" /* 3335 */ - "processArrayByRefItemsWithImplicitIndex\0" /* 3349 */ - "isFlattenableUnpackedArray\0" /* 3389 */ - "index\0" /* 3416 */ - "advanceImplicitIndex\0" /* 3422 */ - "offsetTypes\0" /* 3443 */ - "offsetValueType\0" /* 3455 */ - "valueToWrite\0" /* 3471 */ - "produceArrayDimFetchAssignValueToWrite\0" /* 3484 */ - "arrayDimFetch\0" /* 3523 */ - "PhpParser\\Node\\Expr\\ArrayDimFetch\0" /* 3537 */ - "shouldKeepList\0" /* 3571 */ - "offsetType\0" /* 3586 */ - "trackedLinkImpliesOffset\0" /* 3597 */ - "a\0" /* 3622 */ - "b\0" /* 3624 */ - "isSameVariable\0" /* 3626 */ - "isSameOffset\0" /* 3641 */ - "getLiteralArrayKeyType\0" /* 3654 */ - "propertyFetch\0" /* 3677 */ - "PhpParser\\Node\\Expr\\PropertyFetch|PhpParser\\Node\\Expr\\StaticPropertyFetch\0" /* 3691 */ - "getOriginalPropertyType\0" /* 3765 */ - "array\0" /* 3789 */ - "hasArrayReference\0" /* 3795 */ - "rhs\0" /* 3813 */ - "redundant"; /* 3817 */ + "initializerExprTypeResolver\0" /* 1359 */ + "PHPStan\\Reflection\\InitializerExprTypeResolver\0" /* 1387 */ + "__construct\0" /* 1434 */ + "expr\0" /* 1446 */ + "PhpParser\\Node\\Expr\0" /* 1451 */ + "\0" /* 1471 */ + "supports\0" /* 1472 */ + "nodeScopeResolver\0" /* 1481 */ + "PHPStan\\Analyser\\NodeScopeResolver\0" /* 1499 */ + "stmt\0" /* 1534 */ + "PhpParser\\Node\\Stmt\0" /* 1539 */ + "scope\0" /* 1559 */ + "PHPStan\\Analyser\\MutatingScope\0" /* 1565 */ + "storage\0" /* 1596 */ + "PHPStan\\Analyser\\ExpressionResultStorage\0" /* 1604 */ + "nodeCallback\0" /* 1645 */ + "context\0" /* 1658 */ + "PHPStan\\Analyser\\ExpressionContext\0" /* 1666 */ + "PHPStan\\Analyser\\ExpressionResult\0" /* 1701 */ + "processExpr\0" /* 1735 */ + "assignedExpr\0" /* 1747 */ + "captureAssignedCallArgResults\0" /* 1760 */ + "PhpParser\\Node\\Expr\\Assign\0" /* 1790 */ + "assignedExprResult\0" /* 1817 */ + "beforeScope\0" /* 1836 */ + "Closure\0" /* 1848 */ + "createCreateTypesCallback\0" /* 1856 */ + "createSpecifyTypesCallback\0" /* 1882 */ + "var\0" /* 1909 */ + "null\0" /* 1913 */ + "processVirtualAssign\0" /* 1918 */ + "mode\0" /* 1939 */ + "PHPStan\\Analyser\\AssignTargetWalkMode\0" /* 1944 */ + "PHPStan\\Analyser\\PreparedAssignTarget\0" /* 1982 */ + "prepareTarget\0" /* 2020 */ + "doPrepareTarget\0" /* 2034 */ + "target\0" /* 2050 */ + "valueResult\0" /* 2057 */ + "assignedValueResult\0" /* 2069 */ + "applyWrite\0" /* 2089 */ + "receiverType\0" /* 2100 */ + "PHPStan\\Type\\Type\0" /* 2113 */ + "keyType\0" /* 2131 */ + "valueType\0" /* 2139 */ + "PHPStan\\Analyser\\Generics\\TemplateArgumentConstraints\0" /* 2149 */ + "collectOffsetSetUsage\0" /* 2203 */ + "keyVar\0" /* 2225 */ + "PhpParser\\Node\\Expr\\Variable\0" /* 2232 */ + "arrayArg\0" /* 2261 */ + "narrowedKeyType\0" /* 2270 */ + "dimFetchType\0" /* 2286 */ + "PHPStan\\Analyser\\SpecifiedTypes\0" /* 2299 */ + "createArrayDimFetchConditionalExpressionHolder\0" /* 2331 */ + "readAssignedValueType\0" /* 2378 */ + "varResult\0" /* 2400 */ + "postEvalScope\0" /* 2410 */ + "preEvalScope\0" /* 2424 */ + "resolveContainerTypesAfterAssignedExprEval\0" /* 2437 */ + "nameResult\0" /* 2480 */ + "nativeValueType\0" /* 2491 */ + "assignDynamicVariable\0" /* 2507 */ + "unwrapAssign\0" /* 2529 */ + "variableName\0" /* 2542 */ + "conditionalExpressions\0" /* 2555 */ + "specifiedTypes\0" /* 2578 */ + "variableType\0" /* 2593 */ + "rhsImpurePoints\0" /* 2606 */ + "processSureTypesForConditionalExpressionsAfterAssign\0" /* 2622 */ + "processSureNotTypesForConditionalExpressionsAfterAssign\0" /* 2675 */ + "varExprString\0" /* 2731 */ + "appendedType\0" /* 2745 */ + "remapConditionalExpressionsThroughConcatAssign\0" /* 2758 */ + "branchScope\0" /* 2805 */ + "mergedScope\0" /* 2817 */ + "processDefinednessForConditionalExpressionsAfterAssign\0" /* 2829 */ + "node\0" /* 2884 */ + "PhpParser\\Node\0" /* 2889 */ + "containsVariableAssignment\0" /* 2904 */ + "currentTypeForConditionalHolder\0" /* 2931 */ + "armScope\0" /* 2963 */ + "armExpr\0" /* 2972 */ + "remainderType\0" /* 2980 */ + "otherArmType\0" /* 2994 */ + "processTernaryArmValueImpliedTypesAfterAssign\0" /* 3007 */ + "holderExpr\0" /* 3053 */ + "holderExprString\0" /* 3064 */ + "holderType\0" /* 3081 */ + "holderCertainty\0" /* 3092 */ + "PHPStan\\TrinaryLogic\0" /* 3108 */ + "addConditionalExpressionHolder\0" /* 3129 */ + "newConditionalExpressions\0" /* 3160 */ + "mergeConditionalExpressions\0" /* 3186 */ + "PhpParser\\Node\\Expr\\Match_\0" /* 3214 */ + "processMatchForConditionalExpressionsAfterAssign\0" /* 3241 */ + "assignedType\0" /* 3290 */ + "processDerivedConditionalExpressionsAfterAssign\0" /* 3303 */ + "PhpParser\\Node\\Expr\\FuncCall\0" /* 3351 */ + "processInArrayForConditionalExpressionsAfterAssign\0" /* 3380 */ + "isExprSafeToProjectThroughVariable\0" /* 3431 */ + "dimFetchStack\0" /* 3466 */ + "PHPStan\\Analyser\\Scope\0" /* 3480 */ + "isImplicitArrayCreation\0" /* 3503 */ + "rootVarName\0" /* 3527 */ + "arrayExpr\0" /* 3539 */ + "PhpParser\\Node\\Expr\\Array_\0" /* 3549 */ + "parentExpr\0" /* 3576 */ + "processArrayByRefItems\0" /* 3587 */ + "implicitIndex\0" /* 3610 */ + "processArrayByRefItemsWithImplicitIndex\0" /* 3624 */ + "isFlattenableUnpackedArray\0" /* 3664 */ + "index\0" /* 3691 */ + "advanceImplicitIndex\0" /* 3697 */ + "offsetTypes\0" /* 3718 */ + "offsetValueType\0" /* 3730 */ + "valueToWrite\0" /* 3746 */ + "produceArrayDimFetchAssignValueToWrite\0" /* 3759 */ + "arrayDimFetch\0" /* 3798 */ + "PhpParser\\Node\\Expr\\ArrayDimFetch\0" /* 3812 */ + "shouldKeepList\0" /* 3846 */ + "offsetType\0" /* 3861 */ + "trackedLinkImpliesOffset\0" /* 3872 */ + "a\0" /* 3897 */ + "b\0" /* 3899 */ + "isSameVariable\0" /* 3901 */ + "isSameOffset\0" /* 3916 */ + "getLiteralArrayKeyType\0" /* 3929 */ + "propertyFetch\0" /* 3952 */ + "PhpParser\\Node\\Expr\\PropertyFetch|PhpParser\\Node\\Expr\\StaticPropertyFetch\0" /* 3966 */ + "getOriginalPropertyType\0" /* 4040 */ + "array\0" /* 4064 */ + "hasArrayReference\0" /* 4070 */ + "rhs\0" /* 4088 */ + "redundant"; /* 4092 */ inline constexpr reg::PackedArg args[] = { reg::packed(0, 0, 25), /* __construct $templateArgumentObserver */ reg::packed(76, 0, 99), /* __construct $varAnnotationProcessor */ @@ -249,276 +262,292 @@ inline constexpr reg::PackedArg args[] = { reg::packed(1170, 0, 1202), /* __construct $propertyHookThrowPointsResolver */ reg::packed(1251, 0, 1269), /* __construct $statementsHandler */ reg::packed(1304, 0, 1325), /* __construct $arrayUnpackingHelper */ - reg::packed(1371, 0, 1376), /* supports $expr */ - reg::packed(1396, MAY_BE_BOOL), /* supports return */ - reg::packed(1406, 0, 1424), /* processExpr $nodeScopeResolver */ - reg::packed(1459, 0, 1464), /* processExpr $stmt */ - reg::packed(1371, 0, 1376), /* processExpr $expr */ - reg::packed(1484, 0, 1490), /* processExpr $scope */ - reg::packed(1521, 0, 1529), /* processExpr $storage */ - reg::packed(1570, MAY_BE_CALLABLE), /* processExpr $nodeCallback */ - reg::packed(1583, 0, 1591), /* processExpr $context */ - reg::packed(1396, 0, 1626), /* processExpr return */ - reg::packed(1672, 0, 1376), /* captureAssignedCallArgResults $assignedExpr */ - reg::packed(1521, 0, 1529), /* captureAssignedCallArgResults $storage */ - reg::packed(1396, MAY_BE_ARRAY), /* captureAssignedCallArgResults return */ - reg::packed(1371, 0, 1715), /* createCreateTypesCallback $expr */ - reg::packed(1742, 0, 1626), /* createCreateTypesCallback $assignedExprResult */ - reg::packed(1761, 0, 1490), /* createCreateTypesCallback $beforeScope */ - reg::packed(1396, 0, 1773), /* createCreateTypesCallback return */ - reg::packed(1371, 0, 1715), /* createSpecifyTypesCallback $expr */ - reg::packed(1742, 0, 1626), /* createSpecifyTypesCallback $assignedExprResult */ - reg::packed(1761, 0, 1490), /* createSpecifyTypesCallback $beforeScope */ - reg::packed(1521, 0, 1529), /* createSpecifyTypesCallback $storage */ - reg::packed(1396, 0, 1773), /* createSpecifyTypesCallback return */ - reg::packed(1406, 0, 1424), /* processVirtualAssign $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processVirtualAssign $scope */ - reg::packed(1521, 0, 1529), /* processVirtualAssign $storage */ - reg::packed(1459, 0, 1464), /* processVirtualAssign $stmt */ - reg::packed(1834, 0, 1376), /* processVirtualAssign $var */ - reg::packed(1672, 0, 1376), /* processVirtualAssign $assignedExpr */ - reg::packed(1570, MAY_BE_CALLABLE), /* processVirtualAssign $nodeCallback */ - reg::packed(1742, MAY_BE_NULL, 1626, false, false, 1838), /* processVirtualAssign $assignedExprResult */ - reg::packed(1396, 0, 1626), /* processVirtualAssign return */ - reg::packed(1406, 0, 1424), /* prepareTarget $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* prepareTarget $scope */ - reg::packed(1521, 0, 1529), /* prepareTarget $storage */ - reg::packed(1459, 0, 1464), /* prepareTarget $stmt */ - reg::packed(1834, 0, 1376), /* prepareTarget $var */ - reg::packed(1672, 0, 1376), /* prepareTarget $assignedExpr */ - reg::packed(1570, MAY_BE_CALLABLE), /* prepareTarget $nodeCallback */ - reg::packed(1583, 0, 1591), /* prepareTarget $context */ - reg::packed(1864, 0, 1869), /* prepareTarget $mode */ - reg::packed(1396, 0, 1907), /* prepareTarget return */ - reg::packed(1406, 0, 1424), /* doPrepareTarget $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* doPrepareTarget $scope */ - reg::packed(1521, 0, 1529), /* doPrepareTarget $storage */ - reg::packed(1459, 0, 1464), /* doPrepareTarget $stmt */ - reg::packed(1834, 0, 1376), /* doPrepareTarget $var */ - reg::packed(1672, 0, 1376), /* doPrepareTarget $assignedExpr */ - reg::packed(1570, MAY_BE_CALLABLE), /* doPrepareTarget $nodeCallback */ - reg::packed(1583, 0, 1591), /* doPrepareTarget $context */ - reg::packed(1864, 0, 1869), /* doPrepareTarget $mode */ - reg::packed(1396, 0, 1907), /* doPrepareTarget return */ - reg::packed(1406, 0, 1424), /* applyWrite $nodeScopeResolver */ - reg::packed(1975, 0, 1907), /* applyWrite $target */ - reg::packed(1982, 0, 1626), /* applyWrite $valueResult */ - reg::packed(1994, MAY_BE_NULL, 1626), /* applyWrite $assignedValueResult */ - reg::packed(1459, 0, 1464), /* applyWrite $stmt */ - reg::packed(1521, 0, 1529), /* applyWrite $storage */ - reg::packed(1570, MAY_BE_CALLABLE), /* applyWrite $nodeCallback */ - reg::packed(1583, 0, 1591), /* applyWrite $context */ - reg::packed(1396, 0, 1626), /* applyWrite return */ - reg::packed(1406, 0, 1424), /* collectOffsetSetUsage $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* collectOffsetSetUsage $scope */ - reg::packed(2025, 0, 2038), /* collectOffsetSetUsage $receiverType */ - reg::packed(2056, MAY_BE_NULL, 2038), /* collectOffsetSetUsage $keyType */ - reg::packed(2064, 0, 2038), /* collectOffsetSetUsage $valueType */ - reg::packed(1396, 0, 2074), /* collectOffsetSetUsage return */ - reg::packed(2150, 0, 2157), /* createArrayDimFetchConditionalExpressionHolder $keyVar */ - reg::packed(2186, 0, 1376), /* createArrayDimFetchConditionalExpressionHolder $arrayArg */ - reg::packed(2195, 0, 2038), /* createArrayDimFetchConditionalExpressionHolder $narrowedKeyType */ - reg::packed(2211, 0, 2038), /* createArrayDimFetchConditionalExpressionHolder $dimFetchType */ - reg::packed(1396, 0, 2224), /* createArrayDimFetchConditionalExpressionHolder return */ - reg::packed(1406, 0, 1424), /* readAssignedValueType $nodeScopeResolver */ - reg::packed(1994, MAY_BE_NULL, 1626), /* readAssignedValueType $assignedValueResult */ - reg::packed(1672, 0, 1376), /* readAssignedValueType $assignedExpr */ - reg::packed(1484, 0, 1490), /* readAssignedValueType $scope */ - reg::packed(1396, 0, 2038), /* readAssignedValueType return */ - reg::packed(1406, 0, 1424), /* resolveContainerTypesAfterAssignedExprEval $nodeScopeResolver */ - reg::packed(1834, 0, 1376), /* resolveContainerTypesAfterAssignedExprEval $var */ - reg::packed(2325, 0, 1626), /* resolveContainerTypesAfterAssignedExprEval $varResult */ - reg::packed(2335, 0, 1490), /* resolveContainerTypesAfterAssignedExprEval $postEvalScope */ - reg::packed(2349, MAY_BE_NULL, 1490), /* resolveContainerTypesAfterAssignedExprEval $preEvalScope */ - reg::packed(1521, 0, 1529), /* resolveContainerTypesAfterAssignedExprEval $storage */ - reg::packed(1396, MAY_BE_ARRAY), /* resolveContainerTypesAfterAssignedExprEval return */ - reg::packed(1484, 0, 1490), /* assignDynamicVariable $scope */ - reg::packed(2405, 0, 1626), /* assignDynamicVariable $nameResult */ - reg::packed(2064, 0, 2038), /* assignDynamicVariable $valueType */ - reg::packed(2416, 0, 2038), /* assignDynamicVariable $nativeValueType */ - reg::packed(1396, 0, 1490), /* assignDynamicVariable return */ - reg::packed(1371, 0, 1376), /* unwrapAssign $expr */ - reg::packed(1396, 0, 1376), /* unwrapAssign return */ - reg::packed(1406, 0, 1424), /* processSureTypesForConditionalExpressionsAfterAssign $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processSureTypesForConditionalExpressionsAfterAssign $scope */ - reg::packed(1521, 0, 1529), /* processSureTypesForConditionalExpressionsAfterAssign $storage */ - reg::packed(2467, MAY_BE_STRING), /* processSureTypesForConditionalExpressionsAfterAssign $variableName */ - reg::packed(2480, MAY_BE_ARRAY), /* processSureTypesForConditionalExpressionsAfterAssign $conditionalExpressions */ - reg::packed(2503, 0, 2224), /* processSureTypesForConditionalExpressionsAfterAssign $specifiedTypes */ - reg::packed(2518, 0, 2038), /* processSureTypesForConditionalExpressionsAfterAssign $variableType */ - reg::packed(2531, MAY_BE_ARRAY), /* processSureTypesForConditionalExpressionsAfterAssign $rhsImpurePoints */ - reg::packed(1672, 0, 1376), /* processSureTypesForConditionalExpressionsAfterAssign $assignedExpr */ - reg::packed(1994, MAY_BE_NULL, 1626), /* processSureTypesForConditionalExpressionsAfterAssign $assignedValueResult */ - reg::packed(1396, MAY_BE_ARRAY), /* processSureTypesForConditionalExpressionsAfterAssign return */ - reg::packed(1406, 0, 1424), /* processSureNotTypesForConditionalExpressionsAfterAssign $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processSureNotTypesForConditionalExpressionsAfterAssign $scope */ - reg::packed(1521, 0, 1529), /* processSureNotTypesForConditionalExpressionsAfterAssign $storage */ - reg::packed(2467, MAY_BE_STRING), /* processSureNotTypesForConditionalExpressionsAfterAssign $variableName */ - reg::packed(2480, MAY_BE_ARRAY), /* processSureNotTypesForConditionalExpressionsAfterAssign $conditionalExpressions */ - reg::packed(2503, 0, 2224), /* processSureNotTypesForConditionalExpressionsAfterAssign $specifiedTypes */ - reg::packed(2518, 0, 2038), /* processSureNotTypesForConditionalExpressionsAfterAssign $variableType */ - reg::packed(2531, MAY_BE_ARRAY), /* processSureNotTypesForConditionalExpressionsAfterAssign $rhsImpurePoints */ - reg::packed(1672, 0, 1376), /* processSureNotTypesForConditionalExpressionsAfterAssign $assignedExpr */ - reg::packed(1994, MAY_BE_NULL, 1626), /* processSureNotTypesForConditionalExpressionsAfterAssign $assignedValueResult */ - reg::packed(1396, MAY_BE_ARRAY), /* processSureNotTypesForConditionalExpressionsAfterAssign return */ - reg::packed(1406, 0, 1424), /* currentTypeForConditionalHolder $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* currentTypeForConditionalHolder $scope */ - reg::packed(1521, 0, 1529), /* currentTypeForConditionalHolder $storage */ - reg::packed(1371, 0, 1376), /* currentTypeForConditionalHolder $expr */ - reg::packed(1672, 0, 1376), /* currentTypeForConditionalHolder $assignedExpr */ - reg::packed(1994, MAY_BE_NULL, 1626), /* currentTypeForConditionalHolder $assignedValueResult */ - reg::packed(1396, 0, 2038), /* currentTypeForConditionalHolder return */ - reg::packed(1406, 0, 1424), /* processTernaryArmValueImpliedTypesAfterAssign $nodeScopeResolver */ - reg::packed(2688, 0, 1490), /* processTernaryArmValueImpliedTypesAfterAssign $armScope */ - reg::packed(1521, 0, 1529), /* processTernaryArmValueImpliedTypesAfterAssign $storage */ - reg::packed(2467, MAY_BE_STRING), /* processTernaryArmValueImpliedTypesAfterAssign $variableName */ - reg::packed(2480, MAY_BE_ARRAY), /* processTernaryArmValueImpliedTypesAfterAssign $conditionalExpressions */ - reg::packed(2697, 0, 1376), /* processTernaryArmValueImpliedTypesAfterAssign $armExpr */ - reg::packed(2705, 0, 2038), /* processTernaryArmValueImpliedTypesAfterAssign $remainderType */ - reg::packed(2719, 0, 2038), /* processTernaryArmValueImpliedTypesAfterAssign $otherArmType */ - reg::packed(2531, MAY_BE_ARRAY), /* processTernaryArmValueImpliedTypesAfterAssign $rhsImpurePoints */ - reg::packed(1672, 0, 1376), /* processTernaryArmValueImpliedTypesAfterAssign $assignedExpr */ - reg::packed(1994, MAY_BE_NULL, 1626), /* processTernaryArmValueImpliedTypesAfterAssign $assignedValueResult */ - reg::packed(1396, MAY_BE_ARRAY), /* processTernaryArmValueImpliedTypesAfterAssign return */ - reg::packed(2480, MAY_BE_ARRAY), /* addConditionalExpressionHolder $conditionalExpressions */ - reg::packed(2467, MAY_BE_STRING), /* addConditionalExpressionHolder $variableName */ - reg::packed(2518, 0, 2038), /* addConditionalExpressionHolder $variableType */ - reg::packed(2778, 0, 1376), /* addConditionalExpressionHolder $holderExpr */ - reg::packed(2789, MAY_BE_STRING), /* addConditionalExpressionHolder $holderExprString */ - reg::packed(2806, 0, 2038), /* addConditionalExpressionHolder $holderType */ - reg::packed(2817, 0, 2833), /* addConditionalExpressionHolder $holderCertainty */ - reg::packed(1396, MAY_BE_ARRAY), /* addConditionalExpressionHolder return */ - reg::packed(2480, MAY_BE_ARRAY), /* mergeConditionalExpressions $conditionalExpressions */ - reg::packed(2885, MAY_BE_ARRAY), /* mergeConditionalExpressions $newConditionalExpressions */ - reg::packed(1396, MAY_BE_ARRAY), /* mergeConditionalExpressions return */ - reg::packed(1484, 0, 1490), /* processMatchForConditionalExpressionsAfterAssign $scope */ - reg::packed(2467, MAY_BE_STRING), /* processMatchForConditionalExpressionsAfterAssign $variableName */ - reg::packed(1371, 0, 2939), /* processMatchForConditionalExpressionsAfterAssign $expr */ - reg::packed(1396, MAY_BE_ARRAY), /* processMatchForConditionalExpressionsAfterAssign return */ - reg::packed(1406, 0, 1424), /* processDerivedConditionalExpressionsAfterAssign $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processDerivedConditionalExpressionsAfterAssign $scope */ - reg::packed(2467, MAY_BE_STRING), /* processDerivedConditionalExpressionsAfterAssign $variableName */ - reg::packed(2480, MAY_BE_ARRAY), /* processDerivedConditionalExpressionsAfterAssign $conditionalExpressions */ - reg::packed(1672, 0, 1376), /* processDerivedConditionalExpressionsAfterAssign $assignedExpr */ - reg::packed(3015, 0, 2038), /* processDerivedConditionalExpressionsAfterAssign $assignedType */ - reg::packed(2531, MAY_BE_ARRAY), /* processDerivedConditionalExpressionsAfterAssign $rhsImpurePoints */ - reg::packed(1396, MAY_BE_ARRAY), /* processDerivedConditionalExpressionsAfterAssign return */ - reg::packed(1406, 0, 1424), /* processInArrayForConditionalExpressionsAfterAssign $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processInArrayForConditionalExpressionsAfterAssign $scope */ - reg::packed(2467, MAY_BE_STRING), /* processInArrayForConditionalExpressionsAfterAssign $variableName */ - reg::packed(2480, MAY_BE_ARRAY), /* processInArrayForConditionalExpressionsAfterAssign $conditionalExpressions */ - reg::packed(1672, 0, 3076), /* processInArrayForConditionalExpressionsAfterAssign $assignedExpr */ - reg::packed(3015, 0, 2038), /* processInArrayForConditionalExpressionsAfterAssign $assignedType */ - reg::packed(2531, MAY_BE_ARRAY), /* processInArrayForConditionalExpressionsAfterAssign $rhsImpurePoints */ - reg::packed(1396, MAY_BE_ARRAY), /* processInArrayForConditionalExpressionsAfterAssign return */ - reg::packed(1371, 0, 1376), /* isExprSafeToProjectThroughVariable $expr */ - reg::packed(2467, MAY_BE_STRING), /* isExprSafeToProjectThroughVariable $variableName */ - reg::packed(2531, MAY_BE_ARRAY), /* isExprSafeToProjectThroughVariable $rhsImpurePoints */ - reg::packed(1672, 0, 1376), /* isExprSafeToProjectThroughVariable $assignedExpr */ - reg::packed(1396, MAY_BE_BOOL), /* isExprSafeToProjectThroughVariable return */ - reg::packed(3191, MAY_BE_ARRAY), /* isImplicitArrayCreation $dimFetchStack */ - reg::packed(1484, 0, 3205), /* isImplicitArrayCreation $scope */ - reg::packed(1396, 0, 2833), /* isImplicitArrayCreation return */ - reg::packed(1406, 0, 1424), /* processArrayByRefItems $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processArrayByRefItems $scope */ - reg::packed(1521, 0, 1529), /* processArrayByRefItems $storage */ - reg::packed(3252, MAY_BE_STRING), /* processArrayByRefItems $rootVarName */ - reg::packed(3264, 0, 3274), /* processArrayByRefItems $arrayExpr */ - reg::packed(3301, 0, 1376), /* processArrayByRefItems $parentExpr */ - reg::packed(1396, 0, 1490), /* processArrayByRefItems return */ - reg::packed(1406, 0, 1424), /* processArrayByRefItemsWithImplicitIndex $nodeScopeResolver */ - reg::packed(1484, 0, 1490), /* processArrayByRefItemsWithImplicitIndex $scope */ - reg::packed(1521, 0, 1529), /* processArrayByRefItemsWithImplicitIndex $storage */ - reg::packed(3252, MAY_BE_STRING), /* processArrayByRefItemsWithImplicitIndex $rootVarName */ - reg::packed(3264, 0, 3274), /* processArrayByRefItemsWithImplicitIndex $arrayExpr */ - reg::packed(3301, 0, 1376), /* processArrayByRefItemsWithImplicitIndex $parentExpr */ - reg::packed(3335, MAY_BE_NULL | MAY_BE_LONG), /* processArrayByRefItemsWithImplicitIndex $implicitIndex */ - reg::packed(1396, MAY_BE_ARRAY), /* processArrayByRefItemsWithImplicitIndex return */ - reg::packed(3264, 0, 3274), /* isFlattenableUnpackedArray $arrayExpr */ - reg::packed(1396, MAY_BE_BOOL), /* isFlattenableUnpackedArray return */ - reg::packed(3416, MAY_BE_LONG), /* advanceImplicitIndex $index */ - reg::packed(1396, MAY_BE_NULL | MAY_BE_LONG), /* advanceImplicitIndex return */ - reg::packed(1406, 0, 1424), /* produceArrayDimFetchAssignValueToWrite $nodeScopeResolver */ - reg::packed(3191, MAY_BE_ARRAY), /* produceArrayDimFetchAssignValueToWrite $dimFetchStack */ - reg::packed(3443, MAY_BE_ARRAY), /* produceArrayDimFetchAssignValueToWrite $offsetTypes */ - reg::packed(3455, 0, 2038), /* produceArrayDimFetchAssignValueToWrite $offsetValueType */ - reg::packed(3471, 0, 2038), /* produceArrayDimFetchAssignValueToWrite $valueToWrite */ - reg::packed(1484, 0, 1490), /* produceArrayDimFetchAssignValueToWrite $scope */ - reg::packed(1521, 0, 1529), /* produceArrayDimFetchAssignValueToWrite $storage */ - reg::packed(1396, MAY_BE_ARRAY), /* produceArrayDimFetchAssignValueToWrite return */ - reg::packed(1406, 0, 1424), /* shouldKeepList $nodeScopeResolver */ - reg::packed(3523, 0, 3537), /* shouldKeepList $arrayDimFetch */ - reg::packed(1484, 0, 1490), /* shouldKeepList $scope */ - reg::packed(1521, 0, 1529), /* shouldKeepList $storage */ - reg::packed(3455, 0, 2038), /* shouldKeepList $offsetValueType */ - reg::packed(1396, MAY_BE_BOOL), /* shouldKeepList return */ - reg::packed(3455, 0, 2038), /* trackedLinkImpliesOffset $offsetValueType */ - reg::packed(3586, 0, 2038), /* trackedLinkImpliesOffset $offsetType */ - reg::packed(1396, MAY_BE_BOOL), /* trackedLinkImpliesOffset return */ - reg::packed(3622, 0, 1376), /* isSameVariable $a */ - reg::packed(3624, 0, 1376), /* isSameVariable $b */ - reg::packed(1396, MAY_BE_BOOL), /* isSameVariable return */ - reg::packed(3622, 0, 1376), /* isSameOffset $a */ - reg::packed(3624, 0, 1376), /* isSameOffset $b */ - reg::packed(1396, MAY_BE_BOOL), /* isSameOffset return */ - reg::packed(1371, 0, 1376), /* getLiteralArrayKeyType $expr */ - reg::packed(1396, MAY_BE_NULL, 2038), /* getLiteralArrayKeyType return */ - reg::packed(1406, 0, 1424), /* getOriginalPropertyType $nodeScopeResolver */ - reg::packed(3677, 0, 3691), /* getOriginalPropertyType $propertyFetch */ - reg::packed(1484, 0, 1490), /* getOriginalPropertyType $scope */ - reg::packed(1396, 0, 2038), /* getOriginalPropertyType return */ - reg::packed(3789, 0, 3274), /* hasArrayReference $array */ - reg::packed(1396, MAY_BE_BOOL), /* hasArrayReference return */ - reg::packed(3813, 0, 1626), /* redundant $rhs */ - reg::packed(1975, 0, 1376), /* redundant $target */ - reg::packed(1521, 0, 1529), /* redundant $storage */ - reg::packed(1396, MAY_BE_NULL, 2038), /* redundant return */ + reg::packed(1359, 0, 1387), /* __construct $initializerExprTypeResolver */ + reg::packed(1446, 0, 1451), /* supports $expr */ + reg::packed(1471, MAY_BE_BOOL), /* supports return */ + reg::packed(1481, 0, 1499), /* processExpr $nodeScopeResolver */ + reg::packed(1534, 0, 1539), /* processExpr $stmt */ + reg::packed(1446, 0, 1451), /* processExpr $expr */ + reg::packed(1559, 0, 1565), /* processExpr $scope */ + reg::packed(1596, 0, 1604), /* processExpr $storage */ + reg::packed(1645, MAY_BE_CALLABLE), /* processExpr $nodeCallback */ + reg::packed(1658, 0, 1666), /* processExpr $context */ + reg::packed(1471, 0, 1701), /* processExpr return */ + reg::packed(1747, 0, 1451), /* captureAssignedCallArgResults $assignedExpr */ + reg::packed(1596, 0, 1604), /* captureAssignedCallArgResults $storage */ + reg::packed(1471, MAY_BE_ARRAY), /* captureAssignedCallArgResults return */ + reg::packed(1446, 0, 1790), /* createCreateTypesCallback $expr */ + reg::packed(1817, 0, 1701), /* createCreateTypesCallback $assignedExprResult */ + reg::packed(1836, 0, 1565), /* createCreateTypesCallback $beforeScope */ + reg::packed(1471, 0, 1848), /* createCreateTypesCallback return */ + reg::packed(1446, 0, 1790), /* createSpecifyTypesCallback $expr */ + reg::packed(1817, 0, 1701), /* createSpecifyTypesCallback $assignedExprResult */ + reg::packed(1836, 0, 1565), /* createSpecifyTypesCallback $beforeScope */ + reg::packed(1596, 0, 1604), /* createSpecifyTypesCallback $storage */ + reg::packed(1471, 0, 1848), /* createSpecifyTypesCallback return */ + reg::packed(1481, 0, 1499), /* processVirtualAssign $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processVirtualAssign $scope */ + reg::packed(1596, 0, 1604), /* processVirtualAssign $storage */ + reg::packed(1534, 0, 1539), /* processVirtualAssign $stmt */ + reg::packed(1909, 0, 1451), /* processVirtualAssign $var */ + reg::packed(1747, 0, 1451), /* processVirtualAssign $assignedExpr */ + reg::packed(1645, MAY_BE_CALLABLE), /* processVirtualAssign $nodeCallback */ + reg::packed(1817, MAY_BE_NULL, 1701, false, false, 1913), /* processVirtualAssign $assignedExprResult */ + reg::packed(1471, 0, 1701), /* processVirtualAssign return */ + reg::packed(1481, 0, 1499), /* prepareTarget $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* prepareTarget $scope */ + reg::packed(1596, 0, 1604), /* prepareTarget $storage */ + reg::packed(1534, 0, 1539), /* prepareTarget $stmt */ + reg::packed(1909, 0, 1451), /* prepareTarget $var */ + reg::packed(1747, 0, 1451), /* prepareTarget $assignedExpr */ + reg::packed(1645, MAY_BE_CALLABLE), /* prepareTarget $nodeCallback */ + reg::packed(1658, 0, 1666), /* prepareTarget $context */ + reg::packed(1939, 0, 1944), /* prepareTarget $mode */ + reg::packed(1471, 0, 1982), /* prepareTarget return */ + reg::packed(1481, 0, 1499), /* doPrepareTarget $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* doPrepareTarget $scope */ + reg::packed(1596, 0, 1604), /* doPrepareTarget $storage */ + reg::packed(1534, 0, 1539), /* doPrepareTarget $stmt */ + reg::packed(1909, 0, 1451), /* doPrepareTarget $var */ + reg::packed(1747, 0, 1451), /* doPrepareTarget $assignedExpr */ + reg::packed(1645, MAY_BE_CALLABLE), /* doPrepareTarget $nodeCallback */ + reg::packed(1658, 0, 1666), /* doPrepareTarget $context */ + reg::packed(1939, 0, 1944), /* doPrepareTarget $mode */ + reg::packed(1471, 0, 1982), /* doPrepareTarget return */ + reg::packed(1481, 0, 1499), /* applyWrite $nodeScopeResolver */ + reg::packed(2050, 0, 1982), /* applyWrite $target */ + reg::packed(2057, 0, 1701), /* applyWrite $valueResult */ + reg::packed(2069, MAY_BE_NULL, 1701), /* applyWrite $assignedValueResult */ + reg::packed(1534, 0, 1539), /* applyWrite $stmt */ + reg::packed(1596, 0, 1604), /* applyWrite $storage */ + reg::packed(1645, MAY_BE_CALLABLE), /* applyWrite $nodeCallback */ + reg::packed(1658, 0, 1666), /* applyWrite $context */ + reg::packed(1471, 0, 1701), /* applyWrite return */ + reg::packed(1481, 0, 1499), /* collectOffsetSetUsage $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* collectOffsetSetUsage $scope */ + reg::packed(2100, 0, 2113), /* collectOffsetSetUsage $receiverType */ + reg::packed(2131, MAY_BE_NULL, 2113), /* collectOffsetSetUsage $keyType */ + reg::packed(2139, 0, 2113), /* collectOffsetSetUsage $valueType */ + reg::packed(1471, 0, 2149), /* collectOffsetSetUsage return */ + reg::packed(2225, 0, 2232), /* createArrayDimFetchConditionalExpressionHolder $keyVar */ + reg::packed(2261, 0, 1451), /* createArrayDimFetchConditionalExpressionHolder $arrayArg */ + reg::packed(2270, 0, 2113), /* createArrayDimFetchConditionalExpressionHolder $narrowedKeyType */ + reg::packed(2286, 0, 2113), /* createArrayDimFetchConditionalExpressionHolder $dimFetchType */ + reg::packed(1471, 0, 2299), /* createArrayDimFetchConditionalExpressionHolder return */ + reg::packed(1481, 0, 1499), /* readAssignedValueType $nodeScopeResolver */ + reg::packed(2069, MAY_BE_NULL, 1701), /* readAssignedValueType $assignedValueResult */ + reg::packed(1747, 0, 1451), /* readAssignedValueType $assignedExpr */ + reg::packed(1559, 0, 1565), /* readAssignedValueType $scope */ + reg::packed(1471, 0, 2113), /* readAssignedValueType return */ + reg::packed(1481, 0, 1499), /* resolveContainerTypesAfterAssignedExprEval $nodeScopeResolver */ + reg::packed(1909, 0, 1451), /* resolveContainerTypesAfterAssignedExprEval $var */ + reg::packed(2400, 0, 1701), /* resolveContainerTypesAfterAssignedExprEval $varResult */ + reg::packed(2410, 0, 1565), /* resolveContainerTypesAfterAssignedExprEval $postEvalScope */ + reg::packed(2424, MAY_BE_NULL, 1565), /* resolveContainerTypesAfterAssignedExprEval $preEvalScope */ + reg::packed(1596, 0, 1604), /* resolveContainerTypesAfterAssignedExprEval $storage */ + reg::packed(1471, MAY_BE_ARRAY), /* resolveContainerTypesAfterAssignedExprEval return */ + reg::packed(1559, 0, 1565), /* assignDynamicVariable $scope */ + reg::packed(2480, 0, 1701), /* assignDynamicVariable $nameResult */ + reg::packed(2139, 0, 2113), /* assignDynamicVariable $valueType */ + reg::packed(2491, 0, 2113), /* assignDynamicVariable $nativeValueType */ + reg::packed(1471, 0, 1565), /* assignDynamicVariable return */ + reg::packed(1446, 0, 1451), /* unwrapAssign $expr */ + reg::packed(1471, 0, 1451), /* unwrapAssign return */ + reg::packed(1481, 0, 1499), /* processSureTypesForConditionalExpressionsAfterAssign $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processSureTypesForConditionalExpressionsAfterAssign $scope */ + reg::packed(1596, 0, 1604), /* processSureTypesForConditionalExpressionsAfterAssign $storage */ + reg::packed(2542, MAY_BE_STRING), /* processSureTypesForConditionalExpressionsAfterAssign $variableName */ + reg::packed(2555, MAY_BE_ARRAY), /* processSureTypesForConditionalExpressionsAfterAssign $conditionalExpressions */ + reg::packed(2578, 0, 2299), /* processSureTypesForConditionalExpressionsAfterAssign $specifiedTypes */ + reg::packed(2593, 0, 2113), /* processSureTypesForConditionalExpressionsAfterAssign $variableType */ + reg::packed(2606, MAY_BE_ARRAY), /* processSureTypesForConditionalExpressionsAfterAssign $rhsImpurePoints */ + reg::packed(1747, 0, 1451), /* processSureTypesForConditionalExpressionsAfterAssign $assignedExpr */ + reg::packed(2069, MAY_BE_NULL, 1701), /* processSureTypesForConditionalExpressionsAfterAssign $assignedValueResult */ + reg::packed(1471, MAY_BE_ARRAY), /* processSureTypesForConditionalExpressionsAfterAssign return */ + reg::packed(1481, 0, 1499), /* processSureNotTypesForConditionalExpressionsAfterAssign $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processSureNotTypesForConditionalExpressionsAfterAssign $scope */ + reg::packed(1596, 0, 1604), /* processSureNotTypesForConditionalExpressionsAfterAssign $storage */ + reg::packed(2542, MAY_BE_STRING), /* processSureNotTypesForConditionalExpressionsAfterAssign $variableName */ + reg::packed(2555, MAY_BE_ARRAY), /* processSureNotTypesForConditionalExpressionsAfterAssign $conditionalExpressions */ + reg::packed(2578, 0, 2299), /* processSureNotTypesForConditionalExpressionsAfterAssign $specifiedTypes */ + reg::packed(2593, 0, 2113), /* processSureNotTypesForConditionalExpressionsAfterAssign $variableType */ + reg::packed(2606, MAY_BE_ARRAY), /* processSureNotTypesForConditionalExpressionsAfterAssign $rhsImpurePoints */ + reg::packed(1747, 0, 1451), /* processSureNotTypesForConditionalExpressionsAfterAssign $assignedExpr */ + reg::packed(2069, MAY_BE_NULL, 1701), /* processSureNotTypesForConditionalExpressionsAfterAssign $assignedValueResult */ + reg::packed(1471, MAY_BE_ARRAY), /* processSureNotTypesForConditionalExpressionsAfterAssign return */ + reg::packed(2555, MAY_BE_ARRAY), /* remapConditionalExpressionsThroughConcatAssign $conditionalExpressions */ + reg::packed(2731, MAY_BE_STRING), /* remapConditionalExpressionsThroughConcatAssign $varExprString */ + reg::packed(2745, 0, 2113), /* remapConditionalExpressionsThroughConcatAssign $appendedType */ + reg::packed(1471, MAY_BE_ARRAY), /* remapConditionalExpressionsThroughConcatAssign return */ + reg::packed(2555, MAY_BE_ARRAY), /* processDefinednessForConditionalExpressionsAfterAssign $conditionalExpressions */ + reg::packed(2542, MAY_BE_STRING), /* processDefinednessForConditionalExpressionsAfterAssign $variableName */ + reg::packed(2593, 0, 2113), /* processDefinednessForConditionalExpressionsAfterAssign $variableType */ + reg::packed(2805, 0, 1565), /* processDefinednessForConditionalExpressionsAfterAssign $branchScope */ + reg::packed(2817, 0, 1565), /* processDefinednessForConditionalExpressionsAfterAssign $mergedScope */ + reg::packed(1471, MAY_BE_ARRAY), /* processDefinednessForConditionalExpressionsAfterAssign return */ + reg::packed(2884, 0, 2889), /* containsVariableAssignment $node */ + reg::packed(1471, MAY_BE_BOOL), /* containsVariableAssignment return */ + reg::packed(1481, 0, 1499), /* currentTypeForConditionalHolder $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* currentTypeForConditionalHolder $scope */ + reg::packed(1596, 0, 1604), /* currentTypeForConditionalHolder $storage */ + reg::packed(1446, 0, 1451), /* currentTypeForConditionalHolder $expr */ + reg::packed(1747, 0, 1451), /* currentTypeForConditionalHolder $assignedExpr */ + reg::packed(2069, MAY_BE_NULL, 1701), /* currentTypeForConditionalHolder $assignedValueResult */ + reg::packed(1471, 0, 2113), /* currentTypeForConditionalHolder return */ + reg::packed(1481, 0, 1499), /* processTernaryArmValueImpliedTypesAfterAssign $nodeScopeResolver */ + reg::packed(2963, 0, 1565), /* processTernaryArmValueImpliedTypesAfterAssign $armScope */ + reg::packed(1596, 0, 1604), /* processTernaryArmValueImpliedTypesAfterAssign $storage */ + reg::packed(2542, MAY_BE_STRING), /* processTernaryArmValueImpliedTypesAfterAssign $variableName */ + reg::packed(2555, MAY_BE_ARRAY), /* processTernaryArmValueImpliedTypesAfterAssign $conditionalExpressions */ + reg::packed(2972, 0, 1451), /* processTernaryArmValueImpliedTypesAfterAssign $armExpr */ + reg::packed(2980, 0, 2113), /* processTernaryArmValueImpliedTypesAfterAssign $remainderType */ + reg::packed(2994, 0, 2113), /* processTernaryArmValueImpliedTypesAfterAssign $otherArmType */ + reg::packed(2606, MAY_BE_ARRAY), /* processTernaryArmValueImpliedTypesAfterAssign $rhsImpurePoints */ + reg::packed(1747, 0, 1451), /* processTernaryArmValueImpliedTypesAfterAssign $assignedExpr */ + reg::packed(2069, MAY_BE_NULL, 1701), /* processTernaryArmValueImpliedTypesAfterAssign $assignedValueResult */ + reg::packed(1471, MAY_BE_ARRAY), /* processTernaryArmValueImpliedTypesAfterAssign return */ + reg::packed(2555, MAY_BE_ARRAY), /* addConditionalExpressionHolder $conditionalExpressions */ + reg::packed(2542, MAY_BE_STRING), /* addConditionalExpressionHolder $variableName */ + reg::packed(2593, 0, 2113), /* addConditionalExpressionHolder $variableType */ + reg::packed(3053, 0, 1451), /* addConditionalExpressionHolder $holderExpr */ + reg::packed(3064, MAY_BE_STRING), /* addConditionalExpressionHolder $holderExprString */ + reg::packed(3081, 0, 2113), /* addConditionalExpressionHolder $holderType */ + reg::packed(3092, 0, 3108), /* addConditionalExpressionHolder $holderCertainty */ + reg::packed(1471, MAY_BE_ARRAY), /* addConditionalExpressionHolder return */ + reg::packed(2555, MAY_BE_ARRAY), /* mergeConditionalExpressions $conditionalExpressions */ + reg::packed(3160, MAY_BE_ARRAY), /* mergeConditionalExpressions $newConditionalExpressions */ + reg::packed(1471, MAY_BE_ARRAY), /* mergeConditionalExpressions return */ + reg::packed(1559, 0, 1565), /* processMatchForConditionalExpressionsAfterAssign $scope */ + reg::packed(2542, MAY_BE_STRING), /* processMatchForConditionalExpressionsAfterAssign $variableName */ + reg::packed(1446, 0, 3214), /* processMatchForConditionalExpressionsAfterAssign $expr */ + reg::packed(1471, MAY_BE_ARRAY), /* processMatchForConditionalExpressionsAfterAssign return */ + reg::packed(1481, 0, 1499), /* processDerivedConditionalExpressionsAfterAssign $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processDerivedConditionalExpressionsAfterAssign $scope */ + reg::packed(2542, MAY_BE_STRING), /* processDerivedConditionalExpressionsAfterAssign $variableName */ + reg::packed(2555, MAY_BE_ARRAY), /* processDerivedConditionalExpressionsAfterAssign $conditionalExpressions */ + reg::packed(1747, 0, 1451), /* processDerivedConditionalExpressionsAfterAssign $assignedExpr */ + reg::packed(3290, 0, 2113), /* processDerivedConditionalExpressionsAfterAssign $assignedType */ + reg::packed(2606, MAY_BE_ARRAY), /* processDerivedConditionalExpressionsAfterAssign $rhsImpurePoints */ + reg::packed(1471, MAY_BE_ARRAY), /* processDerivedConditionalExpressionsAfterAssign return */ + reg::packed(1481, 0, 1499), /* processInArrayForConditionalExpressionsAfterAssign $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processInArrayForConditionalExpressionsAfterAssign $scope */ + reg::packed(2542, MAY_BE_STRING), /* processInArrayForConditionalExpressionsAfterAssign $variableName */ + reg::packed(2555, MAY_BE_ARRAY), /* processInArrayForConditionalExpressionsAfterAssign $conditionalExpressions */ + reg::packed(1747, 0, 3351), /* processInArrayForConditionalExpressionsAfterAssign $assignedExpr */ + reg::packed(3290, 0, 2113), /* processInArrayForConditionalExpressionsAfterAssign $assignedType */ + reg::packed(2606, MAY_BE_ARRAY), /* processInArrayForConditionalExpressionsAfterAssign $rhsImpurePoints */ + reg::packed(1471, MAY_BE_ARRAY), /* processInArrayForConditionalExpressionsAfterAssign return */ + reg::packed(1446, 0, 1451), /* isExprSafeToProjectThroughVariable $expr */ + reg::packed(2542, MAY_BE_STRING), /* isExprSafeToProjectThroughVariable $variableName */ + reg::packed(2606, MAY_BE_ARRAY), /* isExprSafeToProjectThroughVariable $rhsImpurePoints */ + reg::packed(1747, 0, 1451), /* isExprSafeToProjectThroughVariable $assignedExpr */ + reg::packed(1471, MAY_BE_BOOL), /* isExprSafeToProjectThroughVariable return */ + reg::packed(3466, MAY_BE_ARRAY), /* isImplicitArrayCreation $dimFetchStack */ + reg::packed(1559, 0, 3480), /* isImplicitArrayCreation $scope */ + reg::packed(1471, 0, 3108), /* isImplicitArrayCreation return */ + reg::packed(1481, 0, 1499), /* processArrayByRefItems $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processArrayByRefItems $scope */ + reg::packed(1596, 0, 1604), /* processArrayByRefItems $storage */ + reg::packed(3527, MAY_BE_STRING), /* processArrayByRefItems $rootVarName */ + reg::packed(3539, 0, 3549), /* processArrayByRefItems $arrayExpr */ + reg::packed(3576, 0, 1451), /* processArrayByRefItems $parentExpr */ + reg::packed(1471, 0, 1565), /* processArrayByRefItems return */ + reg::packed(1481, 0, 1499), /* processArrayByRefItemsWithImplicitIndex $nodeScopeResolver */ + reg::packed(1559, 0, 1565), /* processArrayByRefItemsWithImplicitIndex $scope */ + reg::packed(1596, 0, 1604), /* processArrayByRefItemsWithImplicitIndex $storage */ + reg::packed(3527, MAY_BE_STRING), /* processArrayByRefItemsWithImplicitIndex $rootVarName */ + reg::packed(3539, 0, 3549), /* processArrayByRefItemsWithImplicitIndex $arrayExpr */ + reg::packed(3576, 0, 1451), /* processArrayByRefItemsWithImplicitIndex $parentExpr */ + reg::packed(3610, MAY_BE_NULL | MAY_BE_LONG), /* processArrayByRefItemsWithImplicitIndex $implicitIndex */ + reg::packed(1471, MAY_BE_ARRAY), /* processArrayByRefItemsWithImplicitIndex return */ + reg::packed(3539, 0, 3549), /* isFlattenableUnpackedArray $arrayExpr */ + reg::packed(1471, MAY_BE_BOOL), /* isFlattenableUnpackedArray return */ + reg::packed(3691, MAY_BE_LONG), /* advanceImplicitIndex $index */ + reg::packed(1471, MAY_BE_NULL | MAY_BE_LONG), /* advanceImplicitIndex return */ + reg::packed(1481, 0, 1499), /* produceArrayDimFetchAssignValueToWrite $nodeScopeResolver */ + reg::packed(3466, MAY_BE_ARRAY), /* produceArrayDimFetchAssignValueToWrite $dimFetchStack */ + reg::packed(3718, MAY_BE_ARRAY), /* produceArrayDimFetchAssignValueToWrite $offsetTypes */ + reg::packed(3730, 0, 2113), /* produceArrayDimFetchAssignValueToWrite $offsetValueType */ + reg::packed(3746, 0, 2113), /* produceArrayDimFetchAssignValueToWrite $valueToWrite */ + reg::packed(1559, 0, 1565), /* produceArrayDimFetchAssignValueToWrite $scope */ + reg::packed(1596, 0, 1604), /* produceArrayDimFetchAssignValueToWrite $storage */ + reg::packed(1471, MAY_BE_ARRAY), /* produceArrayDimFetchAssignValueToWrite return */ + reg::packed(1481, 0, 1499), /* shouldKeepList $nodeScopeResolver */ + reg::packed(3798, 0, 3812), /* shouldKeepList $arrayDimFetch */ + reg::packed(1559, 0, 1565), /* shouldKeepList $scope */ + reg::packed(1596, 0, 1604), /* shouldKeepList $storage */ + reg::packed(3730, 0, 2113), /* shouldKeepList $offsetValueType */ + reg::packed(1471, MAY_BE_BOOL), /* shouldKeepList return */ + reg::packed(3730, 0, 2113), /* trackedLinkImpliesOffset $offsetValueType */ + reg::packed(3861, 0, 2113), /* trackedLinkImpliesOffset $offsetType */ + reg::packed(1471, MAY_BE_BOOL), /* trackedLinkImpliesOffset return */ + reg::packed(3897, 0, 1451), /* isSameVariable $a */ + reg::packed(3899, 0, 1451), /* isSameVariable $b */ + reg::packed(1471, MAY_BE_BOOL), /* isSameVariable return */ + reg::packed(3897, 0, 1451), /* isSameOffset $a */ + reg::packed(3899, 0, 1451), /* isSameOffset $b */ + reg::packed(1471, MAY_BE_BOOL), /* isSameOffset return */ + reg::packed(1446, 0, 1451), /* getLiteralArrayKeyType $expr */ + reg::packed(1471, MAY_BE_NULL, 2113), /* getLiteralArrayKeyType return */ + reg::packed(1481, 0, 1499), /* getOriginalPropertyType $nodeScopeResolver */ + reg::packed(3952, 0, 3966), /* getOriginalPropertyType $propertyFetch */ + reg::packed(1559, 0, 1565), /* getOriginalPropertyType $scope */ + reg::packed(1471, 0, 2113), /* getOriginalPropertyType return */ + reg::packed(4064, 0, 3549), /* hasArrayReference $array */ + reg::packed(1471, MAY_BE_BOOL), /* hasArrayReference return */ + reg::packed(4088, 0, 1701), /* redundant $rhs */ + reg::packed(2050, 0, 1451), /* redundant $target */ + reg::packed(1596, 0, 1604), /* redundant $storage */ + reg::packed(1471, MAY_BE_NULL, 2113), /* redundant return */ }; using Sig = reg::Sig; } // namespace sigtab /* the signatures of the methods the class declares itself (a used trait's are in the trait's header) */ namespace sig { -inline constexpr sigtab::Sig __construct = { { 1359 /* __construct */, 20, 0, 20, reg::NoArg, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig supports = { { 1397 /* supports */, 1, 20, 1, 21, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig processExpr = { { 1660 /* processExpr */, 7, 22, 7, 29, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig captureAssignedCallArgResults = { { 1685 /* captureAssignedCallArgResults */, 2, 30, 2, 32, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig createCreateTypesCallback = { { 1781 /* createCreateTypesCallback */, 3, 33, 3, 36, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig createSpecifyTypesCallback = { { 1807 /* createSpecifyTypesCallback */, 4, 37, 4, 41, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processVirtualAssign = { { 1843 /* processVirtualAssign */, 7, 42, 8, 50, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig prepareTarget = { { 1945 /* prepareTarget */, 9, 51, 9, 60, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig doPrepareTarget = { { 1959 /* doPrepareTarget */, 9, 61, 9, 70, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig applyWrite = { { 2014 /* applyWrite */, 8, 71, 8, 79, ZEND_ACC_PUBLIC } }; -inline constexpr sigtab::Sig collectOffsetSetUsage = { { 2128 /* collectOffsetSetUsage */, 5, 80, 5, 85, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig createArrayDimFetchConditionalExpressionHolder = { { 2256 /* createArrayDimFetchConditionalExpressionHolder */, 4, 86, 4, 90, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig readAssignedValueType = { { 2303 /* readAssignedValueType */, 4, 91, 4, 95, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig resolveContainerTypesAfterAssignedExprEval = { { 2362 /* resolveContainerTypesAfterAssignedExprEval */, 6, 96, 6, 102, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig assignDynamicVariable = { { 2432 /* assignDynamicVariable */, 4, 103, 4, 107, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig unwrapAssign = { { 2454 /* unwrapAssign */, 1, 108, 1, 109, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processSureTypesForConditionalExpressionsAfterAssign = { { 2547 /* processSureTypesForConditionalExpressionsAfterAssign */, 10, 110, 10, 120, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processSureNotTypesForConditionalExpressionsAfterAssign = { { 2600 /* processSureNotTypesForConditionalExpressionsAfterAssign */, 10, 121, 10, 131, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig currentTypeForConditionalHolder = { { 2656 /* currentTypeForConditionalHolder */, 6, 132, 6, 138, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processTernaryArmValueImpliedTypesAfterAssign = { { 2732 /* processTernaryArmValueImpliedTypesAfterAssign */, 11, 139, 11, 150, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig addConditionalExpressionHolder = { { 2854 /* addConditionalExpressionHolder */, 7, 151, 7, 158, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig mergeConditionalExpressions = { { 2911 /* mergeConditionalExpressions */, 2, 159, 2, 161, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processMatchForConditionalExpressionsAfterAssign = { { 2966 /* processMatchForConditionalExpressionsAfterAssign */, 3, 162, 3, 165, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processDerivedConditionalExpressionsAfterAssign = { { 3028 /* processDerivedConditionalExpressionsAfterAssign */, 7, 166, 7, 173, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processInArrayForConditionalExpressionsAfterAssign = { { 3105 /* processInArrayForConditionalExpressionsAfterAssign */, 7, 174, 7, 181, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig isExprSafeToProjectThroughVariable = { { 3156 /* isExprSafeToProjectThroughVariable */, 4, 182, 4, 186, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig isImplicitArrayCreation = { { 3228 /* isImplicitArrayCreation */, 2, 187, 2, 189, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processArrayByRefItems = { { 3312 /* processArrayByRefItems */, 6, 190, 6, 196, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig processArrayByRefItemsWithImplicitIndex = { { 3349 /* processArrayByRefItemsWithImplicitIndex */, 7, 197, 7, 204, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig isFlattenableUnpackedArray = { { 3389 /* isFlattenableUnpackedArray */, 1, 205, 1, 206, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig advanceImplicitIndex = { { 3422 /* advanceImplicitIndex */, 1, 207, 1, 208, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig produceArrayDimFetchAssignValueToWrite = { { 3484 /* produceArrayDimFetchAssignValueToWrite */, 7, 209, 7, 216, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig shouldKeepList = { { 3571 /* shouldKeepList */, 5, 217, 5, 222, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig trackedLinkImpliesOffset = { { 3597 /* trackedLinkImpliesOffset */, 2, 223, 2, 225, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig isSameVariable = { { 3626 /* isSameVariable */, 2, 226, 2, 228, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig isSameOffset = { { 3641 /* isSameOffset */, 2, 229, 2, 231, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig getLiteralArrayKeyType = { { 3654 /* getLiteralArrayKeyType */, 1, 232, 1, 233, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig getOriginalPropertyType = { { 3765 /* getOriginalPropertyType */, 3, 234, 3, 237, ZEND_ACC_PRIVATE } }; -inline constexpr sigtab::Sig hasArrayReference = { { 3795 /* hasArrayReference */, 1, 238, 1, 239, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; -inline constexpr sigtab::Sig redundant = { { 3817 /* redundant */, 3, 240, 3, 243, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; +inline constexpr sigtab::Sig __construct = { { 1434 /* __construct */, 21, 0, 21, reg::NoArg, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig supports = { { 1472 /* supports */, 1, 21, 1, 22, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig processExpr = { { 1735 /* processExpr */, 7, 23, 7, 30, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig captureAssignedCallArgResults = { { 1760 /* captureAssignedCallArgResults */, 2, 31, 2, 33, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig createCreateTypesCallback = { { 1856 /* createCreateTypesCallback */, 3, 34, 3, 37, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig createSpecifyTypesCallback = { { 1882 /* createSpecifyTypesCallback */, 4, 38, 4, 42, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processVirtualAssign = { { 1918 /* processVirtualAssign */, 7, 43, 8, 51, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig prepareTarget = { { 2020 /* prepareTarget */, 9, 52, 9, 61, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig doPrepareTarget = { { 2034 /* doPrepareTarget */, 9, 62, 9, 71, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig applyWrite = { { 2089 /* applyWrite */, 8, 72, 8, 80, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig collectOffsetSetUsage = { { 2203 /* collectOffsetSetUsage */, 5, 81, 5, 86, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig createArrayDimFetchConditionalExpressionHolder = { { 2331 /* createArrayDimFetchConditionalExpressionHolder */, 4, 87, 4, 91, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig readAssignedValueType = { { 2378 /* readAssignedValueType */, 4, 92, 4, 96, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig resolveContainerTypesAfterAssignedExprEval = { { 2437 /* resolveContainerTypesAfterAssignedExprEval */, 6, 97, 6, 103, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig assignDynamicVariable = { { 2507 /* assignDynamicVariable */, 4, 104, 4, 108, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig unwrapAssign = { { 2529 /* unwrapAssign */, 1, 109, 1, 110, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processSureTypesForConditionalExpressionsAfterAssign = { { 2622 /* processSureTypesForConditionalExpressionsAfterAssign */, 10, 111, 10, 121, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processSureNotTypesForConditionalExpressionsAfterAssign = { { 2675 /* processSureNotTypesForConditionalExpressionsAfterAssign */, 10, 122, 10, 132, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig remapConditionalExpressionsThroughConcatAssign = { { 2758 /* remapConditionalExpressionsThroughConcatAssign */, 3, 133, 3, 136, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processDefinednessForConditionalExpressionsAfterAssign = { { 2829 /* processDefinednessForConditionalExpressionsAfterAssign */, 5, 137, 5, 142, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig containsVariableAssignment = { { 2904 /* containsVariableAssignment */, 1, 143, 1, 144, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; +inline constexpr sigtab::Sig currentTypeForConditionalHolder = { { 2931 /* currentTypeForConditionalHolder */, 6, 145, 6, 151, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processTernaryArmValueImpliedTypesAfterAssign = { { 3007 /* processTernaryArmValueImpliedTypesAfterAssign */, 11, 152, 11, 163, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig addConditionalExpressionHolder = { { 3129 /* addConditionalExpressionHolder */, 7, 164, 7, 171, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig mergeConditionalExpressions = { { 3186 /* mergeConditionalExpressions */, 2, 172, 2, 174, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processMatchForConditionalExpressionsAfterAssign = { { 3241 /* processMatchForConditionalExpressionsAfterAssign */, 3, 175, 3, 178, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processDerivedConditionalExpressionsAfterAssign = { { 3303 /* processDerivedConditionalExpressionsAfterAssign */, 7, 179, 7, 186, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processInArrayForConditionalExpressionsAfterAssign = { { 3380 /* processInArrayForConditionalExpressionsAfterAssign */, 7, 187, 7, 194, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig isExprSafeToProjectThroughVariable = { { 3431 /* isExprSafeToProjectThroughVariable */, 4, 195, 4, 199, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig isImplicitArrayCreation = { { 3503 /* isImplicitArrayCreation */, 2, 200, 2, 202, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processArrayByRefItems = { { 3587 /* processArrayByRefItems */, 6, 203, 6, 209, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig processArrayByRefItemsWithImplicitIndex = { { 3624 /* processArrayByRefItemsWithImplicitIndex */, 7, 210, 7, 217, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig isFlattenableUnpackedArray = { { 3664 /* isFlattenableUnpackedArray */, 1, 218, 1, 219, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig advanceImplicitIndex = { { 3697 /* advanceImplicitIndex */, 1, 220, 1, 221, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig produceArrayDimFetchAssignValueToWrite = { { 3759 /* produceArrayDimFetchAssignValueToWrite */, 7, 222, 7, 229, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig shouldKeepList = { { 3846 /* shouldKeepList */, 5, 230, 5, 235, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig trackedLinkImpliesOffset = { { 3872 /* trackedLinkImpliesOffset */, 2, 236, 2, 238, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig isSameVariable = { { 3901 /* isSameVariable */, 2, 239, 2, 241, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig isSameOffset = { { 3916 /* isSameOffset */, 2, 242, 2, 244, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig getLiteralArrayKeyType = { { 3929 /* getLiteralArrayKeyType */, 1, 245, 1, 246, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig getOriginalPropertyType = { { 4040 /* getOriginalPropertyType */, 3, 247, 3, 250, ZEND_ACC_PRIVATE } }; +inline constexpr sigtab::Sig hasArrayReference = { { 4070 /* hasArrayReference */, 1, 251, 1, 252, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; +inline constexpr sigtab::Sig redundant = { { 4092 /* redundant */, 3, 253, 3, 256, ZEND_ACC_PRIVATE | ZEND_ACC_STATIC } }; } // namespace sig } // namespace ptdecl::AssignHandler diff --git a/turbo-ext/src/generated/TryCatchHandler.h b/turbo-ext/src/generated/TryCatchHandler.h index 911332d7f79..af137f165b9 100644 --- a/turbo-ext/src/generated/TryCatchHandler.h +++ b/turbo-ext/src/generated/TryCatchHandler.h @@ -45,7 +45,12 @@ inline constexpr char strings[] = "context\0" /* 252 */ "PHPStan\\Analyser\\StatementContext\0" /* 260 */ "PHPStan\\Analyser\\InternalStatementResult\0" /* 294 */ - "processStmt"; /* 335 */ + "processStmt\0" /* 335 */ + "mergedScope\0" /* 347 */ + "nonCatchScope\0" /* 359 */ + "catchEndScope\0" /* 373 */ + "variableName\0" /* 387 */ + "addCatchVariableDefinednessConditionals"; /* 400 */ inline constexpr reg::PackedArg args[] = { reg::packed(0, 0, 18), /* __construct $statementsHandler */ reg::packed(65, 0, 70), /* supports $stmt */ @@ -57,6 +62,11 @@ inline constexpr reg::PackedArg args[] = { reg::packed(239, MAY_BE_CALLABLE), /* processStmt $nodeCallback */ reg::packed(252, 0, 260), /* processStmt $context */ reg::packed(90, 0, 294), /* processStmt return */ + reg::packed(347, 0, 159), /* addCatchVariableDefinednessConditionals $mergedScope */ + reg::packed(359, 0, 159), /* addCatchVariableDefinednessConditionals $nonCatchScope */ + reg::packed(373, 0, 159), /* addCatchVariableDefinednessConditionals $catchEndScope */ + reg::packed(387, MAY_BE_STRING), /* addCatchVariableDefinednessConditionals $variableName */ + reg::packed(90, 0, 159), /* addCatchVariableDefinednessConditionals return */ }; using Sig = reg::Sig; } // namespace sigtab @@ -66,6 +76,7 @@ namespace sig { inline constexpr sigtab::Sig __construct = { { 53 /* __construct */, 1, 0, 1, reg::NoArg, ZEND_ACC_PUBLIC } }; inline constexpr sigtab::Sig supports = { { 91 /* supports */, 1, 1, 1, 2, ZEND_ACC_PUBLIC } }; inline constexpr sigtab::Sig processStmt = { { 335 /* processStmt */, 6, 3, 6, 9, ZEND_ACC_PUBLIC } }; +inline constexpr sigtab::Sig addCatchVariableDefinednessConditionals = { { 400 /* addCatchVariableDefinednessConditionals */, 4, 10, 4, 14, ZEND_ACC_PRIVATE } }; } // namespace sig } // namespace ptdecl::TryCatchHandler