Skip to content

Commit c4d128e

Browse files
committed
Merge branch 'master' of github.com:rust-analyzer/rust-analyzer into fix_4311
2 parents 0bf02f5 + 30eb458 commit c4d128e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+657
-567
lines changed

crates/ra_assists/src/assist_ctx.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ use ra_db::FileRange;
44
use ra_fmt::{leading_indent, reindent};
55
use ra_ide_db::RootDatabase;
66
use ra_syntax::{
7-
algo::{self, find_covering_element, find_node_at_offset},
7+
algo::{self, find_covering_element, find_node_at_offset, SyntaxRewriter},
88
AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange, TextSize,
99
TokenAtOffset,
1010
};
1111
use ra_text_edit::TextEditBuilder;
1212

1313
use crate::{AssistAction, AssistFile, AssistId, AssistLabel, GroupLabel, ResolvedAssist};
14-
use algo::SyntaxRewriter;
1514

1615
#[derive(Clone, Debug)]
1716
pub(crate) struct Assist(pub(crate) Vec<AssistInfo>);
@@ -38,13 +37,10 @@ impl AssistInfo {
3837

3938
pub(crate) fn into_resolved(self) -> Option<ResolvedAssist> {
4039
let label = self.label;
41-
let group_label = self.group_label;
42-
self.action.map(|action| ResolvedAssist { label, group_label, action })
40+
self.action.map(|action| ResolvedAssist { label, action })
4341
}
4442
}
4543

