| 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 |