Apply edits

This commit is contained in:
John Renner 2021-03-01 11:41:22 -08:00
parent 9eecba4dbf
commit f5cde97aae

View file

@ -1,8 +1,14 @@
use ast::{Comment, CommentShape};
use itertools::Itertools; use itertools::Itertools;
use std::convert::identity; use std::convert::identity;
use syntax::{ use syntax::{
ast::{self, edit::IndentLevel, CommentKind, Whitespace}, ast::{
self,
edit::IndentLevel,
Comment, CommentKind,
CommentPlacement::{Inner, Outer},
CommentShape::{self, Block, Line},
Whitespace,
},
AstToken, Direction, SyntaxElement, TextRange, AstToken, Direction, SyntaxElement, TextRange,
}; };
@ -42,6 +48,13 @@ pub(crate) fn convert_comment_block(acc: &mut Assists, ctx: &AssistContext) -> O
} }
fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> { fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
let target = comment.syntax().text_range();
acc.add(
AssistId("block_to_line", AssistKind::RefactorRewrite),
"Replace block comment with line comments",
target,
|edit| {
let indentation = IndentLevel::from_token(comment.syntax()); let indentation = IndentLevel::from_token(comment.syntax());
let line_prefix = let line_prefix =
comment_kind_prefix(CommentKind { shape: CommentShape::Line, ..comment.kind() }); comment_kind_prefix(CommentKind { shape: CommentShape::Line, ..comment.kind() });
@ -64,12 +77,8 @@ fn block_to_line(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
}) })
.join(&format!("\n{}", indent_spaces)); .join(&format!("\n{}", indent_spaces));
let target = comment.syntax().text_range(); edit.replace(target, output)
acc.add( },
AssistId("block_to_line", AssistKind::RefactorRewrite),
"Replace block comment with line comments",
target,
|edit| edit.replace(target, output),
) )
} }
@ -83,6 +92,11 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
comments.last().unwrap().syntax().text_range().end(), comments.last().unwrap().syntax().text_range().end(),
); );
acc.add(
AssistId("line_to_block", AssistKind::RefactorRewrite),
"Replace line comments with a single block comment",
target,
|edit| {
// We pick a single indentation level for the whole block comment based on the // We pick a single indentation level for the whole block comment based on the
// comment where the assist was invoked. This will be prepended to the // comment where the assist was invoked. This will be prepended to the
// contents of each line comment when they're put into the block comment. // contents of each line comment when they're put into the block comment.
@ -94,13 +108,11 @@ fn line_to_block(acc: &mut Assists, comment: ast::Comment) -> Option<()> {
let block_prefix = let block_prefix =
comment_kind_prefix(CommentKind { shape: CommentShape::Block, ..comment.kind() }); comment_kind_prefix(CommentKind { shape: CommentShape::Block, ..comment.kind() });
let output = format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation.to_string()); let output =
format!("{}\n{}\n{}*/", block_prefix, block_comment_body, indentation.to_string());
acc.add( edit.replace(target, output)
AssistId("line_to_block", AssistKind::RefactorRewrite), },
"Replace line comments with a single block comment",
target,
|edit| edit.replace(target, output),
) )
} }
@ -160,27 +172,18 @@ fn relevant_line_comments(comment: &ast::Comment) -> Vec<Comment> {
// //
// But since such comments aren't idiomatic we're okay with this. // But since such comments aren't idiomatic we're okay with this.
fn line_comment_text(indentation: IndentLevel, comm: ast::Comment) -> String { fn line_comment_text(indentation: IndentLevel, comm: ast::Comment) -> String {
let contents = trim_one(comm.text().strip_prefix(comm.prefix()).unwrap()).to_owned(); let contents_without_prefix = comm.text().strip_prefix(comm.prefix()).unwrap();
let contents = contents_without_prefix.strip_prefix(' ').unwrap_or(contents_without_prefix);
// Don't add the indentation if the line is empty // Don't add the indentation if the line is empty
if contents.is_empty() { if contents.is_empty() {
contents contents.to_owned()
} else { } else {
indentation.to_string() + &contents indentation.to_string() + &contents
} }
} }
fn trim_one(text: &str) -> &str {
if text.starts_with(' ') {
&text[1..]
} else {
text
}
}
fn comment_kind_prefix(ck: ast::CommentKind) -> &'static str { fn comment_kind_prefix(ck: ast::CommentKind) -> &'static str {
use ast::CommentPlacement::{Inner, Outer};
use ast::CommentShape::{Block, Line};
match (ck.shape, ck.doc) { match (ck.shape, ck.doc) {
(Line, Some(Inner)) => "//!", (Line, Some(Inner)) => "//!",
(Line, Some(Outer)) => "///", (Line, Some(Outer)) => "///",