46-
pub(crate) type AssistHandler = fn(AssistCtx) -> Option<Assist>;
47-
4844
/// `AssistCtx` allows to apply an assist or check if it could be applied.
4945
///
5046
/// Assists use a somewhat over-engineered approach, given the current needs. The
@@ -100,7 +96,7 @@ impl<'a> AssistCtx<'a> {
10096
label: impl Into<String>,
10197
f: impl FnOnce(&mut ActionBuilder),
10298
) -> Option<Assist> {
103-
let label = AssistLabel::new(label.into(), id);
99+
let label = AssistLabel::new(id, label.into(), None);
104100

105101
let mut info = AssistInfo::new(label);
106102
if self.should_compute_edit {
@@ -116,7 +112,8 @@ impl<'a> AssistCtx<'a> {
116112
}
117113

118114
pub(crate) fn add_assist_group(self, group_name: impl Into<String>) -> AssistGroup<'a> {
119-
AssistGroup { ctx: self, group_name: group_name.into(), assists: Vec::new() }
115+
let group = GroupLabel(group_name.into());
116+
AssistGroup { ctx: self, group, assists: Vec::new() }
120117
}
121118

122119
pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
@@ -146,7 +143,7 @@ impl<'a> AssistCtx<'a> {
146143

147144
pub(crate) struct AssistGroup<'a> {
148145
ctx: AssistCtx<'a>,
149-
group_name: String,
146+
group: GroupLabel,
150147
assists: Vec<AssistInfo>,
151148
}
152149

@@ -157,9 +154,9 @@ impl<'a> AssistGroup<'a> {
157154
label: impl Into<String>,
158155
f: impl FnOnce(&mut ActionBuilder),
159156
) {
160-
let label = AssistLabel::new(label.into(), id);
157+
let label = AssistLabel::new(id, label.into(), Some(self.group.clone()));
161158

162-
let mut info = AssistInfo::new(label).with_group(GroupLabel(self.group_name.clone()));
159+
let mut info = AssistInfo::new(label).with_group(self.group.clone());
163160
if self.ctx.should_compute_edit {
164161
let action = {
165162
let mut edit = ActionBuilder::new(&self.ctx);

crates/ra_assists/src/doc_tests.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ fn check(assist_id: &str, before: &str, after: &str) {
3030
)
3131
});
3232

33-
let actual = assist.action.edit.apply(&before);
33+
let actual = {
34+
let mut actual = before.clone();
35+
assist.action.edit.apply(&mut actual);
36+
actual
37+
};
3438
assert_eq_text!(after, &actual);
3539
}

crates/ra_assists/src/handlers/add_missing_impl_members.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use ra_syntax::{
1010

1111
use crate::{
1212
ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams},
13-
utils::{get_missing_impl_items, resolve_target_trait},
13+
utils::{get_missing_assoc_items, resolve_target_trait},
1414
Assist, AssistCtx, AssistId,
1515
};
1616

@@ -112,25 +112,25 @@ fn add_missing_impl_members_inner(
112112

113113
let trait_ = resolve_target_trait(&ctx.sema, &impl_node)?;
114114

115-
let def_name = |item: &ast::ImplItem| -> Option<SmolStr> {
115+
let def_name = |item: &ast::AssocItem| -> Option<SmolStr> {
116116
match item {
117-
ast::ImplItem::FnDef(def) => def.name(),
118-
ast::ImplItem::TypeAliasDef(def) => def.name(),
119-
ast::ImplItem::ConstDef(def) => def.name(),
117+
ast::AssocItem::FnDef(def) => def.name(),
118+
ast::AssocItem::TypeAliasDef(def) => def.name(),
119+
ast::AssocItem::ConstDef(def) => def.name(),
120120
}
121121
.map(|it| it.text().clone())
122122
};
123123

124-
let missing_items = get_missing_impl_items(&ctx.sema, &impl_node)
124+
let missing_items = get_missing_assoc_items(&ctx.sema, &impl_node)
125125
.iter()
126126
.map(|i| match i {
127-
hir::AssocItem::Function(i) => ast::ImplItem::FnDef(i.source(ctx.db).value),
128-
hir::AssocItem::TypeAlias(i) => ast::ImplItem::TypeAliasDef(i.source(ctx.db).value),
129-
hir::AssocItem::Const(i) => ast::ImplItem::ConstDef(i.source(ctx.db).value),
127+
hir::AssocItem::Function(i) => ast::AssocItem::FnDef(i.source(ctx.db).value),
128+
hir::AssocItem::TypeAlias(i) => ast::AssocItem::TypeAliasDef(i.source(ctx.db).value),
129+
hir::AssocItem::Const(i) => ast::AssocItem::ConstDef(i.source(ctx.db).value),
130130
})
131131
.filter(|t| def_name(&t).is_some())
132132
.filter(|t| match t {
133-
ast::ImplItem::FnDef(def) => match mode {
133+
ast::AssocItem::FnDef(def) => match mode {
134134
AddMissingImplMembersMode::DefaultMethodsOnly => def.body().is_some(),
135135
AddMissingImplMembersMode::NoDefaultMethods => def.body().is_none(),
136136
},
@@ -145,7 +145,7 @@ fn add_missing_impl_members_inner(
145145
let sema = ctx.sema;
146146

147147
ctx.add_assist(AssistId(assist_id), label, |edit| {
148-
let n_existing_items = impl_item_list.impl_items().count();
148+
let n_existing_items = impl_item_list.assoc_items().count();
149149
let source_scope = sema.scope_for_def(trait_);
150150
let target_scope = sema.scope(impl_item_list.syntax());
151151
let ast_transform = QualifyPaths::new(&target_scope, &source_scope)
@@ -154,13 +154,13 @@ fn add_missing_impl_members_inner(
154154
.into_iter()
155155
.map(|it| ast_transform::apply(&*ast_transform, it))
156156
.map(|it| match it {
157-
ast::ImplItem::FnDef(def) => ast::ImplItem::FnDef(add_body(def)),
157+
ast::AssocItem::FnDef(def) => ast::AssocItem::FnDef(add_body(def)),
158158
_ => it,
159159
})
160160
.map(|it| edit::remove_attrs_and_docs(&it));
161161
let new_impl_item_list = impl_item_list.append_items(items);
162162
let cursor_position = {
163-
let first_new_item = new_impl_item_list.impl_items().nth(n_existing_items).unwrap();
163+
let first_new_item = new_impl_item_list.assoc_items().nth(n_existing_items).unwrap();
164164
first_new_item.syntax().text_range().start()
165165
};
166166

crates/ra_assists/src/handlers/add_new.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ fn find_struct_impl(ctx: &AssistCtx, strukt: &ast::StructDef) -> Option<Option<a
162162

163163
fn has_new_fn(imp: &ast::ImplDef) -> bool {
164164
if let Some(il) = imp.item_list() {
165-
for item in il.impl_items() {
166-
if let ast::ImplItem::FnDef(f) = item {
165+
for item in il.assoc_items() {
166+
if let ast::AssocItem::FnDef(f) = item {
167167
if let Some(name) = f.name() {
168168
if name.text().eq_ignore_ascii_case("new") {
169169
return true;

crates/ra_assists/src/handlers/change_visibility.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
4747
return None;
4848
}
4949
(vis_offset(&parent), keyword.text_range())
50-
} else {
51-
let field_name: ast::Name = ctx.find_node_at_offset()?;
50+
} else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() {
5251
let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
5352
if field.name()? != field_name {
5453
tested_by!(change_visibility_field_false_positive);
@@ -58,6 +57,13 @@ fn add_vis(ctx: AssistCtx) -> Option<Assist> {
5857
return None;
5958
}
6059
(vis_offset(field.syntax()), field_name.syntax().text_range())
60+
} else if let Some(field) = ctx.find_node_at_offset::<ast::TupleFieldDef>() {
61+
if field.visibility().is_some() {
62+
return None;
63+
}
64+
(vis_offset(field.syntax()), field.syntax().text_range())
65+
} else {
66+
return None;
6167
};
6268

6369
ctx.add_assist(AssistId("change_visibility"), "Change visibility to pub(crate)", |edit| {
@@ -129,7 +135,8 @@ mod tests {
129135
change_visibility,
130136
r"struct S { <|>field: u32 }",
131137
r"struct S { <|>pub(crate) field: u32 }",
132-
)
138+
);
139+
check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( <|>pub(crate) u32 )");
133140
}
134141

135142
#[test]

crates/ra_assists/src/lib.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ mod doc_tests;
1717
pub mod utils;
1818
pub mod ast_transform;
1919

20+
use hir::Semantics;
2021
use ra_db::{FileId, FileRange};
2122
use ra_ide_db::RootDatabase;
2223
use ra_syntax::{TextRange, TextSize};
2324
use ra_text_edit::TextEdit;
2425

25-
pub(crate) use crate::assist_ctx::{Assist, AssistCtx, AssistHandler};
26-
use hir::Semantics;
26+
pub(crate) use crate::assist_ctx::{Assist, AssistCtx};
2727

2828
/// Unique identifier of the assist, should not be shown to the user
2929
/// directly.
@@ -32,19 +32,20 @@ pub struct AssistId(pub &'static str);
3232

3333
#[derive(Debug, Clone)]
3434
pub struct AssistLabel {
35+
pub id: AssistId,
3536
/// Short description of the assist, as shown in the UI.
3637
pub label: String,
37-
pub id: AssistId,
38+
pub group: Option<GroupLabel>,
3839
}
3940

4041
#[derive(Clone, Debug)]
4142
pub struct GroupLabel(pub String);
4243

4344
impl AssistLabel {
44-
pub(crate) fn new(label: String, id: AssistId) -> AssistLabel {
45+
pub(crate) fn new(id: AssistId, label: String, group: Option<GroupLabel>) -> AssistLabel {
4546
// FIXME: make fields private, so that this invariant can't be broken
4647
assert!(label.starts_with(|c: char| c.is_uppercase()));
47-
AssistLabel { label, id }
48+
AssistLabel { id, label, group }
4849
}
4950
}
5051

@@ -60,7 +61,6 @@ pub struct AssistAction {
6061
#[derive(Debug, Clone)]
6162
pub struct ResolvedAssist {
6263
pub label: AssistLabel,
63-
pub group_label: Option<GroupLabel>,
6464
pub action: AssistAction,
6565
}
6666

@@ -109,7 +109,9 @@ pub fn resolved_assists(db: &RootDatabase, range: FileRange) -> Vec<ResolvedAssi
109109
}
110110

111111
mod handlers {
112-
use crate::AssistHandler;
112+
use crate::{Assist, AssistCtx};
113+
114+
pub(crate) type Handler = fn(AssistCtx) -> Option<Assist>;
113115

114116
mod add_custom_impl;
115117
mod add_derive;
@@ -145,12 +147,13 @@ mod handlers {
145147
mod reorder_fields;
146148
mod unwrap_block;
147149

148-
pub(crate) fn all() -> &'static [AssistHandler] {
150+
pub(crate) fn all() -> &'static [Handler] {
149151
&[
150152
// These are alphabetic for the foolish consistency
151153
add_custom_impl::add_custom_impl,
152154
add_derive::add_derive,
153155
add_explicit_type::add_explicit_type,
156+
add_from_impl_for_enum::add_from_impl_for_enum,
154157
add_function::add_function,
155158
add_impl::add_impl,
156159
add_new::add_new,
@@ -176,17 +179,18 @@ mod handlers {
176179
raw_string::remove_hash,
177180
remove_dbg::remove_dbg,
178181
remove_mut::remove_mut,
182+
reorder_fields::reorder_fields,
179183
replace_if_let_with_match::replace_if_let_with_match,
180184
replace_let_with_if_let::replace_let_with_if_let,
181185
replace_qualified_name_with_use::replace_qualified_name_with_use,
182186
replace_unwrap_with_match::replace_unwrap_with_match,
183187
split_import::split_import,
184-
add_from_impl_for_enum::add_from_impl_for_enum,
185188
unwrap_block::unwrap_block,
186189
// These are manually sorted for better priorities
187190
add_missing_impl_members::add_missing_impl_members,
188191
add_missing_impl_members::add_missing_default_members,
189-
reorder_fields::reorder_fields,
192+
// Are you sure you want to add new assist here, and not to the
193+
// sorted list above?
190194
]
191195
}
192196
}
@@ -195,12 +199,12 @@ mod handlers {
195199
mod helpers {
196200
use std::sync::Arc;
197201

202+
use hir::Semantics;
198203
use ra_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt};
199204
use ra_ide_db::{symbol_index::SymbolsDatabase, RootDatabase};
200205
use test_utils::{add_cursor, assert_eq_text, extract_range_or_offset, RangeOrOffset};
201206

202-
use crate::{AssistCtx, AssistFile, AssistHandler};
203-
use hir::Semantics;
207+
use crate::{handlers::Handler, AssistCtx, AssistFile};
204208

205209
pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) {
206210
let (mut db, file_id) = RootDatabase::with_single_file(text);
@@ -210,22 +214,18 @@ mod helpers {
210214
(db, file_id)
211215
}
212216

213-
pub(crate) fn check_assist(
214-
assist: AssistHandler,
215-
ra_fixture_before: &str,
216-
ra_fixture_after: &str,
217-
) {
217+
pub(crate) fn check_assist(assist: Handler, ra_fixture_before: &str, ra_fixture_after: &str) {
218218
check(assist, ra_fixture_before, ExpectedResult::After(ra_fixture_after));
219219
}
220220

221221
// FIXME: instead of having a separate function here, maybe use
222222
// `extract_ranges` and mark the target as `<target> </target>` in the
223223
// fixuture?
224-
pub(crate) fn check_assist_target(assist: AssistHandler, ra_fixture: &str, target: &str) {
224+
pub(crate) fn check_assist_target(assist: Handler, ra_fixture: &str, target: &str) {
225225
check(assist, ra_fixture, ExpectedResult::Target(target));
226226
}
227227

228-
pub(crate) fn check_assist_not_applicable(assist: AssistHandler, ra_fixture: &str) {
228+
pub(crate) fn check_assist_not_applicable(assist: Handler, ra_fixture: &str) {
229229
check(assist, ra_fixture, ExpectedResult::NotApplicable);
230230
}
231231

@@ -235,7 +235,7 @@ mod helpers {
235235
Target(&'a str),
236236
}
237237

238-
fn check(assist: AssistHandler, before: &str, expected: ExpectedResult) {
238+
fn check(assist: Handler, before: &str, expected: ExpectedResult) {
239239
let (text_without_caret, file_with_caret_id, range_or_offset, db) =
240240
if before.contains("//-") {
241241
let (mut db, position) = RootDatabase::with_position(before);
@@ -261,13 +261,13 @@ mod helpers {
261261
(Some(assist), ExpectedResult::After(after)) => {
262262
let action = assist.0[0].action.clone().unwrap();
263263

264-
let assisted_file_text = if let AssistFile::TargetFile(file_id) = action.file {
264+
let mut actual = if let AssistFile::TargetFile(file_id) = action.file {
265265
db.file_text(file_id).as_ref().to_owned()
266266
} else {
267267
text_without_caret
268268
};
269+
action.edit.apply(&mut actual);
269270

270-
let mut actual = action.edit.apply(&assisted_file_text);
271271
match action.cursor_position {
272272
None => {
273273
if let RangeOrOffset::Offset(before_cursor_pos) = range_or_offset {

crates/ra_assists/src/utils.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rustc_hash::FxHashSet;
1313

1414
pub(crate) use insert_use::insert_use_statement;
1515

16-
pub fn get_missing_impl_items(
16+
pub fn get_missing_assoc_items(
1717
sema: &Semantics<RootDatabase>,
1818
impl_def: &ast::ImplDef,
1919
) -> Vec<hir::AssocItem> {
@@ -23,21 +23,21 @@ pub fn get_missing_impl_items(
2323
let mut impl_type = FxHashSet::default();
2424

2525
if let Some(item_list) = impl_def.item_list() {
26-
for item in item_list.impl_items() {
26+
for item in item_list.assoc_items() {
2727
match item {
28-
ast::ImplItem::FnDef(f) => {
28+
ast::AssocItem::FnDef(f) => {
2929
if let Some(n) = f.name() {
3030
impl_fns_consts.insert(n.syntax().to_string());
3131
}
3232
}
3333

34-
ast::ImplItem::TypeAliasDef(t) => {
34+
ast::AssocItem::TypeAliasDef(t) => {
3535
if let Some(n) = t.name() {
3636
impl_type.insert(n.syntax().to_string());
3737
}
3838
}
3939

40-
ast::ImplItem::ConstDef(c) => {
40+
ast::AssocItem::ConstDef(c) => {
4141
if let Some(n) = c.name() {
4242
impl_fns_consts.insert(n.syntax().to_string());
4343
}

0 commit comments

Comments
 (0)