mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
SSR: Move search code into a submodule
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.
This commit is contained in:
parent
113abbeefe
commit
13f901f636
2 changed files with 56 additions and 48 deletions
|
@ -6,6 +6,7 @@
|
|||
mod matching;
|
||||
mod parsing;
|
||||
mod replacing;
|
||||
mod search;
|
||||
#[macro_use]
|
||||
mod errors;
|
||||
#[cfg(test)]
|
||||
|
@ -83,7 +84,7 @@ impl<'db> MatchFinder<'db> {
|
|||
let file = self.sema.parse(file_id);
|
||||
let code = file.syntax();
|
||||
let mut matches = SsrMatches::default();
|
||||
self.find_matches(code, &None, &mut matches);
|
||||
self.slow_scan_node(code, &None, &mut matches.matches);
|
||||
matches
|
||||
}
|
||||
|
||||
|
@ -120,53 +121,6 @@ impl<'db> MatchFinder<'db> {
|
|||
}
|
||||
}
|
||||
|
||||
fn find_matches(
|
||||
&self,
|
||||
code: &SyntaxNode,
|
||||
restrict_range: &Option<FileRange>,
|
||||
matches_out: &mut SsrMatches,
|
||||
) {
|
||||
for rule in &self.rules {
|
||||
if let Ok(mut m) = matching::get_match(false, rule, &code, restrict_range, &self.sema) {
|
||||
// Continue searching in each of our placeholders.
|
||||
for placeholder_value in m.placeholder_values.values_mut() {
|
||||
if let Some(placeholder_node) = &placeholder_value.node {
|
||||
// Don't search our placeholder if it's the entire matched node, otherwise we'd
|
||||
// find the same match over and over until we got a stack overflow.
|
||||
if placeholder_node != code {
|
||||
self.find_matches(
|
||||
placeholder_node,
|
||||
restrict_range,
|
||||
&mut placeholder_value.inner_matches,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
matches_out.matches.push(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If we've got a macro call, we already tried matching it pre-expansion, which is the only
|
||||
// way to match the whole macro, now try expanding it and matching the expansion.
|
||||
if let Some(macro_call) = ast::MacroCall::cast(code.clone()) {
|
||||
if let Some(expanded) = self.sema.expand(¯o_call) {
|
||||
if let Some(tt) = macro_call.token_tree() {
|
||||
// When matching within a macro expansion, we only want to allow matches of
|
||||
// nodes that originated entirely from within the token tree of the macro call.
|
||||
// i.e. we don't want to match something that came from the macro itself.
|
||||
self.find_matches(
|
||||
&expanded,
|
||||
&Some(self.sema.original_range(tt.syntax())),
|
||||
matches_out,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
for child in code.children() {
|
||||
self.find_matches(&child, restrict_range, matches_out);
|
||||
}
|
||||
}
|
||||
|
||||
fn output_debug_for_nodes_at_range(
|
||||
&self,
|
||||
node: &SyntaxNode,
|
||||
|
|
54
crates/ra_ssr/src/search.rs
Normal file
54
crates/ra_ssr/src/search.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
//! Searching for matches.
|
||||
|
||||
use crate::{matching, Match, MatchFinder};
|
||||
use ra_db::FileRange;
|
||||
use ra_syntax::{ast, AstNode, SyntaxNode};
|
||||
|
||||
impl<'db> MatchFinder<'db> {
|
||||
pub(crate) fn slow_scan_node(
|
||||
&self,
|
||||
code: &SyntaxNode,
|
||||
restrict_range: &Option<FileRange>,
|
||||
matches_out: &mut Vec<Match>,
|
||||
) {
|
||||
for rule in &self.rules {
|
||||
if let Ok(mut m) = matching::get_match(false, rule, &code, restrict_range, &self.sema) {
|
||||
// Continue searching in each of our placeholders.
|
||||
for placeholder_value in m.placeholder_values.values_mut() {
|
||||
if let Some(placeholder_node) = &placeholder_value.node {
|
||||
// Don't search our placeholder if it's the entire matched node, otherwise we'd
|
||||
// find the same match over and over until we got a stack overflow.
|
||||
if placeholder_node != code {
|
||||
self.slow_scan_node(
|
||||
placeholder_node,
|
||||
restrict_range,
|
||||
&mut placeholder_value.inner_matches.matches,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
matches_out.push(m);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// If we've got a macro call, we already tried matching it pre-expansion, which is the only
|
||||
// way to match the whole macro, now try expanding it and matching the expansion.
|
||||
if let Some(macro_call) = ast::MacroCall::cast(code.clone()) {
|
||||
if let Some(expanded) = self.sema.expand(¯o_call) {
|
||||
if let Some(tt) = macro_call.token_tree() {
|
||||
// When matching within a macro expansion, we only want to allow matches of
|
||||
// nodes that originated entirely from within the token tree of the macro call.
|
||||
// i.e. we don't want to match something that came from the macro itself.
|
||||
self.slow_scan_node(
|
||||
&expanded,
|
||||
&Some(self.sema.original_range(tt.syntax())),
|
||||
matches_out,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
for child in code.children() {
|
||||
self.slow_scan_node(&child, restrict_range, matches_out);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue