OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright (c) 2009 Google Inc. All rights reserved. | 3 # Copyright (c) 2009 Google Inc. All rights reserved. |
4 # | 4 # |
5 # Redistribution and use in source and binary forms, with or without | 5 # Redistribution and use in source and binary forms, with or without |
6 # modification, are permitted provided that the following conditions are | 6 # modification, are permitted provided that the following conditions are |
7 # met: | 7 # met: |
8 # | 8 # |
9 # * Redistributions of source code must retain the above copyright | 9 # * Redistributions of source code must retain the above copyright |
10 # notice, this list of conditions and the following disclaimer. | 10 # notice, this list of conditions and the following disclaimer. |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 'build/printf_format', | 187 'build/printf_format', |
188 'build/storage_class', | 188 'build/storage_class', |
189 'legal/copyright', | 189 'legal/copyright', |
190 'readability/alt_tokens', | 190 'readability/alt_tokens', |
191 'readability/braces', | 191 'readability/braces', |
192 'readability/casting', | 192 'readability/casting', |
193 'readability/check', | 193 'readability/check', |
194 'readability/constructors', | 194 'readability/constructors', |
195 'readability/fn_size', | 195 'readability/fn_size', |
196 'readability/function', | 196 'readability/function', |
| 197 'readability/inheritance', |
197 'readability/multiline_comment', | 198 'readability/multiline_comment', |
198 'readability/multiline_string', | 199 'readability/multiline_string', |
199 'readability/namespace', | 200 'readability/namespace', |
200 'readability/nolint', | 201 'readability/nolint', |
201 'readability/nul', | 202 'readability/nul', |
202 'readability/streams', | 203 'readability/streams', |
203 'readability/todo', | 204 'readability/todo', |
204 'readability/utf8', | 205 'readability/utf8', |
205 'runtime/arrays', | 206 'runtime/arrays', |
206 'runtime/casting', | 207 'runtime/casting', |
207 'runtime/explicit', | 208 'runtime/explicit', |
208 'runtime/int', | 209 'runtime/int', |
209 'runtime/init', | 210 'runtime/init', |
210 'runtime/invalid_increment', | 211 'runtime/invalid_increment', |
211 'runtime/member_string_references', | 212 'runtime/member_string_references', |
212 'runtime/memset', | 213 'runtime/memset', |
| 214 'runtime/indentation_namespace', |
213 'runtime/operator', | 215 'runtime/operator', |
214 'runtime/printf', | 216 'runtime/printf', |
215 'runtime/printf_format', | 217 'runtime/printf_format', |
216 'runtime/references', | 218 'runtime/references', |
217 'runtime/string', | 219 'runtime/string', |
218 'runtime/threadsafe_fn', | 220 'runtime/threadsafe_fn', |
219 'runtime/vlog', | 221 'runtime/vlog', |
220 'whitespace/blank_line', | 222 'whitespace/blank_line', |
221 'whitespace/braces', | 223 'whitespace/braces', |
222 'whitespace/comma', | 224 'whitespace/comma', |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 'cstdlib', | 378 'cstdlib', |
377 'cstring', | 379 'cstring', |
378 'ctgmath', | 380 'ctgmath', |
379 'ctime', | 381 'ctime', |
380 'cuchar', | 382 'cuchar', |
381 'cwchar', | 383 'cwchar', |
382 'cwctype', | 384 'cwctype', |
383 ]) | 385 ]) |
384 | 386 |
385 | 387 |
| 388 # These headers are excluded from [build/include] and [build/include_order] |
| 389 # checks: |
| 390 # - Anything not following google file name conventions (containing an |
| 391 # uppercase character, such as Python.h or nsStringAPI.h, for example). |
| 392 # - Lua headers. |
| 393 _THIRD_PARTY_HEADERS_PATTERN = re.compile( |
| 394 r'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$') |
| 395 |
| 396 |
386 # Assertion macros. These are defined in base/logging.h and | 397 # Assertion macros. These are defined in base/logging.h and |
387 # testing/base/gunit.h. Note that the _M versions need to come first | 398 # testing/base/gunit.h. Note that the _M versions need to come first |
388 # for substring matching to work. | 399 # for substring matching to work. |
389 _CHECK_MACROS = [ | 400 _CHECK_MACROS = [ |
390 'DCHECK', 'CHECK', | 401 'DCHECK', 'CHECK', |
391 'EXPECT_TRUE_M', 'EXPECT_TRUE', | 402 'EXPECT_TRUE_M', 'EXPECT_TRUE', |
392 'ASSERT_TRUE_M', 'ASSERT_TRUE', | 403 'ASSERT_TRUE_M', 'ASSERT_TRUE', |
393 'EXPECT_FALSE_M', 'EXPECT_FALSE', | 404 'EXPECT_FALSE_M', 'EXPECT_FALSE', |
394 'ASSERT_FALSE_M', 'ASSERT_FALSE', | 405 'ASSERT_FALSE_M', 'ASSERT_FALSE', |
395 ] | 406 ] |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 _BLOCK_ASM = 3 # The whole block is an inline assembly block | 469 _BLOCK_ASM = 3 # The whole block is an inline assembly block |
459 | 470 |
460 # Match start of assembly blocks | 471 # Match start of assembly blocks |
461 _MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' | 472 _MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' |
462 r'(?:\s+(volatile|__volatile__))?' | 473 r'(?:\s+(volatile|__volatile__))?' |
463 r'\s*[{(]') | 474 r'\s*[{(]') |
464 | 475 |
465 | 476 |
466 _regexp_compile_cache = {} | 477 _regexp_compile_cache = {} |
467 | 478 |
468 # Finds occurrences of NOLINT or NOLINT(...). | |
469 _RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?') | |
470 | |
471 # {str, set(int)}: a map from error categories to sets of linenumbers | 479 # {str, set(int)}: a map from error categories to sets of linenumbers |
472 # on which those errors are expected and should be suppressed. | 480 # on which those errors are expected and should be suppressed. |
473 _error_suppressions = {} | 481 _error_suppressions = {} |
474 | 482 |
475 # The root directory used for deriving header guard CPP variable. | 483 # The root directory used for deriving header guard CPP variable. |
476 # This is set by --root flag. | 484 # This is set by --root flag. |
477 _root = None | 485 _root = None |
478 | 486 |
479 # The allowed line length of files. | 487 # The allowed line length of files. |
480 # This is set by --linelength flag. | 488 # This is set by --linelength flag. |
481 _line_length = 80 | 489 _line_length = 80 |
482 | 490 |
483 # The allowed extensions for file names | 491 # The allowed extensions for file names |
484 # This is set by --extensions flag. | 492 # This is set by --extensions flag. |
485 _valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) | 493 _valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) |
486 | 494 |
487 def ParseNolintSuppressions(filename, raw_line, linenum, error): | 495 def ParseNolintSuppressions(filename, raw_line, linenum, error): |
488 """Updates the global list of error-suppressions. | 496 """Updates the global list of error-suppressions. |
489 | 497 |
490 Parses any NOLINT comments on the current line, updating the global | 498 Parses any NOLINT comments on the current line, updating the global |
491 error_suppressions store. Reports an error if the NOLINT comment | 499 error_suppressions store. Reports an error if the NOLINT comment |
492 was malformed. | 500 was malformed. |
493 | 501 |
494 Args: | 502 Args: |
495 filename: str, the name of the input file. | 503 filename: str, the name of the input file. |
496 raw_line: str, the line of input text, with comments. | 504 raw_line: str, the line of input text, with comments. |
497 linenum: int, the number of the current line. | 505 linenum: int, the number of the current line. |
498 error: function, an error handler. | 506 error: function, an error handler. |
499 """ | 507 """ |
500 # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*). | 508 matched = Search(r'\bNOLINT(NEXTLINE)?\b(\([^)]+\))?', raw_line) |
501 matched = _RE_SUPPRESSION.search(raw_line) | |
502 if matched: | 509 if matched: |
503 category = matched.group(1) | 510 if matched.group(1): |
| 511 suppressed_line = linenum + 1 |
| 512 else: |
| 513 suppressed_line = linenum |
| 514 category = matched.group(2) |
504 if category in (None, '(*)'): # => "suppress all" | 515 if category in (None, '(*)'): # => "suppress all" |
505 _error_suppressions.setdefault(None, set()).add(linenum) | 516 _error_suppressions.setdefault(None, set()).add(suppressed_line) |
506 else: | 517 else: |
507 if category.startswith('(') and category.endswith(')'): | 518 if category.startswith('(') and category.endswith(')'): |
508 category = category[1:-1] | 519 category = category[1:-1] |
509 if category in _ERROR_CATEGORIES: | 520 if category in _ERROR_CATEGORIES: |
510 _error_suppressions.setdefault(category, set()).add(linenum) | 521 _error_suppressions.setdefault(category, set()).add(suppressed_line) |
511 else: | 522 else: |
512 error(filename, linenum, 'readability/nolint', 5, | 523 error(filename, linenum, 'readability/nolint', 5, |
513 'Unknown NOLINT error category: %s' % category) | 524 'Unknown NOLINT error category: %s' % category) |
514 | 525 |
515 | 526 |
516 def ResetNolintSuppressions(): | 527 def ResetNolintSuppressions(): |
517 "Resets the set of NOLINT suppressions to empty." | 528 """Resets the set of NOLINT suppressions to empty.""" |
518 _error_suppressions.clear() | 529 _error_suppressions.clear() |
519 | 530 |
520 | 531 |
521 def IsErrorSuppressedByNolint(category, linenum): | 532 def IsErrorSuppressedByNolint(category, linenum): |
522 """Returns true if the specified error category is suppressed on this line. | 533 """Returns true if the specified error category is suppressed on this line. |
523 | 534 |
524 Consults the global error_suppressions map populated by | 535 Consults the global error_suppressions map populated by |
525 ParseNolintSuppressions/ResetNolintSuppressions. | 536 ParseNolintSuppressions/ResetNolintSuppressions. |
526 | 537 |
527 Args: | 538 Args: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 return _regexp_compile_cache[pattern].sub(rep, s) | 573 return _regexp_compile_cache[pattern].sub(rep, s) |
563 | 574 |
564 | 575 |
565 def Search(pattern, s): | 576 def Search(pattern, s): |
566 """Searches the string for the pattern, caching the compiled regexp.""" | 577 """Searches the string for the pattern, caching the compiled regexp.""" |
567 if pattern not in _regexp_compile_cache: | 578 if pattern not in _regexp_compile_cache: |
568 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) | 579 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) |
569 return _regexp_compile_cache[pattern].search(s) | 580 return _regexp_compile_cache[pattern].search(s) |
570 | 581 |
571 | 582 |
572 class _IncludeState(dict): | 583 class _IncludeState(object): |
573 """Tracks line numbers for includes, and the order in which includes appear. | 584 """Tracks line numbers for includes, and the order in which includes appear. |
574 | 585 |
575 As a dict, an _IncludeState object serves as a mapping between include | 586 include_list contains list of lists of (header, line number) pairs. |
576 filename and line number on which that file was included. | 587 It's a lists of lists rather than just one flat list to make it |
| 588 easier to update across preprocessor boundaries. |
577 | 589 |
578 Call CheckNextIncludeOrder() once for each header in the file, passing | 590 Call CheckNextIncludeOrder() once for each header in the file, passing |
579 in the type constants defined above. Calls in an illegal order will | 591 in the type constants defined above. Calls in an illegal order will |
580 raise an _IncludeError with an appropriate error message. | 592 raise an _IncludeError with an appropriate error message. |
581 | 593 |
582 """ | 594 """ |
583 # self._section will move monotonically through this set. If it ever | 595 # self._section will move monotonically through this set. If it ever |
584 # needs to move backwards, CheckNextIncludeOrder will raise an error. | 596 # needs to move backwards, CheckNextIncludeOrder will raise an error. |
585 _INITIAL_SECTION = 0 | 597 _INITIAL_SECTION = 0 |
586 _MY_H_SECTION = 1 | 598 _MY_H_SECTION = 1 |
(...skipping 10 matching lines...) Expand all Loading... |
597 } | 609 } |
598 _SECTION_NAMES = { | 610 _SECTION_NAMES = { |
599 _INITIAL_SECTION: "... nothing. (This can't be an error.)", | 611 _INITIAL_SECTION: "... nothing. (This can't be an error.)", |
600 _MY_H_SECTION: 'a header this file implements', | 612 _MY_H_SECTION: 'a header this file implements', |
601 _C_SECTION: 'C system header', | 613 _C_SECTION: 'C system header', |
602 _CPP_SECTION: 'C++ system header', | 614 _CPP_SECTION: 'C++ system header', |
603 _OTHER_H_SECTION: 'other header', | 615 _OTHER_H_SECTION: 'other header', |
604 } | 616 } |
605 | 617 |
606 def __init__(self): | 618 def __init__(self): |
607 dict.__init__(self) | 619 self.include_list = [[]] |
608 self.ResetSection() | 620 self.ResetSection('') |
609 | 621 |
610 def ResetSection(self): | 622 def FindHeader(self, header): |
| 623 """Check if a header has already been included. |
| 624 |
| 625 Args: |
| 626 header: header to check. |
| 627 Returns: |
| 628 Line number of previous occurrence, or -1 if the header has not |
| 629 been seen before. |
| 630 """ |
| 631 for section_list in self.include_list: |
| 632 for f in section_list: |
| 633 if f[0] == header: |
| 634 return f[1] |
| 635 return -1 |
| 636 |
| 637 def ResetSection(self, directive): |
| 638 """Reset section checking for preprocessor directive. |
| 639 |
| 640 Args: |
| 641 directive: preprocessor directive (e.g. "if", "else"). |
| 642 """ |
611 # The name of the current section. | 643 # The name of the current section. |
612 self._section = self._INITIAL_SECTION | 644 self._section = self._INITIAL_SECTION |
613 # The path of last found header. | 645 # The path of last found header. |
614 self._last_header = '' | 646 self._last_header = '' |
615 | 647 |
| 648 # Update list of includes. Note that we never pop from the |
| 649 # include list. |
| 650 if directive in ('if', 'ifdef', 'ifndef'): |
| 651 self.include_list.append([]) |
| 652 elif directive in ('else', 'elif'): |
| 653 self.include_list[-1] = [] |
| 654 |
616 def SetLastHeader(self, header_path): | 655 def SetLastHeader(self, header_path): |
617 self._last_header = header_path | 656 self._last_header = header_path |
618 | 657 |
619 def CanonicalizeAlphabeticalOrder(self, header_path): | 658 def CanonicalizeAlphabeticalOrder(self, header_path): |
620 """Returns a path canonicalized for alphabetical comparison. | 659 """Returns a path canonicalized for alphabetical comparison. |
621 | 660 |
622 - replaces "-" with "_" so they both cmp the same. | 661 - replaces "-" with "_" so they both cmp the same. |
623 - removes '-inl' since we don't require them to be after the main header. | 662 - removes '-inl' since we don't require them to be after the main header. |
624 - lowercase everything, just in case. | 663 - lowercase everything, just in case. |
625 | 664 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 error message. | 876 error message. |
838 | 877 |
839 Args: | 878 Args: |
840 filters: A string of comma-separated filters (eg "whitespace/indent"). | 879 filters: A string of comma-separated filters (eg "whitespace/indent"). |
841 Each filter should start with + or -; else we die. | 880 Each filter should start with + or -; else we die. |
842 """ | 881 """ |
843 _cpplint_state.SetFilters(filters) | 882 _cpplint_state.SetFilters(filters) |
844 | 883 |
845 def _AddFilters(filters): | 884 def _AddFilters(filters): |
846 """Adds more filter overrides. | 885 """Adds more filter overrides. |
847 | 886 |
848 Unlike _SetFilters, this function does not reset the current list of filters | 887 Unlike _SetFilters, this function does not reset the current list of filters |
849 available. | 888 available. |
850 | 889 |
851 Args: | 890 Args: |
852 filters: A string of comma-separated filters (eg "whitespace/indent"). | 891 filters: A string of comma-separated filters (eg "whitespace/indent"). |
853 Each filter should start with + or -; else we die. | 892 Each filter should start with + or -; else we die. |
854 """ | 893 """ |
855 _cpplint_state.AddFilters(filters) | 894 _cpplint_state.AddFilters(filters) |
856 | 895 |
857 def _BackupFilters(): | 896 def _BackupFilters(): |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 def End(self): | 955 def End(self): |
917 """Stop analyzing function body.""" | 956 """Stop analyzing function body.""" |
918 self.in_a_function = False | 957 self.in_a_function = False |
919 | 958 |
920 | 959 |
921 class _IncludeError(Exception): | 960 class _IncludeError(Exception): |
922 """Indicates a problem with the include order in a file.""" | 961 """Indicates a problem with the include order in a file.""" |
923 pass | 962 pass |
924 | 963 |
925 | 964 |
926 class FileInfo: | 965 class FileInfo(object): |
927 """Provides utility functions for filenames. | 966 """Provides utility functions for filenames. |
928 | 967 |
929 FileInfo provides easy access to the components of a file's path | 968 FileInfo provides easy access to the components of a file's path |
930 relative to the project root. | 969 relative to the project root. |
931 """ | 970 """ |
932 | 971 |
933 def __init__(self, filename): | 972 def __init__(self, filename): |
934 self._filename = filename | 973 self._filename = filename |
935 | 974 |
936 def FullName(self): | 975 def FullName(self): |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1627 | 1666 |
1628 Logs an error if no #ifndef header guard is present. For other | 1667 Logs an error if no #ifndef header guard is present. For other |
1629 headers, checks that the full pathname is used. | 1668 headers, checks that the full pathname is used. |
1630 | 1669 |
1631 Args: | 1670 Args: |
1632 filename: The name of the C++ header file. | 1671 filename: The name of the C++ header file. |
1633 lines: An array of strings, each representing a line of the file. | 1672 lines: An array of strings, each representing a line of the file. |
1634 error: The function to call with any errors found. | 1673 error: The function to call with any errors found. |
1635 """ | 1674 """ |
1636 | 1675 |
| 1676 # Don't check for header guards if there are error suppression |
| 1677 # comments somewhere in this file. |
| 1678 # |
| 1679 # Because this is silencing a warning for a nonexistent line, we |
| 1680 # only support the very specific NOLINT(build/header_guard) syntax, |
| 1681 # and not the general NOLINT or NOLINT(*) syntax. |
| 1682 for i in lines: |
| 1683 if Search(r'//\s*NOLINT\(build/header_guard\)', i): |
| 1684 return |
| 1685 |
1637 cppvar = GetHeaderGuardCPPVariable(filename) | 1686 cppvar = GetHeaderGuardCPPVariable(filename) |
1638 | 1687 |
1639 ifndef = None | 1688 ifndef = None |
1640 ifndef_linenum = 0 | 1689 ifndef_linenum = 0 |
1641 define = None | 1690 define = None |
1642 endif = None | 1691 endif = None |
1643 endif_linenum = 0 | 1692 endif_linenum = 0 |
1644 for linenum, line in enumerate(lines): | 1693 for linenum, line in enumerate(lines): |
1645 linesplit = line.split() | 1694 linesplit = line.split() |
1646 if len(linesplit) >= 2: | 1695 if len(linesplit) >= 2: |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1873 clean_lines: A CleansedLines instance containing the file. | 1922 clean_lines: A CleansedLines instance containing the file. |
1874 linenum: The number of the line to check. | 1923 linenum: The number of the line to check. |
1875 error: The function to call with any errors found. | 1924 error: The function to call with any errors found. |
1876 """ | 1925 """ |
1877 line = clean_lines.elided[linenum] | 1926 line = clean_lines.elided[linenum] |
1878 if _RE_PATTERN_INVALID_INCREMENT.match(line): | 1927 if _RE_PATTERN_INVALID_INCREMENT.match(line): |
1879 error(filename, linenum, 'runtime/invalid_increment', 5, | 1928 error(filename, linenum, 'runtime/invalid_increment', 5, |
1880 'Changing pointer instead of value (or unused value of operator*).') | 1929 'Changing pointer instead of value (or unused value of operator*).') |
1881 | 1930 |
1882 | 1931 |
| 1932 def IsMacroDefinition(clean_lines, linenum): |
| 1933 if Search(r'^#define', clean_lines[linenum]): |
| 1934 return True |
| 1935 |
| 1936 if linenum > 0 and Search(r'\\$', clean_lines[linenum - 1]): |
| 1937 return True |
| 1938 |
| 1939 return False |
| 1940 |
| 1941 |
| 1942 def IsForwardClassDeclaration(clean_lines, linenum): |
| 1943 return Match(r'^\s*(\btemplate\b)*.*class\s+\w+;\s*$', clean_lines[linenum]) |
| 1944 |
| 1945 |
1883 class _BlockInfo(object): | 1946 class _BlockInfo(object): |
1884 """Stores information about a generic block of code.""" | 1947 """Stores information about a generic block of code.""" |
1885 | 1948 |
1886 def __init__(self, seen_open_brace): | 1949 def __init__(self, seen_open_brace): |
1887 self.seen_open_brace = seen_open_brace | 1950 self.seen_open_brace = seen_open_brace |
1888 self.open_parentheses = 0 | 1951 self.open_parentheses = 0 |
1889 self.inline_asm = _NO_ASM | 1952 self.inline_asm = _NO_ASM |
| 1953 self.check_namespace_indentation = False |
1890 | 1954 |
1891 def CheckBegin(self, filename, clean_lines, linenum, error): | 1955 def CheckBegin(self, filename, clean_lines, linenum, error): |
1892 """Run checks that applies to text up to the opening brace. | 1956 """Run checks that applies to text up to the opening brace. |
1893 | 1957 |
1894 This is mostly for checking the text after the class identifier | 1958 This is mostly for checking the text after the class identifier |
1895 and the "{", usually where the base class is specified. For other | 1959 and the "{", usually where the base class is specified. For other |
1896 blocks, there isn't much to check, so we always pass. | 1960 blocks, there isn't much to check, so we always pass. |
1897 | 1961 |
1898 Args: | 1962 Args: |
1899 filename: The name of the current file. | 1963 filename: The name of the current file. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1936 | 2000 |
1937 | 2001 |
1938 class _ClassInfo(_BlockInfo): | 2002 class _ClassInfo(_BlockInfo): |
1939 """Stores information about a class.""" | 2003 """Stores information about a class.""" |
1940 | 2004 |
1941 def __init__(self, name, class_or_struct, clean_lines, linenum): | 2005 def __init__(self, name, class_or_struct, clean_lines, linenum): |
1942 _BlockInfo.__init__(self, False) | 2006 _BlockInfo.__init__(self, False) |
1943 self.name = name | 2007 self.name = name |
1944 self.starting_linenum = linenum | 2008 self.starting_linenum = linenum |
1945 self.is_derived = False | 2009 self.is_derived = False |
| 2010 self.check_namespace_indentation = True |
1946 if class_or_struct == 'struct': | 2011 if class_or_struct == 'struct': |
1947 self.access = 'public' | 2012 self.access = 'public' |
1948 self.is_struct = True | 2013 self.is_struct = True |
1949 else: | 2014 else: |
1950 self.access = 'private' | 2015 self.access = 'private' |
1951 self.is_struct = False | 2016 self.is_struct = False |
1952 | 2017 |
1953 # Remember initial indentation level for this class. Using raw_lines here | 2018 # Remember initial indentation level for this class. Using raw_lines here |
1954 # instead of elided to account for leading comments. | 2019 # instead of elided to account for leading comments. |
1955 self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) | 2020 self.class_indent = GetIndentLevel(clean_lines.raw_lines[linenum]) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1987 'Closing brace should be aligned with beginning of %s' % parent) | 2052 'Closing brace should be aligned with beginning of %s' % parent) |
1988 | 2053 |
1989 | 2054 |
1990 class _NamespaceInfo(_BlockInfo): | 2055 class _NamespaceInfo(_BlockInfo): |
1991 """Stores information about a namespace.""" | 2056 """Stores information about a namespace.""" |
1992 | 2057 |
1993 def __init__(self, name, linenum): | 2058 def __init__(self, name, linenum): |
1994 _BlockInfo.__init__(self, False) | 2059 _BlockInfo.__init__(self, False) |
1995 self.name = name or '' | 2060 self.name = name or '' |
1996 self.starting_linenum = linenum | 2061 self.starting_linenum = linenum |
| 2062 self.check_namespace_indentation = True |
1997 | 2063 |
1998 def CheckEnd(self, filename, clean_lines, linenum, error): | 2064 def CheckEnd(self, filename, clean_lines, linenum, error): |
1999 """Check end of namespace comments.""" | 2065 """Check end of namespace comments.""" |
2000 line = clean_lines.raw_lines[linenum] | 2066 line = clean_lines.raw_lines[linenum] |
2001 | 2067 |
2002 # Check how many lines is enclosed in this namespace. Don't issue | 2068 # Check how many lines is enclosed in this namespace. Don't issue |
2003 # warning for missing namespace comments if there aren't enough | 2069 # warning for missing namespace comments if there aren't enough |
2004 # lines. However, do apply checks if there is already an end of | 2070 # lines. However, do apply checks if there is already an end of |
2005 # namespace comment and it's incorrect. | 2071 # namespace comment and it's incorrect. |
2006 # | 2072 # |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2524 # the class head is not completed yet. | 2590 # the class head is not completed yet. |
2525 classinfo = nesting_state.InnermostClass() | 2591 classinfo = nesting_state.InnermostClass() |
2526 if not classinfo or not classinfo.seen_open_brace: | 2592 if not classinfo or not classinfo.seen_open_brace: |
2527 return | 2593 return |
2528 | 2594 |
2529 # The class may have been declared with namespace or classname qualifiers. | 2595 # The class may have been declared with namespace or classname qualifiers. |
2530 # The constructor and destructor will not have those qualifiers. | 2596 # The constructor and destructor will not have those qualifiers. |
2531 base_classname = classinfo.name.split('::')[-1] | 2597 base_classname = classinfo.name.split('::')[-1] |
2532 | 2598 |
2533 # Look for single-argument constructors that aren't marked explicit. | 2599 # Look for single-argument constructors that aren't marked explicit. |
2534 # Technically a valid construct, but against style. | 2600 # Technically a valid construct, but against style. Also look for |
2535 args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)' | 2601 # non-single-argument constructors which are also technically valid, but |
2536 % re.escape(base_classname), | 2602 # strongly suggest something is wrong. |
2537 line) | 2603 explicit_constructor_match = Match( |
2538 if (args and | 2604 r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*' |
2539 args.group(1) != 'void' and | 2605 r'\(((?:[^()]|\([^()]*\))*)\)' |
2540 not Search(r'\bstd::initializer_list\b', args.group(1)) and | 2606 % re.escape(base_classname), |
2541 not Match(r'(const\s+)?%s(\s+const)?\s*(?:<\w+>\s*)?&' | 2607 line) |
2542 % re.escape(base_classname), args.group(1).strip())): | 2608 |
2543 error(filename, linenum, 'runtime/explicit', 5, | 2609 if explicit_constructor_match: |
2544 'Single-argument constructors should be marked explicit.') | 2610 is_marked_explicit = explicit_constructor_match.group(1) |
| 2611 |
| 2612 if not explicit_constructor_match.group(2): |
| 2613 constructor_args = [] |
| 2614 else: |
| 2615 constructor_args = explicit_constructor_match.group(2).split(',') |
| 2616 |
| 2617 # collapse arguments so that commas in template parameter lists and function |
| 2618 # argument parameter lists don't split arguments in two |
| 2619 i = 0 |
| 2620 while i < len(constructor_args): |
| 2621 constructor_arg = constructor_args[i] |
| 2622 while (constructor_arg.count('<') > constructor_arg.count('>') or |
| 2623 constructor_arg.count('(') > constructor_arg.count(')')): |
| 2624 constructor_arg += ',' + constructor_args[i + 1] |
| 2625 del constructor_args[i + 1] |
| 2626 constructor_args[i] = constructor_arg |
| 2627 i += 1 |
| 2628 |
| 2629 defaulted_args = [arg for arg in constructor_args if '=' in arg] |
| 2630 noarg_constructor = (not constructor_args or # empty arg list |
| 2631 # 'void' arg specifier |
| 2632 (len(constructor_args) == 1 and |
| 2633 constructor_args[0].strip() == 'void')) |
| 2634 onearg_constructor = ((len(constructor_args) == 1 and # exactly one arg |
| 2635 not noarg_constructor) or |
| 2636 # all but at most one arg defaulted |
| 2637 (len(constructor_args) >= 1 and |
| 2638 not noarg_constructor and |
| 2639 len(defaulted_args) >= len(constructor_args) - 1)) |
| 2640 initializer_list_constructor = bool( |
| 2641 onearg_constructor and |
| 2642 Search(r'\bstd\s*::\s*initializer_list\b', constructor_args[0])) |
| 2643 copy_constructor = bool( |
| 2644 onearg_constructor and |
| 2645 Match(r'(const\s+)?%s(\s*<[^>]*>)?(\s+const)?\s*(?:<\w+>\s*)?&' |
| 2646 % re.escape(base_classname), constructor_args[0].strip())) |
| 2647 |
| 2648 if (not is_marked_explicit and |
| 2649 onearg_constructor and |
| 2650 not initializer_list_constructor and |
| 2651 not copy_constructor): |
| 2652 if defaulted_args: |
| 2653 error(filename, linenum, 'runtime/explicit', 5, |
| 2654 'Constructors callable with one argument ' |
| 2655 'should be marked explicit.') |
| 2656 else: |
| 2657 error(filename, linenum, 'runtime/explicit', 5, |
| 2658 'Single-parameter constructors should be marked explicit.') |
| 2659 elif is_marked_explicit and not onearg_constructor: |
| 2660 if noarg_constructor: |
| 2661 error(filename, linenum, 'runtime/explicit', 5, |
| 2662 'Zero-parameter constructors should not be marked explicit.') |
| 2663 else: |
| 2664 error(filename, linenum, 'runtime/explicit', 0, |
| 2665 'Constructors that require multiple arguments ' |
| 2666 'should not be marked explicit.') |
2545 | 2667 |
2546 | 2668 |
2547 def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): | 2669 def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): |
2548 """Checks for the correctness of various spacing around function calls. | 2670 """Checks for the correctness of various spacing around function calls. |
2549 | 2671 |
2550 Args: | 2672 Args: |
2551 filename: The name of the current file. | 2673 filename: The name of the current file. |
2552 clean_lines: A CleansedLines instance containing the file. | 2674 clean_lines: A CleansedLines instance containing the file. |
2553 linenum: The number of the line to check. | 2675 linenum: The number of the line to check. |
2554 error: The function to call with any errors found. | 2676 error: The function to call with any errors found. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2627 | 2749 |
2628 Args: | 2750 Args: |
2629 line: A line of a string. | 2751 line: A line of a string. |
2630 | 2752 |
2631 Returns: | 2753 Returns: |
2632 True, if the given line is blank. | 2754 True, if the given line is blank. |
2633 """ | 2755 """ |
2634 return not line or line.isspace() | 2756 return not line or line.isspace() |
2635 | 2757 |
2636 | 2758 |
| 2759 def CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line, |
| 2760 error): |
| 2761 is_namespace_indent_item = ( |
| 2762 len(nesting_state.stack) > 1 and |
| 2763 nesting_state.stack[-1].check_namespace_indentation and |
| 2764 isinstance(nesting_state.previous_stack_top, _NamespaceInfo) and |
| 2765 nesting_state.previous_stack_top == nesting_state.stack[-2]) |
| 2766 |
| 2767 if ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item, |
| 2768 clean_lines.elided, line): |
| 2769 CheckItemIndentationInNamespace(filename, clean_lines.elided, |
| 2770 line, error) |
| 2771 |
| 2772 |
2637 def CheckForFunctionLengths(filename, clean_lines, linenum, | 2773 def CheckForFunctionLengths(filename, clean_lines, linenum, |
2638 function_state, error): | 2774 function_state, error): |
2639 """Reports for long function bodies. | 2775 """Reports for long function bodies. |
2640 | 2776 |
2641 For an overview why this is done, see: | 2777 For an overview why this is done, see: |
2642 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Fun
ctions | 2778 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Fun
ctions |
2643 | 2779 |
2644 Uses a simplistic algorithm assuming other style guidelines | 2780 Uses a simplistic algorithm assuming other style guidelines |
2645 (especially spacing) are followed. | 2781 (especially spacing) are followed. |
2646 Only checks unindented functions, so class members are unchecked. | 2782 Only checks unindented functions, so class members are unchecked. |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2765 filename: The name of the current file. | 2901 filename: The name of the current file. |
2766 clean_lines: A CleansedLines instance containing the file. | 2902 clean_lines: A CleansedLines instance containing the file. |
2767 linenum: The number of the line to check. | 2903 linenum: The number of the line to check. |
2768 nesting_state: A NestingState instance which maintains information about | 2904 nesting_state: A NestingState instance which maintains information about |
2769 the current stack of nested blocks being parsed. | 2905 the current stack of nested blocks being parsed. |
2770 error: The function to call with any errors found. | 2906 error: The function to call with any errors found. |
2771 """ | 2907 """ |
2772 line = clean_lines.elided[linenum] # get rid of comments and strings | 2908 line = clean_lines.elided[linenum] # get rid of comments and strings |
2773 | 2909 |
2774 matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|' | 2910 matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|' |
2775 r'DISALLOW_EVIL_CONSTRUCTORS|' | |
2776 r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line) | 2911 r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line) |
2777 if not matched: | 2912 if not matched: |
2778 return | 2913 return |
2779 if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo): | 2914 if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo): |
2780 if nesting_state.stack[-1].access != 'private': | 2915 if nesting_state.stack[-1].access != 'private': |
2781 error(filename, linenum, 'readability/constructors', 3, | 2916 error(filename, linenum, 'readability/constructors', 3, |
2782 '%s must be in the private: section' % matched.group(1)) | 2917 '%s must be in the private: section' % matched.group(1)) |
2783 | 2918 |
2784 else: | 2919 else: |
2785 # Found DISALLOW* macro outside a class declaration, or perhaps it | 2920 # Found DISALLOW* macro outside a class declaration, or perhaps it |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2987 match = Match(r'^(.*[^-\s>])>[^\s=>,]', line) | 3122 match = Match(r'^(.*[^-\s>])>[^\s=>,]', line) |
2988 if match: | 3123 if match: |
2989 (_, _, start_pos) = ReverseCloseExpression( | 3124 (_, _, start_pos) = ReverseCloseExpression( |
2990 clean_lines, linenum, len(match.group(1))) | 3125 clean_lines, linenum, len(match.group(1))) |
2991 if start_pos <= -1: | 3126 if start_pos <= -1: |
2992 error(filename, linenum, 'whitespace/operators', 3, | 3127 error(filename, linenum, 'whitespace/operators', 3, |
2993 'Missing spaces around >') | 3128 'Missing spaces around >') |
2994 | 3129 |
2995 # We allow no-spaces around << when used like this: 10<<20, but | 3130 # We allow no-spaces around << when used like this: 10<<20, but |
2996 # not otherwise (particularly, not when used as streams) | 3131 # not otherwise (particularly, not when used as streams) |
| 3132 # |
2997 # We also allow operators following an opening parenthesis, since | 3133 # We also allow operators following an opening parenthesis, since |
2998 # those tend to be macros that deal with operators. | 3134 # those tend to be macros that deal with operators. |
2999 match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<([^\s,=])', line) | 3135 match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<([^\s,=])', line) |
3000 if (match and match.group(1) != '(' and | 3136 if (match and match.group(1) != '(' and |
3001 not (match.group(1).isdigit() and match.group(2).isdigit()) and | 3137 not (match.group(1).isdigit() and match.group(2).isdigit()) and |
3002 not (match.group(1) == 'operator' and match.group(2) == ';')): | 3138 not (match.group(1) == 'operator' and match.group(2) == ';')): |
3003 error(filename, linenum, 'whitespace/operators', 3, | 3139 error(filename, linenum, 'whitespace/operators', 3, |
3004 'Missing spaces around <<') | 3140 'Missing spaces around <<') |
3005 | 3141 |
3006 # We allow no-spaces around >> for almost anything. This is because | 3142 # We allow no-spaces around >> for almost anything. This is because |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3080 # You should always have a space after a comma (either as fn arg or operator) | 3216 # You should always have a space after a comma (either as fn arg or operator) |
3081 # | 3217 # |
3082 # This does not apply when the non-space character following the | 3218 # This does not apply when the non-space character following the |
3083 # comma is another comma, since the only time when that happens is | 3219 # comma is another comma, since the only time when that happens is |
3084 # for empty macro arguments. | 3220 # for empty macro arguments. |
3085 # | 3221 # |
3086 # We run this check in two passes: first pass on elided lines to | 3222 # We run this check in two passes: first pass on elided lines to |
3087 # verify that lines contain missing whitespaces, second pass on raw | 3223 # verify that lines contain missing whitespaces, second pass on raw |
3088 # lines to confirm that those missing whitespaces are not due to | 3224 # lines to confirm that those missing whitespaces are not due to |
3089 # elided comments. | 3225 # elided comments. |
3090 if Search(r',[^,\s]', line) and Search(r',[^,\s]', raw[linenum]): | 3226 if (Search(r',[^,\s]', ReplaceAll(r'\boperator\s*,\s*\(', 'F(', line)) and |
| 3227 Search(r',[^,\s]', raw[linenum])): |
3091 error(filename, linenum, 'whitespace/comma', 3, | 3228 error(filename, linenum, 'whitespace/comma', 3, |
3092 'Missing space after ,') | 3229 'Missing space after ,') |
3093 | 3230 |
3094 # You should always have a space after a semicolon | 3231 # You should always have a space after a semicolon |
3095 # except for few corner cases | 3232 # except for few corner cases |
3096 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more | 3233 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more |
3097 # space after ; | 3234 # space after ; |
3098 if Search(r';[^\s};\\)/]', line): | 3235 if Search(r';[^\s};\\)/]', line): |
3099 error(filename, linenum, 'whitespace/semicolon', 3, | 3236 error(filename, linenum, 'whitespace/semicolon', 3, |
3100 'Missing space after ;') | 3237 'Missing space after ;') |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3385 # The last '+' represents operators such as '+' and '-'. | 3522 # The last '+' represents operators such as '+' and '-'. |
3386 if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text): | 3523 if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text): |
3387 return False | 3524 return False |
3388 | 3525 |
3389 # Something else. Check that tokens to the left look like | 3526 # Something else. Check that tokens to the left look like |
3390 # return_type function_name | 3527 # return_type function_name |
3391 match_func = Match(r'^(.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', | 3528 match_func = Match(r'^(.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', |
3392 match_symbol.group(1)) | 3529 match_symbol.group(1)) |
3393 if match_func: | 3530 if match_func: |
3394 # Check for constructors, which don't have return types. | 3531 # Check for constructors, which don't have return types. |
3395 if Search(r'\bexplicit$', match_func.group(1)): | 3532 if Search(r'\b(?:explicit|inline)$', match_func.group(1)): |
3396 return True | 3533 return True |
3397 implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix) | 3534 implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix) |
3398 if (implicit_constructor and | 3535 if (implicit_constructor and |
3399 implicit_constructor.group(1) == implicit_constructor.group(2)): | 3536 implicit_constructor.group(1) == implicit_constructor.group(2)): |
3400 return True | 3537 return True |
3401 return IsRValueType(clean_lines, nesting_state, linenum, | 3538 return IsRValueType(clean_lines, nesting_state, linenum, |
3402 len(match_func.group(1))) | 3539 len(match_func.group(1))) |
3403 | 3540 |
3404 # Nothing before the function name. If this is inside a block scope, | 3541 # Nothing before the function name. If this is inside a block scope, |
3405 # this is probably a function call. | 3542 # this is probably a function call. |
3406 return not (nesting_state.previous_stack_top and | 3543 return not (nesting_state.previous_stack_top and |
3407 nesting_state.previous_stack_top.IsBlockInfo()) | 3544 nesting_state.previous_stack_top.IsBlockInfo()) |
3408 | 3545 |
3409 if match_symbol.group(2) == '>': | 3546 if match_symbol.group(2) == '>': |
3410 # Possibly a closing bracket, check that what's on the other side | 3547 # Possibly a closing bracket, check that what's on the other side |
3411 # looks like the start of a template. | 3548 # looks like the start of a template. |
3412 return IsTemplateParameterList( | 3549 return IsTemplateParameterList( |
3413 clean_lines, start, len(match_symbol.group(1))) | 3550 clean_lines, start, len(match_symbol.group(1))) |
3414 | 3551 |
3415 # Some other symbol, usually something like "a=b&&c". This is most | 3552 # Some other symbol, usually something like "a=b&&c". This is most |
3416 # likely not a type. | 3553 # likely not a type. |
3417 return False | 3554 return False |
3418 | 3555 |
3419 | 3556 |
3420 def IsRValueAllowed(clean_lines, linenum): | 3557 def IsDeletedOrDefault(clean_lines, linenum): |
3421 """Check if RValue reference is allowed within some range of lines. | 3558 """Check if current constructor or operator is deleted or default. |
3422 | 3559 |
3423 Args: | 3560 Args: |
3424 clean_lines: A CleansedLines instance containing the file. | 3561 clean_lines: A CleansedLines instance containing the file. |
| 3562 linenum: The number of the line to check. |
| 3563 Returns: |
| 3564 True if this is a deleted or default constructor. |
| 3565 """ |
| 3566 open_paren = clean_lines.elided[linenum].find('(') |
| 3567 if open_paren < 0: |
| 3568 return False |
| 3569 (close_line, _, close_paren) = CloseExpression( |
| 3570 clean_lines, linenum, open_paren) |
| 3571 if close_paren < 0: |
| 3572 return False |
| 3573 return Match(r'\s*=\s*(?:delete|default)\b', close_line[close_paren:]) |
| 3574 |
| 3575 |
| 3576 def IsRValueAllowed(clean_lines, linenum): |
| 3577 """Check if RValue reference is allowed on a particular line. |
| 3578 |
| 3579 Args: |
| 3580 clean_lines: A CleansedLines instance containing the file. |
3425 linenum: The number of the line to check. | 3581 linenum: The number of the line to check. |
3426 Returns: | 3582 Returns: |
3427 True if line is within the region where RValue references are allowed. | 3583 True if line is within the region where RValue references are allowed. |
3428 """ | 3584 """ |
| 3585 # Allow region marked by PUSH/POP macros |
3429 for i in xrange(linenum, 0, -1): | 3586 for i in xrange(linenum, 0, -1): |
3430 line = clean_lines.elided[i] | 3587 line = clean_lines.elided[i] |
3431 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): | 3588 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): |
3432 if not line.endswith('PUSH'): | 3589 if not line.endswith('PUSH'): |
3433 return False | 3590 return False |
3434 for j in xrange(linenum, clean_lines.NumLines(), 1): | 3591 for j in xrange(linenum, clean_lines.NumLines(), 1): |
3435 line = clean_lines.elided[j] | 3592 line = clean_lines.elided[j] |
3436 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): | 3593 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): |
3437 return line.endswith('POP') | 3594 return line.endswith('POP') |
| 3595 |
| 3596 # Allow operator= |
| 3597 line = clean_lines.elided[linenum] |
| 3598 if Search(r'\boperator\s*=\s*\(', line): |
| 3599 return IsDeletedOrDefault(clean_lines, linenum) |
| 3600 |
| 3601 # Allow constructors |
| 3602 match = Match(r'\s*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line) |
| 3603 if match and match.group(1) == match.group(2): |
| 3604 return IsDeletedOrDefault(clean_lines, linenum) |
| 3605 if Search(r'\b(?:explicit|inline)\s+[\w<>]+\s*\(', line): |
| 3606 return IsDeletedOrDefault(clean_lines, linenum) |
| 3607 |
| 3608 if Match(r'\s*[\w<>]+\s*\(', line): |
| 3609 previous_line = 'ReturnType' |
| 3610 if linenum > 0: |
| 3611 previous_line = clean_lines.elided[linenum - 1] |
| 3612 if Match(r'^\s*$', previous_line) or Search(r'[{}:;]\s*$', previous_line): |
| 3613 return IsDeletedOrDefault(clean_lines, linenum) |
| 3614 |
3438 return False | 3615 return False |
3439 | 3616 |
3440 | 3617 |
3441 def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): | 3618 def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): |
3442 """Check for rvalue references. | 3619 """Check for rvalue references. |
3443 | 3620 |
3444 Args: | 3621 Args: |
3445 filename: The name of the current file. | 3622 filename: The name of the current file. |
3446 clean_lines: A CleansedLines instance containing the file. | 3623 clean_lines: A CleansedLines instance containing the file. |
3447 linenum: The number of the line to check. | 3624 linenum: The number of the line to check. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3636 while (endlinenum < len(clean_lines.elided) | 3813 while (endlinenum < len(clean_lines.elided) |
3637 and ';' not in clean_lines.elided[endlinenum][endpos:]): | 3814 and ';' not in clean_lines.elided[endlinenum][endpos:]): |
3638 endlinenum += 1 | 3815 endlinenum += 1 |
3639 endpos = 0 | 3816 endpos = 0 |
3640 if endlinenum < len(clean_lines.elided): | 3817 if endlinenum < len(clean_lines.elided): |
3641 endline = clean_lines.elided[endlinenum] | 3818 endline = clean_lines.elided[endlinenum] |
3642 # We allow a mix of whitespace and closing braces (e.g. for one-liner | 3819 # We allow a mix of whitespace and closing braces (e.g. for one-liner |
3643 # methods) and a single \ after the semicolon (for macros) | 3820 # methods) and a single \ after the semicolon (for macros) |
3644 endpos = endline.find(';') | 3821 endpos = endline.find(';') |
3645 if not Match(r';[\s}]*(\\?)$', endline[endpos:]): | 3822 if not Match(r';[\s}]*(\\?)$', endline[endpos:]): |
3646 # Semicolon isn't the last character, there's something trailing | 3823 # Semicolon isn't the last character, there's something trailing. |
3647 error(filename, linenum, 'readability/braces', 4, | 3824 # Output a warning if the semicolon is not contained inside |
3648 'If/else bodies with multiple statements require braces') | 3825 # a lambda expression. |
| 3826 if not Match(r'^[^{};]*\[[^\[\]]*\][^{}]*\{[^{}]*\}\s*\)*[;,]\s*$', |
| 3827 endline): |
| 3828 error(filename, linenum, 'readability/braces', 4, |
| 3829 'If/else bodies with multiple statements require braces') |
3649 elif endlinenum < len(clean_lines.elided) - 1: | 3830 elif endlinenum < len(clean_lines.elided) - 1: |
3650 # Make sure the next line is dedented | 3831 # Make sure the next line is dedented |
3651 next_line = clean_lines.elided[endlinenum + 1] | 3832 next_line = clean_lines.elided[endlinenum + 1] |
3652 next_indent = GetIndentLevel(next_line) | 3833 next_indent = GetIndentLevel(next_line) |
3653 # With ambiguous nested if statements, this will error out on the | 3834 # With ambiguous nested if statements, this will error out on the |
3654 # if that *doesn't* match the else, regardless of whether it's the | 3835 # if that *doesn't* match the else, regardless of whether it's the |
3655 # inner one or outer one. | 3836 # inner one or outer one. |
3656 if (if_match and Match(r'\s*else\b', next_line) | 3837 if (if_match and Match(r'\s*else\b', next_line) |
3657 and next_indent != if_indent): | 3838 and next_indent != if_indent): |
3658 error(filename, linenum, 'readability/braces', 4, | 3839 error(filename, linenum, 'readability/braces', 4, |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3869 lines = clean_lines.elided | 4050 lines = clean_lines.elided |
3870 (check_macro, start_pos) = FindCheckMacro(lines[linenum]) | 4051 (check_macro, start_pos) = FindCheckMacro(lines[linenum]) |
3871 if not check_macro: | 4052 if not check_macro: |
3872 return | 4053 return |
3873 | 4054 |
3874 # Find end of the boolean expression by matching parentheses | 4055 # Find end of the boolean expression by matching parentheses |
3875 (last_line, end_line, end_pos) = CloseExpression( | 4056 (last_line, end_line, end_pos) = CloseExpression( |
3876 clean_lines, linenum, start_pos) | 4057 clean_lines, linenum, start_pos) |
3877 if end_pos < 0: | 4058 if end_pos < 0: |
3878 return | 4059 return |
| 4060 |
| 4061 # If the check macro is followed by something other than a |
| 4062 # semicolon, assume users will log their own custom error messages |
| 4063 # and don't suggest any replacements. |
| 4064 if not Match(r'\s*;', last_line[end_pos:]): |
| 4065 return |
| 4066 |
3879 if linenum == end_line: | 4067 if linenum == end_line: |
3880 expression = lines[linenum][start_pos + 1:end_pos - 1] | 4068 expression = lines[linenum][start_pos + 1:end_pos - 1] |
3881 else: | 4069 else: |
3882 expression = lines[linenum][start_pos + 1:] | 4070 expression = lines[linenum][start_pos + 1:] |
3883 for i in xrange(linenum + 1, end_line): | 4071 for i in xrange(linenum + 1, end_line): |
3884 expression += lines[i] | 4072 expression += lines[i] |
3885 expression += last_line[0:end_pos - 1] | 4073 expression += last_line[0:end_pos - 1] |
3886 | 4074 |
3887 # Parse expression so that we can take parentheses into account. | 4075 # Parse expression so that we can take parentheses into account. |
3888 # This avoids false positives for inputs like "CHECK((a < 4) == b)", | 4076 # This avoids false positives for inputs like "CHECK((a < 4) == b)", |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4132 CheckBracesSpacing(filename, clean_lines, linenum, error) | 4320 CheckBracesSpacing(filename, clean_lines, linenum, error) |
4133 CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) | 4321 CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) |
4134 CheckRValueReference(filename, clean_lines, linenum, nesting_state, error) | 4322 CheckRValueReference(filename, clean_lines, linenum, nesting_state, error) |
4135 CheckCheck(filename, clean_lines, linenum, error) | 4323 CheckCheck(filename, clean_lines, linenum, error) |
4136 CheckAltTokens(filename, clean_lines, linenum, error) | 4324 CheckAltTokens(filename, clean_lines, linenum, error) |
4137 classinfo = nesting_state.InnermostClass() | 4325 classinfo = nesting_state.InnermostClass() |
4138 if classinfo: | 4326 if classinfo: |
4139 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) | 4327 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) |
4140 | 4328 |
4141 | 4329 |
4142 _RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"') | |
4143 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') | 4330 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') |
4144 # Matches the first component of a filename delimited by -s and _s. That is: | 4331 # Matches the first component of a filename delimited by -s and _s. That is: |
4145 # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' | 4332 # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' |
4146 # _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' | 4333 # _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo' |
4147 # _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' | 4334 # _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo' |
4148 # _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' | 4335 # _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo' |
4149 _RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') | 4336 _RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+') |
4150 | 4337 |
4151 | 4338 |
4152 def _DropCommonSuffixes(filename): | 4339 def _DropCommonSuffixes(filename): |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4264 filename: The name of the current file. | 4451 filename: The name of the current file. |
4265 clean_lines: A CleansedLines instance containing the file. | 4452 clean_lines: A CleansedLines instance containing the file. |
4266 linenum: The number of the line to check. | 4453 linenum: The number of the line to check. |
4267 include_state: An _IncludeState instance in which the headers are inserted. | 4454 include_state: An _IncludeState instance in which the headers are inserted. |
4268 error: The function to call with any errors found. | 4455 error: The function to call with any errors found. |
4269 """ | 4456 """ |
4270 fileinfo = FileInfo(filename) | 4457 fileinfo = FileInfo(filename) |
4271 line = clean_lines.lines[linenum] | 4458 line = clean_lines.lines[linenum] |
4272 | 4459 |
4273 # "include" should use the new style "foo/bar.h" instead of just "bar.h" | 4460 # "include" should use the new style "foo/bar.h" instead of just "bar.h" |
4274 if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line): | 4461 # Only do this check if the included header follows google naming |
| 4462 # conventions. If not, assume that it's a 3rd party API that |
| 4463 # requires special include conventions. |
| 4464 # |
| 4465 # We also make an exception for Lua headers, which follow google |
| 4466 # naming convention but not the include convention. |
| 4467 match = Match(r'#include\s*"([^/]+\.h)"', line) |
| 4468 if match and not _THIRD_PARTY_HEADERS_PATTERN.match(match.group(1)): |
4275 error(filename, linenum, 'build/include', 4, | 4469 error(filename, linenum, 'build/include', 4, |
4276 'Include the directory when naming .h files') | 4470 'Include the directory when naming .h files') |
4277 | 4471 |
4278 # we shouldn't include a file more than once. actually, there are a | 4472 # we shouldn't include a file more than once. actually, there are a |
4279 # handful of instances where doing so is okay, but in general it's | 4473 # handful of instances where doing so is okay, but in general it's |
4280 # not. | 4474 # not. |
4281 match = _RE_PATTERN_INCLUDE.search(line) | 4475 match = _RE_PATTERN_INCLUDE.search(line) |
4282 if match: | 4476 if match: |
4283 include = match.group(2) | 4477 include = match.group(2) |
4284 is_system = (match.group(1) == '<') | 4478 is_system = (match.group(1) == '<') |
4285 if include in include_state: | 4479 duplicate_line = include_state.FindHeader(include) |
| 4480 if duplicate_line >= 0: |
4286 error(filename, linenum, 'build/include', 4, | 4481 error(filename, linenum, 'build/include', 4, |
4287 '"%s" already included at %s:%s' % | 4482 '"%s" already included at %s:%s' % |
4288 (include, filename, include_state[include])) | 4483 (include, filename, duplicate_line)) |
4289 else: | 4484 elif not _THIRD_PARTY_HEADERS_PATTERN.match(include): |
4290 include_state[include] = linenum | 4485 include_state.include_list[-1].append((include, linenum)) |
4291 | 4486 |
4292 # We want to ensure that headers appear in the right order: | 4487 # We want to ensure that headers appear in the right order: |
4293 # 1) for foo.cc, foo.h (preferred location) | 4488 # 1) for foo.cc, foo.h (preferred location) |
4294 # 2) c system files | 4489 # 2) c system files |
4295 # 3) cpp system files | 4490 # 3) cpp system files |
4296 # 4) for foo.cc, foo.h (deprecated location) | 4491 # 4) for foo.cc, foo.h (deprecated location) |
4297 # 5) other google headers | 4492 # 5) other google headers |
4298 # | 4493 # |
4299 # We classify each include statement as one of those 5 types | 4494 # We classify each include statement as one of those 5 types |
4300 # using a number of techniques. The include_state object keeps | 4495 # using a number of techniques. The include_state object keeps |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4434 if not line: | 4629 if not line: |
4435 return | 4630 return |
4436 | 4631 |
4437 match = _RE_PATTERN_INCLUDE.search(line) | 4632 match = _RE_PATTERN_INCLUDE.search(line) |
4438 if match: | 4633 if match: |
4439 CheckIncludeLine(filename, clean_lines, linenum, include_state, error) | 4634 CheckIncludeLine(filename, clean_lines, linenum, include_state, error) |
4440 return | 4635 return |
4441 | 4636 |
4442 # Reset include state across preprocessor directives. This is meant | 4637 # Reset include state across preprocessor directives. This is meant |
4443 # to silence warnings for conditional includes. | 4638 # to silence warnings for conditional includes. |
4444 if Match(r'^\s*#\s*(?:ifdef|elif|else|endif)\b', line): | 4639 match = Match(r'^\s*#\s*(if|ifdef|ifndef|elif|else|endif)\b', line) |
4445 include_state.ResetSection() | 4640 if match: |
| 4641 include_state.ResetSection(match.group(1)) |
4446 | 4642 |
4447 # Make Windows paths like Unix. | 4643 # Make Windows paths like Unix. |
4448 fullname = os.path.abspath(filename).replace('\\', '/') | 4644 fullname = os.path.abspath(filename).replace('\\', '/') |
4449 | 4645 |
4450 # Perform other checks now that we are sure that this is not an include line | 4646 # Perform other checks now that we are sure that this is not an include line |
4451 CheckCasts(filename, clean_lines, linenum, error) | 4647 CheckCasts(filename, clean_lines, linenum, error) |
4452 CheckGlobalStatic(filename, clean_lines, linenum, error) | 4648 CheckGlobalStatic(filename, clean_lines, linenum, error) |
4453 CheckPrintf(filename, clean_lines, linenum, error) | 4649 CheckPrintf(filename, clean_lines, linenum, error) |
4454 | 4650 |
4455 if file_extension == 'h': | 4651 if file_extension == 'h': |
4456 # TODO(unknown): check that 1-arg constructors are explicit. | 4652 # TODO(unknown): check that 1-arg constructors are explicit. |
4457 # How to tell it's a constructor? | 4653 # How to tell it's a constructor? |
4458 # (handled in CheckForNonStandardConstructs for now) | 4654 # (handled in CheckForNonStandardConstructs for now) |
4459 # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS | 4655 # TODO(unknown): check that classes declare or disable copy/assign |
4460 # (level 1 error) | 4656 # (level 1 error) |
4461 pass | 4657 pass |
4462 | 4658 |
4463 # Check if people are using the verboten C basic types. The only exception | 4659 # Check if people are using the verboten C basic types. The only exception |
4464 # we regularly allow is "unsigned short port" for port. | 4660 # we regularly allow is "unsigned short port" for port. |
4465 if Search(r'\bshort port\b', line): | 4661 if Search(r'\bshort port\b', line): |
4466 if not Search(r'\bunsigned short port\b', line): | 4662 if not Search(r'\bunsigned short port\b', line): |
4467 error(filename, linenum, 'runtime/int', 4, | 4663 error(filename, linenum, 'runtime/int', 4, |
4468 'Use "unsigned short" for ports, not "short"') | 4664 'Use "unsigned short" for ports, not "short"') |
4469 else: | 4665 else: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4549 if tok.startswith('sizeof'): | 4745 if tok.startswith('sizeof'): |
4550 skip_next = True | 4746 skip_next = True |
4551 continue | 4747 continue |
4552 is_const = False | 4748 is_const = False |
4553 break | 4749 break |
4554 if not is_const: | 4750 if not is_const: |
4555 error(filename, linenum, 'runtime/arrays', 1, | 4751 error(filename, linenum, 'runtime/arrays', 1, |
4556 'Do not use variable-length arrays. Use an appropriately named ' | 4752 'Do not use variable-length arrays. Use an appropriately named ' |
4557 "('k' followed by CamelCase) compile-time constant for the size.") | 4753 "('k' followed by CamelCase) compile-time constant for the size.") |
4558 | 4754 |
4559 # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or | 4755 # If DISALLOW_COPY_AND_ASSIGN DISALLOW_IMPLICIT_CONSTRUCTORS is present, |
4560 # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing | 4756 # then it should be the last thing in the class declaration. |
4561 # in the class declaration. | |
4562 match = Match( | 4757 match = Match( |
4563 (r'\s*' | 4758 (r'\s*' |
4564 r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' | 4759 r'(DISALLOW_(COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' |
4565 r'\(.*\);$'), | 4760 r'\(.*\);$'), |
4566 line) | 4761 line) |
4567 if match and linenum + 1 < clean_lines.NumLines(): | 4762 if match and linenum + 1 < clean_lines.NumLines(): |
4568 next_line = clean_lines.elided[linenum + 1] | 4763 next_line = clean_lines.elided[linenum + 1] |
4569 # We allow some, but not all, declarations of variables to be present | 4764 # We allow some, but not all, declarations of variables to be present |
4570 # in the statement that defines the class. The [\w\*,\s]* fragment of | 4765 # in the statement that defines the class. The [\w\*,\s]* fragment of |
4571 # the regular expression below allows users to declare instances of | 4766 # the regular expression below allows users to declare instances of |
4572 # the class or pointers to instances, but not less common types such | 4767 # the class or pointers to instances, but not less common types such |
4573 # as function pointers or arrays. It's a tradeoff between allowing | 4768 # as function pointers or arrays. It's a tradeoff between allowing |
4574 # reasonable code and avoiding trying to parse more C++ using regexps. | 4769 # reasonable code and avoiding trying to parse more C++ using regexps. |
(...skipping 17 matching lines...) Expand all Loading... |
4592 """Check for unsafe global or static objects. | 4787 """Check for unsafe global or static objects. |
4593 | 4788 |
4594 Args: | 4789 Args: |
4595 filename: The name of the current file. | 4790 filename: The name of the current file. |
4596 clean_lines: A CleansedLines instance containing the file. | 4791 clean_lines: A CleansedLines instance containing the file. |
4597 linenum: The number of the line to check. | 4792 linenum: The number of the line to check. |
4598 error: The function to call with any errors found. | 4793 error: The function to call with any errors found. |
4599 """ | 4794 """ |
4600 line = clean_lines.elided[linenum] | 4795 line = clean_lines.elided[linenum] |
4601 | 4796 |
| 4797 # Match two lines at a time to support multiline declarations |
| 4798 if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): |
| 4799 line += clean_lines.elided[linenum + 1].strip() |
| 4800 |
4602 # Check for people declaring static/global STL strings at the top level. | 4801 # Check for people declaring static/global STL strings at the top level. |
4603 # This is dangerous because the C++ language does not guarantee that | 4802 # This is dangerous because the C++ language does not guarantee that |
4604 # globals with constructors are initialized before the first access. | 4803 # globals with constructors are initialized before the first access. |
4605 match = Match( | 4804 match = Match( |
4606 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', | 4805 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', |
4607 line) | 4806 line) |
| 4807 |
4608 # Remove false positives: | 4808 # Remove false positives: |
4609 # - String pointers (as opposed to values). | 4809 # - String pointers (as opposed to values). |
4610 # string *pointer | 4810 # string *pointer |
4611 # const string *pointer | 4811 # const string *pointer |
4612 # string const *pointer | 4812 # string const *pointer |
4613 # string *const pointer | 4813 # string *const pointer |
4614 # | 4814 # |
4615 # - Functions and template specializations. | 4815 # - Functions and template specializations. |
4616 # string Function<Type>(... | 4816 # string Function<Type>(... |
4617 # string Class<Type>::Method(... | 4817 # string Class<Type>::Method(... |
4618 # | 4818 # |
4619 # - Operators. These are matched separately because operator names | 4819 # - Operators. These are matched separately because operator names |
4620 # cross non-word boundaries, and trying to match both operators | 4820 # cross non-word boundaries, and trying to match both operators |
4621 # and functions at the same time would decrease accuracy of | 4821 # and functions at the same time would decrease accuracy of |
4622 # matching identifiers. | 4822 # matching identifiers. |
4623 # string Class::operator*() | 4823 # string Class::operator*() |
4624 if (match and | 4824 if (match and |
4625 not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and | 4825 not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and |
4626 not Search(r'\boperator\W', line) and | 4826 not Search(r'\boperator\W', line) and |
4627 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)', match.group(3))): | 4827 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(3))): |
4628 error(filename, linenum, 'runtime/string', 4, | 4828 error(filename, linenum, 'runtime/string', 4, |
4629 'For a static/global string constant, use a C style string instead: ' | 4829 'For a static/global string constant, use a C style string instead: ' |
4630 '"%schar %s[]".' % | 4830 '"%schar %s[]".' % |
4631 (match.group(1), match.group(2))) | 4831 (match.group(1), match.group(2))) |
4632 | 4832 |
4633 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): | 4833 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): |
4634 error(filename, linenum, 'runtime/init', 4, | 4834 error(filename, linenum, 'runtime/init', 4, |
4635 'You seem to be initializing a member variable with itself.') | 4835 'You seem to be initializing a member variable with itself.') |
4636 | 4836 |
4637 | 4837 |
(...skipping 10 matching lines...) Expand all Loading... |
4648 | 4848 |
4649 # When snprintf is used, the second argument shouldn't be a literal. | 4849 # When snprintf is used, the second argument shouldn't be a literal. |
4650 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) | 4850 match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line) |
4651 if match and match.group(2) != '0': | 4851 if match and match.group(2) != '0': |
4652 # If 2nd arg is zero, snprintf is used to calculate size. | 4852 # If 2nd arg is zero, snprintf is used to calculate size. |
4653 error(filename, linenum, 'runtime/printf', 3, | 4853 error(filename, linenum, 'runtime/printf', 3, |
4654 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' | 4854 'If you can, use sizeof(%s) instead of %s as the 2nd arg ' |
4655 'to snprintf.' % (match.group(1), match.group(2))) | 4855 'to snprintf.' % (match.group(1), match.group(2))) |
4656 | 4856 |
4657 # Check if some verboten C functions are being used. | 4857 # Check if some verboten C functions are being used. |
4658 if Search(r'\bsprintf\b', line): | 4858 if Search(r'\bsprintf\s*\(', line): |
4659 error(filename, linenum, 'runtime/printf', 5, | 4859 error(filename, linenum, 'runtime/printf', 5, |
4660 'Never use sprintf. Use snprintf instead.') | 4860 'Never use sprintf. Use snprintf instead.') |
4661 match = Search(r'\b(strcpy|strcat)\b', line) | 4861 match = Search(r'\b(strcpy|strcat)\s*\(', line) |
4662 if match: | 4862 if match: |
4663 error(filename, linenum, 'runtime/printf', 4, | 4863 error(filename, linenum, 'runtime/printf', 4, |
4664 'Almost always, snprintf is better than %s' % match.group(1)) | 4864 'Almost always, snprintf is better than %s' % match.group(1)) |
4665 | 4865 |
4666 | 4866 |
4667 def IsDerivedFunction(clean_lines, linenum): | 4867 def IsDerivedFunction(clean_lines, linenum): |
4668 """Check if current line contains an inherited function. | 4868 """Check if current line contains an inherited function. |
4669 | 4869 |
4670 Args: | 4870 Args: |
4671 clean_lines: A CleansedLines instance containing the file. | 4871 clean_lines: A CleansedLines instance containing the file. |
4672 linenum: The number of the line to check. | 4872 linenum: The number of the line to check. |
4673 Returns: | 4873 Returns: |
4674 True if current line contains a function with "override" | 4874 True if current line contains a function with "override" |
4675 virt-specifier. | 4875 virt-specifier. |
4676 """ | 4876 """ |
4677 # Look for leftmost opening parenthesis on current line | 4877 # Scan back a few lines for start of current function |
4678 opening_paren = clean_lines.elided[linenum].find('(') | 4878 for i in xrange(linenum, max(-1, linenum - 10), -1): |
4679 if opening_paren < 0: return False | 4879 match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) |
4680 | 4880 if match: |
4681 # Look for "override" after the matching closing parenthesis | 4881 # Look for "override" after the matching closing parenthesis |
4682 line, _, closing_paren = CloseExpression(clean_lines, linenum, opening_paren) | 4882 line, _, closing_paren = CloseExpression( |
4683 return closing_paren >= 0 and Search(r'\boverride\b', line[closing_paren:]) | 4883 clean_lines, i, len(match.group(1))) |
| 4884 return (closing_paren >= 0 and |
| 4885 Search(r'\boverride\b', line[closing_paren:])) |
| 4886 return False |
4684 | 4887 |
4685 | 4888 |
4686 def IsInitializerList(clean_lines, linenum): | 4889 def IsInitializerList(clean_lines, linenum): |
4687 """Check if current line is inside constructor initializer list. | 4890 """Check if current line is inside constructor initializer list. |
4688 | 4891 |
4689 Args: | 4892 Args: |
4690 clean_lines: A CleansedLines instance containing the file. | 4893 clean_lines: A CleansedLines instance containing the file. |
4691 linenum: The number of the line to check. | 4894 linenum: The number of the line to check. |
4692 Returns: | 4895 Returns: |
4693 True if current line appears to be inside constructor initializer | 4896 True if current line appears to be inside constructor initializer |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4799 # inside declarators: reference parameter | 5002 # inside declarators: reference parameter |
4800 # We will exclude the first two cases by checking that we are not inside a | 5003 # We will exclude the first two cases by checking that we are not inside a |
4801 # function body, including one that was just introduced by a trailing '{'. | 5004 # function body, including one that was just introduced by a trailing '{'. |
4802 # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. | 5005 # TODO(unknown): Doesn't account for 'catch(Exception& e)' [rare]. |
4803 if (nesting_state.previous_stack_top and | 5006 if (nesting_state.previous_stack_top and |
4804 not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or | 5007 not (isinstance(nesting_state.previous_stack_top, _ClassInfo) or |
4805 isinstance(nesting_state.previous_stack_top, _NamespaceInfo))): | 5008 isinstance(nesting_state.previous_stack_top, _NamespaceInfo))): |
4806 # Not at toplevel, not within a class, and not within a namespace | 5009 # Not at toplevel, not within a class, and not within a namespace |
4807 return | 5010 return |
4808 | 5011 |
| 5012 # Avoid initializer lists. We only need to scan back from the |
| 5013 # current line for something that starts with ':'. |
| 5014 # |
| 5015 # We don't need to check the current line, since the '&' would |
| 5016 # appear inside the second set of parentheses on the current line as |
| 5017 # opposed to the first set. |
| 5018 if linenum > 0: |
| 5019 for i in xrange(linenum - 1, max(0, linenum - 10), -1): |
| 5020 previous_line = clean_lines.elided[i] |
| 5021 if not Search(r'[),]\s*$', previous_line): |
| 5022 break |
| 5023 if Match(r'^\s*:\s+\S', previous_line): |
| 5024 return |
| 5025 |
4809 # Avoid preprocessors | 5026 # Avoid preprocessors |
4810 if Search(r'\\\s*$', line): | 5027 if Search(r'\\\s*$', line): |
4811 return | 5028 return |
4812 | 5029 |
4813 # Avoid constructor initializer lists | 5030 # Avoid constructor initializer lists |
4814 if IsInitializerList(clean_lines, linenum): | 5031 if IsInitializerList(clean_lines, linenum): |
4815 return | 5032 return |
4816 | 5033 |
4817 # We allow non-const references in a few standard places, like functions | 5034 # We allow non-const references in a few standard places, like functions |
4818 # called "swap()" or iostream operators like "<<" or ">>". Do not check | 5035 # called "swap()" or iostream operators like "<<" or ">>". Do not check |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4874 # For template arguments, we match on types immediately following | 5091 # For template arguments, we match on types immediately following |
4875 # an opening bracket without any spaces. This is a fast way to | 5092 # an opening bracket without any spaces. This is a fast way to |
4876 # silence the common case where the function type is the first | 5093 # silence the common case where the function type is the first |
4877 # template argument. False negative with less-than comparison is | 5094 # template argument. False negative with less-than comparison is |
4878 # avoided because those operators are usually followed by a space. | 5095 # avoided because those operators are usually followed by a space. |
4879 # | 5096 # |
4880 # function<double(double)> // bracket + no space = false positive | 5097 # function<double(double)> // bracket + no space = false positive |
4881 # value < double(42) // bracket + space = true positive | 5098 # value < double(42) // bracket + space = true positive |
4882 matched_new_or_template = match.group(1) | 5099 matched_new_or_template = match.group(1) |
4883 | 5100 |
| 5101 # Avoid arrays by looking for brackets that come after the closing |
| 5102 # parenthesis. |
| 5103 if Match(r'\([^()]+\)\s*\[', match.group(3)): |
| 5104 return |
| 5105 |
4884 # Other things to ignore: | 5106 # Other things to ignore: |
4885 # - Function pointers | 5107 # - Function pointers |
4886 # - Casts to pointer types | 5108 # - Casts to pointer types |
4887 # - Placement new | 5109 # - Placement new |
4888 # - Alias declarations | 5110 # - Alias declarations |
4889 matched_funcptr = match.group(3) | 5111 matched_funcptr = match.group(3) |
4890 if (matched_new_or_template is None and | 5112 if (matched_new_or_template is None and |
4891 not (matched_funcptr and | 5113 not (matched_funcptr and |
4892 (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', | 5114 (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', |
4893 matched_funcptr) or | 5115 matched_funcptr) or |
4894 matched_funcptr.startswith('(*)'))) and | 5116 matched_funcptr.startswith('(*)'))) and |
4895 not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and | 5117 not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and |
4896 not Search(r'new\(\S+\)\s*' + matched_type, line)): | 5118 not Search(r'new\(\S+\)\s*' + matched_type, line)): |
4897 error(filename, linenum, 'readability/casting', 4, | 5119 error(filename, linenum, 'readability/casting', 4, |
4898 'Using deprecated casting style. ' | 5120 'Using deprecated casting style. ' |
4899 'Use static_cast<%s>(...) instead' % | 5121 'Use static_cast<%s>(...) instead' % |
4900 matched_type) | 5122 matched_type) |
4901 | 5123 |
4902 if not expecting_function: | 5124 if not expecting_function: |
4903 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], | 5125 CheckCStyleCast(filename, clean_lines, linenum, 'static_cast', |
4904 'static_cast', | |
4905 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) | 5126 r'\((int|float|double|bool|char|u?int(16|32|64))\)', error) |
4906 | 5127 |
4907 # This doesn't catch all cases. Consider (const char * const)"hello". | 5128 # This doesn't catch all cases. Consider (const char * const)"hello". |
4908 # | 5129 # |
4909 # (char *) "foo" should always be a const_cast (reinterpret_cast won't | 5130 # (char *) "foo" should always be a const_cast (reinterpret_cast won't |
4910 # compile). | 5131 # compile). |
4911 if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], | 5132 if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast', |
4912 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error): | 5133 r'\((char\s?\*+\s?)\)\s*"', error): |
4913 pass | 5134 pass |
4914 else: | 5135 else: |
4915 # Check pointer casts for other than string constants | 5136 # Check pointer casts for other than string constants |
4916 CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum], | 5137 CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast', |
4917 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error) | 5138 r'\((\w+\s?\*+\s?)\)', error) |
4918 | 5139 |
4919 # In addition, we look for people taking the address of a cast. This | 5140 # In addition, we look for people taking the address of a cast. This |
4920 # is dangerous -- casts can assign to temporaries, so the pointer doesn't | 5141 # is dangerous -- casts can assign to temporaries, so the pointer doesn't |
4921 # point where you think. | 5142 # point where you think. |
| 5143 # |
| 5144 # Some non-identifier character is required before the '&' for the |
| 5145 # expression to be recognized as a cast. These are casts: |
| 5146 # expression = &static_cast<int*>(temporary()); |
| 5147 # function(&(int*)(temporary())); |
| 5148 # |
| 5149 # This is not a cast: |
| 5150 # reference_type&(int* function_param); |
4922 match = Search( | 5151 match = Search( |
4923 r'(?:&\(([^)]+)\)[\w(])|' | 5152 r'(?:[^\w]&\(([^)]+)\)[\w(])|' |
4924 r'(?:&(static|dynamic|down|reinterpret)_cast\b)', line) | 5153 r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line) |
4925 if match and match.group(1) != '*': | 5154 if match and match.group(1) != '*': |
4926 # Try a better error message when the & is bound to something | 5155 # Try a better error message when the & is bound to something |
4927 # dereferenced by the casted pointer, as opposed to the casted | 5156 # dereferenced by the casted pointer, as opposed to the casted |
4928 # pointer itself. | 5157 # pointer itself. |
4929 parenthesis_error = False | 5158 parenthesis_error = False |
4930 match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) | 5159 match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) |
4931 if match: | 5160 if match: |
4932 _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) | 5161 _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) |
4933 if x1 >= 0 and clean_lines.elided[y1][x1] == '(': | 5162 if x1 >= 0 and clean_lines.elided[y1][x1] == '(': |
4934 _, y2, x2 = CloseExpression(clean_lines, y1, x1) | 5163 _, y2, x2 = CloseExpression(clean_lines, y1, x1) |
4935 if x2 >= 0: | 5164 if x2 >= 0: |
4936 extended_line = clean_lines.elided[y2][x2:] | 5165 extended_line = clean_lines.elided[y2][x2:] |
4937 if y2 < clean_lines.NumLines() - 1: | 5166 if y2 < clean_lines.NumLines() - 1: |
4938 extended_line += clean_lines.elided[y2 + 1] | 5167 extended_line += clean_lines.elided[y2 + 1] |
4939 if Match(r'\s*(?:->|\[)', extended_line): | 5168 if Match(r'\s*(?:->|\[)', extended_line): |
4940 parenthesis_error = True | 5169 parenthesis_error = True |
4941 | 5170 |
4942 if parenthesis_error: | 5171 if parenthesis_error: |
4943 error(filename, linenum, 'readability/casting', 4, | 5172 error(filename, linenum, 'readability/casting', 4, |
4944 ('Are you taking an address of something dereferenced ' | 5173 ('Are you taking an address of something dereferenced ' |
4945 'from a cast? Wrapping the dereferenced expression in ' | 5174 'from a cast? Wrapping the dereferenced expression in ' |
4946 'parentheses will make the binding more obvious')) | 5175 'parentheses will make the binding more obvious')) |
4947 else: | 5176 else: |
4948 error(filename, linenum, 'runtime/casting', 4, | 5177 error(filename, linenum, 'runtime/casting', 4, |
4949 ('Are you taking an address of a cast? ' | 5178 ('Are you taking an address of a cast? ' |
4950 'This is dangerous: could be a temp var. ' | 5179 'This is dangerous: could be a temp var. ' |
4951 'Take the address before doing the cast, rather than after')) | 5180 'Take the address before doing the cast, rather than after')) |
4952 | 5181 |
4953 | 5182 |
4954 def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern, | 5183 def CheckCStyleCast(filename, clean_lines, linenum, cast_type, pattern, error): |
4955 error): | |
4956 """Checks for a C-style cast by looking for the pattern. | 5184 """Checks for a C-style cast by looking for the pattern. |
4957 | 5185 |
4958 Args: | 5186 Args: |
4959 filename: The name of the current file. | 5187 filename: The name of the current file. |
| 5188 clean_lines: A CleansedLines instance containing the file. |
4960 linenum: The number of the line to check. | 5189 linenum: The number of the line to check. |
4961 line: The line of code to check. | |
4962 raw_line: The raw line of code to check, with comments. | |
4963 cast_type: The string for the C++ cast to recommend. This is either | 5190 cast_type: The string for the C++ cast to recommend. This is either |
4964 reinterpret_cast, static_cast, or const_cast, depending. | 5191 reinterpret_cast, static_cast, or const_cast, depending. |
4965 pattern: The regular expression used to find C-style casts. | 5192 pattern: The regular expression used to find C-style casts. |
4966 error: The function to call with any errors found. | 5193 error: The function to call with any errors found. |
4967 | 5194 |
4968 Returns: | 5195 Returns: |
4969 True if an error was emitted. | 5196 True if an error was emitted. |
4970 False otherwise. | 5197 False otherwise. |
4971 """ | 5198 """ |
| 5199 line = clean_lines.elided[linenum] |
4972 match = Search(pattern, line) | 5200 match = Search(pattern, line) |
4973 if not match: | 5201 if not match: |
4974 return False | 5202 return False |
4975 | 5203 |
4976 # Exclude lines with keywords that tend to look like casts, and also | 5204 # Exclude lines with keywords that tend to look like casts |
4977 # macros which are generally troublesome. | 5205 context = line[0:match.start(1) - 1] |
4978 if Match(r'.*\b(?:sizeof|alignof|alignas|[A-Z_]+)\s*$', | 5206 if Match(r'.*\b(?:sizeof|alignof|alignas|[_A-Z][_A-Z0-9]*)\s*$', context): |
4979 line[0:match.start(1) - 1]): | 5207 return False |
| 5208 |
| 5209 # Try expanding current context to see if we one level of |
| 5210 # parentheses inside a macro. |
| 5211 if linenum > 0: |
| 5212 for i in xrange(linenum - 1, max(0, linenum - 5), -1): |
| 5213 context = clean_lines.elided[i] + context |
| 5214 if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): |
4980 return False | 5215 return False |
4981 | 5216 |
4982 # operator++(int) and operator--(int) | 5217 # operator++(int) and operator--(int) |
4983 if (line[0:match.start(1) - 1].endswith(' operator++') or | 5218 if context.endswith(' operator++') or context.endswith(' operator--'): |
4984 line[0:match.start(1) - 1].endswith(' operator--')): | |
4985 return False | 5219 return False |
4986 | 5220 |
4987 # A single unnamed argument for a function tends to look like old | 5221 # A single unnamed argument for a function tends to look like old |
4988 # style cast. If we see those, don't issue warnings for deprecated | 5222 # style cast. If we see those, don't issue warnings for deprecated |
4989 # casts, instead issue warnings for unnamed arguments where | 5223 # casts, instead issue warnings for unnamed arguments where |
4990 # appropriate. | 5224 # appropriate. |
4991 # | 5225 # |
4992 # These are things that we want warnings for, since the style guide | 5226 # These are things that we want warnings for, since the style guide |
4993 # explicitly require all parameters to be named: | 5227 # explicitly require all parameters to be named: |
4994 # Function(int); | 5228 # Function(int); |
4995 # Function(int) { | 5229 # Function(int) { |
4996 # ConstMember(int) const; | 5230 # ConstMember(int) const; |
4997 # ConstMember(int) const { | 5231 # ConstMember(int) const { |
4998 # ExceptionMember(int) throw (...); | 5232 # ExceptionMember(int) throw (...); |
4999 # ExceptionMember(int) throw (...) { | 5233 # ExceptionMember(int) throw (...) { |
5000 # PureVirtual(int) = 0; | 5234 # PureVirtual(int) = 0; |
5001 # | 5235 # |
5002 # These are functions of some sort, where the compiler would be fine | 5236 # These are functions of some sort, where the compiler would be fine |
5003 # if they had named parameters, but people often omit those | 5237 # if they had named parameters, but people often omit those |
5004 # identifiers to reduce clutter: | 5238 # identifiers to reduce clutter: |
5005 # (FunctionPointer)(int); | 5239 # (FunctionPointer)(int); |
5006 # (FunctionPointer)(int) = value; | 5240 # (FunctionPointer)(int) = value; |
5007 # Function((function_pointer_arg)(int)) | 5241 # Function((function_pointer_arg)(int)) |
| 5242 # Function((function_pointer_arg)(int), int param) |
5008 # <TemplateArgument(int)>; | 5243 # <TemplateArgument(int)>; |
5009 # <(FunctionPointerTemplateArgument)(int)>; | 5244 # <(FunctionPointerTemplateArgument)(int)>; |
5010 remainder = line[match.end(0):] | 5245 remainder = line[match.end(0):] |
5011 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|=|>|\{|\))', | 5246 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),])', |
5012 remainder): | 5247 remainder): |
5013 # Looks like an unnamed parameter. | 5248 # Looks like an unnamed parameter. |
5014 | 5249 |
5015 # Don't warn on any kind of template arguments. | 5250 # Don't warn on any kind of template arguments. |
5016 if Match(r'^\s*>', remainder): | 5251 if Match(r'^\s*>', remainder): |
5017 return False | 5252 return False |
5018 | 5253 |
5019 # Don't warn on assignments to function pointers, but keep warnings for | 5254 # Don't warn on assignments to function pointers, but keep warnings for |
5020 # unnamed parameters to pure virtual functions. Note that this pattern | 5255 # unnamed parameters to pure virtual functions. Note that this pattern |
5021 # will also pass on assignments of "0" to function pointers, but the | 5256 # will also pass on assignments of "0" to function pointers, but the |
5022 # preferred values for those would be "nullptr" or "NULL". | 5257 # preferred values for those would be "nullptr" or "NULL". |
5023 matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder) | 5258 matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder) |
5024 if matched_zero and matched_zero.group(1) != '0': | 5259 if matched_zero and matched_zero.group(1) != '0': |
5025 return False | 5260 return False |
5026 | 5261 |
5027 # Don't warn on function pointer declarations. For this we need | 5262 # Don't warn on function pointer declarations. For this we need |
5028 # to check what came before the "(type)" string. | 5263 # to check what came before the "(type)" string. |
5029 if Match(r'.*\)\s*$', line[0:match.start(0)]): | 5264 if Match(r'.*\)\s*$', line[0:match.start(0)]): |
5030 return False | 5265 return False |
5031 | 5266 |
5032 # Don't warn if the parameter is named with block comments, e.g.: | 5267 # Don't warn if the parameter is named with block comments, e.g.: |
5033 # Function(int /*unused_param*/); | 5268 # Function(int /*unused_param*/); |
| 5269 raw_line = clean_lines.raw_lines[linenum] |
5034 if '/*' in raw_line: | 5270 if '/*' in raw_line: |
5035 return False | 5271 return False |
5036 | 5272 |
5037 # Passed all filters, issue warning here. | 5273 # Passed all filters, issue warning here. |
5038 error(filename, linenum, 'readability/function', 3, | 5274 error(filename, linenum, 'readability/function', 3, |
5039 'All parameters should be named in a function') | 5275 'All parameters should be named in a function') |
5040 return True | 5276 return True |
5041 | 5277 |
5042 # At this point, all that should be left is actual casts. | 5278 # At this point, all that should be left is actual casts. |
5043 error(filename, linenum, 'readability/casting', 4, | 5279 error(filename, linenum, 'readability/casting', 4, |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5175 filename_h = filename_h.replace('/public/', '/') | 5411 filename_h = filename_h.replace('/public/', '/') |
5176 filename_h = filename_h.replace('/internal/', '/') | 5412 filename_h = filename_h.replace('/internal/', '/') |
5177 | 5413 |
5178 files_belong_to_same_module = filename_cc.endswith(filename_h) | 5414 files_belong_to_same_module = filename_cc.endswith(filename_h) |
5179 common_path = '' | 5415 common_path = '' |
5180 if files_belong_to_same_module: | 5416 if files_belong_to_same_module: |
5181 common_path = filename_cc[:-len(filename_h)] | 5417 common_path = filename_cc[:-len(filename_h)] |
5182 return files_belong_to_same_module, common_path | 5418 return files_belong_to_same_module, common_path |
5183 | 5419 |
5184 | 5420 |
5185 def UpdateIncludeState(filename, include_state, io=codecs): | 5421 def UpdateIncludeState(filename, include_dict, io=codecs): |
5186 """Fill up the include_state with new includes found from the file. | 5422 """Fill up the include_dict with new includes found from the file. |
5187 | 5423 |
5188 Args: | 5424 Args: |
5189 filename: the name of the header to read. | 5425 filename: the name of the header to read. |
5190 include_state: an _IncludeState instance in which the headers are inserted. | 5426 include_dict: a dictionary in which the headers are inserted. |
5191 io: The io factory to use to read the file. Provided for testability. | 5427 io: The io factory to use to read the file. Provided for testability. |
5192 | 5428 |
5193 Returns: | 5429 Returns: |
5194 True if a header was succesfully added. False otherwise. | 5430 True if a header was successfully added. False otherwise. |
5195 """ | 5431 """ |
5196 headerfile = None | 5432 headerfile = None |
5197 try: | 5433 try: |
5198 headerfile = io.open(filename, 'r', 'utf8', 'replace') | 5434 headerfile = io.open(filename, 'r', 'utf8', 'replace') |
5199 except IOError: | 5435 except IOError: |
5200 return False | 5436 return False |
5201 linenum = 0 | 5437 linenum = 0 |
5202 for line in headerfile: | 5438 for line in headerfile: |
5203 linenum += 1 | 5439 linenum += 1 |
5204 clean_line = CleanseComments(line) | 5440 clean_line = CleanseComments(line) |
5205 match = _RE_PATTERN_INCLUDE.search(clean_line) | 5441 match = _RE_PATTERN_INCLUDE.search(clean_line) |
5206 if match: | 5442 if match: |
5207 include = match.group(2) | 5443 include = match.group(2) |
5208 # The value formatting is cute, but not really used right now. | 5444 include_dict.setdefault(include, linenum) |
5209 # What matters here is that the key is in include_state. | |
5210 include_state.setdefault(include, '%s:%d' % (filename, linenum)) | |
5211 return True | 5445 return True |
5212 | 5446 |
5213 | 5447 |
5214 def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, | 5448 def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error, |
5215 io=codecs): | 5449 io=codecs): |
5216 """Reports for missing stl includes. | 5450 """Reports for missing stl includes. |
5217 | 5451 |
5218 This function will output warnings to make sure you are including the headers | 5452 This function will output warnings to make sure you are including the headers |
5219 necessary for the stl containers and functions that you use. We only give one | 5453 necessary for the stl containers and functions that you use. We only give one |
5220 reason to include a header. For example, if you use both equal_to<> and | 5454 reason to include a header. For example, if you use both equal_to<> and |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5253 # The following function is just a speed up, no semantics are changed. | 5487 # The following function is just a speed up, no semantics are changed. |
5254 if not '<' in line: # Reduces the cpu time usage by skipping lines. | 5488 if not '<' in line: # Reduces the cpu time usage by skipping lines. |
5255 continue | 5489 continue |
5256 | 5490 |
5257 for pattern, template, header in _re_pattern_templates: | 5491 for pattern, template, header in _re_pattern_templates: |
5258 if pattern.search(line): | 5492 if pattern.search(line): |
5259 required[header] = (linenum, template) | 5493 required[header] = (linenum, template) |
5260 | 5494 |
5261 # The policy is that if you #include something in foo.h you don't need to | 5495 # The policy is that if you #include something in foo.h you don't need to |
5262 # include it again in foo.cc. Here, we will look at possible includes. | 5496 # include it again in foo.cc. Here, we will look at possible includes. |
5263 # Let's copy the include_state so it is only messed up within this function. | 5497 # Let's flatten the include_state include_list and copy it into a dictionary. |
5264 include_state = include_state.copy() | 5498 include_dict = dict([item for sublist in include_state.include_list |
| 5499 for item in sublist]) |
5265 | 5500 |
5266 # Did we find the header for this file (if any) and succesfully load it? | 5501 # Did we find the header for this file (if any) and successfully load it? |
5267 header_found = False | 5502 header_found = False |
5268 | 5503 |
5269 # Use the absolute path so that matching works properly. | 5504 # Use the absolute path so that matching works properly. |
5270 abs_filename = FileInfo(filename).FullName() | 5505 abs_filename = FileInfo(filename).FullName() |
5271 | 5506 |
5272 # For Emacs's flymake. | 5507 # For Emacs's flymake. |
5273 # If cpplint is invoked from Emacs's flymake, a temporary file is generated | 5508 # If cpplint is invoked from Emacs's flymake, a temporary file is generated |
5274 # by flymake and that file name might end with '_flymake.cc'. In that case, | 5509 # by flymake and that file name might end with '_flymake.cc'. In that case, |
5275 # restore original file name here so that the corresponding header file can be | 5510 # restore original file name here so that the corresponding header file can be |
5276 # found. | 5511 # found. |
5277 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' | 5512 # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h' |
5278 # instead of 'foo_flymake.h' | 5513 # instead of 'foo_flymake.h' |
5279 abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) | 5514 abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename) |
5280 | 5515 |
5281 # include_state is modified during iteration, so we iterate over a copy of | 5516 # include_dict is modified during iteration, so we iterate over a copy of |
5282 # the keys. | 5517 # the keys. |
5283 header_keys = include_state.keys() | 5518 header_keys = include_dict.keys() |
5284 for header in header_keys: | 5519 for header in header_keys: |
5285 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) | 5520 (same_module, common_path) = FilesBelongToSameModule(abs_filename, header) |
5286 fullpath = common_path + header | 5521 fullpath = common_path + header |
5287 if same_module and UpdateIncludeState(fullpath, include_state, io): | 5522 if same_module and UpdateIncludeState(fullpath, include_dict, io): |
5288 header_found = True | 5523 header_found = True |
5289 | 5524 |
5290 # If we can't find the header file for a .cc, assume it's because we don't | 5525 # If we can't find the header file for a .cc, assume it's because we don't |
5291 # know where to look. In that case we'll give up as we're not sure they | 5526 # know where to look. In that case we'll give up as we're not sure they |
5292 # didn't include it in the .h file. | 5527 # didn't include it in the .h file. |
5293 # TODO(unknown): Do a better job of finding .h files so we are confident that | 5528 # TODO(unknown): Do a better job of finding .h files so we are confident that |
5294 # not having the .h file means there isn't one. | 5529 # not having the .h file means there isn't one. |
5295 if filename.endswith('.cc') and not header_found: | 5530 if filename.endswith('.cc') and not header_found: |
5296 return | 5531 return |
5297 | 5532 |
5298 # All the lines have been processed, report the errors found. | 5533 # All the lines have been processed, report the errors found. |
5299 for required_header_unstripped in required: | 5534 for required_header_unstripped in required: |
5300 template = required[required_header_unstripped][1] | 5535 template = required[required_header_unstripped][1] |
5301 if required_header_unstripped.strip('<>"') not in include_state: | 5536 if required_header_unstripped.strip('<>"') not in include_dict: |
5302 error(filename, required[required_header_unstripped][0], | 5537 error(filename, required[required_header_unstripped][0], |
5303 'build/include_what_you_use', 4, | 5538 'build/include_what_you_use', 4, |
5304 'Add #include ' + required_header_unstripped + ' for ' + template) | 5539 'Add #include ' + required_header_unstripped + ' for ' + template) |
5305 | 5540 |
5306 | 5541 |
5307 _RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') | 5542 _RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<') |
5308 | 5543 |
5309 | 5544 |
5310 def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): | 5545 def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error): |
5311 """Check that make_pair's template arguments are deduced. | 5546 """Check that make_pair's template arguments are deduced. |
5312 | 5547 |
5313 G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are | 5548 G++ 4.6 in C++11 mode fails badly if make_pair's template arguments are |
5314 specified explicitly, and such use isn't intended in any case. | 5549 specified explicitly, and such use isn't intended in any case. |
5315 | 5550 |
5316 Args: | 5551 Args: |
5317 filename: The name of the current file. | 5552 filename: The name of the current file. |
5318 clean_lines: A CleansedLines instance containing the file. | 5553 clean_lines: A CleansedLines instance containing the file. |
5319 linenum: The number of the line to check. | 5554 linenum: The number of the line to check. |
5320 error: The function to call with any errors found. | 5555 error: The function to call with any errors found. |
5321 """ | 5556 """ |
5322 line = clean_lines.elided[linenum] | 5557 line = clean_lines.elided[linenum] |
5323 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) | 5558 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) |
5324 if match: | 5559 if match: |
5325 error(filename, linenum, 'build/explicit_make_pair', | 5560 error(filename, linenum, 'build/explicit_make_pair', |
5326 4, # 4 = high confidence | 5561 4, # 4 = high confidence |
5327 'For C++11-compatibility, omit template arguments from make_pair' | 5562 'For C++11-compatibility, omit template arguments from make_pair' |
5328 ' OR use pair directly OR if appropriate, construct a pair directly') | 5563 ' OR use pair directly OR if appropriate, construct a pair directly') |
| 5564 |
| 5565 |
5329 def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error): | 5566 def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error): |
5330 """Check that default lambda captures are not used. | 5567 """Check that default lambda captures are not used. |
5331 | 5568 |
5332 Args: | 5569 Args: |
5333 filename: The name of the current file. | 5570 filename: The name of the current file. |
5334 clean_lines: A CleansedLines instance containing the file. | 5571 clean_lines: A CleansedLines instance containing the file. |
5335 linenum: The number of the line to check. | 5572 linenum: The number of the line to check. |
5336 error: The function to call with any errors found. | 5573 error: The function to call with any errors found. |
5337 """ | 5574 """ |
5338 line = clean_lines.elided[linenum] | 5575 line = clean_lines.elided[linenum] |
5339 | 5576 |
5340 # A lambda introducer specifies a default capture if it starts with "[=" | 5577 # A lambda introducer specifies a default capture if it starts with "[=" |
5341 # or if it starts with "[&" _not_ followed by an identifier. | 5578 # or if it starts with "[&" _not_ followed by an identifier. |
5342 match = Match(r'^(.*)\[\s*(?:=|&[^\w])', line) | 5579 match = Match(r'^(.*)\[\s*(?:=|&[^\w])', line) |
5343 if match: | 5580 if match: |
5344 # Found a potential error, check what comes after the lambda-introducer. | 5581 # Found a potential error, check what comes after the lambda-introducer. |
5345 # If it's not open parenthesis (for lambda-declarator) or open brace | 5582 # If it's not open parenthesis (for lambda-declarator) or open brace |
5346 # (for compound-statement), it's not a lambda. | 5583 # (for compound-statement), it's not a lambda. |
5347 line, _, pos = CloseExpression(clean_lines, linenum, len(match.group(1))) | 5584 line, _, pos = CloseExpression(clean_lines, linenum, len(match.group(1))) |
5348 if pos >= 0 and Match(r'^\s*[{(]', line[pos:]): | 5585 if pos >= 0 and Match(r'^\s*[{(]', line[pos:]): |
5349 error(filename, linenum, 'build/c++11', | 5586 error(filename, linenum, 'build/c++11', |
5350 4, # 4 = high confidence | 5587 4, # 4 = high confidence |
5351 'Default lambda captures are an unapproved C++ feature.') | 5588 'Default lambda captures are an unapproved C++ feature.') |
5352 | 5589 |
5353 | 5590 |
| 5591 def CheckRedundantVirtual(filename, clean_lines, linenum, error): |
| 5592 """Check if line contains a redundant "virtual" function-specifier. |
| 5593 |
| 5594 Args: |
| 5595 filename: The name of the current file. |
| 5596 clean_lines: A CleansedLines instance containing the file. |
| 5597 linenum: The number of the line to check. |
| 5598 error: The function to call with any errors found. |
| 5599 """ |
| 5600 # Look for "virtual" on current line. |
| 5601 line = clean_lines.elided[linenum] |
| 5602 virtual = Match(r'^(.*\bvirtual\b)', line) |
| 5603 if not virtual: return |
| 5604 |
| 5605 # Look for the next opening parenthesis. This is the start of the |
| 5606 # parameter list (possibly on the next line shortly after virtual). |
| 5607 # TODO(unknown): doesn't work if there are virtual functions with |
| 5608 # decltype() or other things that use parentheses, but csearch suggests |
| 5609 # that this is rare. |
| 5610 end_col = -1 |
| 5611 end_line = -1 |
| 5612 start_col = len(virtual.group(1)) |
| 5613 for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): |
| 5614 line = clean_lines.elided[start_line][start_col:] |
| 5615 parameter_list = Match(r'^([^(]*)\(', line) |
| 5616 if parameter_list: |
| 5617 # Match parentheses to find the end of the parameter list |
| 5618 (_, end_line, end_col) = CloseExpression( |
| 5619 clean_lines, start_line, start_col + len(parameter_list.group(1))) |
| 5620 break |
| 5621 start_col = 0 |
| 5622 |
| 5623 if end_col < 0: |
| 5624 return # Couldn't find end of parameter list, give up |
| 5625 |
| 5626 # Look for "override" or "final" after the parameter list |
| 5627 # (possibly on the next few lines). |
| 5628 for i in xrange(end_line, min(end_line + 3, clean_lines.NumLines())): |
| 5629 line = clean_lines.elided[i][end_col:] |
| 5630 match = Search(r'\b(override|final)\b', line) |
| 5631 if match: |
| 5632 error(filename, linenum, 'readability/inheritance', 4, |
| 5633 ('"virtual" is redundant since function is ' |
| 5634 'already declared as "%s"' % match.group(1))) |
| 5635 |
| 5636 # Set end_col to check whole lines after we are done with the |
| 5637 # first line. |
| 5638 end_col = 0 |
| 5639 if Search(r'[^\w]\s*$', line): |
| 5640 break |
| 5641 |
| 5642 |
| 5643 def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error): |
| 5644 """Check if line contains a redundant "override" or "final" virt-specifier. |
| 5645 |
| 5646 Args: |
| 5647 filename: The name of the current file. |
| 5648 clean_lines: A CleansedLines instance containing the file. |
| 5649 linenum: The number of the line to check. |
| 5650 error: The function to call with any errors found. |
| 5651 """ |
| 5652 # Check that at most one of "override" or "final" is present, not both |
| 5653 line = clean_lines.elided[linenum] |
| 5654 if Search(r'\boverride\b', line) and Search(r'\bfinal\b', line): |
| 5655 error(filename, linenum, 'readability/inheritance', 4, |
| 5656 ('"override" is redundant since function is ' |
| 5657 'already declared as "final"')) |
| 5658 |
| 5659 |
5354 | 5660 |
5355 | 5661 |
| 5662 # Returns true if we are at a new block, and it is directly |
| 5663 # inside of a namespace. |
| 5664 def IsBlockInNameSpace(nesting_state, is_forward_declaration): |
| 5665 """Checks that the new block is directly in a namespace. |
| 5666 |
| 5667 Args: |
| 5668 nesting_state: The _NestingState object that contains info about our state. |
| 5669 is_forward_declaration: If the class is a forward declared class. |
| 5670 Returns: |
| 5671 Whether or not the new block is directly in a namespace. |
| 5672 """ |
| 5673 if is_forward_declaration: |
| 5674 if len(nesting_state.stack) >= 1 and ( |
| 5675 isinstance(nesting_state.stack[-1], _NamespaceInfo)): |
| 5676 return True |
| 5677 else: |
| 5678 return False |
| 5679 |
| 5680 return (len(nesting_state.stack) > 1 and |
| 5681 nesting_state.stack[-1].check_namespace_indentation and |
| 5682 isinstance(nesting_state.stack[-2], _NamespaceInfo)) |
| 5683 |
| 5684 |
| 5685 def ShouldCheckNamespaceIndentation(nesting_state, is_namespace_indent_item, |
| 5686 raw_lines_no_comments, linenum): |
| 5687 """This method determines if we should apply our namespace indentation check. |
| 5688 |
| 5689 Args: |
| 5690 nesting_state: The current nesting state. |
| 5691 is_namespace_indent_item: If we just put a new class on the stack, True. |
| 5692 If the top of the stack is not a class, or we did not recently |
| 5693 add the class, False. |
| 5694 raw_lines_no_comments: The lines without the comments. |
| 5695 linenum: The current line number we are processing. |
| 5696 |
| 5697 Returns: |
| 5698 True if we should apply our namespace indentation check. Currently, it |
| 5699 only works for classes and namespaces inside of a namespace. |
| 5700 """ |
| 5701 |
| 5702 is_forward_declaration = IsForwardClassDeclaration(raw_lines_no_comments, |
| 5703 linenum) |
| 5704 |
| 5705 if not (is_namespace_indent_item or is_forward_declaration): |
| 5706 return False |
| 5707 |
| 5708 # If we are in a macro, we do not want to check the namespace indentation. |
| 5709 if IsMacroDefinition(raw_lines_no_comments, linenum): |
| 5710 return False |
| 5711 |
| 5712 return IsBlockInNameSpace(nesting_state, is_forward_declaration) |
| 5713 |
| 5714 |
| 5715 # Call this method if the line is directly inside of a namespace. |
| 5716 # If the line above is blank (excluding comments) or the start of |
| 5717 # an inner namespace, it cannot be indented. |
| 5718 def CheckItemIndentationInNamespace(filename, raw_lines_no_comments, linenum, |
| 5719 error): |
| 5720 line = raw_lines_no_comments[linenum] |
| 5721 if Match(r'^\s+', line): |
| 5722 error(filename, linenum, 'runtime/indentation_namespace', 4, |
| 5723 'Do not indent within a namespace') |
| 5724 |
| 5725 |
5356 def ProcessLine(filename, file_extension, clean_lines, line, | 5726 def ProcessLine(filename, file_extension, clean_lines, line, |
5357 include_state, function_state, nesting_state, error, | 5727 include_state, function_state, nesting_state, error, |
5358 extra_check_functions=[]): | 5728 extra_check_functions=[]): |
5359 """Processes a single line in the file. | 5729 """Processes a single line in the file. |
5360 | 5730 |
5361 Args: | 5731 Args: |
5362 filename: Filename of the file that is being processed. | 5732 filename: Filename of the file that is being processed. |
5363 file_extension: The extension (dot not included) of the file. | 5733 file_extension: The extension (dot not included) of the file. |
5364 clean_lines: An array of strings, each representing a line of the file, | 5734 clean_lines: An array of strings, each representing a line of the file, |
5365 with comments stripped. | 5735 with comments stripped. |
5366 line: Number of line being processed. | 5736 line: Number of line being processed. |
5367 include_state: An _IncludeState instance in which the headers are inserted. | 5737 include_state: An _IncludeState instance in which the headers are inserted. |
5368 function_state: A _FunctionState instance which counts function lines, etc. | 5738 function_state: A _FunctionState instance which counts function lines, etc. |
5369 nesting_state: A NestingState instance which maintains information about | 5739 nesting_state: A NestingState instance which maintains information about |
5370 the current stack of nested blocks being parsed. | 5740 the current stack of nested blocks being parsed. |
5371 error: A callable to which errors are reported, which takes 4 arguments: | 5741 error: A callable to which errors are reported, which takes 4 arguments: |
5372 filename, line number, error level, and message | 5742 filename, line number, error level, and message |
5373 extra_check_functions: An array of additional check functions that will be | 5743 extra_check_functions: An array of additional check functions that will be |
5374 run on each source line. Each function takes 4 | 5744 run on each source line. Each function takes 4 |
5375 arguments: filename, clean_lines, line, error | 5745 arguments: filename, clean_lines, line, error |
5376 """ | 5746 """ |
5377 raw_lines = clean_lines.raw_lines | 5747 raw_lines = clean_lines.raw_lines |
5378 ParseNolintSuppressions(filename, raw_lines[line], line, error) | 5748 ParseNolintSuppressions(filename, raw_lines[line], line, error) |
5379 nesting_state.Update(filename, clean_lines, line, error) | 5749 nesting_state.Update(filename, clean_lines, line, error) |
| 5750 CheckForNamespaceIndentation(filename, nesting_state, clean_lines, line, |
| 5751 error) |
5380 if nesting_state.InAsmBlock(): return | 5752 if nesting_state.InAsmBlock(): return |
5381 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) | 5753 CheckForFunctionLengths(filename, clean_lines, line, function_state, error) |
5382 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) | 5754 CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error) |
5383 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) | 5755 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) |
5384 CheckLanguage(filename, clean_lines, line, file_extension, include_state, | 5756 CheckLanguage(filename, clean_lines, line, file_extension, include_state, |
5385 nesting_state, error) | 5757 nesting_state, error) |
5386 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) | 5758 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) |
5387 CheckForNonStandardConstructs(filename, clean_lines, line, | 5759 CheckForNonStandardConstructs(filename, clean_lines, line, |
5388 nesting_state, error) | 5760 nesting_state, error) |
5389 CheckVlogArguments(filename, clean_lines, line, error) | 5761 CheckVlogArguments(filename, clean_lines, line, error) |
5390 CheckPosixThreading(filename, clean_lines, line, error) | 5762 CheckPosixThreading(filename, clean_lines, line, error) |
5391 CheckInvalidIncrement(filename, clean_lines, line, error) | 5763 CheckInvalidIncrement(filename, clean_lines, line, error) |
5392 CheckMakePairUsesDeduction(filename, clean_lines, line, error) | 5764 CheckMakePairUsesDeduction(filename, clean_lines, line, error) |
5393 CheckDefaultLambdaCaptures(filename, clean_lines, line, error) | 5765 CheckDefaultLambdaCaptures(filename, clean_lines, line, error) |
| 5766 CheckRedundantVirtual(filename, clean_lines, line, error) |
| 5767 CheckRedundantOverrideOrFinal(filename, clean_lines, line, error) |
5394 for check_fn in extra_check_functions: | 5768 for check_fn in extra_check_functions: |
5395 check_fn(filename, clean_lines, line, error) | 5769 check_fn(filename, clean_lines, line, error) |
5396 | 5770 |
5397 def FlagCxx11Features(filename, clean_lines, linenum, error): | 5771 def FlagCxx11Features(filename, clean_lines, linenum, error): |
5398 """Flag those c++11 features that we only allow in certain places. | 5772 """Flag those c++11 features that we only allow in certain places. |
5399 | 5773 |
5400 Args: | 5774 Args: |
5401 filename: The name of the current file. | 5775 filename: The name of the current file. |
5402 clean_lines: A CleansedLines instance containing the file. | 5776 clean_lines: A CleansedLines instance containing the file. |
5403 linenum: The number of the line to check. | 5777 linenum: The number of the line to check. |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5752 _cpplint_state.ResetErrorCounts() | 6126 _cpplint_state.ResetErrorCounts() |
5753 for filename in filenames: | 6127 for filename in filenames: |
5754 ProcessFile(filename, _cpplint_state.verbose_level) | 6128 ProcessFile(filename, _cpplint_state.verbose_level) |
5755 _cpplint_state.PrintErrorCounts() | 6129 _cpplint_state.PrintErrorCounts() |
5756 | 6130 |
5757 sys.exit(_cpplint_state.error_count > 0) | 6131 sys.exit(_cpplint_state.error_count > 0) |
5758 | 6132 |
5759 | 6133 |
5760 if __name__ == '__main__': | 6134 if __name__ == '__main__': |
5761 main() | 6135 main() |
OLD | NEW |