diff options
author | Florian Diebold <[email protected]> | 2020-03-13 14:18:17 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-03-16 17:38:19 +0000 |
commit | 6305d094ac61ed6e437537b93f4e587b415678c9 (patch) | |
tree | 89ec8942a287c8a1f6d2955602fe1a3415262cac /crates | |
parent | b973158aeb337041d4e1434cf5d8c609a0b02bef (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.rs | 39 | ||||
-rw-r--r-- | crates/ra_mbe/src/mbe_expander.rs | 19 | ||||
-rw-r--r-- | crates/ra_mbe/src/mbe_expander/matcher.rs | 4 |
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 | ||
31 | fn expand_rule(rule: &crate::Rule, input: &tt::Subtree) -> ExpandResult<tt::Subtree> { | 34 | fn 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 | ||
68 | pub(super) fn match_(pattern: &tt::Subtree, src: &tt::Subtree) -> ExpandResult<Bindings> { | 68 | pub(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 | ||
83 | fn match_subtree( | 83 | fn match_subtree( |