Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #12811 - TopGunSnake:12790, r=Veykril
fix: Insert `pub(crate)` after doc comments and attribute macros
Fixes #12790
Original behavior was to insert `pub(crate)` at the `first_child_or_token`, which for an item with a comment or attribute macro, would put the visibility marker before the comment or macro, instead of after.
This merge request alters the call to find the node with appropriate `SyntaxKind` in the `children_or_tokens`. It also adds a test case to the module to verify the behavior. Test case verifies function, module, records, enum, impl, trait, and type cases.
| -rw-r--r-- | crates/ide-assists/src/handlers/extract_module.rs | 190 |
1 files changed, 188 insertions, 2 deletions
diff --git a/crates/ide-assists/src/handlers/extract_module.rs b/crates/ide-assists/src/handlers/extract_module.rs index 11349b45d3..154856df54 100644 --- a/crates/ide-assists/src/handlers/extract_module.rs +++ b/crates/ide-assists/src/handlers/extract_module.rs @@ -19,7 +19,7 @@ use syntax::{ make, HasName, HasVisibility, }, match_ast, ted, AstNode, SourceFile, - SyntaxKind::WHITESPACE, + SyntaxKind::{self, WHITESPACE}, SyntaxNode, TextRange, }; @@ -380,7 +380,16 @@ impl Module { } for (vis, syntax) in replacements { - add_change_vis(vis, syntax.first_child_or_token()); + let item = syntax.children_with_tokens().find(|node_or_token| { + match node_or_token.kind() { + // We're skipping comments, doc comments, and attribute macros that may precede the keyword + // that the visibility should be placed before. + SyntaxKind::COMMENT | SyntaxKind::ATTR | SyntaxKind::WHITESPACE => false, + _ => true, + } + }); + + add_change_vis(vis, item); } } @@ -1581,4 +1590,181 @@ mod modname { ", ) } + + #[test] + fn test_issue_12790() { + check_assist( + extract_module, + r" + $0/// A documented function + fn documented_fn() {} + + // A commented function with a #[] attribute macro + #[cfg(test)] + fn attribute_fn() {} + + // A normally commented function + fn normal_fn() {} + + /// A documented Struct + struct DocumentedStruct { + // Normal field + x: i32, + + /// Documented field + y: i32, + + // Macroed field + #[cfg(test)] + z: i32, + } + + // A macroed Struct + #[cfg(test)] + struct MacroedStruct { + // Normal field + x: i32, + + /// Documented field + y: i32, + + // Macroed field + #[cfg(test)] + z: i32, + } + + // A normal Struct + struct NormalStruct { + // Normal field + x: i32, + + /// Documented field + y: i32, + + // Macroed field + #[cfg(test)] + z: i32, + } + + /// A documented type + type DocumentedType = i32; + + // A macroed type + #[cfg(test)] + type MacroedType = i32; + + /// A module to move + mod module {} + + /// An impl to move + impl NormalStruct { + /// A method + fn new() {} + } + + /// A documented trait + trait DocTrait { + /// Inner function + fn doc() {} + } + + /// An enum + enum DocumentedEnum { + /// A variant + A, + /// Another variant + B { x: i32, y: i32 } + } + + /// Documented const + const MY_CONST: i32 = 0;$0 + ", + r" + mod modname { + /// A documented function + pub(crate) fn documented_fn() {} + + // A commented function with a #[] attribute macro + #[cfg(test)] + pub(crate) fn attribute_fn() {} + + // A normally commented function + pub(crate) fn normal_fn() {} + + /// A documented Struct + pub(crate) struct DocumentedStruct { + // Normal field + pub(crate) x: i32, + + /// Documented field + pub(crate) y: i32, + + // Macroed field + #[cfg(test)] + pub(crate) z: i32, + } + + // A macroed Struct + #[cfg(test)] + pub(crate) struct MacroedStruct { + // Normal field + pub(crate) x: i32, + + /// Documented field + pub(crate) y: i32, + + // Macroed field + #[cfg(test)] + pub(crate) z: i32, + } + + // A normal Struct + pub(crate) struct NormalStruct { + // Normal field + pub(crate) x: i32, + + /// Documented field + pub(crate) y: i32, + + // Macroed field + #[cfg(test)] + pub(crate) z: i32, + } + + /// A documented type + pub(crate) type DocumentedType = i32; + + // A macroed type + #[cfg(test)] + pub(crate) type MacroedType = i32; + + /// A module to move + pub(crate) mod module {} + + /// An impl to move + impl NormalStruct { + /// A method + pub(crate) fn new() {} + } + + /// A documented trait + pub(crate) trait DocTrait { + /// Inner function + fn doc() {} + } + + /// An enum + pub(crate) enum DocumentedEnum { + /// A variant + A, + /// Another variant + B { x: i32, y: i32 } + } + + /// Documented const + pub(crate) const MY_CONST: i32 = 0; + } + ", + ) + } } |