Checks for additional blank line issues related to sections. Currently the only thing checked here is blank line before protected/private. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. class_info: A _ClassInfo obj
(filename, clean_lines, class_info, linenum, error)
| 4663 | |
| 4664 | |
| 4665 | def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): |
| 4666 | """Checks for additional blank line issues related to sections. |
| 4667 | |
| 4668 | Currently the only thing checked here is blank line before protected/private. |
| 4669 | |
| 4670 | Args: |
| 4671 | filename: The name of the current file. |
| 4672 | clean_lines: A CleansedLines instance containing the file. |
| 4673 | class_info: A _ClassInfo objects. |
| 4674 | linenum: The number of the line to check. |
| 4675 | error: The function to call with any errors found. |
| 4676 | """ |
| 4677 | # Skip checks if the class is small, where small means 25 lines or less. |
| 4678 | # 25 lines seems like a good cutoff since that's the usual height of |
| 4679 | # terminals, and any class that can't fit in one screen can't really |
| 4680 | # be considered "small". |
| 4681 | # |
| 4682 | # Also skip checks if we are on the first line. This accounts for |
| 4683 | # classes that look like |
| 4684 | # class Foo { public: ... }; |
| 4685 | # |
| 4686 | # If we didn't find the end of the class, last_line would be zero, |
| 4687 | # and the check will be skipped by the first condition. |
| 4688 | if ( |
| 4689 | class_info.last_line - class_info.starting_linenum <= 24 |
| 4690 | or linenum <= class_info.starting_linenum |
| 4691 | ): |
| 4692 | return |
| 4693 | |
| 4694 | matched = re.match(r"\s*(public|protected|private):", clean_lines.lines[linenum]) |
| 4695 | if matched: |
| 4696 | # Issue warning if the line before public/protected/private was |
| 4697 | # not a blank line, but don't do this if the previous line contains |
| 4698 | # "class" or "struct". This can happen two ways: |
| 4699 | # - We are at the beginning of the class. |
| 4700 | # - We are forward-declaring an inner class that is semantically |
| 4701 | # private, but needed to be public for implementation reasons. |
| 4702 | # Also ignores cases where the previous line ends with a backslash as can be |
| 4703 | # common when defining classes in C macros. |
| 4704 | prev_line = clean_lines.lines[linenum - 1] |
| 4705 | if ( |
| 4706 | not IsBlankLine(prev_line) |
| 4707 | and not re.search(r"\b(class|struct)\b", prev_line) |
| 4708 | and not re.search(r"\\$", prev_line) |
| 4709 | ): |
| 4710 | # Try a bit harder to find the beginning of the class. This is to |
| 4711 | # account for multi-line base-specifier lists, e.g.: |
| 4712 | # class Derived |
| 4713 | # : public Base { |
| 4714 | end_class_head = class_info.starting_linenum |
| 4715 | for i in range(class_info.starting_linenum, linenum): |
| 4716 | if re.search(r"\{\s*$", clean_lines.lines[i]): |
| 4717 | end_class_head = i |
| 4718 | break |
| 4719 | if end_class_head < linenum - 1: |
| 4720 | error( |
| 4721 | filename, |
| 4722 | linenum, |
no test coverage detected