Implement complete constant resolution algorithm #2136
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Motivation
Now that we have ancestor linearization, we can finally resolve constants properly. This PR implements the algorithm for constant resolution in Ruby - with a few twists due to the nature of lazy static analysis.
Implementation
We tried to document the code as much as possible. I'll describe the algorithm, which has essentially 3 distinct paths.
Top level references
Top level references are the simplest ones. The nesting is completely ignored. All we have to do is try to find the name in the index. We do need to account for aliases too since the top level reference can include a portion of the name that points to an alias.
Qualified references
For qualified references, this is the order of resolution:
First::Second::Third::CONST
First::Second
First::Third::CONST
Third::CONST
in the top levelUnqualified references
Unqualified references have the order of operations swapped:
First::Second::CONST
First::CONST
First::Second
CONST
in the top levelNotes
name + nesting
and points to the resolved name. However, knowing when to invalidate the cache would be quite tricky. I recommend we avoid caching for nowIndexTest#test_resolving_circular_alias and IndexTesttest_resolving_circular_alias_three_levels
. This is why we need thatseen_names
array, which not only protects the index from infinite recursion, but also allows us to resolve these casesAutomated Tests
Added a bunch of tests for various constant reference scenarios, but if you can think of anything that we missed, please propose more tests.