aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/assists/src/handlers/add_missing_impl_members.rs63
-rw-r--r--crates/assists/src/lib.rs37
-rw-r--r--crates/assists/src/tests/generated.rs3
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/traits.rs4
-rw-r--r--crates/proc_macro_api/src/lib.rs6
-rw-r--r--crates/rust-analyzer/src/handlers.rs4
-rw-r--r--crates/rust-analyzer/src/lsp_ext.rs7
-rw-r--r--crates/rust-analyzer/src/reload.rs5
-rw-r--r--crates/rust-analyzer/src/to_proto.rs8
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/ast/edit.rs29
12 files changed, 121 insertions, 53 deletions
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs
index 81b61ebf8..83a2ada9a 100644
--- a/crates/assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/assists/src/handlers/add_missing_impl_members.rs
@@ -48,7 +48,6 @@ enum AddMissingImplMembersMode {
48// fn foo(&self) -> u32 { 48// fn foo(&self) -> u32 {
49// ${0:todo!()} 49// ${0:todo!()}
50// } 50// }
51//
52// } 51// }
53// ``` 52// ```
54pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 53pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
@@ -89,8 +88,8 @@ pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) -
89// impl Trait for () { 88// impl Trait for () {
90// Type X = (); 89// Type X = ();
91// fn foo(&self) {} 90// fn foo(&self) {}
92// $0fn bar(&self) {}
93// 91//
92// $0fn bar(&self) {}
94// } 93// }
95// ``` 94// ```
96pub(crate) fn add_missing_default_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 95pub(crate) fn add_missing_default_members(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
@@ -240,15 +239,18 @@ struct S;
240 239
241impl Foo for S { 240impl Foo for S {
242 fn bar(&self) {} 241 fn bar(&self) {}
242
243 $0type Output; 243 $0type Output;
244
244 const CONST: usize = 42; 245 const CONST: usize = 42;
246
245 fn foo(&self) { 247 fn foo(&self) {
246 todo!() 248 todo!()
247 } 249 }
250
248 fn baz(&self) { 251 fn baz(&self) {
249 todo!() 252 todo!()
250 } 253 }
251
252}"#, 254}"#,
253 ); 255 );
254 } 256 }
@@ -281,10 +283,10 @@ struct S;
281 283
282impl Foo for S { 284impl Foo for S {
283 fn bar(&self) {} 285 fn bar(&self) {}
286
284 fn foo(&self) { 287 fn foo(&self) {
285 ${0:todo!()} 288 ${0:todo!()}
286 } 289 }
287
288}"#, 290}"#,
289 ); 291 );
290 } 292 }
@@ -599,6 +601,7 @@ trait Foo {
599struct S; 601struct S;
600impl Foo for S { 602impl Foo for S {
601 $0type Output; 603 $0type Output;
604
602 fn foo(&self) { 605 fn foo(&self) {
603 todo!() 606 todo!()
604 } 607 }
@@ -708,4 +711,56 @@ impl Tr for () {
708}"#, 711}"#,
709 ) 712 )
710 } 713 }
714
715 #[test]
716 fn test_whitespace_fixup_preserves_bad_tokens() {
717 check_assist(
718 add_missing_impl_members,
719 r#"
720trait Tr {
721 fn foo();
722}
723
724impl Tr for ()<|> {
725 +++
726}"#,
727 r#"
728trait Tr {
729 fn foo();
730}
731
732impl Tr for () {
733 fn foo() {
734 ${0:todo!()}
735 }
736 +++
737}"#,
738 )
739 }
740
741 #[test]
742 fn test_whitespace_fixup_preserves_comments() {
743 check_assist(
744 add_missing_impl_members,
745 r#"
746trait Tr {
747 fn foo();
748}
749
750impl Tr for ()<|> {
751 // very important
752}"#,
753 r#"
754trait Tr {
755 fn foo();
756}
757
758impl Tr for () {
759 fn foo() {
760 ${0:todo!()}
761 }
762 // very important
763}"#,
764 )
765 }
711} 766}
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs
index ae90d68a3..c589b08dc 100644
--- a/crates/assists/src/lib.rs
+++ b/crates/assists/src/lib.rs
@@ -66,13 +66,13 @@ pub struct GroupLabel(pub String);
66 66
67#[derive(Debug, Clone)] 67#[derive(Debug, Clone)]
68pub struct Assist { 68pub struct Assist {
69 id: AssistId, 69 pub id: AssistId,
70 /// Short description of the assist, as shown in the UI. 70 /// Short description of the assist, as shown in the UI.
71 label: String, 71 label: String,
72 group: Option<GroupLabel>, 72 pub group: Option<GroupLabel>,
73 /// Target ranges are used to sort assists: the smaller the target range, 73 /// Target ranges are used to sort assists: the smaller the target range,
74 /// the more specific assist is, and so it should be sorted first. 74 /// the more specific assist is, and so it should be sorted first.
75 target: TextRange, 75 pub target: TextRange,
76} 76}
77 77
78#[derive(Debug, Clone)] 78#[derive(Debug, Clone)]
@@ -82,6 +82,11 @@ pub struct ResolvedAssist {
82} 82}
83 83
84impl Assist { 84impl Assist {
85 fn new(id: AssistId, label: String, group: Option<GroupLabel>, target: TextRange) -> Assist {
86 assert!(label.starts_with(char::is_uppercase));
87 Assist { id, label, group, target }
88 }
89
85 /// Return all the assists applicable at the given position. 90 /// Return all the assists applicable at the given position.
86 /// 91 ///
87 /// Assists are returned in the "unresolved" state, that is only labels are 92 /// Assists are returned in the "unresolved" state, that is only labels are
@@ -114,30 +119,8 @@ impl Assist {
114 acc.finish_resolved() 119 acc.finish_resolved()
115 } 120 }
116 121
117 pub(crate) fn new( 122 pub fn label(&self) -> &str {
118 id: AssistId, 123 self.label.as_str()
119 label: String,
120 group: Option<GroupLabel>,
121 target: TextRange,
122 ) -> Assist {
123 assert!(label.starts_with(|c: char| c.is_uppercase()));
124 Assist { id, label, group, target }
125 }
126
127 pub fn id(&self) -> AssistId {
128 self.id
129 }
130
131 pub fn label(&self) -> String {
132 self.label.clone()
133 }
134
135 pub fn group(&self) -> Option<GroupLabel> {
136 self.group.clone()
137 }
138
139 pub fn target(&self) -> TextRange {
140 self.target
141 } 124 }
142} 125}
143 126
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs
index d16e6fb0a..173567003 100644
--- a/crates/assists/src/tests/generated.rs
+++ b/crates/assists/src/tests/generated.rs
@@ -82,8 +82,8 @@ trait Trait {
82impl Trait for () { 82impl Trait for () {
83 Type X = (); 83 Type X = ();
84 fn foo(&self) {} 84 fn foo(&self) {}
85 $0fn bar(&self) {}
86 85
86 $0fn bar(&self) {}
87} 87}
88"#####, 88"#####,
89 ) 89 )
@@ -115,7 +115,6 @@ impl Trait<u32> for () {
115 fn foo(&self) -> u32 { 115 fn foo(&self) -> u32 {
116 ${0:todo!()} 116 ${0:todo!()}
117 } 117 }
118
119} 118}
120"#####, 119"#####,
121 ) 120 )
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 83b5013a9..a319b0ce8 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -16,9 +16,9 @@ ena = "0.14.0"
16log = "0.4.8" 16log = "0.4.8"
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18scoped-tls = "1" 18scoped-tls = "1"
19chalk-solve = { version = "0.21.0" } 19chalk-solve = { version = "0.23.0" }
20chalk-ir = { version = "0.21.0" } 20chalk-ir = { version = "0.23.0" }
21chalk-recursive = { version = "0.21.0" } 21chalk-recursive = { version = "0.23.0" }
22 22
23stdx = { path = "../stdx" } 23stdx = { path = "../stdx" }
24hir_def = { path = "../hir_def" } 24hir_def = { path = "../hir_def" }
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 1c3abb18f..14cd3a2b4 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -170,11 +170,11 @@ fn solve(
170 let mut solve = || { 170 let mut solve = || {
171 if is_chalk_print() { 171 if is_chalk_print() {
172 let logging_db = LoggingRustIrDatabase::new(context); 172 let logging_db = LoggingRustIrDatabase::new(context);
173 let solution = solver.solve_limited(&logging_db, goal, should_continue); 173 let solution = solver.solve_limited(&logging_db, goal, &should_continue);
174 log::debug!("chalk program:\n{}", logging_db); 174 log::debug!("chalk program:\n{}", logging_db);
175 solution 175 solution
176 } else { 176 } else {
177 solver.solve_limited(&context, goal, should_continue) 177 solver.solve_limited(&context, goal, &should_continue)
178 } 178 }
179 }; 179 };
180 180
diff --git a/crates/proc_macro_api/src/lib.rs b/crates/proc_macro_api/src/lib.rs
index 15db57eb2..d5e87cf7d 100644
--- a/crates/proc_macro_api/src/lib.rs
+++ b/crates/proc_macro_api/src/lib.rs
@@ -89,9 +89,8 @@ impl ProcMacroClient {
89 macros 89 macros
90 .into_iter() 90 .into_iter()
91 .filter_map(|(name, kind)| { 91 .filter_map(|(name, kind)| {
92 // FIXME: Support custom derive only for now.
93 match kind { 92 match kind {
94 ProcMacroKind::CustomDerive => { 93 ProcMacroKind::CustomDerive | ProcMacroKind::FuncLike => {
95 let name = SmolStr::new(&name); 94 let name = SmolStr::new(&name);
96 let expander: Arc<dyn tt::TokenExpander> = 95 let expander: Arc<dyn tt::TokenExpander> =
97 Arc::new(ProcMacroProcessExpander { 96 Arc::new(ProcMacroProcessExpander {
@@ -101,7 +100,8 @@ impl ProcMacroClient {
101 }); 100 });
102 Some((name, expander)) 101 Some((name, expander))
103 } 102 }
104 _ => None, 103 // FIXME: Attribute macro are currently unsupported.
104 ProcMacroKind::Attr => None,
105 } 105 }
106 }) 106 })
107 .collect() 107 .collect()
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 74f73655a..e05ffc768 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -859,10 +859,10 @@ pub(crate) fn handle_resolve_code_action(
859 .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); 859 .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
860 860
861 let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?; 861 let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?;
862 let (id_string, index) = split_once(&params.id, ':').unwrap(); 862 let (id, index) = split_once(&params.id, ':').unwrap();
863 let index = index.parse::<usize>().unwrap(); 863 let index = index.parse::<usize>().unwrap();
864 let assist = &assists[index]; 864 let assist = &assists[index];
865 assert!(assist.assist.id().0 == id_string); 865 assert!(assist.assist.id.0 == id);
866 Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit) 866 Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit)
867} 867}
868 868
diff --git a/crates/rust-analyzer/src/lsp_ext.rs b/crates/rust-analyzer/src/lsp_ext.rs
index 3976b6529..e1a28b1b4 100644
--- a/crates/rust-analyzer/src/lsp_ext.rs
+++ b/crates/rust-analyzer/src/lsp_ext.rs
@@ -237,8 +237,13 @@ pub enum Status {
237 Invalid, 237 Invalid,
238} 238}
239 239
240#[derive(Deserialize, Serialize)]
241pub struct StatusParams {
242 pub status: Status,
243}
244
240impl Notification for StatusNotification { 245impl Notification for StatusNotification {
241 type Params = Status; 246 type Params = StatusParams;
242 const METHOD: &'static str = "rust-analyzer/status"; 247 const METHOD: &'static str = "rust-analyzer/status";
243} 248}
244 249
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index a2cfb4e0d..505505a77 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -13,6 +13,7 @@ use crate::{
13 lsp_ext, 13 lsp_ext,
14 main_loop::Task, 14 main_loop::Task,
15}; 15};
16use lsp_ext::StatusParams;
16 17
17impl GlobalState { 18impl GlobalState {
18 pub(crate) fn update_configuration(&mut self, config: Config) { 19 pub(crate) fn update_configuration(&mut self, config: Config) {
@@ -85,7 +86,9 @@ impl GlobalState {
85 Status::Invalid => lsp_ext::Status::Invalid, 86 Status::Invalid => lsp_ext::Status::Invalid,
86 Status::NeedsReload => lsp_ext::Status::NeedsReload, 87 Status::NeedsReload => lsp_ext::Status::NeedsReload,
87 }; 88 };
88 self.send_notification::<lsp_ext::StatusNotification>(lsp_status); 89 self.send_notification::<lsp_ext::StatusNotification>(StatusParams {
90 status: lsp_status,
91 });
89 } 92 }
90 } 93 }
91 pub(crate) fn fetch_workspaces(&mut self) { 94 pub(crate) fn fetch_workspaces(&mut self) {
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 8a2cfa2ae..535de2f71 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -704,10 +704,10 @@ pub(crate) fn unresolved_code_action(
704 index: usize, 704 index: usize,
705) -> Result<lsp_ext::CodeAction> { 705) -> Result<lsp_ext::CodeAction> {
706 let res = lsp_ext::CodeAction { 706 let res = lsp_ext::CodeAction {
707 title: assist.label(), 707 title: assist.label().to_string(),
708 id: Some(format!("{}:{}", assist.id().0.to_owned(), index.to_string())), 708 id: Some(format!("{}:{}", assist.id.0, index.to_string())),
709 group: assist.group().filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), 709 group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0),
710 kind: Some(code_action_kind(assist.id().1)), 710 kind: Some(code_action_kind(assist.id.1)),
711 edit: None, 711 edit: None,
712 is_preferred: None, 712 is_preferred: None,
713 }; 713 };
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index 47e351f9d..ec3132da8 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
13[dependencies] 13[dependencies]
14itertools = "0.9.0" 14itertools = "0.9.0"
15rowan = "0.10.0" 15rowan = "0.10.0"
16rustc_lexer = { version = "671.0.0", package = "rustc-ap-rustc_lexer" } 16rustc_lexer = { version = "673.0.0", package = "rustc-ap-rustc_lexer" }
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18arrayvec = "0.5.1" 18arrayvec = "0.5.1"
19once_cell = "1.3.1" 19once_cell = "1.3.1"
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 190746e09..060b20966 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -91,29 +91,52 @@ impl ast::AssocItemList {
91 res = make_multiline(res); 91 res = make_multiline(res);
92 } 92 }
93 items.into_iter().for_each(|it| res = res.append_item(it)); 93 items.into_iter().for_each(|it| res = res.append_item(it));
94 res 94 res.fixup_trailing_whitespace().unwrap_or(res)
95 } 95 }
96 96
97 #[must_use] 97 #[must_use]
98 pub fn append_item(&self, item: ast::AssocItem) -> ast::AssocItemList { 98 pub fn append_item(&self, item: ast::AssocItem) -> ast::AssocItemList {
99 let (indent, position) = match self.assoc_items().last() { 99 let (indent, position, whitespace) = match self.assoc_items().last() {
100 Some(it) => ( 100 Some(it) => (
101 leading_indent(it.syntax()).unwrap_or_default().to_string(), 101 leading_indent(it.syntax()).unwrap_or_default().to_string(),
102 InsertPosition::After(it.syntax().clone().into()), 102 InsertPosition::After(it.syntax().clone().into()),
103 "\n\n",
103 ), 104 ),
104 None => match self.l_curly_token() { 105 None => match self.l_curly_token() {
105 Some(it) => ( 106 Some(it) => (
106 " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(), 107 " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(),
107 InsertPosition::After(it.into()), 108 InsertPosition::After(it.into()),
109 "\n",
108 ), 110 ),
109 None => return self.clone(), 111 None => return self.clone(),
110 }, 112 },
111 }; 113 };
112 let ws = tokens::WsBuilder::new(&format!("\n{}", indent)); 114 let ws = tokens::WsBuilder::new(&format!("{}{}", whitespace, indent));
113 let to_insert: ArrayVec<[SyntaxElement; 2]> = 115 let to_insert: ArrayVec<[SyntaxElement; 2]> =
114 [ws.ws().into(), item.syntax().clone().into()].into(); 116 [ws.ws().into(), item.syntax().clone().into()].into();
115 self.insert_children(position, to_insert) 117 self.insert_children(position, to_insert)
116 } 118 }
119
120 /// Remove extra whitespace between last item and closing curly brace.
121 fn fixup_trailing_whitespace(&self) -> Option<ast::AssocItemList> {
122 let first_token_after_items =
123 self.assoc_items().last()?.syntax().next_sibling_or_token()?;
124 let last_token_before_curly = self.r_curly_token()?.prev_sibling_or_token()?;
125 if last_token_before_curly != first_token_after_items {
126 // there is something more between last item and
127 // right curly than just whitespace - bail out
128 return None;
129 }
130 let whitespace =
131 last_token_before_curly.clone().into_token().and_then(ast::Whitespace::cast)?;
132 let text = whitespace.syntax().text();
133 let newline = text.rfind("\n")?;
134 let keep = tokens::WsBuilder::new(&text[newline..]);
135 Some(self.replace_children(
136 first_token_after_items..=last_token_before_curly,
137 std::iter::once(keep.ws().into()),
138 ))
139 }
117} 140}
118 141
119impl ast::RecordExprFieldList { 142impl ast::RecordExprFieldList {