Skip to content

Use resolved paths in SSR rules #5518

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

Merged
merged 14 commits into from
Jul 24, 2020
Merged

Conversation

davidlattimore
Copy link
Contributor

The main user-visible changes are:

  • SSR now matches paths based on whether they resolve to the same thing instead of whether they're written the same.
    • So foo() won't match foo() if it's a different function foo(), but will match bar::foo() if it's the same foo.
  • Paths in the replacement will now be rendered with appropriate qualification for their context.
    • For example foo::Bar will render as just Bar inside the module foo, but might render as baz::foo::Bar from elsewhere.
  • This means that all paths in the search pattern and replacement template must be able to be resolved.
  • It now also matters where you invoke SSR from, since paths are resolved relative to wherever that is.
  • Search now uses find-uses on paths to locate places to try matching. This means that when a path is present in the pattern, search will generally be pretty fast.
  • Function calls can now match method calls again, but this time only if they resolve to the same function.

Previously we had:

- Multiple rules
  - Each rule had its pattern parsed as an expression, path etc

This meant that there were two levels at which there could be multiple
rules.

Now we just have multiple rules. If a pattern can parse as more than one
kind of thing, then they get stored as multiple separate rules.

We also now don't have separate fields for the different kinds of things
that a pattern can parse as. This makes adding new kinds of things
simpler.

Previously, add_search_pattern would construct a rule with a dummy
replacement. Now the replacement is an Option. This is slightly cleaner
and also opens the way for parsing the replacement template as the same
kind of thing as the search pattern.
This is in preparation for a subsequent commit where we add special
handling for paths in the template, allowing them to be qualified
differently in different contexts.
Also renamed find_matches to slow_scan_node to reflect that it's a slow
way to do things. Actually the name came from a later commit and
probably makes more sense once there's an alternative.
The methods `edits_for_file` and `find_matches_in_file` are replaced with just `edits` and `matches`. This simplifies the API a bit, but more importantly it makes it possible in a subsequent commit for SSR to decide to not search all files.
In a later commit, paths in templates will be resolved. This allows us
to render the path with appropriate qualifiers for its context. Here we
prepare for that change by updating existing tests where I'd previously
not bothered to define the items that the template referred to.
These tests already pass, however once we switch to non-recursive
search, it'd be easy for these tests to not pass.
Previously, submatches were handled simply by searching in placeholders
for more matches. That only works if we search all nodes in the tree
recursively. In a subsequent commit, I intend to make search not always
be recursive recursive. This commit prepares for that by finding all
matches, even if they overlap, then nesting them and removing
overlapping matches.
In a subsequent commit, it will be used for resolving paths.
Also render template paths appropriately for their context.
When the search pattern contains a path, this substantially speeds up finding matches, especially if the path references a private item.
It currently does the wrong thing when the use declaration contains
braces.
This differs from how this used to work before I removed it in that:
a) It's only one direction. Function calls in the pattern can match
method calls in the code, but not the other way around.
b) We now check that the function call in the pattern resolves to the
same function as the method call in the code.

The lack of (b) was the reason I felt the need to remove the feature
before.
Copy link
Member

@matklad matklad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bors r+

Some(NameRefClass::Definition(resolved.into()))
}

impl From<PathResolution> for Definition {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

if (!client) return;
if (!editor || !client) return;

const position = editor.selection.active;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is OK as first solution, but we probably should move to that "ssr via assit" idea some time in the future. Currently, the association between position and action is pretty weak.

It might also be a good idea to think about how this should work in the CLI setting.

@bors
Copy link
Contributor

bors bot commented Jul 24, 2020

@bors bors bot merged commit c3defe2 into rust-lang:master Jul 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants