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 <mail4score@gmail.com>
This commit is contained in:
bors[bot] 2020-02-12 15:08:34 +00:00 committed by GitHub
commit 5bf6698609
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 7 deletions

View File

@ -431,7 +431,12 @@ fn best_action_for_target(
.find(|n| n.text_range().start() < anchor.text_range().start())
.or_else(|| Some(anchor));
ImportAction::add_new_use(anchor, false)
let add_after_anchor = anchor
.clone()
.and_then(ast::Attr::cast)
.map(|attr| attr.kind() == ast::AttrKind::Inner)
.unwrap_or(false);
ImportAction::add_new_use(anchor, add_after_anchor)
}
}
}
@ -958,6 +963,28 @@ mod foo {
Debug<|>
}
}
",
);
}
#[test]
fn inserts_imports_after_inner_attributes() {
check_assist(
replace_qualified_name_with_use,
"
#![allow(dead_code)]
fn main() {
std::fmt::Debug<|>
}
",
"
#![allow(dead_code)]
use std::fmt::Debug;
fn main() {
Debug<|>
}
",
);

View File

@ -18,8 +18,8 @@ use crate::{
pub use self::{
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
extensions::{
FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind,
VisibilityKind,
AttrKind, FieldKind, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind,
TypeBoundKind, VisibilityKind,
},
generated::*,
tokens::*,
@ -217,10 +217,7 @@ fn test_doc_comment_multi_line_block_strips_suffix() {
#[test]
fn test_comments_preserve_trailing_whitespace() {
let file = SourceFile::parse(
r#"
/// Representation of a Realm.
/// In the specification these are called Realm Records.
struct Realm {}"#,
"\n/// Representation of a Realm. \n/// In the specification these are called Realm Records.\nstruct Realm {}",
)
.ok()
.unwrap();

View File

@ -37,6 +37,12 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum AttrKind {
Inner,
Outer,
}
impl ast::Attr {
pub fn as_simple_atom(&self) -> Option<SmolStr> {
match self.input() {
@ -71,6 +77,18 @@ impl ast::Attr {
_ => None,
}
}
pub fn kind(&self) -> AttrKind {
let first_token = self.syntax().first_token();
let first_token_kind = first_token.as_ref().map(SyntaxToken::kind);
let second_token_kind =
first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind);
match (first_token_kind, second_token_kind) {
(Some(SyntaxKind::POUND), Some(SyntaxKind::EXCL)) => AttrKind::Inner,
_ => AttrKind::Outer,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]