Skip to content

Commit 5bf6698

Browse files
Merge #3121
3121: Do not add imports before inner attributes r=matklad a=SomeoneToIgnore Current `insert_use_statement` function adds imports before inner attributes which results in compiler errors: <img width="1440" alt="image" src="https://user-images.githubusercontent.com/2690773/74344019-a3749500-4db4-11ea-9d88-f71e903e795a.png"> Co-authored-by: Kirill Bulatov <[email protected]>
2 parents 4216092 + 2a7d97d commit 5bf6698

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,12 @@ fn best_action_for_target(
431431
.find(|n| n.text_range().start() < anchor.text_range().start())
432432
.or_else(|| Some(anchor));
433433

434-
ImportAction::add_new_use(anchor, false)
434+
let add_after_anchor = anchor
435+
.clone()
436+
.and_then(ast::Attr::cast)
437+
.map(|attr| attr.kind() == ast::AttrKind::Inner)
438+
.unwrap_or(false);
439+
ImportAction::add_new_use(anchor, add_after_anchor)
435440
}
436441
}
437442
}
@@ -958,6 +963,28 @@ mod foo {
958963
959964
Debug<|>
960965
}
966+
}
967+
",
968+
);
969+
}
970+
971+
#[test]
972+
fn inserts_imports_after_inner_attributes() {
973+
check_assist(
974+
replace_qualified_name_with_use,
975+
"
976+
#![allow(dead_code)]
977+
978+
fn main() {
979+
std::fmt::Debug<|>
980+
}
981+
",
982+
"
983+
#![allow(dead_code)]
984+
use std::fmt::Debug;
985+
986+
fn main() {
987+
Debug<|>
961988
}
962989
",
963990
);

crates/ra_syntax/src/ast.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::{
1818
pub use self::{
1919
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
2020
extensions::{
21-
FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind,
22-
VisibilityKind,
21+
AttrKind, FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind,
22+
TypeBoundKind, VisibilityKind,
2323
},
2424
generated::*,
2525
tokens::*,
@@ -217,10 +217,7 @@ fn test_doc_comment_multi_line_block_strips_suffix() {
217217
#[test]
218218
fn test_comments_preserve_trailing_whitespace() {
219219
let file = SourceFile::parse(
220-
r#"
221-
/// Representation of a Realm.
222-
/// In the specification these are called Realm Records.
223-
struct Realm {}"#,
220+
"\n/// Representation of a Realm. \n/// In the specification these are called Realm Records.\nstruct Realm {}",
224221
)
225222
.ok()
226223
.unwrap();

crates/ra_syntax/src/ast/extensions.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
3737
node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
3838
}
3939

40+
#[derive(Debug, Clone, PartialEq, Eq)]
41+
pub enum AttrKind {
42+
Inner,
43+
Outer,
44+
}
45+
4046
impl ast::Attr {
4147
pub fn as_simple_atom(&self) -> Option<SmolStr> {
4248
match self.input() {
@@ -71,6 +77,18 @@ impl ast::Attr {
7177
_ => None,
7278
}
7379
}
80+
81+
pub fn kind(&self) -> AttrKind {
82+
let first_token = self.syntax().first_token();
83+
let first_token_kind = first_token.as_ref().map(SyntaxToken::kind);
84+
let second_token_kind =
85+
first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind);
86+
87+
match (first_token_kind, second_token_kind) {
88+
(Some(SyntaxKind::POUND), Some(SyntaxKind::EXCL)) => AttrKind::Inner,
89+
_ => AttrKind::Outer,
90+
}
91+
}
7492
}
7593

7694
#[derive(Debug, Clone, PartialEq, Eq)]

0 commit comments

Comments
 (0)