use std::{self, borrow::Cow, iter};
use itertools::{multipeek, MultiPeek};
-use syntax::source_map::Span;
+use rustc_span::Span;
use crate::config::Config;
use crate::rewrite::RewriteContext;
}
#[derive(Copy, Clone, PartialEq, Eq)]
-pub enum CommentStyle<'a> {
+pub(crate) enum CommentStyle<'a> {
DoubleSlash,
TripleSlash,
Doc,
impl<'a> CommentStyle<'a> {
/// Returns `true` if the commenting style covers a line only.
- pub fn is_line_comment(&self) -> bool {
+ pub(crate) fn is_line_comment(&self) -> bool {
match *self {
CommentStyle::DoubleSlash
| CommentStyle::TripleSlash
}
/// Returns `true` if the commenting style can span over multiple lines.
- pub fn is_block_comment(&self) -> bool {
+ pub(crate) fn is_block_comment(&self) -> bool {
match *self {
CommentStyle::SingleBullet | CommentStyle::DoubleBullet | CommentStyle::Exclamation => {
true
}
/// Returns `true` if the commenting style is for documentation.
- pub fn is_doc_comment(&self) -> bool {
+ pub(crate) fn is_doc_comment(&self) -> bool {
match *self {
CommentStyle::TripleSlash | CommentStyle::Doc => true,
_ => false,
}
}
- pub fn opener(&self) -> &'a str {
+ pub(crate) fn opener(&self) -> &'a str {
match *self {
CommentStyle::DoubleSlash => "// ",
CommentStyle::TripleSlash => "/// ",
}
}
- pub fn closer(&self) -> &'a str {
+ pub(crate) fn closer(&self) -> &'a str {
match *self {
CommentStyle::DoubleSlash
| CommentStyle::TripleSlash
| CommentStyle::Custom(..)
| CommentStyle::Doc => "",
- CommentStyle::DoubleBullet => " **/",
- CommentStyle::SingleBullet | CommentStyle::Exclamation => " */",
+ CommentStyle::SingleBullet | CommentStyle::DoubleBullet | CommentStyle::Exclamation => {
+ " */"
+ }
}
}
- pub fn line_start(&self) -> &'a str {
+ pub(crate) fn line_start(&self) -> &'a str {
match *self {
CommentStyle::DoubleSlash => "// ",
CommentStyle::TripleSlash => "/// ",
CommentStyle::Doc => "//! ",
- CommentStyle::SingleBullet | CommentStyle::Exclamation => " * ",
- CommentStyle::DoubleBullet => " ** ",
+ CommentStyle::SingleBullet | CommentStyle::DoubleBullet | CommentStyle::Exclamation => {
+ " * "
+ }
CommentStyle::Custom(opener) => opener,
}
}
- pub fn to_str_tuplet(&self) -> (&'a str, &'a str, &'a str) {
+ pub(crate) fn to_str_tuplet(&self) -> (&'a str, &'a str, &'a str) {
(self.opener(), self.closer(), self.line_start())
}
}
-fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle<'_> {
+pub(crate) fn comment_style(orig: &str, normalize_comments: bool) -> CommentStyle<'_> {
if !normalize_comments {
if orig.starts_with("/**") && !orig.starts_with("/**/") {
CommentStyle::DoubleBullet
}
/// Returns true if the last line of the passed string finishes with a block-comment.
-pub fn is_last_comment_block(s: &str) -> bool {
+pub(crate) fn is_last_comment_block(s: &str) -> bool {
s.trim_end().ends_with("*/")
}
/// recovered. If `allow_extend` is true and there is no comment between the two
/// strings, then they will be put on a single line as long as doing so does not
/// exceed max width.
-pub fn combine_strs_with_missing_comments(
+pub(crate) fn combine_strs_with_missing_comments(
context: &RewriteContext<'_>,
prev_str: &str,
next_str: &str,
Some(result)
}
-pub fn rewrite_doc_comment(orig: &str, shape: Shape, config: &Config) -> Option<String> {
+pub(crate) fn rewrite_doc_comment(orig: &str, shape: Shape, config: &Config) -> Option<String> {
identify_comment(orig, false, shape, config, true)
}
-pub fn rewrite_comment(
+pub(crate) fn rewrite_comment(
orig: &str,
block_style: bool,
shape: Shape,
trim_left_preserve_layout(first_group, shape.indent, config)?
} else if !config.normalize_comments()
&& !config.wrap_comments()
- && !config.format_doc_comments()
+ && !config.format_code_in_doc_comments()
{
light_rewrite_comment(first_group, shape.indent, config, is_doc_comment)
} else {
.checked_sub(closer.len() + opener.len())
.unwrap_or(1);
let indent_str = shape.indent.to_string_with_newline(config).to_string();
- let fmt_indent = shape.indent + (opener.len() - line_start.len());
let mut cr = CommentRewrite {
result: String::with_capacity(orig.len() * 2),
comment_line_separator: format!("{}{}", indent_str, line_start),
max_width,
indent_str,
- fmt_indent,
+ fmt_indent: shape.indent,
fmt: StringFormat {
opener: "",
closer: "",
line_start,
line_end: "",
- shape: Shape::legacy(max_width, fmt_indent),
+ shape: Shape::legacy(max_width, shape.indent),
trim_end: true,
config,
},
_ => {
let mut config = self.fmt.config.clone();
config.set().wrap_comments(false);
- match crate::format_code_block(&self.code_block_buffer, &config) {
- Some(ref s) => trim_custom_comment_prefix(&s.snippet),
- None => trim_custom_comment_prefix(&self.code_block_buffer),
+ if config.format_code_in_doc_comments() {
+ if let Some(s) =
+ crate::format_code_block(&self.code_block_buffer, &config)
+ {
+ trim_custom_comment_prefix(&s.snippet)
+ } else {
+ trim_custom_comment_prefix(&self.code_block_buffer)
+ }
+ } else {
+ trim_custom_comment_prefix(&self.code_block_buffer)
}
}
};
const RUSTFMT_CUSTOM_COMMENT_PREFIX: &str = "//#### ";
fn hide_sharp_behind_comment(s: &str) -> Cow<'_, str> {
- if s.trim_start().starts_with("# ") {
+ let s_trimmed = s.trim();
+ if s_trimmed.starts_with("# ") || s_trimmed == "#" {
Cow::from(format!("{}{}", RUSTFMT_CUSTOM_COMMENT_PREFIX, s))
} else {
Cow::from(s)
/// Given the span, rewrite the missing comment inside it if available.
/// Note that the given span must only include comments (or leading/trailing whitespaces).
-pub fn rewrite_missing_comment(
+pub(crate) fn rewrite_missing_comment(
span: Span,
shape: Shape,
context: &RewriteContext<'_>,
) -> Option<String> {
let missing_snippet = context.snippet(span);
let trimmed_snippet = missing_snippet.trim();
- if !trimmed_snippet.is_empty() {
+ // check the span starts with a comment
+ let pos = trimmed_snippet.find('/');
+ if !trimmed_snippet.is_empty() && pos.is_some() {
rewrite_comment(trimmed_snippet, false, shape, context.config)
} else {
Some(String::new())
/// Recover the missing comments in the specified span, if available.
/// The layout of the comments will be preserved as long as it does not break the code
/// and its total width does not exceed the max width.
-pub fn recover_missing_comment_in_span(
+pub(crate) fn recover_missing_comment_in_span(
span: Span,
shape: Shape,
context: &RewriteContext<'_>,
Some(String::new())
} else {
let missing_snippet = context.snippet(span);
- let pos = missing_snippet.find('/').unwrap_or(0);
+ let pos = missing_snippet.find('/')?;
// 1 = ` `
let total_width = missing_comment.len() + used_width + 1;
let force_new_line_before_comment =
}
}
-pub trait FindUncommented {
+pub(crate) trait FindUncommented {
fn find_uncommented(&self, pat: &str) -> Option<usize>;
}
// is expected to be prefixed by a comment, including delimiters.
// Good: `/* /* inner */ outer */ code();`
// Bad: `code(); // hello\n world!`
-pub fn find_comment_end(s: &str) -> Option<usize> {
+pub(crate) fn find_comment_end(s: &str) -> Option<usize> {
let mut iter = CharClasses::new(s.char_indices());
for (kind, (i, _c)) in &mut iter {
if kind == FullCodeCharKind::Normal || kind == FullCodeCharKind::InString {
}
/// Returns `true` if text contains any comment.
-pub fn contains_comment(text: &str) -> bool {
+pub(crate) fn contains_comment(text: &str) -> bool {
CharClasses::new(text.chars()).any(|(kind, _)| kind.is_comment())
}
-pub struct CharClasses<T>
+pub(crate) struct CharClasses<T>
where
T: Iterator,
T::Item: RichChar,
status: CharClassesStatus,
}
-pub trait RichChar {
+pub(crate) trait RichChar {
fn get_char(&self) -> char;
}
/// Distinguish between functional part of code and comments
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-pub enum CodeCharKind {
+pub(crate) enum CodeCharKind {
Normal,
Comment,
}
/// describing opening and closing of comments for ease when chunking
/// code from tagged characters
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
-pub enum FullCodeCharKind {
+pub(crate) enum FullCodeCharKind {
Normal,
/// The first character of a comment, there is only one for a comment (always '/')
StartComment,
}
impl FullCodeCharKind {
- pub fn is_comment(self) -> bool {
+ pub(crate) fn is_comment(self) -> bool {
match self {
FullCodeCharKind::StartComment
| FullCodeCharKind::InComment
}
/// Returns true if the character is inside a comment
- pub fn inside_comment(self) -> bool {
+ pub(crate) fn inside_comment(self) -> bool {
match self {
FullCodeCharKind::InComment
| FullCodeCharKind::StartStringCommented
}
}
- pub fn is_string(self) -> bool {
+ pub(crate) fn is_string(self) -> bool {
self == FullCodeCharKind::InString || self == FullCodeCharKind::StartString
}
/// Returns true if the character is within a commented string
- pub fn is_commented_string(self) -> bool {
+ pub(crate) fn is_commented_string(self) -> bool {
self == FullCodeCharKind::InStringCommented
|| self == FullCodeCharKind::StartStringCommented
}
T: Iterator,
T::Item: RichChar,
{
- pub fn new(base: T) -> CharClasses<T> {
+ pub(crate) fn new(base: T) -> CharClasses<T> {
CharClasses {
base: multipeek(base),
status: CharClassesStatus::Normal,
},
CharClassesStatus::LitCharEscape => CharClassesStatus::LitChar,
CharClassesStatus::Normal => match chr {
- 'r' => match self.base.peek().map(|c| c.get_char()) {
+ 'r' => match self.base.peek().map(RichChar::get_char) {
Some('#') | Some('"') => {
char_kind = FullCodeCharKind::InString;
CharClassesStatus::RawStringPrefix(0)
/// An iterator over the lines of a string, paired with the char kind at the
/// end of the line.
-pub struct LineClasses<'a> {
+pub(crate) struct LineClasses<'a> {
base: iter::Peekable<CharClasses<std::str::Chars<'a>>>,
kind: FullCodeCharKind,
}
impl<'a> LineClasses<'a> {
- pub fn new(s: &'a str) -> Self {
+ pub(crate) fn new(s: &'a str) -> Self {
LineClasses {
base: CharClasses::new(s.chars()).peekable(),
kind: FullCodeCharKind::Normal,
/// Iterator over an alternating sequence of functional and commented parts of
/// a string. The first item is always a, possibly zero length, subslice of
/// functional text. Line style comments contain their ending newlines.
-pub struct CommentCodeSlices<'a> {
+pub(crate) struct CommentCodeSlices<'a> {
slice: &'a str,
last_slice_kind: CodeCharKind,
last_slice_end: usize,
}
impl<'a> CommentCodeSlices<'a> {
- pub fn new(slice: &'a str) -> CommentCodeSlices<'a> {
+ pub(crate) fn new(slice: &'a str) -> CommentCodeSlices<'a> {
CommentCodeSlices {
slice,
last_slice_kind: CodeCharKind::Comment,
/// Checks is `new` didn't miss any comment from `span`, if it removed any, return previous text
/// (if it fits in the width/offset, else return `None`), else return `new`
-pub fn recover_comment_removed(
+pub(crate) fn recover_comment_removed(
new: String,
span: Span,
context: &RewriteContext<'_>,
// We missed some comments. Warn and keep the original text.
if context.config.error_on_unformatted() {
context.report.append(
- context.source_map.span_to_filename(span).into(),
+ context.parse_sess.span_to_filename(span),
vec![FormattingError::from_span(
span,
- &context.source_map,
+ &context.parse_sess,
ErrorKind::LostComment,
)],
);
}
}
-pub fn filter_normal_code(code: &str) -> String {
+pub(crate) fn filter_normal_code(code: &str) -> String {
let mut buffer = String::with_capacity(code.len());
LineClasses::new(code).for_each(|(kind, line)| match kind {
FullCodeCharKind::Normal