-
Notifications
You must be signed in to change notification settings - Fork 179
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid collecting duplicates in reference finder #3098
Conversation
How to use the Graphite Merge QueueAdd the label graphite-merge to this PR to add it to the merge queue. You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the PR!
I think we can avoid looking backwards in previously collected locations.
The reason for the duplicates is the fact that a class/module node will match both on_class/module_node_enter
and on_constant_*
because there's a constant node inside of the declaration.
Instead of looking backwards, let's stop pushing references in the on_class_node_enter
and on_module_node_enter
events. This will already get rid of the duplication.
The only piece left in the fix will be determining if a constant is a declaration or not. In collect_constant_references
, we need to check if there's a declaration for the constant we just resolved, so that we can then consider it as declaration: true
.
Something like this:
entries = @index.resolve(name, @stack)
return unless entries
# Get the fully qualified name of the constant we just resolved
full_constant_name = T.must(entries.first).name
# Check if this constant is a namespace declaration
# (class or module)
declaration = @index[full_constant_name].any? { |e| e.is_a?(Entry::Namespace) }
Thank for the feedback @vinistock. I just pushed an update to incorporate it, please let me know of any other tweaks or adjustments. |
It's almost there. I think this is what we need to do. There are a couple of pieces missing, like implementing def collect_constant_references(name, location)
return unless @target.is_a?(ConstTarget)
entries = @index.resolve(name, @stack)
return unless entries
# Filter down to all constant declarations that match the expected name and type
matching_entries = entries.select do |e|
[Entry::Namespace, Entry::Constant, Entry::ConstantAlias, Entry::UnresolvedConstantAlias].include?(e.class) &&
e.name == @target.fully_qualified_name
end
# If any of the matching entries have the same location as the constant and were
# defined in the same file, then it is that constant's declaration
#
# Note: we will need to implement `==` on RubyIndexer::Location to accept either
# another `RubyIndexer::Location` or a `Prism::Location`, so that we can compare with
# both.
#
# Additionally, we don't currently pass the `@uri` to the reference finder, but we will
# need it so that we can check if the declaration was made in the same file
declaration = matching_entries.any? do |e|
e.name_location == location && e.uri == @uri
end
@references << Reference.new(name, location, declaration: declaration)
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vinistock I incorporated the next round of feedback. I left one comment with one question I have for your consideration.
Please let me know of any additional feedback/changes. I appreciate all the help
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one minor modification, but this looks good
Co-authored-by: Vinicius Stock <vinistock@users.noreply.github.com>
@vinistock Just incorporated the change. I think it might be good be go |
The changes look good to me. There are still some linting errors. You can run linting locally with Also, there's a conflict that needs to be resolved. |
Thanks! Just corrected the linting error and incorporated changes from main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution!
Merge activity
|
Motivation
Closes #3088
As I was playing around with the gem in Neovim I discovered some over reporting of references when a project has classes that are re-opened throughout the codebase.
Implementation
Stop adding references on class and node module enter events and enhance the way we collect constant references to add additional logic to determine whether a reference is a constant or not.
Automated Tests
Added one new test case to reference_finder_test.rb that covers for the scenario presented above.