-
Notifications
You must be signed in to change notification settings - Fork 0
fix: Return explicit error when dependent rule is not found during deserialization #103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
37e86fc
edc574e
3504b87
3620b09
a79e527
64f71ee
7e04537
71a2b4e
37e8317
d8783ba
c148107
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,23 +30,13 @@ extend-ignore-identifiers-re = [ | |
| "prev", | ||
| "normalises", | ||
| "goes", | ||
| "Bare", | ||
| "inout", | ||
| "ba", | ||
| "ede", | ||
| ] | ||
|
|
||
| [default.extend-words] | ||
| Bare = "Bare" | ||
| Supress = "Supress" | ||
| teh = "teh" | ||
| Teh = "Teh" | ||
|
|
||
| [files] | ||
| ignore-hidden = false | ||
| ignore-files = true | ||
| extend-exclude = [ | ||
| "CHANGELOG.md", | ||
| "./CHANGELOG.md", | ||
| "/usr/**/*", | ||
| "/tmp/**/*", | ||
|
Comment on lines
38
to
41
|
||
| "/**/node_modules/**", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -101,9 +101,6 @@ fn get_new_line<C: Content>() -> C::Underlying { | |
| fn get_space<C: Content>() -> C::Underlying { | ||
| C::decode_str(" ")[0].clone() | ||
| } | ||
| fn get_tab<C: Content>() -> C::Underlying { | ||
| C::decode_str("\t")[0].clone() | ||
| } | ||
|
|
||
| const MAX_LOOK_AHEAD: usize = 512; | ||
|
|
||
|
|
@@ -186,16 +183,21 @@ pub fn formatted_slice<'a, C: Content>( | |
| if !slice.contains(&get_new_line::<C>()) { | ||
| return Cow::Borrowed(slice); | ||
| } | ||
| let (indent, is_tab) = get_indent_at_offset_with_tab::<C>(content.get_range(0..start)); | ||
| Cow::Owned( | ||
| indent_lines::<C>(0, &DeindentedExtract::MultiLine(slice, indent), is_tab).into_owned(), | ||
| indent_lines::<C>( | ||
| 0, | ||
| &DeindentedExtract::MultiLine( | ||
| slice, | ||
| get_indent_at_offset::<C>(content.get_range(0..start)), | ||
| ), | ||
| ) | ||
| .into_owned(), | ||
| ) | ||
| } | ||
|
|
||
| pub fn indent_lines<'a, C: Content>( | ||
| indent: usize, | ||
| extract: &'a DeindentedExtract<'a, C>, | ||
| is_tab: bool, | ||
| ) -> Cow<'a, [C::Underlying]> { | ||
| use DeindentedExtract::{MultiLine, SingleLine}; | ||
| let (lines, original_indent) = match extract { | ||
|
|
@@ -211,27 +213,18 @@ pub fn indent_lines<'a, C: Content>( | |
| Ordering::Less => Cow::Owned(indent_lines_impl::<C, _>( | ||
| indent - original_indent, | ||
| lines.split(|b| *b == get_new_line::<C>()), | ||
| is_tab, | ||
| )), | ||
| } | ||
| } | ||
|
|
||
| fn indent_lines_impl<'a, C, Lines>( | ||
| indent: usize, | ||
| mut lines: Lines, | ||
| is_tab: bool, | ||
| ) -> Vec<C::Underlying> | ||
| fn indent_lines_impl<'a, C, Lines>(indent: usize, mut lines: Lines) -> Vec<C::Underlying> | ||
| where | ||
| C: Content + 'a, | ||
| Lines: Iterator<Item = &'a [C::Underlying]>, | ||
| { | ||
| let mut ret = vec![]; | ||
| let indent_char = if is_tab { | ||
| get_tab::<C>() | ||
| } else { | ||
| get_space::<C>() | ||
| }; | ||
| let leading: Vec<_> = std::iter::repeat_n(indent_char, indent).collect(); | ||
| let space = get_space::<C>(); | ||
| let leading: Vec<_> = std::iter::repeat_n(space, indent).collect(); | ||
| // first line wasn't indented, so we don't add leading spaces | ||
| if let Some(line) = lines.next() { | ||
| ret.extend(line.iter().cloned()); | ||
|
|
@@ -248,62 +241,40 @@ where | |
| /// returns 0 if no indent is found before the offset | ||
| /// either truly no indent exists, or the offset is in a long line | ||
| pub fn get_indent_at_offset<C: Content>(src: &[C::Underlying]) -> usize { | ||
| get_indent_at_offset_with_tab::<C>(src).0 | ||
| } | ||
|
|
||
| /// returns (indent, `is_tab`) | ||
| pub fn get_indent_at_offset_with_tab<C: Content>(src: &[C::Underlying]) -> (usize, bool) { | ||
| let lookahead = src.len().max(MAX_LOOK_AHEAD) - MAX_LOOK_AHEAD; | ||
|
|
||
| let mut indent = 0; | ||
| let mut is_tab = false; | ||
| let new_line = get_new_line::<C>(); | ||
| let space = get_space::<C>(); | ||
| let tab = get_tab::<C>(); | ||
| // TODO: support TAB. only whitespace is supported now | ||
| for c in src[lookahead..].iter().rev() { | ||
| if *c == new_line { | ||
| return (indent, is_tab); | ||
| return indent; | ||
| } | ||
| if *c == space { | ||
| indent += 1; | ||
| } else if *c == tab { | ||
| indent += 1; | ||
| is_tab = true; | ||
| } else { | ||
| indent = 0; | ||
| is_tab = false; | ||
| } | ||
| } | ||
| // lookahead == 0 means we have indentation at first line. | ||
| if lookahead == 0 && indent != 0 { | ||
| (indent, is_tab) | ||
| indent | ||
| } else { | ||
| (0, false) | ||
| 0 | ||
| } | ||
| } | ||
|
|
||
| // NOTE: we assume input is well indented. | ||
| // following lines should have fewer indentations than initial line | ||
| fn remove_indent<C: Content>(indent: usize, src: &[C::Underlying]) -> Vec<C::Underlying> { | ||
| let indentation: Vec<_> = std::iter::repeat_n(get_space::<C>(), indent).collect(); | ||
| let new_line = get_new_line::<C>(); | ||
| let space = get_space::<C>(); | ||
| let tab = get_tab::<C>(); | ||
| let lines: Vec<_> = src | ||
| .split(|b| *b == new_line) | ||
| .map(|line| { | ||
| let mut stripped = line; | ||
| let mut count = 0; | ||
| while count < indent { | ||
| if let Some(rest) = stripped.strip_prefix(std::slice::from_ref(&space)) { | ||
| stripped = rest; | ||
| } else if let Some(rest) = stripped.strip_prefix(std::slice::from_ref(&tab)) { | ||
| stripped = rest; | ||
| } else { | ||
| break; | ||
| } | ||
| count += 1; | ||
| } | ||
| stripped | ||
| .map(|line| match line.strip_prefix(&*indentation) { | ||
| Some(stripped) => stripped, | ||
|
Comment on lines
243
to
+276
|
||
| None => line, | ||
| }) | ||
| .collect(); | ||
| lines.join(&new_line).clone() | ||
|
|
@@ -328,7 +299,7 @@ mod test { | |
| .count(); | ||
| let end = source.chars().count() - trailing_white; | ||
| let extracted = extract_with_deindent(&source, start..end); | ||
| let result_bytes = indent_lines::<String>(0, &extracted, source.contains('\t')); | ||
| let result_bytes = indent_lines::<String>(0, &extracted); | ||
| let actual = std::str::from_utf8(&result_bytes).unwrap(); | ||
| assert_eq!(actual, expected); | ||
| } | ||
|
|
@@ -420,8 +391,8 @@ pass | |
| fn test_replace_with_indent(target: &str, start: usize, inserted: &str) -> String { | ||
| let target = target.to_string(); | ||
| let replace_lines = DeindentedExtract::MultiLine(inserted.as_bytes(), 0); | ||
| let (indent, is_tab) = get_indent_at_offset_with_tab::<String>(&target.as_bytes()[..start]); | ||
| let ret = indent_lines::<String>(indent, &replace_lines, is_tab); | ||
| let indent = get_indent_at_offset::<String>(&target.as_bytes()[..start]); | ||
| let ret = indent_lines::<String>(indent, &replace_lines); | ||
| String::from_utf8(ret.to_vec()).unwrap() | ||
| } | ||
|
|
||
|
|
@@ -474,26 +445,4 @@ pass | |
| let actual = test_replace_with_indent(target, 6, inserted); | ||
| assert_eq!(actual, "def abc():\n pass"); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_tab_indent() { | ||
| let src = "\n\t\tdef test():\n\t\t\tpass"; | ||
| let expected = "def test():\n\tpass"; | ||
| test_deindent(src, expected, 0); | ||
| } | ||
|
|
||
| #[test] | ||
| fn test_tab_replace() { | ||
| let target = "\t\t"; | ||
| let inserted = "def abc(): pass"; | ||
| let actual = test_replace_with_indent(target, 2, inserted); | ||
| assert_eq!(actual, "def abc(): pass"); | ||
| let inserted = "def abc():\n\tpass"; | ||
| let actual = test_replace_with_indent(target, 2, inserted); | ||
| assert_eq!(actual, "def abc():\n\t\t\tpass"); | ||
|
|
||
| let target = "\t\tdef abc():\n\t\t\t"; | ||
| let actual = test_replace_with_indent(target, 14, inserted); | ||
| assert_eq!(actual, "def abc():\n\t\tpass"); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_typos.tomlremoved the identifier ignore forinout, but this PR also introduces"inout"intoclassifications/_universal_rules.json. Iftyposdoesn't treatinoutas a valid word/identifier, CI will start failing. Consider keepinginoutinextend-ignore-identifiers-reor adding it to allowed words to match the repository's actual vocabulary.