Skip to content

[perf] Hoist cheap node guards before reflection/scope in two rules - #8706

Merged
TomasVotruba merged 1 commit into
mainfrom
hoist-guards-before-reflection
Oct 19, 2026
Merged

TomasVotruba merged 1 commit into
mainfrom
hoist-guards-before-reflection

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Two refactor() methods paid for reflection or array-callable matching before a cheap node-only guard could bail.

ExplicitAttributeNamedArgsRector - resolveConstructorReflectionFromAttribute() ran first, but an attribute with no arguments always returns null afterwards. Bail on $node->args === [] first, so no-argument attributes (the common case) skip the constructor reflection entirely.

ArrayToFirstClassCallableRector - the IS_CLASS_CONST_VALUE, IS_DEFAULT_PROPERTY_VALUE, IS_PARAM_DEFAULT and IS_UNPACKED_ARG_VALUE attribute checks sat below arrayCallableMethodMatcher->match(). They are plain node-attribute reads that return null regardless of the match result, so they move up above the match and arrays in those positions skip it.

Behavior unchanged - all 37 fixtures across both rules pass.

@TomasVotruba
TomasVotruba merged commit 1e66aba into main Oct 19, 2026
49 checks passed
@TomasVotruba
TomasVotruba deleted the hoist-guards-before-reflection branch October 19, 2026 08:55
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