Skip to content

Conversation

@staabm
Copy link
Contributor

@staabm staabm commented Dec 1, 2025

as in

  • } elseif ($node instanceof Node\Scalar\InterpolatedString) {
    $resultType = null;
    foreach ($node->parts as $part) {
    if ($part instanceof InterpolatedStringPart) {
    $partType = new ConstantStringType($part->value);
    } else {
    $partType = $this->getType($part)->toString();
    }
    if ($resultType === null) {
    $resultType = $partType;
    continue;
    }
    $resultType = $this->initializerExprTypeResolver->resolveConcatType($resultType, $partType);
    }
  • } elseif ($expr instanceof Node\Scalar\InterpolatedString) {
    $hasYield = false;
    $throwPoints = [];
    $impurePoints = [];
    $isAlwaysTerminating = false;
    foreach ($expr->parts as $part) {
    if (!$part instanceof Expr) {
    continue;
    }
    $result = $this->processExprNode($stmt, $part, $scope, $nodeCallback, $context->enterDeep());
    $hasYield = $hasYield || $result->hasYield();
    $throwPoints = array_merge($throwPoints, $result->getThrowPoints());
    $impurePoints = array_merge($impurePoints, $result->getImpurePoints());
    $isAlwaysTerminating = $isAlwaysTerminating || $result->isAlwaysTerminating();
    $scope = $result->getScope();
    }

if ($part instanceof InterpolatedStringPart) {
$partType = new ConstantStringType($part->value);
} else {
$result = yield new ExprAnalysisRequest($stmt, $part, $scope, $context->enterDeep(), new NoopNodeCallback());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

is noop-correct here?

Copy link
Member

Choose a reason for hiding this comment

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

I don't think so. It'd mean that for $part no rule is executed. NoopNodeCallback is the equivalent of static function () {} when calling ->processExprNode or ->processStmtNode in NodeScopeResolver.

So it's used when we want a result of a synthetic node (where we do new SomeAstNode(...) because we're interested in the result but otherwise the node is not in the original source so it would not make sense to report errors on it).

Also we'd use NoopNodeCallback when we need ExprAnalysisRequest for something that we're sure has already been analysed. Thanks to

if ($alternativeNodeCallback instanceof NoopNodeCallback) {
return $foundExprAnalysisResult;
}
it'd just return the result instead of throwing an exception.

@staabm staabm marked this pull request as ready for review December 1, 2025 07:14
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

if ($part instanceof InterpolatedStringPart) {
$partType = new ConstantStringType($part->value);
} else {
$result = yield new ExprAnalysisRequest($stmt, $part, $scope, $context->enterDeep(), new NoopNodeCallback());
Copy link
Member

Choose a reason for hiding this comment

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

I don't think so. It'd mean that for $part no rule is executed. NoopNodeCallback is the equivalent of static function () {} when calling ->processExprNode or ->processStmtNode in NodeScopeResolver.

So it's used when we want a result of a synthetic node (where we do new SomeAstNode(...) because we're interested in the result but otherwise the node is not in the original source so it would not make sense to report errors on it).

Also we'd use NoopNodeCallback when we need ExprAnalysisRequest for something that we're sure has already been analysed. Thanks to

if ($alternativeNodeCallback instanceof NoopNodeCallback) {
return $foundExprAnalysisResult;
}
it'd just return the result instead of throwing an exception.

$type = $resultType ?? new ConstantStringType('');
return new ExprAnalysisResult(
$type,
$type,
Copy link
Member

Choose a reason for hiding this comment

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

What about native type here? :)

@ondrejmirtes ondrejmirtes merged commit 0feb183 into phpstan:2.1.x Dec 1, 2025
607 of 637 checks passed
@ondrejmirtes
Copy link
Member

Thank you!

@staabm staabm deleted the interpol branch December 1, 2025 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants