@@ -9,7 +9,7 @@ use syntax::{
99 edit:: { AstNodeEdit , IndentLevel } ,
1010 make, AstNode , PathSegmentKind , VisibilityOwner ,
1111 } ,
12- InsertPosition , SyntaxElement , SyntaxNode ,
12+ AstToken , InsertPosition , NodeOrToken , SyntaxElement , SyntaxNode , SyntaxToken ,
1313} ;
1414use test_utils:: mark;
1515
@@ -63,27 +63,30 @@ impl ImportScope {
6363 }
6464 }
6565
66- fn insert_pos_after_inner_attribute ( & self ) -> ( InsertPosition < SyntaxElement > , AddBlankLine ) {
67- // check if the scope has inner attributes, we dont want to insert in front of them
68- match self
69- . as_syntax_node ( )
70- . children ( )
71- // no flat_map here cause we want to short circuit the iterator
72- . map ( ast:: Attr :: cast)
73- . take_while ( |attr| {
74- attr. as_ref ( ) . map ( |attr| attr. kind ( ) == ast:: AttrKind :: Inner ) . unwrap_or ( false )
66+ fn insert_pos_after_last_inner_element ( & self ) -> ( InsertPosition < SyntaxElement > , AddBlankLine ) {
67+ self . as_syntax_node ( )
68+ . children_with_tokens ( )
69+ . filter ( |child| match child {
70+ NodeOrToken :: Node ( node) => is_inner_attribute ( node. clone ( ) ) ,
71+ NodeOrToken :: Token ( token) => is_inner_comment ( token. clone ( ) ) ,
7572 } )
7673 . last ( )
77- . flatten ( )
78- {
79- Some ( attr) => {
80- ( InsertPosition :: After ( attr. syntax ( ) . clone ( ) . into ( ) ) , AddBlankLine :: BeforeTwice )
81- }
82- None => self . first_insert_pos ( ) ,
83- }
74+ . map ( |last_inner_element| {
75+ ( InsertPosition :: After ( last_inner_element. into ( ) ) , AddBlankLine :: BeforeTwice )
76+ } )
77+ . unwrap_or_else ( || self . first_insert_pos ( ) )
8478 }
8579}
8680
81+ fn is_inner_attribute ( node : SyntaxNode ) -> bool {
82+ ast:: Attr :: cast ( node) . map ( |attr| attr. kind ( ) ) == Some ( ast:: AttrKind :: Inner )
83+ }
84+
85+ fn is_inner_comment ( token : SyntaxToken ) -> bool {
86+ ast:: Comment :: cast ( token) . and_then ( |comment| comment. kind ( ) . doc )
87+ == Some ( ast:: CommentPlacement :: Inner )
88+ }
89+
8790/// Insert an import path into the given file/node. A `merge` value of none indicates that no import merging is allowed to occur.
8891pub ( crate ) fn insert_use < ' a > (
8992 scope : & ImportScope ,
@@ -558,7 +561,7 @@ fn find_insert_position(
558561 ( InsertPosition :: After ( node. into ( ) ) , AddBlankLine :: BeforeTwice )
559562 }
560563 // there are no imports in this file at all
561- None => scope. insert_pos_after_inner_attribute ( ) ,
564+ None => scope. insert_pos_after_last_inner_element ( ) ,
562565 } ,
563566 }
564567 }
@@ -830,12 +833,67 @@ use foo::bar;",
830833 "foo::bar" ,
831834 r"#![allow(unused_imports)]
832835
836+ #![no_std]
833837fn main() {}" ,
834838 r"#![allow(unused_imports)]
835839
836- use foo::bar;
840+ #![no_std]
837841
842+ use foo::bar;
838843fn main() {}" ,
844+ ) ;
845+ }
846+
847+ #[ test]
848+ fn inserts_after_single_line_inner_comments ( ) {
849+ check_none (
850+ "foo::bar::Baz" ,
851+ "//! Single line inner comments do not allow any code before them." ,
852+ r#"//! Single line inner comments do not allow any code before them.
853+
854+ use foo::bar::Baz;"# ,
855+ ) ;
856+ }
857+
858+ #[ test]
859+ fn inserts_after_multiline_inner_comments ( ) {
860+ check_none (
861+ "foo::bar::Baz" ,
862+ r#"/*! Multiline inner comments do not allow any code before them. */
863+
864+ /*! Still an inner comment, cannot place any code before. */
865+ fn main() {}"# ,
866+ r#"/*! Multiline inner comments do not allow any code before them. */
867+
868+ /*! Still an inner comment, cannot place any code before. */
869+
870+ use foo::bar::Baz;
871+ fn main() {}"# ,
872+ )
873+ }
874+
875+ #[ test]
876+ fn inserts_after_all_inner_items ( ) {
877+ check_none (
878+ "foo::bar::Baz" ,
879+ r#"#![allow(unused_imports)]
880+ /*! Multiline line comment 2 */
881+
882+
883+ //! Single line comment 1
884+ #![no_std]
885+ //! Single line comment 2
886+ fn main() {}"# ,
887+ r#"#![allow(unused_imports)]
888+ /*! Multiline line comment 2 */
889+
890+
891+ //! Single line comment 1
892+ #![no_std]
893+ //! Single line comment 2
894+
895+ use foo::bar::Baz;
896+ fn main() {}"# ,
839897 )
840898 }
841899
0 commit comments