Skip to content

[perf] Drop AstResolver from named-arg position resolution#8099

Merged
TomasVotruba merged 1 commit into
mainfrom
drop-ast-resolver-named-args
Jun 28, 2026
Merged

[perf] Drop AstResolver from named-arg position resolution#8099
TomasVotruba merged 1 commit into
mainfrom
drop-ast-resolver-named-args

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

What

RemoveMethodCallParamRector and ArgumentDefaultValueReplacer both resolve a named-argument position by reading the parameter name at a given index of the called method/function. They did this via AstResolver->resolveClassMethodOrFunctionFromCall(), which re-parses the callee's source file into a decorated AST — heavy — only to read $param->var->name.

This swaps that for ReflectionResolver->resolveFunctionLikeReflectionFromCall() + ParametersAcceptorSelector, reading the name straight off ParameterReflection::getName(). No file re-parse.

$reflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node);
if (! $reflection instanceof MethodReflection && ! $reflection instanceof FunctionReflection) {
    return null;
}
$parametersAcceptor = ParametersAcceptorSelector::combineAcceptors($reflection->getVariants());
$parameterReflection = $parametersAcceptor->getParameters()[$position] ?? null;

Same pattern already used by CallLikeParamDefaultResolver.

Why

AstResolver is one of the costlier analyses in the engine (parses extra files beyond the one being processed). These two sites needed only metadata reflection already holds, so the parse was pure overhead. The branch is only hit when a call uses named arguments, but removing the dependency is free correctness/perf.

Scope note

Only the two sites that need just the param name are converted. Other AstResolver callers genuinely need the AST (default-value expressions, attributes, method bodies, docblocks) and are left untouched.

Tests

Existing named-argument fixtures (remove_named_arguments, replace_named_arguments) cover the changed branch. vendor/bin/phpunit rules-tests/Arguments green (37 tests). ECS + PHPStan clean.

Replace AstResolver->resolveClassMethodOrFunctionFromCall() with
ReflectionResolver in RemoveMethodCallParamRector and
ArgumentDefaultValueReplacer.

Both rules only need the parameter *name* at a given position to map it
to a named-argument position. AstResolver re-parses the callee's source
file into AST just to read that name; ParameterReflection (via
ParametersAcceptorSelector) already exposes it without parsing.
@TomasVotruba TomasVotruba changed the title [Arguments] Drop AstResolver from named-arg position resolution [perf] Drop AstResolver from named-arg position resolution Jun 28, 2026
@TomasVotruba TomasVotruba merged commit 9703109 into main Jun 28, 2026
65 checks passed
@TomasVotruba TomasVotruba deleted the drop-ast-resolver-named-args branch June 28, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant