Skip to content

Commit 26932e0

Browse files
Merge #5478
5478: Replace existing visibility modifier in fix_visibility r=matklad a=TimoFreiberg Fixes #4636 I would have liked to do something about the `// FIXME: this really should be a fix for diagnostic, rather than an assist.`, but that would take a while and there's no reason not to fix this immediately. Co-authored-by: Timo Freiberg <[email protected]>
2 parents 2e73ba1 + 3d9c123 commit 26932e0

File tree

1 file changed

+75
-15
lines changed

1 file changed

+75
-15
lines changed

crates/ra_assists/src/handlers/fix_visibility.rs

Lines changed: 75 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use ra_db::FileId;
33
use ra_syntax::{ast, AstNode, TextRange, TextSize};
44

55
use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
6+
use ast::VisibilityOwner;
67

78
// FIXME: this really should be a fix for diagnostic, rather than an assist.
89

@@ -48,7 +49,8 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> O
4849
return None;
4950
};
5051

51-
let (offset, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?;
52+
let (offset, current_visibility, target, target_file, target_name) =
53+
target_data_for_def(ctx.db(), def)?;
5254

5355
let missing_visibility =
5456
if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
@@ -61,8 +63,20 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> O
6163
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
6264
builder.edit_file(target_file);
6365
match ctx.config.snippet_cap {
64-
Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
65-
None => builder.insert(offset, format!("{} ", missing_visibility)),
66+
Some(cap) => match current_visibility {
67+
Some(current_visibility) => builder.replace_snippet(
68+
cap,
69+
current_visibility.syntax().text_range(),
70+
format!("$0{}", missing_visibility),
71+
),
72+
None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
73+
},
74+
None => match current_visibility {
75+
Some(current_visibility) => {
76+
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
77+
}
78+
None => builder.insert(offset, format!("{} ", missing_visibility)),
79+
},
6680
}
6781
})
6882
}
@@ -82,14 +96,14 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
8296
let target_module = parent.module(ctx.db());
8397

8498
let in_file_source = record_field_def.source(ctx.db());
85-
let (offset, target) = match in_file_source.value {
99+
let (offset, current_visibility, target) = match in_file_source.value {
86100
hir::FieldSource::Named(it) => {
87101
let s = it.syntax();
88-
(vis_offset(s), s.text_range())
102+
(vis_offset(s), it.visibility(), s.text_range())
89103
}
90104
hir::FieldSource::Pos(it) => {
91105
let s = it.syntax();
92-
(vis_offset(s), s.text_range())
106+
(vis_offset(s), it.visibility(), s.text_range())
93107
}
94108
};
95109

@@ -104,33 +118,51 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) ->
104118
acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
105119
builder.edit_file(target_file);
106120
match ctx.config.snippet_cap {
107-
Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
108-
None => builder.insert(offset, format!("{} ", missing_visibility)),
121+
Some(cap) => match current_visibility {
122+
Some(current_visibility) => builder.replace_snippet(
123+
cap,
124+
dbg!(current_visibility.syntax()).text_range(),
125+
format!("$0{}", missing_visibility),
126+
),
127+
None => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
128+
},
129+
None => match current_visibility {
130+
Some(current_visibility) => {
131+
builder.replace(current_visibility.syntax().text_range(), missing_visibility)
132+
}
133+
None => builder.insert(offset, format!("{} ", missing_visibility)),
134+
},
109135
}
110136
})
111137
}
112138

113139
fn target_data_for_def(
114140
db: &dyn HirDatabase,
115141
def: hir::ModuleDef,
116-
) -> Option<(TextSize, TextRange, FileId, Option<hir::Name>)> {
142+
) -> Option<(TextSize, Option<ast::Visibility>, TextRange, FileId, Option<hir::Name>)> {
117143
fn offset_target_and_file_id<S, Ast>(
118144
db: &dyn HirDatabase,
119145
x: S,
120-
) -> (TextSize, TextRange, FileId)
146+
) -> (TextSize, Option<ast::Visibility>, TextRange, FileId)
121147
where
122148
S: HasSource<Ast = Ast>,
123-
Ast: AstNode,
149+
Ast: AstNode + ast::VisibilityOwner,
124150
{
125151
let source = x.source(db);
126152
let in_file_syntax = source.syntax();
127153
let file_id = in_file_syntax.file_id;
128154
let syntax = in_file_syntax.value;
129-
(vis_offset(syntax), syntax.text_range(), file_id.original_file(db.upcast()))
155+
let current_visibility = source.value.visibility();
156+
(
157+
vis_offset(syntax),
158+
current_visibility,
159+
syntax.text_range(),
160+
file_id.original_file(db.upcast()),
161+
)
130162
}
131163

132164
let target_name;
133-
let (offset, target, target_file) = match def {
165+
let (offset, current_visibility, target, target_file) = match def {
134166
hir::ModuleDef::Function(f) => {
135167
target_name = Some(f.name(db));
136168
offset_target_and_file_id(db, f)
@@ -164,13 +196,13 @@ fn target_data_for_def(
164196
let in_file_source = m.declaration_source(db)?;
165197
let file_id = in_file_source.file_id.original_file(db.upcast());
166198
let syntax = in_file_source.value.syntax();
167-
(vis_offset(syntax), syntax.text_range(), file_id)
199+
(vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
168200
}
169201
// Enum variants can't be private, we can't modify builtin types
170202
hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None,
171203
};
172204

173-
Some((offset, target, target_file, target_name))
205+
Some((offset, current_visibility, target, target_file, target_name))
174206
}
175207

176208
#[cfg(test)]
@@ -522,6 +554,34 @@ struct Bar;
522554
)
523555
}
524556

557+
#[test]
558+
fn replaces_pub_crate_with_pub() {
559+
check_assist(
560+
fix_visibility,
561+
r"
562+
//- /main.rs crate:a deps:foo
563+
foo::Bar<|>
564+
//- /lib.rs crate:foo
565+
pub(crate) struct Bar;
566+
",
567+
r"$0pub struct Bar;
568+
",
569+
);
570+
check_assist(
571+
fix_visibility,
572+
r"
573+
//- /main.rs crate:a deps:foo
574+
fn main() {
575+
foo::Foo { <|>bar: () };
576+
}
577+
//- /lib.rs crate:foo
578+
pub struct Foo { pub(crate) bar: () }
579+
",
580+
r"pub struct Foo { $0pub bar: () }
581+
",
582+
);
583+
}
584+
525585
#[test]
526586
#[ignore]
527587
// FIXME handle reexports properly

0 commit comments

Comments
 (0)