diff options
author | John Bytheway <jbytheway@gmail.com> | 2019-01-16 22:57:50 +0000 |
---|---|---|
committer | Kim Gräsman <kim.grasman@gmail.com> | 2019-01-30 20:50:20 +0100 |
commit | 6e4330dfcf36c3c2b9a7f2dfa02df6081bd4f868 (patch) | |
tree | 0761965dee615e4924a00029c9996fe71b2dfe9a | |
parent | 4c7fa216ac12d8d81f8be9fb79710c128e8b3c25 (diff) |
Better fix_includes handling of template lines
When multiple forward declarations were present of the form:
template<typename T>
class Foo;
fix_includes.py would consider the multiple 'template<typename T>'
lines to be duplicates and delete all but one.
Fix that, and add a test for it.
-rwxr-xr-x | fix_includes.py | 22 | ||||
-rwxr-xr-x | fix_includes_test.py | 66 |
2 files changed, 77 insertions, 11 deletions
diff --git a/fix_includes.py b/fix_includes.py index cf9e9e5..c696e3f 100755 --- a/fix_includes.py +++ b/fix_includes.py @@ -1124,6 +1124,8 @@ def _DeleteDuplicateLines(file_lines, line_ranges): particular, it should not cover lines that may have C literal strings in them. + We only delete whole move_spans, not lines within them. + Arguments: file_lines: an array of LineInfo objects. line_ranges: a list of [start_line, end_line) pairs. @@ -1131,13 +1133,21 @@ def _DeleteDuplicateLines(file_lines, line_ranges): seen_lines = set() for line_range in line_ranges: for line_number in range(*line_range): - if file_lines[line_number].type in (_BLANK_LINE_RE, _COMMENT_LINE_RE): + line_info = file_lines[line_number] + if line_info.type in (_BLANK_LINE_RE, _COMMENT_LINE_RE): + continue + if line_number != line_info.move_span[0]: continue - uncommented_line = _COMMENT_RE.sub('', file_lines[line_number].line) - if uncommented_line in seen_lines: - file_lines[line_number].deleted = True - elif not file_lines[line_number].deleted: - seen_lines.add(uncommented_line) + span_line_numbers = range(line_info.move_span[0], line_info.move_span[1]) + line_infos_in_span = [file_lines[i] for i in span_line_numbers] + uncommented_lines = [ + _COMMENT_RE.sub('', inf.line.strip()) for inf in line_infos_in_span] + uncommented_span = ' '.join(uncommented_lines) + if uncommented_span in seen_lines: + for info in line_infos_in_span: + info.deleted = True + elif not line_info.deleted: + seen_lines.add(uncommented_span) def _DeleteExtraneousBlankLines(file_lines, line_range): diff --git a/fix_includes_test.py b/fix_includes_test.py index 09ffb69..1592b7c 100755 --- a/fix_includes_test.py +++ b/fix_includes_test.py @@ -2810,7 +2810,7 @@ The full include-list for comments_with_includes: self.RegisterFileContents({'comments_with_includes': infile}) self.ProcessAndTest(iwyu_output) - def testRemoveDuplicates(self): + def testRemoveDuplicateIncludes(self): """Tests we uniquify if an #include is in there twice.""" infile = """\ // Copyright 2010 @@ -2830,19 +2830,75 @@ The full include-list for comments_with_includes: int main() { return 0; } """ iwyu_output = """\ -remove_duplicates should add these lines: +remove_duplicate_includes should add these lines: #include <stdio.h> -remove_duplicates should remove these lines: +remove_duplicate_includes should remove these lines: - #include <notused.h> // lines 3-3 -The full include-list for remove_duplicates: +The full include-list for remove_duplicate_includes: #include <stdio.h> #include "used.h" #include "used2.h" --- """ - self.RegisterFileContents({'remove_duplicates': infile}) + self.RegisterFileContents({'remove_duplicate_includes': infile}) + self.ProcessAndTest(iwyu_output) + + def testRemoveDuplicateForwardDeclarations(self): + """Tests we uniquify if an #include is in there twice.""" + infile = """\ +#include <notused.h> ///- +class A; +template<typename T> // Comment in the middle not a problem +class B; +class A; ///- +template<typename T> ///- +class B; ///- +template<typename T> class B; ///- + +int main() { return 0; } +""" + iwyu_output = """\ +remove_duplicate_forward_declarations should add these lines: + +remove_duplicate_forward_declarations should remove these lines: +- #include <notused.h> // lines 1-1 + +The full include-list for remove_duplicate_forward_declarations: +class A; // lines 2-2 +template <typename T> class B; // lines 3-4 +class A; // lines 5-5 +template <typename T> class B; // lines 6-7 +template <typename T> class B; // lines 8-8 +--- +""" + self.RegisterFileContents({'remove_duplicate_forward_declarations': infile}) + self.ProcessAndTest(iwyu_output) + + def testDontRemoveTemplateLines(self): + """Tests we don't accidentally think repeated template lines are dupes.""" + infile = """\ +#include <notused.h> ///- +template<typename T> +class A; +template<typename T> +class B; + +void f(A&, B&); +""" + iwyu_output = """\ +dont_remove_template_lines should add these lines: + +dont_remove_template_lines should remove these lines: +- #include <notused.h> // lines 1-1 + +The full include-list for dont_remove_template_lines: +template <typename T> class A; // lines 2-3 +template <typename T> class B; // lines 4-5 +--- +""" + self.RegisterFileContents({'dont_remove_template_lines': infile}) self.ProcessAndTest(iwyu_output) def testNestedNamespaces(self): |