recognize strings inside comments in order to avoid indenting them
Close #3270
This commit is contained in:
parent
2c204c11d1
commit
baa62c609e
7 changed files with 114 additions and 38 deletions
|
|
@ -1029,21 +1029,28 @@ impl RichChar for (usize, char) {
|
||||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||||
enum CharClassesStatus {
|
enum CharClassesStatus {
|
||||||
Normal,
|
Normal,
|
||||||
|
/// Character is within a string
|
||||||
LitString,
|
LitString,
|
||||||
LitStringEscape,
|
LitStringEscape,
|
||||||
|
/// Character is within a raw string
|
||||||
LitRawString(u32),
|
LitRawString(u32),
|
||||||
RawStringPrefix(u32),
|
RawStringPrefix(u32),
|
||||||
RawStringSuffix(u32),
|
RawStringSuffix(u32),
|
||||||
LitChar,
|
LitChar,
|
||||||
LitCharEscape,
|
LitCharEscape,
|
||||||
// The u32 is the nesting deepness of the comment
|
/// Character inside a block comment, with the integer indicating the nesting deepness of the
|
||||||
|
/// comment
|
||||||
BlockComment(u32),
|
BlockComment(u32),
|
||||||
// Status when the '/' has been consumed, but not yet the '*', deepness is
|
/// Character inside a block-commented string, with the integer indicating the nesting deepness
|
||||||
// the new deepness (after the comment opening).
|
/// of the comment
|
||||||
|
StringInBlockComment(u32),
|
||||||
|
/// Status when the '/' has been consumed, but not yet the '*', deepness is
|
||||||
|
/// the new deepness (after the comment opening).
|
||||||
BlockCommentOpening(u32),
|
BlockCommentOpening(u32),
|
||||||
// Status when the '*' has been consumed, but not yet the '/', deepness is
|
/// Status when the '*' has been consumed, but not yet the '/', deepness is
|
||||||
// the new deepness (after the comment closing).
|
/// the new deepness (after the comment closing).
|
||||||
BlockCommentClosing(u32),
|
BlockCommentClosing(u32),
|
||||||
|
/// Character is within a line comment
|
||||||
LineComment,
|
LineComment,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1067,6 +1074,12 @@ pub enum FullCodeCharKind {
|
||||||
InComment,
|
InComment,
|
||||||
/// Last character of a comment, '\n' for a line comment, '/' for a block comment.
|
/// Last character of a comment, '\n' for a line comment, '/' for a block comment.
|
||||||
EndComment,
|
EndComment,
|
||||||
|
/// Start of a mutlitine string inside a comment
|
||||||
|
StartStringCommented,
|
||||||
|
/// End of a mutlitine string inside a comment
|
||||||
|
EndStringCommented,
|
||||||
|
/// Inside a commented string
|
||||||
|
InStringCommented,
|
||||||
/// Start of a mutlitine string
|
/// Start of a mutlitine string
|
||||||
StartString,
|
StartString,
|
||||||
/// End of a mutlitine string
|
/// End of a mutlitine string
|
||||||
|
|
@ -1080,7 +1093,21 @@ impl FullCodeCharKind {
|
||||||
match self {
|
match self {
|
||||||
FullCodeCharKind::StartComment
|
FullCodeCharKind::StartComment
|
||||||
| FullCodeCharKind::InComment
|
| FullCodeCharKind::InComment
|
||||||
| FullCodeCharKind::EndComment => true,
|
| FullCodeCharKind::EndComment
|
||||||
|
| FullCodeCharKind::StartStringCommented
|
||||||
|
| FullCodeCharKind::InStringCommented
|
||||||
|
| FullCodeCharKind::EndStringCommented => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the character is inside a comment
|
||||||
|
pub fn inside_comment(self) -> bool {
|
||||||
|
match self {
|
||||||
|
FullCodeCharKind::InComment
|
||||||
|
| FullCodeCharKind::StartStringCommented
|
||||||
|
| FullCodeCharKind::InStringCommented
|
||||||
|
| FullCodeCharKind::EndStringCommented => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1089,6 +1116,12 @@ impl FullCodeCharKind {
|
||||||
self == FullCodeCharKind::InString || self == FullCodeCharKind::StartString
|
self == FullCodeCharKind::InString || self == FullCodeCharKind::StartString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the character is within a commented string
|
||||||
|
pub fn is_commented_string(self) -> bool {
|
||||||
|
self == FullCodeCharKind::InStringCommented
|
||||||
|
|| self == FullCodeCharKind::StartStringCommented
|
||||||
|
}
|
||||||
|
|
||||||
fn to_codecharkind(self) -> CodeCharKind {
|
fn to_codecharkind(self) -> CodeCharKind {
|
||||||
if self.is_comment() {
|
if self.is_comment() {
|
||||||
CodeCharKind::Comment
|
CodeCharKind::Comment
|
||||||
|
|
@ -1232,18 +1265,27 @@ where
|
||||||
},
|
},
|
||||||
_ => CharClassesStatus::Normal,
|
_ => CharClassesStatus::Normal,
|
||||||
},
|
},
|
||||||
|
CharClassesStatus::StringInBlockComment(deepness) => {
|
||||||
|
char_kind = FullCodeCharKind::InStringCommented;
|
||||||
|
if chr == '"' {
|
||||||
|
CharClassesStatus::BlockComment(deepness)
|
||||||
|
} else {
|
||||||
|
CharClassesStatus::StringInBlockComment(deepness)
|
||||||
|
}
|
||||||
|
}
|
||||||
CharClassesStatus::BlockComment(deepness) => {
|
CharClassesStatus::BlockComment(deepness) => {
|
||||||
assert_ne!(deepness, 0);
|
assert_ne!(deepness, 0);
|
||||||
self.status = match self.base.peek() {
|
char_kind = FullCodeCharKind::InComment;
|
||||||
|
match self.base.peek() {
|
||||||
Some(next) if next.get_char() == '/' && chr == '*' => {
|
Some(next) if next.get_char() == '/' && chr == '*' => {
|
||||||
CharClassesStatus::BlockCommentClosing(deepness - 1)
|
CharClassesStatus::BlockCommentClosing(deepness - 1)
|
||||||
}
|
}
|
||||||
Some(next) if next.get_char() == '*' && chr == '/' => {
|
Some(next) if next.get_char() == '*' && chr == '/' => {
|
||||||
CharClassesStatus::BlockCommentOpening(deepness + 1)
|
CharClassesStatus::BlockCommentOpening(deepness + 1)
|
||||||
}
|
}
|
||||||
_ => CharClassesStatus::BlockComment(deepness),
|
_ if chr == '"' => CharClassesStatus::StringInBlockComment(deepness),
|
||||||
};
|
_ => self.status,
|
||||||
return Some((FullCodeCharKind::InComment, item));
|
}
|
||||||
}
|
}
|
||||||
CharClassesStatus::BlockCommentOpening(deepness) => {
|
CharClassesStatus::BlockCommentOpening(deepness) => {
|
||||||
assert_eq!(chr, '*');
|
assert_eq!(chr, '*');
|
||||||
|
|
@ -1299,26 +1341,33 @@ impl<'a> Iterator for LineClasses<'a> {
|
||||||
|
|
||||||
let mut line = String::new();
|
let mut line = String::new();
|
||||||
|
|
||||||
let start_class = match self.base.peek() {
|
let start_kind = match self.base.peek() {
|
||||||
Some((kind, _)) => *kind,
|
Some((kind, _)) => *kind,
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
while let Some((kind, c)) = self.base.next() {
|
while let Some((kind, c)) = self.base.next() {
|
||||||
|
// needed to set the kind of the ending character on the last line
|
||||||
|
self.kind = kind;
|
||||||
if c == '\n' {
|
if c == '\n' {
|
||||||
self.kind = match (start_class, kind) {
|
self.kind = match (start_kind, kind) {
|
||||||
(FullCodeCharKind::Normal, FullCodeCharKind::InString) => {
|
(FullCodeCharKind::Normal, FullCodeCharKind::InString) => {
|
||||||
FullCodeCharKind::StartString
|
FullCodeCharKind::StartString
|
||||||
}
|
}
|
||||||
(FullCodeCharKind::InString, FullCodeCharKind::Normal) => {
|
(FullCodeCharKind::InString, FullCodeCharKind::Normal) => {
|
||||||
FullCodeCharKind::EndString
|
FullCodeCharKind::EndString
|
||||||
}
|
}
|
||||||
|
(FullCodeCharKind::InComment, FullCodeCharKind::InStringCommented) => {
|
||||||
|
FullCodeCharKind::StartStringCommented
|
||||||
|
}
|
||||||
|
(FullCodeCharKind::InStringCommented, FullCodeCharKind::InComment) => {
|
||||||
|
FullCodeCharKind::EndStringCommented
|
||||||
|
}
|
||||||
_ => kind,
|
_ => kind,
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
line.push(c);
|
|
||||||
}
|
}
|
||||||
|
line.push(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Workaround for CRLF newline.
|
// Workaround for CRLF newline.
|
||||||
|
|
@ -1364,7 +1413,12 @@ impl<'a> Iterator for UngroupedCommentCodeSlices<'a> {
|
||||||
}
|
}
|
||||||
FullCodeCharKind::StartComment => {
|
FullCodeCharKind::StartComment => {
|
||||||
// Consume the whole comment
|
// Consume the whole comment
|
||||||
while let Some((FullCodeCharKind::InComment, (_, _))) = self.iter.next() {}
|
loop {
|
||||||
|
match self.iter.next() {
|
||||||
|
Some((kind, ..)) if kind.inside_comment() => continue,
|
||||||
|
_ => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
15
src/utils.rs
15
src/utils.rs
|
|
@ -527,8 +527,10 @@ pub fn trim_left_preserve_layout(orig: &str, indent: Indent, config: &Config) ->
|
||||||
Some(get_prefix_space_width(config, &line))
|
Some(get_prefix_space_width(config, &line))
|
||||||
};
|
};
|
||||||
|
|
||||||
let line = if veto_trim || (kind.is_string() && !line.ends_with('\\')) {
|
let new_veto_trim_value =
|
||||||
veto_trim = kind.is_string() && !line.ends_with('\\');
|
(kind.is_string() || kind.is_commented_string()) && !line.ends_with('\\');
|
||||||
|
let line = if veto_trim || new_veto_trim_value {
|
||||||
|
veto_trim = new_veto_trim_value;
|
||||||
trimmed = false;
|
trimmed = false;
|
||||||
line
|
line
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -536,10 +538,13 @@ pub fn trim_left_preserve_layout(orig: &str, indent: Indent, config: &Config) ->
|
||||||
};
|
};
|
||||||
trimmed_lines.push((trimmed, line, prefix_space_width));
|
trimmed_lines.push((trimmed, line, prefix_space_width));
|
||||||
|
|
||||||
// When computing the minimum, do not consider lines within a string.
|
// Because there is a veto against trimming and indenting lines within a string,
|
||||||
// The reason is there is a veto against trimming and indenting such lines
|
// such lines should not be taken into account when computing the minimum.
|
||||||
match kind {
|
match kind {
|
||||||
FullCodeCharKind::InString | FullCodeCharKind::EndString => None,
|
FullCodeCharKind::InString
|
||||||
|
| FullCodeCharKind::EndString
|
||||||
|
| FullCodeCharKind::InStringCommented
|
||||||
|
| FullCodeCharKind::EndStringCommented => None,
|
||||||
_ => prefix_space_width,
|
_ => prefix_space_width,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
fn test() {
|
|
||||||
/*
|
|
||||||
a
|
|
||||||
*/
|
|
||||||
let x = 42;
|
|
||||||
/*
|
|
||||||
aaa
|
|
||||||
"line 1
|
|
||||||
line 2
|
|
||||||
line 3"
|
|
||||||
*/
|
|
||||||
let x = 42;
|
|
||||||
}
|
|
||||||
10
tests/source/issue-3270.rs
Normal file
10
tests/source/issue-3270.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
pub fn main() {
|
||||||
|
/* let s = String::from(
|
||||||
|
"
|
||||||
|
hello
|
||||||
|
world
|
||||||
|
",
|
||||||
|
); */
|
||||||
|
|
||||||
|
assert_eq!(s, "\nhello\nworld\n");
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,10 @@ fn test() {
|
||||||
*/
|
*/
|
||||||
let x = 42;
|
let x = 42;
|
||||||
/*
|
/*
|
||||||
aaa
|
aaa
|
||||||
"line 1
|
"line 1
|
||||||
line 2
|
line 2
|
||||||
line 3"
|
line 3"
|
||||||
*/
|
*/
|
||||||
let x = 42;
|
let x = 42;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
tests/target/issue-3270-wrap.rs
Normal file
10
tests/target/issue-3270-wrap.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
// rustfmt-wrap_comments: true
|
||||||
|
|
||||||
|
fn func() {
|
||||||
|
let x = 42;
|
||||||
|
/*
|
||||||
|
let something = "one line line line line line line line line line line line line
|
||||||
|
two lines
|
||||||
|
three lines";
|
||||||
|
*/
|
||||||
|
}
|
||||||
10
tests/target/issue-3270.rs
Normal file
10
tests/target/issue-3270.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
pub fn main() {
|
||||||
|
/* let s = String::from(
|
||||||
|
"
|
||||||
|
hello
|
||||||
|
world
|
||||||
|
",
|
||||||
|
); */
|
||||||
|
|
||||||
|
assert_eq!(s, "\nhello\nworld\n");
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue