aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/assist_ctx.rs
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-10-31 08:43:20 +0000
committerSeivan Heidari <[email protected]>2019-10-31 08:43:20 +0000
commit8edda0e7b164009d6c03bb3d4be603fb38ad2e2a (patch)
tree744cf81075d394e2f9c06afb07642a2601800dda /crates/ra_assists/src/assist_ctx.rs
parent49562d36b97ddde34cf7585a8c2e8f232519b657 (diff)
parentd067afb064a7fa67b172abf561b7d80740cd6f18 (diff)
Merge branch 'master' into feature/themes
Diffstat (limited to 'crates/ra_assists/src/assist_ctx.rs')
-rw-r--r--crates/ra_assists/src/assist_ctx.rs52
1 files changed, 24 insertions, 28 deletions
diff --git a/crates/ra_assists/src/assist_ctx.rs b/crates/ra_assists/src/assist_ctx.rs
index e270c5d60..1908bdec9 100644
--- a/crates/ra_assists/src/assist_ctx.rs
+++ b/crates/ra_assists/src/assist_ctx.rs
@@ -1,11 +1,11 @@
1//! FIXME: write short doc here 1//! This module defines `AssistCtx` -- the API surface that is exposed to assists.
2 2
3use hir::db::HirDatabase; 3use hir::db::HirDatabase;
4use ra_db::FileRange; 4use ra_db::FileRange;
5use ra_fmt::{leading_indent, reindent}; 5use ra_fmt::{leading_indent, reindent};
6use ra_syntax::{ 6use ra_syntax::{
7 algo::{self, find_covering_element, find_node_at_offset}, 7 algo::{self, find_covering_element, find_node_at_offset},
8 AstNode, SourceFile, SyntaxElement, SyntaxNode, SyntaxToken, TextRange, TextUnit, 8 AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextUnit,
9 TokenAtOffset, 9 TokenAtOffset,
10}; 10};
11use ra_text_edit::TextEditBuilder; 11use ra_text_edit::TextEditBuilder;
@@ -14,8 +14,8 @@ use crate::{AssistAction, AssistId, AssistLabel};
14 14
15#[derive(Clone, Debug)] 15#[derive(Clone, Debug)]
16pub(crate) enum Assist { 16pub(crate) enum Assist {
17 Unresolved(Vec<AssistLabel>), 17 Unresolved { label: AssistLabel },
18 Resolved(Vec<(AssistLabel, AssistAction)>), 18 Resolved { label: AssistLabel, action: AssistAction },
19} 19}
20 20
21/// `AssistCtx` allows to apply an assist or check if it could be applied. 21/// `AssistCtx` allows to apply an assist or check if it could be applied.
@@ -54,7 +54,6 @@ pub(crate) struct AssistCtx<'a, DB> {
54 pub(crate) frange: FileRange, 54 pub(crate) frange: FileRange,
55 source_file: SourceFile, 55 source_file: SourceFile,
56 should_compute_edit: bool, 56 should_compute_edit: bool,
57 assist: Assist,
58} 57}
59 58
60impl<'a, DB> Clone for AssistCtx<'a, DB> { 59impl<'a, DB> Clone for AssistCtx<'a, DB> {
@@ -64,7 +63,6 @@ impl<'a, DB> Clone for AssistCtx<'a, DB> {
64 frange: self.frange, 63 frange: self.frange,
65 source_file: self.source_file.clone(), 64 source_file: self.source_file.clone(),
66 should_compute_edit: self.should_compute_edit, 65 should_compute_edit: self.should_compute_edit,
67 assist: self.assist.clone(),
68 } 66 }
69 } 67 }
70} 68}
@@ -75,43 +73,41 @@ impl<'a, DB: HirDatabase> AssistCtx<'a, DB> {
75 F: FnOnce(AssistCtx<DB>) -> T, 73 F: FnOnce(AssistCtx<DB>) -> T,
76 { 74 {
77 let parse = db.parse(frange.file_id); 75 let parse = db.parse(frange.file_id);
78 let assist =
79 if should_compute_edit { Assist::Resolved(vec![]) } else { Assist::Unresolved(vec![]) };
80 76
81 let ctx = AssistCtx { db, frange, source_file: parse.tree(), should_compute_edit, assist }; 77 let ctx = AssistCtx { db, frange, source_file: parse.tree(), should_compute_edit };
82 f(ctx) 78 f(ctx)
83 } 79 }
84 80
85 pub(crate) fn add_action( 81 pub(crate) fn add_assist(
86 &mut self, 82 self,
87 id: AssistId, 83 id: AssistId,
88 label: impl Into<String>, 84 label: impl Into<String>,
89 f: impl FnOnce(&mut AssistBuilder), 85 f: impl FnOnce(&mut AssistBuilder),
90 ) -> &mut Self { 86 ) -> Option<Assist> {
91 let label = AssistLabel { label: label.into(), id }; 87 let label = AssistLabel { label: label.into(), id };
92 match &mut self.assist { 88 let assist = if self.should_compute_edit {
93 Assist::Unresolved(labels) => labels.push(label), 89 let action = {
94 Assist::Resolved(labels_actions) => { 90 let mut edit = AssistBuilder::default();
95 let action = { 91 f(&mut edit);
96 let mut edit = AssistBuilder::default(); 92 edit.build()
97 f(&mut edit); 93 };
98 edit.build() 94 Assist::Resolved { label, action }
99 }; 95 } else {
100 labels_actions.push((label, action)); 96 Assist::Unresolved { label }
101 } 97 };
102 }
103 self
104 }
105 98
106 pub(crate) fn build(self) -> Option<Assist> { 99 Some(assist)
107 Some(self.assist)
108 } 100 }
109 101
110 pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> { 102 pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
111 self.source_file.syntax().token_at_offset(self.frange.range.start()) 103 self.source_file.syntax().token_at_offset(self.frange.range.start())
112 } 104 }
113 105
114 pub(crate) fn node_at_offset<N: AstNode>(&self) -> Option<N> { 106 pub(crate) fn find_token_at_offset(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
107 self.token_at_offset().find(|it| it.kind() == kind)
108 }
109
110 pub(crate) fn find_node_at_offset<N: AstNode>(&self) -> Option<N> {
115 find_node_at_offset(self.source_file.syntax(), self.frange.range.start()) 111 find_node_at_offset(self.source_file.syntax(), self.frange.range.start())
116 } 112 }
117 pub(crate) fn covering_element(&self) -> SyntaxElement { 113 pub(crate) fn covering_element(&self) -> SyntaxElement {