Update nesting state with current line. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found.
(self, filename: str, clean_lines: CleansedLines, linenum: int, error)
| 3539 | |
| 3540 | # TODO(google): Update() is too long, but we will refactor later. |
| 3541 | def Update(self, filename: str, clean_lines: CleansedLines, linenum: int, error): |
| 3542 | """Update nesting state with current line. |
| 3543 | |
| 3544 | Args: |
| 3545 | filename: The name of the current file. |
| 3546 | clean_lines: A CleansedLines instance containing the file. |
| 3547 | linenum: The number of the line to check. |
| 3548 | error: The function to call with any errors found. |
| 3549 | """ |
| 3550 | line = clean_lines.elided[linenum] |
| 3551 | |
| 3552 | # Remember top of the previous nesting stack. |
| 3553 | # |
| 3554 | # The stack is always pushed/popped and not modified in place, so |
| 3555 | # we can just do a shallow copy instead of copy.deepcopy. Using |
| 3556 | # deepcopy would slow down cpplint by ~28%. |
| 3557 | if self.stack: |
| 3558 | self.previous_stack_top = self.stack[-1] |
| 3559 | self.previous_open_parentheses = self.stack[-1].open_parentheses |
| 3560 | else: |
| 3561 | self.previous_stack_top = None |
| 3562 | |
| 3563 | # Update pp_stack |
| 3564 | self.UpdatePreprocessor(line) |
| 3565 | |
| 3566 | self._CountOpenParentheses(line) |
| 3567 | |
| 3568 | # Consume namespace declaration at the beginning of the line. Do |
| 3569 | # this in a loop so that we catch same line declarations like this: |
| 3570 | # namespace proto2 { namespace bridge { class MessageSet; } } |
| 3571 | while (new_line := self._UpdateNamesapce(line, linenum)) is not None: # could be empty str |
| 3572 | line = new_line |
| 3573 | |
| 3574 | # Look for a class declaration in whatever is left of the line |
| 3575 | # after parsing namespaces. The regexp accounts for decorated classes |
| 3576 | # such as in: |
| 3577 | # class LOCKABLE API Object { |
| 3578 | # }; |
| 3579 | class_decl_match = re.match( |
| 3580 | r"^(\s*(?:template\s*<[\w\s<>,:=]*>\s*)?" |
| 3581 | r"(class|struct)\s+(?:[a-zA-Z0-9_]+\s+)*(\w+(?:::\w+)*))" |
| 3582 | r"(.*)$", |
| 3583 | line, |
| 3584 | ) |
| 3585 | if class_decl_match and (not self.stack or self.stack[-1].open_parentheses == 0): |
| 3586 | # We do not want to accept classes that are actually template arguments: |
| 3587 | # template <class Ignore1, |
| 3588 | # class Ignore2 = Default<Args>, |
| 3589 | # template <Args> class Ignore3> |
| 3590 | # void Function() {}; |
| 3591 | # |
| 3592 | # To avoid template argument cases, we scan forward and look for |
| 3593 | # an unmatched '>'. If we see one, assume we are inside a |
| 3594 | # template argument list. |
| 3595 | end_declaration = len(class_decl_match.group(1)) |
| 3596 | if not self.InTemplateArgumentList(clean_lines, linenum, end_declaration): |
| 3597 | self.stack.append( |
| 3598 | _ClassInfo( |
no test coverage detected