aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-03-13 14:18:17 +0000
committerFlorian Diebold <[email protected]>2020-03-16 17:38:19 +0000
commit6305d094ac61ed6e437537b93f4e587b415678c9 (patch)
tree89ec8942a287c8a1f6d2955602fe1a3415262cac /crates
parentb973158aeb337041d4e1434cf5d8c609a0b02bef (diff)
Attempt to implement ranking of rules when none matches perfectly (wip)
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide/src/completion/complete_scope.rs39
-rw-r--r--crates/ra_mbe/src/mbe_expander.rs19
-rw-r--r--crates/ra_mbe/src/mbe_expander/matcher.rs4
3 files changed, 51 insertions, 11 deletions
diff --git a/crates/ra_ide/src/completion/complete_scope.rs b/crates/ra_ide/src/completion/complete_scope.rs
index 5ffff5a1c..2733922f8 100644
--- a/crates/ra_ide/src/completion/complete_scope.rs
+++ b/crates/ra_ide/src/completion/complete_scope.rs
@@ -811,7 +811,44 @@ mod tests {
811 } 811 }
812 " 812 "
813 ), 813 ),
814 @"[]" 814 @r###"
815 [
816 CompletionItem {
817 label: "m!",
818 source_range: [145; 145),
819 delete: [145; 145),
820 insert: "m!($0)",
821 kind: Macro,
822 detail: "macro_rules! m",
823 },
824 CompletionItem {
825 label: "quux(…)",
826 source_range: [145; 145),
827 delete: [145; 145),
828 insert: "quux(${1:x})$0",
829 kind: Function,
830 lookup: "quux",
831 detail: "fn quux(x: i32)",
832 trigger_call_info: true,
833 },
834 CompletionItem {
835 label: "x",
836 source_range: [145; 145),
837 delete: [145; 145),
838 insert: "x",
839 kind: Binding,
840 detail: "i32",
841 },
842 CompletionItem {
843 label: "y",
844 source_range: [145; 145),
845 delete: [145; 145),
846 insert: "y",
847 kind: Binding,
848 detail: "i32",
849 },
850 ]
851 "###
815 ); 852 );
816 } 853 }
817 854
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs
index da3952428..5083d5410 100644
--- a/crates/ra_mbe/src/mbe_expander.rs
+++ b/crates/ra_mbe/src/mbe_expander.rs
@@ -14,24 +14,27 @@ pub(crate) fn expand(
14 rules: &crate::MacroRules, 14 rules: &crate::MacroRules,
15 input: &tt::Subtree, 15 input: &tt::Subtree,
16) -> ExpandResult<tt::Subtree> { 16) -> ExpandResult<tt::Subtree> {
17 let (mut result, mut err) = (tt::Subtree::default(), Some(ExpandError::NoMatchingRule)); 17 let (mut result, mut left_over, mut err) = (tt::Subtree::default(), usize::max_value(), Some(ExpandError::NoMatchingRule));
18 for rule in &rules.rules { 18 for rule in &rules.rules {
19 let (res, e) = expand_rule(rule, input); 19 let ((res, left), e) = expand_rule(rule, input);
20 if e.is_none() { 20 if e.is_none() {
21 // if we find a rule that applies without errors, we're done 21 // if we find a rule that applies without errors, we're done
22 return (res, None); 22 return (res, None);
23 } 23 }
24 // TODO decide which result is better 24 // use the rule if we matched more tokens
25 result = res; 25 if left < left_over {
26 err = e; 26 result = res;
27 err = e;
28 left_over = left;
29 }
27 } 30 }
28 (result, err) 31 (result, err)
29} 32}
30 33
31fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> ExpandResult<tt::Subtree> { 34fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> ExpandResult<(tt::Subtree, usize)> {
32 let (bindings, bindings_err) = dbg!(matcher::match_(&rule.lhs, input)); 35 let ((bindings, left_over), bindings_err) = dbg!(matcher::match_(&rule.lhs, input));
33 let (res, transcribe_err) = dbg!(transcriber::transcribe(&rule.rhs, &bindings)); 36 let (res, transcribe_err) = dbg!(transcriber::transcribe(&rule.rhs, &bindings));
34 (res, bindings_err.or(transcribe_err)) 37 ((res, left_over), bindings_err.or(transcribe_err))
35} 38}
36 39
37/// The actual algorithm for expansion is not too hard, but is pretty tricky. 40/// The actual algorithm for expansion is not too hard, but is pretty tricky.
diff --git a/crates/ra_mbe/src/mbe_expander/matcher.rs b/crates/ra_mbe/src/mbe_expander/matcher.rs
index f9d4952c6..52f1ac252 100644
--- a/crates/ra_mbe/src/mbe_expander/matcher.rs
+++ b/crates/ra_mbe/src/mbe_expander/matcher.rs
@@ -65,7 +65,7 @@ macro_rules! bail {
65 }; 65 };
66} 66}
67 67
68pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<Bindings> { 68pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<(Bindings, usize)> {
69 assert!(pattern.delimiter == None); 69 assert!(pattern.delimiter == None);
70 70
71 let mut res = Bindings::default(); 71 let mut res = Bindings::default();
@@ -77,7 +77,7 @@ pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<B
77 err = Some(err!("leftover tokens")); 77 err = Some(err!("leftover tokens"));
78 } 78 }
79 79
80 (res, err) 80 ((res, src.len()), err)
81} 81}
82 82
83fn match_subtree( 83fn match_subtree(