Skip to content

Fix infinite recursion in NodeExpressionResolver when resolving self-referencing class constants#178

Merged
lisachenko merged 3 commits into
masterfrom
copilot/fix-infinite-recursion-issue
Apr 27, 2026
Merged

Fix infinite recursion in NodeExpressionResolver when resolving self-referencing class constants#178
lisachenko merged 3 commits into
masterfrom
copilot/fix-infinite-recursion-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 27, 2026

Resolving a class constant whose value references the same class by explicit name (e.g. const RELATIVE = GlobalNamespaceClass::LITERAL) caused infinite recursion: each call to resolveExprClassConstFetch() created a new ReflectionClass instance with no constants cache, triggering collectSelfConstants() again indefinitely.

Root cause

fetchReflectionClass() always created new ReflectionClass($className) for FQN names, even when the context was already the same class mid-way through computing its constants. The new instance had no partial constants cache, so getConstants() re-entered collectSelfConstants() recursively.

Changes

  • src/Resolver/NodeExpressionResolver.php

    • Added getContextClass() helper that extracts a \ReflectionClass from any supported context type (ReflectionClass, ReflectionMethod, ReflectionProperty, ReflectionClassConstant, ReflectionParameter)
    • In fetchReflectionClass(), before constructing a new ReflectionClass($className), check if the context class matches the requested name and return it directly — reusing the in-progress instance with its partially-populated constants cache
  • tests/Stub/FileWithClasses55.php

    • Added ClassWithSelfReferencingConstant stub, picked up automatically by ReflectionClassConstantTest
class GlobalNamespaceClass
{
    const LITERAL = 1;
    const RELATIVE = GlobalNamespaceClass::LITERAL; // previously caused infinite recursion
}

Copilot AI and others added 2 commits April 27, 2026 17:47
Copilot AI changed the title [WIP] Fix infinite recursion in NodeExpressionResolver::resolveExprClassConstFetch Fix infinite recursion in NodeExpressionResolver when resolving self-referencing class constants Apr 27, 2026
Copilot AI requested a review from lisachenko April 27, 2026 17:49
@lisachenko lisachenko added this to the 4.0.0 milestone Apr 27, 2026
@lisachenko lisachenko marked this pull request as ready for review April 27, 2026 17:53
@lisachenko lisachenko merged commit 9914b22 into master Apr 27, 2026
7 checks passed
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.

Infinite recursion in NodeExpressionResolver::resolveExprClassConstFetch()

2 participants