mirror of
https://github.com/servo/servo.git
synced 2025-07-22 06:43:40 +01:00
Make tidy aware of Rust multiline strings
As a result of tighter and more correct handling of character literals, this now catches a few kinds of syntax involving lifetimes that were previously missed, so those have been updated.
This commit is contained in:
parent
5c797d1943
commit
c9dafda03a
6 changed files with 55 additions and 15 deletions
|
@ -137,7 +137,7 @@ impl<'a> InorderFlowTraversal for ResolveGeneratedContent<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The object that mutates the generated content fragments.
|
/// The object that mutates the generated content fragments.
|
||||||
struct ResolveGeneratedContentFragmentMutator<'a,'b:'a> {
|
struct ResolveGeneratedContentFragmentMutator<'a, 'b: 'a> {
|
||||||
/// The traversal.
|
/// The traversal.
|
||||||
traversal: &'a mut ResolveGeneratedContent<'b>,
|
traversal: &'a mut ResolveGeneratedContent<'b>,
|
||||||
/// The level we're at in the flow tree.
|
/// The level we're at in the flow tree.
|
||||||
|
@ -148,7 +148,7 @@ struct ResolveGeneratedContentFragmentMutator<'a,'b:'a> {
|
||||||
incremented: bool,
|
incremented: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
|
impl<'a, 'b> ResolveGeneratedContentFragmentMutator<'a, 'b> {
|
||||||
fn mutate_fragment(&mut self, fragment: &mut Fragment) {
|
fn mutate_fragment(&mut self, fragment: &mut Fragment) {
|
||||||
// We only reset and/or increment counters once per flow. This avoids double-incrementing
|
// We only reset and/or increment counters once per flow. This avoids double-incrementing
|
||||||
// counters on list items (once for the main fragment and once for the marker).
|
// counters on list items (once for the main fragment and once for the marker).
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl<T> Clone for PersistentList<T> where T: Send + Sync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PersistentListIterator<'a,T> where T: 'a + Send + Sync {
|
pub struct PersistentListIterator<'a, T> where T: 'a + Send + Sync {
|
||||||
entry: Option<&'a PersistentListEntry<T>>,
|
entry: Option<&'a PersistentListEntry<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -163,7 +163,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnrootedPass {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FnDefVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
|
struct FnDefVisitor<'a, 'b: 'a, 'tcx: 'a + 'b> {
|
||||||
cx: &'a LateContext<'b, 'tcx>,
|
cx: &'a LateContext<'b, 'tcx>,
|
||||||
in_new_function: bool,
|
in_new_function: bool,
|
||||||
}
|
}
|
||||||
|
|
|
@ -467,15 +467,6 @@ def check_rust(file_name, lines):
|
||||||
prev_indent = indent
|
prev_indent = indent
|
||||||
indent = len(original_line) - len(line)
|
indent = len(original_line) - len(line)
|
||||||
|
|
||||||
# Hack for components/selectors/build.rs
|
|
||||||
if multi_line_string:
|
|
||||||
if line.startswith('"#'):
|
|
||||||
multi_line_string = False
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
if line.endswith('r#"'):
|
|
||||||
multi_line_string = True
|
|
||||||
|
|
||||||
is_attribute = re.search(r"#\[.*\]", line)
|
is_attribute = re.search(r"#\[.*\]", line)
|
||||||
is_comment = re.search(r"^//|^/\*|^\*", line)
|
is_comment = re.search(r"^//|^/\*|^\*", line)
|
||||||
|
|
||||||
|
@ -494,6 +485,14 @@ def check_rust(file_name, lines):
|
||||||
line = merged_lines + line
|
line = merged_lines + line
|
||||||
merged_lines = ''
|
merged_lines = ''
|
||||||
|
|
||||||
|
if multi_line_string:
|
||||||
|
line, count = re.subn(
|
||||||
|
r'^(\\.|[^"\\])*?"', '', line, count=1)
|
||||||
|
if count == 1:
|
||||||
|
multi_line_string = False
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
|
||||||
# Ignore attributes, comments, and imports
|
# Ignore attributes, comments, and imports
|
||||||
# Keep track of whitespace to enable checking for a merged import block
|
# Keep track of whitespace to enable checking for a merged import block
|
||||||
if import_block:
|
if import_block:
|
||||||
|
@ -504,9 +503,17 @@ def check_rust(file_name, lines):
|
||||||
import_block = False
|
import_block = False
|
||||||
|
|
||||||
# get rid of strings and chars because cases like regex expression, keep attributes
|
# get rid of strings and chars because cases like regex expression, keep attributes
|
||||||
if not is_attribute:
|
if not is_attribute and not is_comment:
|
||||||
line = re.sub(r'"(\\.|[^\\"])*?"', '""', line)
|
line = re.sub(r'"(\\.|[^\\"])*?"', '""', line)
|
||||||
line = re.sub(r"'(\\.|[^\\'])*?'", "''", line)
|
line = re.sub(
|
||||||
|
r"'(\\.|[^\\']|(\\x[0-9a-fA-F]{2})|(\\u{[0-9a-fA-F]{1,6}}))'",
|
||||||
|
"''", line)
|
||||||
|
# If, after parsing all single-line strings, we still have
|
||||||
|
# an odd number of double quotes, this line starts a
|
||||||
|
# multiline string
|
||||||
|
if line.count('"') % 2 == 1:
|
||||||
|
line = re.sub(r'"(\\.|[^\\"])*?$', '""', line)
|
||||||
|
multi_line_string = True
|
||||||
|
|
||||||
# get rid of comments
|
# get rid of comments
|
||||||
line = re.sub('//.*?$|/\*.*?$|^\*.*?$', '//', line)
|
line = re.sub('//.*?$|/\*.*?$|^\*.*?$', '//', line)
|
||||||
|
|
28
python/tidy/servo_tidy_tests/multiline_string.rs
Normal file
28
python/tidy/servo_tidy_tests/multiline_string.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
|
||||||
|
// This puts a "multi-line string
|
||||||
|
// inside of a comment" and then subsequently has a hyphenated-phrase
|
||||||
|
|
||||||
|
|
||||||
|
const FOO: &'static str = "Do not confuse 'apostrophes',
|
||||||
|
They can be 'lifetimes' or 'characters'";
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert!(foo("test
|
||||||
|
foo-bar"));
|
||||||
|
|
||||||
|
assert!(foo("test
|
||||||
|
test2 \"
|
||||||
|
foo-bar"));
|
||||||
|
|
||||||
|
assert!(foo("test
|
||||||
|
test2 \
|
||||||
|
foo-bar"));
|
||||||
|
|
||||||
|
println!("This is a multiline string with a URL, which kinda, \
|
||||||
|
sorta looks like a comment https://github.com/servo/servo/");
|
||||||
|
}
|
|
@ -266,6 +266,11 @@ class CheckTidiness(unittest.TestCase):
|
||||||
lst = list(file_list)
|
lst = list(file_list)
|
||||||
self.assertEqual([os.path.join(base_path, 'whee', 'test.rs')], lst)
|
self.assertEqual([os.path.join(base_path, 'whee', 'test.rs')], lst)
|
||||||
|
|
||||||
|
def test_multiline_string(self):
|
||||||
|
errors = tidy.collect_errors_for_files(iterFile('multiline_string.rs'), [], [tidy.check_rust], print_text=True)
|
||||||
|
self.assertNoMoreErrors(errors)
|
||||||
|
|
||||||
|
|
||||||
def do_tests():
|
def do_tests():
|
||||||
suite = unittest.TestLoader().loadTestsFromTestCase(CheckTidiness)
|
suite = unittest.TestLoader().loadTestsFromTestCase(CheckTidiness)
|
||||||
return 0 if unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() else 1
|
return 0 if unittest.TextTestRunner(verbosity=2).run(suite).wasSuccessful() else 1
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue