Unnamed repository; edit this file 'description' to name the repository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
ASYNC_KW "async"
WHITESPACE " "
FN_KW "fn"
WHITESPACE " "
USE_KW "use"
WHITESPACE " "
STRUCT_KW "struct"
WHITESPACE " "
TRAIT_KW "trait"
WHITESPACE " "
ENUM_KW "enum"
WHITESPACE " "
IMPL_KW "impl"
WHITESPACE " "
TRUE_KW "true"
WHITESPACE " "
FALSE_KW "false"
WHITESPACE " "
AS_KW "as"
WHITESPACE " "
EXTERN_KW "extern"
WHITESPACE " "
CRATE_KW "crate"
WHITESPACE "\n"
MOD_KW "mod"
WHITESPACE " "
PUB_KW "pub"
WHITESPACE " "
SELF_KW "self"
WHITESPACE " "
SUPER_KW "super"
WHITESPACE " "
IN_KW "in"
WHITESPACE " "
WHERE_KW "where"
WHITESPACE " "
FOR_KW "for"
WHITESPACE " "
LOOP_KW "loop"
WHITESPACE " "
WHILE_KW "while"
WHITESPACE " "
IF_KW "if"
WHITESPACE " "
MATCH_KW "match"
WHITESPACE " "
CONST_KW "const"
WHITESPACE "\n"
STATIC_KW "static"
WHITESPACE " "
MUT_KW "mut"
WHITESPACE " "
TYPE_KW "type"
WHITESPACE " "
REF_KW "ref"
WHITESPACE " "
LET_KW "let"
WHITESPACE " "
ELSE_KW "else"
WHITESPACE " "
MOVE_KW "move"
WHITESPACE " "
RETURN_KW "return"
WHITESPACE "\n"
ut self, m: Match, sema: &hir::Semantics<'_, ide_db::RootDatabase>) { let matched_node = m.matched_node.clone(); if let Some(existing) = self.matches_by_node.get_mut(&matched_node) { try_add_sub_match(m, existing, sema); return; } for ancestor in sema.ancestors_with_macros(m.matched_node.clone()) { if let Some(existing) = self.matches_by_node.get_mut(&ancestor) { try_add_sub_match(m, existing, sema); return; } } self.matches_by_node.insert(matched_node, m); } } /// Attempts to add `m` as a sub-match of `existing`. fn try_add_sub_match( m: Match, existing: &mut Match, sema: &hir::Semantics<'_, ide_db::RootDatabase>, ) { for p in existing.placeholder_values.values_mut() { // Note, no need to check if p.range.file is equal to m.range.file, since we // already know we're within `existing`. if p.range.range.contains_range(m.range.range) { // Convert the inner matches in `p` into a temporary MatchCollector. When // we're done, we then convert it back into an SsrMatches. If we expected // lots of inner matches, it might be worthwhile keeping a MatchCollector // around for each placeholder match. However we expect most placeholder // will have 0 and a few will have 1. More than that should hopefully be // exceptional. let mut collector = MatchCollector::default(); for m in std::mem::take(&mut p.inner_matches.matches) { collector.matches_by_node.insert(m.matched_node.clone(), m); } collector.add_match(m, sema); p.inner_matches = collector.into(); break; } } } impl From<MatchCollector> for SsrMatches { fn from(mut match_collector: MatchCollector) -> Self { let mut matches = SsrMatches::default(); for (_, m) in match_collector.matches_by_node.drain() { matches.matches.push(m); } matches.matches.sort_by(|a, b| { // Order matches by file_id then by start range. This should be sufficient since ranges // shouldn't be overlapping. a.range .file_id .cmp(&b.range.file_id) .then_with(|| a.range.range.start().cmp(&b.range.range.start())) }); matches } }