| 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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 build/include_alpha as well as excludes all .cc from being | 168 build/include_alpha as well as excludes all .cc from being |
| 169 processed by linter, in the current directory (where the .cfg | 169 processed by linter, in the current directory (where the .cfg |
| 170 file is located) and all sub-directories. | 170 file is located) and all sub-directories. |
| 171 """ | 171 """ |
| 172 | 172 |
| 173 # We categorize each error message we print. Here are the categories. | 173 # We categorize each error message we print. Here are the categories. |
| 174 # We want an explicit list so we can list them all in cpplint --filter=. | 174 # We want an explicit list so we can list them all in cpplint --filter=. |
| 175 # If you add a new error message with a new category, add it to the list | 175 # If you add a new error message with a new category, add it to the list |
| 176 # here! cpplint_unittest.py should tell you if you forget to do this. | 176 # here! cpplint_unittest.py should tell you if you forget to do this. |
| 177 _ERROR_CATEGORIES = [ | 177 _ERROR_CATEGORIES = [ |
| 178 'build/class', | 178 'build/class', |
| 179 'build/c++11', | 179 'build/c++11', |
| 180 'build/deprecated', | 180 'build/deprecated', |
| 181 'build/endif_comment', | 181 'build/endif_comment', |
| 182 'build/explicit_make_pair', | 182 'build/explicit_make_pair', |
| 183 'build/forward_decl', | 183 'build/forward_decl', |
| 184 'build/header_guard', | 184 'build/header_guard', |
| 185 'build/include', | 185 'build/include', |
| 186 'build/include_alpha', | 186 'build/include_alpha', |
| 187 'build/include_order', | 187 'build/include_order', |
| 188 'build/include_what_you_use', | 188 'build/include_what_you_use', |
| 189 'build/namespaces', | 189 'build/namespaces', |
| 190 'build/printf_format', | 190 'build/printf_format', |
| 191 'build/storage_class', | 191 'build/storage_class', |
| 192 'legal/copyright', | 192 'legal/copyright', |
| 193 'readability/alt_tokens', | 193 'readability/alt_tokens', |
| 194 'readability/braces', | 194 'readability/braces', |
| 195 'readability/casting', | 195 'readability/casting', |
| 196 'readability/check', | 196 'readability/check', |
| 197 'readability/constructors', | 197 'readability/constructors', |
| 198 'readability/fn_size', | 198 'readability/fn_size', |
| 199 'readability/function', | 199 'readability/function', |
| 200 'readability/inheritance', | 200 'readability/inheritance', |
| 201 'readability/multiline_comment', | 201 'readability/multiline_comment', |
| 202 'readability/multiline_string', | 202 'readability/multiline_string', |
| 203 'readability/namespace', | 203 'readability/namespace', |
| 204 'readability/nolint', | 204 'readability/nolint', |
| 205 'readability/nul', | 205 'readability/nul', |
| 206 'readability/streams', | 206 'readability/strings', |
| 207 'readability/todo', | 207 'readability/todo', |
| 208 'readability/utf8', | 208 'readability/utf8', |
| 209 'runtime/arrays', | 209 'runtime/arrays', |
| 210 'runtime/casting', | 210 'runtime/casting', |
| 211 'runtime/explicit', | 211 'runtime/explicit', |
| 212 'runtime/int', | 212 'runtime/int', |
| 213 'runtime/init', | 213 'runtime/init', |
| 214 'runtime/invalid_increment', | 214 'runtime/invalid_increment', |
| 215 'runtime/member_string_references', | 215 'runtime/member_string_references', |
| 216 'runtime/memset', | 216 'runtime/memset', |
| 217 'runtime/indentation_namespace', | 217 'runtime/indentation_namespace', |
| 218 'runtime/operator', | 218 'runtime/operator', |
| 219 'runtime/printf', | 219 'runtime/printf', |
| 220 'runtime/printf_format', | 220 'runtime/printf_format', |
| 221 'runtime/references', | 221 'runtime/references', |
| 222 'runtime/string', | 222 'runtime/string', |
| 223 'runtime/threadsafe_fn', | 223 'runtime/threadsafe_fn', |
| 224 'runtime/vlog', | 224 'runtime/vlog', |
| 225 'whitespace/blank_line', | 225 'whitespace/blank_line', |
| 226 'whitespace/braces', | 226 'whitespace/braces', |
| 227 'whitespace/comma', | 227 'whitespace/comma', |
| 228 'whitespace/comments', | 228 'whitespace/comments', |
| 229 'whitespace/empty_conditional_body', | 229 'whitespace/empty_conditional_body', |
| 230 'whitespace/empty_loop_body', | 230 'whitespace/empty_loop_body', |
| 231 'whitespace/end_of_line', | 231 'whitespace/end_of_line', |
| 232 'whitespace/ending_newline', | 232 'whitespace/ending_newline', |
| 233 'whitespace/forcolon', | 233 'whitespace/forcolon', |
| 234 'whitespace/indent', | 234 'whitespace/indent', |
| 235 'whitespace/line_length', | 235 'whitespace/line_length', |
| 236 'whitespace/newline', | 236 'whitespace/newline', |
| 237 'whitespace/operators', | 237 'whitespace/operators', |
| 238 'whitespace/parens', | 238 'whitespace/parens', |
| 239 'whitespace/semicolon', | 239 'whitespace/semicolon', |
| 240 'whitespace/tab', | 240 'whitespace/tab', |
| 241 'whitespace/todo' | 241 'whitespace/todo', |
| 242 ] | 242 ] |
| 243 |
| 244 # These error categories are no longer enforced by cpplint, but for backwards- |
| 245 # compatibility they may still appear in NOLINT comments. |
| 246 _LEGACY_ERROR_CATEGORIES = [ |
| 247 'readability/streams', |
| 248 ] |
| 243 | 249 |
| 244 # The default state of the category filter. This is overridden by the --filter= | 250 # The default state of the category filter. This is overridden by the --filter= |
| 245 # flag. By default all errors are on, so only add here categories that should be | 251 # flag. By default all errors are on, so only add here categories that should be |
| 246 # off by default (i.e., categories that must be enabled by the --filter= flags). | 252 # off by default (i.e., categories that must be enabled by the --filter= flags). |
| 247 # All entries here should start with a '-' or '+', as in the --filter= flag. | 253 # All entries here should start with a '-' or '+', as in the --filter= flag. |
| 248 _DEFAULT_FILTERS = ['-build/include_alpha'] | 254 _DEFAULT_FILTERS = ['-build/include_alpha'] |
| 249 | 255 |
| 250 # We used to check for high-bit characters, but after much discussion we | 256 # We used to check for high-bit characters, but after much discussion we |
| 251 # decided those were OK, as long as they were in UTF-8 and didn't represent | 257 # decided those were OK, as long as they were in UTF-8 and didn't represent |
| 252 # hard-coded international strings, which belong in a separate i18n file. | 258 # hard-coded international strings, which belong in a separate i18n file. |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 else: | 521 else: |
| 516 suppressed_line = linenum | 522 suppressed_line = linenum |
| 517 category = matched.group(2) | 523 category = matched.group(2) |
| 518 if category in (None, '(*)'): # => "suppress all" | 524 if category in (None, '(*)'): # => "suppress all" |
| 519 _error_suppressions.setdefault(None, set()).add(suppressed_line) | 525 _error_suppressions.setdefault(None, set()).add(suppressed_line) |
| 520 else: | 526 else: |
| 521 if category.startswith('(') and category.endswith(')'): | 527 if category.startswith('(') and category.endswith(')'): |
| 522 category = category[1:-1] | 528 category = category[1:-1] |
| 523 if category in _ERROR_CATEGORIES: | 529 if category in _ERROR_CATEGORIES: |
| 524 _error_suppressions.setdefault(category, set()).add(suppressed_line) | 530 _error_suppressions.setdefault(category, set()).add(suppressed_line) |
| 525 else: | 531 elif category not in _LEGACY_ERROR_CATEGORIES: |
| 526 error(filename, linenum, 'readability/nolint', 5, | 532 error(filename, linenum, 'readability/nolint', 5, |
| 527 'Unknown NOLINT error category: %s' % category) | 533 'Unknown NOLINT error category: %s' % category) |
| 528 | 534 |
| 529 | 535 |
| 530 def ResetNolintSuppressions(): | 536 def ResetNolintSuppressions(): |
| 531 """Resets the set of NOLINT suppressions to empty.""" | 537 """Resets the set of NOLINT suppressions to empty.""" |
| 532 _error_suppressions.clear() | 538 _error_suppressions.clear() |
| 533 | 539 |
| 534 | 540 |
| 535 def IsErrorSuppressedByNolint(category, linenum): | 541 def IsErrorSuppressedByNolint(category, linenum): |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 | 689 |
| 684 Returns: | 690 Returns: |
| 685 Returns true if the header is in alphabetical order. | 691 Returns true if the header is in alphabetical order. |
| 686 """ | 692 """ |
| 687 # If previous section is different from current section, _last_header will | 693 # If previous section is different from current section, _last_header will |
| 688 # be reset to empty string, so it's always less than current header. | 694 # be reset to empty string, so it's always less than current header. |
| 689 # | 695 # |
| 690 # If previous line was a blank line, assume that the headers are | 696 # If previous line was a blank line, assume that the headers are |
| 691 # intentionally sorted the way they are. | 697 # intentionally sorted the way they are. |
| 692 if (self._last_header > header_path and | 698 if (self._last_header > header_path and |
| 693 not Match(r'^\s*$', clean_lines.elided[linenum - 1])): | 699 Match(r'^\s*#\s*include\b', clean_lines.elided[linenum - 1])): |
| 694 return False | 700 return False |
| 695 return True | 701 return True |
| 696 | 702 |
| 697 def CheckNextIncludeOrder(self, header_type): | 703 def CheckNextIncludeOrder(self, header_type): |
| 698 """Returns a non-empty error message if the next header is out of order. | 704 """Returns a non-empty error message if the next header is out of order. |
| 699 | 705 |
| 700 This function also updates the internal state to be ready to check | 706 This function also updates the internal state to be ready to check |
| 701 the next include. | 707 the next include. |
| 702 | 708 |
| 703 Args: | 709 Args: |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1239 return lineix | 1245 return lineix |
| 1240 lineix += 1 | 1246 lineix += 1 |
| 1241 return len(lines) | 1247 return len(lines) |
| 1242 | 1248 |
| 1243 | 1249 |
| 1244 def RemoveMultiLineCommentsFromRange(lines, begin, end): | 1250 def RemoveMultiLineCommentsFromRange(lines, begin, end): |
| 1245 """Clears a range of lines for multi-line comments.""" | 1251 """Clears a range of lines for multi-line comments.""" |
| 1246 # Having // dummy comments makes the lines non-empty, so we will not get | 1252 # Having // dummy comments makes the lines non-empty, so we will not get |
| 1247 # unnecessary blank line warnings later in the code. | 1253 # unnecessary blank line warnings later in the code. |
| 1248 for i in range(begin, end): | 1254 for i in range(begin, end): |
| 1249 lines[i] = '// dummy' | 1255 lines[i] = '/**/' |
| 1250 | 1256 |
| 1251 | 1257 |
| 1252 def RemoveMultiLineComments(filename, lines, error): | 1258 def RemoveMultiLineComments(filename, lines, error): |
| 1253 """Removes multiline (c-style) comments from lines.""" | 1259 """Removes multiline (c-style) comments from lines.""" |
| 1254 lineix = 0 | 1260 lineix = 0 |
| 1255 while lineix < len(lines): | 1261 while lineix < len(lines): |
| 1256 lineix_begin = FindNextMultiLineCommentStart(lines, lineix) | 1262 lineix_begin = FindNextMultiLineCommentStart(lines, lineix) |
| 1257 if lineix_begin >= len(lines): | 1263 if lineix_begin >= len(lines): |
| 1258 return | 1264 return |
| 1259 lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) | 1265 lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1275 The line with single-line comments removed. | 1281 The line with single-line comments removed. |
| 1276 """ | 1282 """ |
| 1277 commentpos = line.find('//') | 1283 commentpos = line.find('//') |
| 1278 if commentpos != -1 and not IsCppString(line[:commentpos]): | 1284 if commentpos != -1 and not IsCppString(line[:commentpos]): |
| 1279 line = line[:commentpos].rstrip() | 1285 line = line[:commentpos].rstrip() |
| 1280 # get rid of /* ... */ | 1286 # get rid of /* ... */ |
| 1281 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) | 1287 return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line) |
| 1282 | 1288 |
| 1283 | 1289 |
| 1284 class CleansedLines(object): | 1290 class CleansedLines(object): |
| 1285 """Holds 3 copies of all lines with different preprocessing applied to them. | 1291 """Holds 4 copies of all lines with different preprocessing applied to them. |
| 1286 | 1292 |
| 1287 1) elided member contains lines without strings and comments, | 1293 1) elided member contains lines without strings and comments. |
| 1288 2) lines member contains lines without comments, and | 1294 2) lines member contains lines without comments. |
| 1289 3) raw_lines member contains all the lines without processing. | 1295 3) raw_lines member contains all the lines without processing. |
| 1290 All these three members are of <type 'list'>, and of the same length. | 1296 4) lines_without_raw_strings member is same as raw_lines, but with C++11 raw |
| 1297 strings removed. |
| 1298 All these members are of <type 'list'>, and of the same length. |
| 1291 """ | 1299 """ |
| 1292 | 1300 |
| 1293 def __init__(self, lines): | 1301 def __init__(self, lines): |
| 1294 self.elided = [] | 1302 self.elided = [] |
| 1295 self.lines = [] | 1303 self.lines = [] |
| 1296 self.raw_lines = lines | 1304 self.raw_lines = lines |
| 1297 self.num_lines = len(lines) | 1305 self.num_lines = len(lines) |
| 1298 self.lines_without_raw_strings = CleanseRawStrings(lines) | 1306 self.lines_without_raw_strings = CleanseRawStrings(lines) |
| 1299 for linenum in range(len(self.lines_without_raw_strings)): | 1307 for linenum in range(len(self.lines_without_raw_strings)): |
| 1300 self.lines.append(CleanseComments( | 1308 self.lines.append(CleanseComments( |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1649 Returns: | 1657 Returns: |
| 1650 The CPP variable that should be used as a header guard in the | 1658 The CPP variable that should be used as a header guard in the |
| 1651 named file. | 1659 named file. |
| 1652 | 1660 |
| 1653 """ | 1661 """ |
| 1654 | 1662 |
| 1655 # Restores original filename in case that cpplint is invoked from Emacs's | 1663 # Restores original filename in case that cpplint is invoked from Emacs's |
| 1656 # flymake. | 1664 # flymake. |
| 1657 filename = re.sub(r'_flymake\.h$', '.h', filename) | 1665 filename = re.sub(r'_flymake\.h$', '.h', filename) |
| 1658 filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) | 1666 filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename) |
| 1659 | 1667 # Replace 'c++' with 'cpp'. |
| 1668 filename = filename.replace('C++', 'cpp').replace('c++', 'cpp') |
| 1669 |
| 1660 fileinfo = FileInfo(filename) | 1670 fileinfo = FileInfo(filename) |
| 1661 file_path_from_root = fileinfo.RepositoryName() | 1671 file_path_from_root = fileinfo.RepositoryName() |
| 1662 if _root: | 1672 if _root: |
| 1663 file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root) | 1673 file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root) |
| 1664 return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_' | 1674 return re.sub(r'[^a-zA-Z0-9]', '_', file_path_from_root).upper() + '_' |
| 1665 | 1675 |
| 1666 | 1676 |
| 1667 def CheckForHeaderGuard(filename, lines, error): | 1677 def CheckForHeaderGuard(filename, clean_lines, error): |
| 1668 """Checks that the file contains a header guard. | 1678 """Checks that the file contains a header guard. |
| 1669 | 1679 |
| 1670 Logs an error if no #ifndef header guard is present. For other | 1680 Logs an error if no #ifndef header guard is present. For other |
| 1671 headers, checks that the full pathname is used. | 1681 headers, checks that the full pathname is used. |
| 1672 | 1682 |
| 1673 Args: | 1683 Args: |
| 1674 filename: The name of the C++ header file. | 1684 filename: The name of the C++ header file. |
| 1675 lines: An array of strings, each representing a line of the file. | 1685 clean_lines: A CleansedLines instance containing the file. |
| 1676 error: The function to call with any errors found. | 1686 error: The function to call with any errors found. |
| 1677 """ | 1687 """ |
| 1678 | 1688 |
| 1679 # Don't check for header guards if there are error suppression | 1689 # Don't check for header guards if there are error suppression |
| 1680 # comments somewhere in this file. | 1690 # comments somewhere in this file. |
| 1681 # | 1691 # |
| 1682 # Because this is silencing a warning for a nonexistent line, we | 1692 # Because this is silencing a warning for a nonexistent line, we |
| 1683 # only support the very specific NOLINT(build/header_guard) syntax, | 1693 # only support the very specific NOLINT(build/header_guard) syntax, |
| 1684 # and not the general NOLINT or NOLINT(*) syntax. | 1694 # and not the general NOLINT or NOLINT(*) syntax. |
| 1685 for i in lines: | 1695 raw_lines = clean_lines.lines_without_raw_strings |
| 1696 for i in raw_lines: |
| 1686 if Search(r'//\s*NOLINT\(build/header_guard\)', i): | 1697 if Search(r'//\s*NOLINT\(build/header_guard\)', i): |
| 1687 return | 1698 return |
| 1688 | 1699 |
| 1689 cppvar = GetHeaderGuardCPPVariable(filename) | 1700 cppvar = GetHeaderGuardCPPVariable(filename) |
| 1690 | 1701 |
| 1691 ifndef = None | 1702 ifndef = '' |
| 1692 ifndef_linenum = 0 | 1703 ifndef_linenum = 0 |
| 1693 define = None | 1704 define = '' |
| 1694 endif = None | 1705 endif = '' |
| 1695 endif_linenum = 0 | 1706 endif_linenum = 0 |
| 1696 for linenum, line in enumerate(lines): | 1707 for linenum, line in enumerate(raw_lines): |
| 1697 linesplit = line.split() | 1708 linesplit = line.split() |
| 1698 if len(linesplit) >= 2: | 1709 if len(linesplit) >= 2: |
| 1699 # find the first occurrence of #ifndef and #define, save arg | 1710 # find the first occurrence of #ifndef and #define, save arg |
| 1700 if not ifndef and linesplit[0] == '#ifndef': | 1711 if not ifndef and linesplit[0] == '#ifndef': |
| 1701 # set ifndef to the header guard presented on the #ifndef line. | 1712 # set ifndef to the header guard presented on the #ifndef line. |
| 1702 ifndef = linesplit[1] | 1713 ifndef = linesplit[1] |
| 1703 ifndef_linenum = linenum | 1714 ifndef_linenum = linenum |
| 1704 if not define and linesplit[0] == '#define': | 1715 if not define and linesplit[0] == '#define': |
| 1705 define = linesplit[1] | 1716 define = linesplit[1] |
| 1706 # find the last occurrence of #endif, save entire line | 1717 # find the last occurrence of #endif, save entire line |
| 1707 if line.startswith('#endif'): | 1718 if line.startswith('#endif'): |
| 1708 endif = line | 1719 endif = line |
| 1709 endif_linenum = linenum | 1720 endif_linenum = linenum |
| 1710 | 1721 |
| 1711 if not ifndef: | 1722 if not ifndef or not define or ifndef != define: |
| 1712 error(filename, 0, 'build/header_guard', 5, | 1723 error(filename, 0, 'build/header_guard', 5, |
| 1713 'No #ifndef header guard found, suggested CPP variable is: %s' % | 1724 'No #ifndef header guard found, suggested CPP variable is: %s' % |
| 1714 cppvar) | 1725 cppvar) |
| 1715 return | 1726 return |
| 1716 | 1727 |
| 1717 if not define: | |
| 1718 error(filename, 0, 'build/header_guard', 5, | |
| 1719 'No #define header guard found, suggested CPP variable is: %s' % | |
| 1720 cppvar) | |
| 1721 return | |
| 1722 | |
| 1723 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ | 1728 # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__ |
| 1724 # for backward compatibility. | 1729 # for backward compatibility. |
| 1725 if ifndef != cppvar: | 1730 if ifndef != cppvar: |
| 1726 error_level = 0 | 1731 error_level = 0 |
| 1727 if ifndef != cppvar + '_': | 1732 if ifndef != cppvar + '_': |
| 1728 error_level = 5 | 1733 error_level = 5 |
| 1729 | 1734 |
| 1730 ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum, | 1735 ParseNolintSuppressions(filename, raw_lines[ifndef_linenum], ifndef_linenum, |
| 1731 error) | 1736 error) |
| 1732 error(filename, ifndef_linenum, 'build/header_guard', error_level, | 1737 error(filename, ifndef_linenum, 'build/header_guard', error_level, |
| 1733 '#ifndef header guard has wrong style, please use: %s' % cppvar) | 1738 '#ifndef header guard has wrong style, please use: %s' % cppvar) |
| 1734 | 1739 |
| 1735 if define != ifndef: | 1740 # Check for "//" comments on endif line. |
| 1736 error(filename, 0, 'build/header_guard', 5, | 1741 ParseNolintSuppressions(filename, raw_lines[endif_linenum], endif_linenum, |
| 1737 '#ifndef and #define don\'t match, suggested CPP variable is: %s' % | 1742 error) |
| 1738 cppvar) | 1743 match = Match(r'#endif\s*//\s*' + cppvar + r'(_)?\b', endif) |
| 1744 if match: |
| 1745 if match.group(1) == '_': |
| 1746 # Issue low severity warning for deprecated double trailing underscore |
| 1747 error(filename, endif_linenum, 'build/header_guard', 0, |
| 1748 '#endif line should be "#endif // %s"' % cppvar) |
| 1739 return | 1749 return |
| 1740 | 1750 |
| 1741 if endif != ('#endif // %s' % cppvar): | 1751 # Didn't find the corresponding "//" comment. If this file does not |
| 1742 error_level = 0 | 1752 # contain any "//" comments at all, it could be that the compiler |
| 1743 if endif != ('#endif // %s' % (cppvar + '_')): | 1753 # only wants "/**/" comments, look for those instead. |
| 1744 error_level = 5 | 1754 no_single_line_comments = True |
| 1755 for i in xrange(1, len(raw_lines) - 1): |
| 1756 line = raw_lines[i] |
| 1757 if Match(r'^(?:(?:\'(?:\.|[^\'])*\')|(?:"(?:\.|[^"])*")|[^\'"])*//', line): |
| 1758 no_single_line_comments = False |
| 1759 break |
| 1745 | 1760 |
| 1746 ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum, | 1761 if no_single_line_comments: |
| 1747 error) | 1762 match = Match(r'#endif\s*/\*\s*' + cppvar + r'(_)?\s*\*/', endif) |
| 1748 error(filename, endif_linenum, 'build/header_guard', error_level, | 1763 if match: |
| 1749 '#endif line should be "#endif // %s"' % cppvar) | 1764 if match.group(1) == '_': |
| 1765 # Low severity warning for double trailing underscore |
| 1766 error(filename, endif_linenum, 'build/header_guard', 0, |
| 1767 '#endif line should be "#endif /* %s */"' % cppvar) |
| 1768 return |
| 1769 |
| 1770 # Didn't find anything |
| 1771 error(filename, endif_linenum, 'build/header_guard', 5, |
| 1772 '#endif line should be "#endif // %s"' % cppvar) |
| 1773 |
| 1774 |
| 1775 def CheckHeaderFileIncluded(filename, include_state, error): |
| 1776 """Logs an error if a .cc file does not include its header.""" |
| 1777 |
| 1778 # Do not check test files |
| 1779 if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'): |
| 1780 return |
| 1781 |
| 1782 fileinfo = FileInfo(filename) |
| 1783 headerfile = filename[0:len(filename) - 2] + 'h' |
| 1784 if not os.path.exists(headerfile): |
| 1785 return |
| 1786 headername = FileInfo(headerfile).RepositoryName() |
| 1787 first_include = 0 |
| 1788 for section_list in include_state.include_list: |
| 1789 for f in section_list: |
| 1790 if headername in f[0] or f[0] in headername: |
| 1791 return |
| 1792 if not first_include: |
| 1793 first_include = f[1] |
| 1794 |
| 1795 error(filename, first_include, 'build/include', 5, |
| 1796 '%s should include its header file %s' % (fileinfo.RepositoryName(), |
| 1797 headername)) |
| 1750 | 1798 |
| 1751 | 1799 |
| 1752 def CheckForBadCharacters(filename, lines, error): | 1800 def CheckForBadCharacters(filename, lines, error): |
| 1753 """Logs an error for each line containing bad characters. | 1801 """Logs an error for each line containing bad characters. |
| 1754 | 1802 |
| 1755 Two kinds of bad characters: | 1803 Two kinds of bad characters: |
| 1756 | 1804 |
| 1757 1. Unicode replacement characters: These indicate that either the file | 1805 1. Unicode replacement characters: These indicate that either the file |
| 1758 contained invalid UTF-8 (likely) or Unicode replacement characters (which | 1806 contained invalid UTF-8 (likely) or Unicode replacement characters (which |
| 1759 it shouldn't). Note that it's possible for this to throw off line | 1807 it shouldn't). Note that it's possible for this to throw off line |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 if not depth: | 2083 if not depth: |
| 2036 self.last_line = i | 2084 self.last_line = i |
| 2037 break | 2085 break |
| 2038 | 2086 |
| 2039 def CheckBegin(self, filename, clean_lines, linenum, error): | 2087 def CheckBegin(self, filename, clean_lines, linenum, error): |
| 2040 # Look for a bare ':' | 2088 # Look for a bare ':' |
| 2041 if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): | 2089 if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]): |
| 2042 self.is_derived = True | 2090 self.is_derived = True |
| 2043 | 2091 |
| 2044 def CheckEnd(self, filename, clean_lines, linenum, error): | 2092 def CheckEnd(self, filename, clean_lines, linenum, error): |
| 2093 # If there is a DISALLOW macro, it should appear near the end of |
| 2094 # the class. |
| 2095 seen_last_thing_in_class = False |
| 2096 for i in xrange(linenum - 1, self.starting_linenum, -1): |
| 2097 match = Search( |
| 2098 r'\b(DISALLOW_COPY_AND_ASSIGN|DISALLOW_IMPLICIT_CONSTRUCTORS)\(' + |
| 2099 self.name + r'\)', |
| 2100 clean_lines.elided[i]) |
| 2101 if match: |
| 2102 if seen_last_thing_in_class: |
| 2103 error(filename, i, 'readability/constructors', 3, |
| 2104 match.group(1) + ' should be the last thing in the class') |
| 2105 break |
| 2106 |
| 2107 if not Match(r'^\s*$', clean_lines.elided[i]): |
| 2108 seen_last_thing_in_class = True |
| 2109 |
| 2045 # Check that closing brace is aligned with beginning of the class. | 2110 # Check that closing brace is aligned with beginning of the class. |
| 2046 # Only do this if the closing brace is indented by only whitespaces. | 2111 # Only do this if the closing brace is indented by only whitespaces. |
| 2047 # This means we will not check single-line class definitions. | 2112 # This means we will not check single-line class definitions. |
| 2048 indent = Match(r'^( *)\}', clean_lines.elided[linenum]) | 2113 indent = Match(r'^( *)\}', clean_lines.elided[linenum]) |
| 2049 if indent and len(indent.group(1)) != self.class_indent: | 2114 if indent and len(indent.group(1)) != self.class_indent: |
| 2050 if self.is_struct: | 2115 if self.is_struct: |
| 2051 parent = 'struct ' + self.name | 2116 parent = 'struct ' + self.name |
| 2052 else: | 2117 else: |
| 2053 parent = 'class ' + self.name | 2118 parent = 'class ' + self.name |
| 2054 error(filename, linenum, 'whitespace/indent', 3, | 2119 error(filename, linenum, 'whitespace/indent', 3, |
| (...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2715 # Ignore pointers/references to arrays. | 2780 # Ignore pointers/references to arrays. |
| 2716 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): | 2781 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): |
| 2717 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call | 2782 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call |
| 2718 error(filename, linenum, 'whitespace/parens', 4, | 2783 error(filename, linenum, 'whitespace/parens', 4, |
| 2719 'Extra space after ( in function call') | 2784 'Extra space after ( in function call') |
| 2720 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): | 2785 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): |
| 2721 error(filename, linenum, 'whitespace/parens', 2, | 2786 error(filename, linenum, 'whitespace/parens', 2, |
| 2722 'Extra space after (') | 2787 'Extra space after (') |
| 2723 if (Search(r'\w\s+\(', fncall) and | 2788 if (Search(r'\w\s+\(', fncall) and |
| 2724 not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and | 2789 not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and |
| 2725 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall)): | 2790 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and |
| 2791 not Search(r'\bcase\s+\(', fncall)): |
| 2726 # TODO(unknown): Space after an operator function seem to be a common | 2792 # TODO(unknown): Space after an operator function seem to be a common |
| 2727 # error, silence those for now by restricting them to highest verbosity. | 2793 # error, silence those for now by restricting them to highest verbosity. |
| 2728 if Search(r'\boperator_*\b', line): | 2794 if Search(r'\boperator_*\b', line): |
| 2729 error(filename, linenum, 'whitespace/parens', 0, | 2795 error(filename, linenum, 'whitespace/parens', 0, |
| 2730 'Extra space before ( in function call') | 2796 'Extra space before ( in function call') |
| 2731 else: | 2797 else: |
| 2732 error(filename, linenum, 'whitespace/parens', 4, | 2798 error(filename, linenum, 'whitespace/parens', 4, |
| 2733 'Extra space before ( in function call') | 2799 'Extra space before ( in function call') |
| 2734 # If the ) is followed only by a newline or a { + newline, assume it's | 2800 # If the ) is followed only by a newline or a { + newline, assume it's |
| 2735 # part of a control statement (if/while/etc), and don't complain | 2801 # part of a control statement (if/while/etc), and don't complain |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2885 'Missing username in TODO; it should look like ' | 2951 'Missing username in TODO; it should look like ' |
| 2886 '"// TODO(my_username): Stuff."') | 2952 '"// TODO(my_username): Stuff."') |
| 2887 | 2953 |
| 2888 middle_whitespace = match.group(3) | 2954 middle_whitespace = match.group(3) |
| 2889 # Comparisons made explicit for correctness -- pylint: disable=g-explici
t-bool-comparison | 2955 # Comparisons made explicit for correctness -- pylint: disable=g-explici
t-bool-comparison |
| 2890 if middle_whitespace != ' ' and middle_whitespace != '': | 2956 if middle_whitespace != ' ' and middle_whitespace != '': |
| 2891 error(filename, linenum, 'whitespace/todo', 2, | 2957 error(filename, linenum, 'whitespace/todo', 2, |
| 2892 'TODO(my_username) should be followed by a space') | 2958 'TODO(my_username) should be followed by a space') |
| 2893 | 2959 |
| 2894 # If the comment contains an alphanumeric character, there | 2960 # If the comment contains an alphanumeric character, there |
| 2895 # should be a space somewhere between it and the //. | 2961 # should be a space somewhere between it and the // unless |
| 2896 if Match(r'//[^ ]*\w', comment): | 2962 # it's a /// or //! Doxygen comment. |
| 2963 if (Match(r'//[^ ]*\w', comment) and |
| 2964 not Match(r'(///|//\!)(\s+|$)', comment)): |
| 2897 error(filename, linenum, 'whitespace/comments', 4, | 2965 error(filename, linenum, 'whitespace/comments', 4, |
| 2898 'Should have a space between // and comment') | 2966 'Should have a space between // and comment') |
| 2899 | 2967 |
| 2968 |
| 2900 def CheckAccess(filename, clean_lines, linenum, nesting_state, error): | 2969 def CheckAccess(filename, clean_lines, linenum, nesting_state, error): |
| 2901 """Checks for improper use of DISALLOW* macros. | 2970 """Checks for improper use of DISALLOW* macros. |
| 2902 | 2971 |
| 2903 Args: | 2972 Args: |
| 2904 filename: The name of the current file. | 2973 filename: The name of the current file. |
| 2905 clean_lines: A CleansedLines instance containing the file. | 2974 clean_lines: A CleansedLines instance containing the file. |
| 2906 linenum: The number of the line to check. | 2975 linenum: The number of the line to check. |
| 2907 nesting_state: A NestingState instance which maintains information about | 2976 nesting_state: A NestingState instance which maintains information about |
| 2908 the current stack of nested blocks being parsed. | 2977 the current stack of nested blocks being parsed. |
| 2909 error: The function to call with any errors found. | 2978 error: The function to call with any errors found. |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3076 match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line) | 3145 match = Match(r'^(.*\boperator\b)(\S+)(\s*\(.*)$', line) |
| 3077 if match: | 3146 if match: |
| 3078 line = match.group(1) + ('_' * len(match.group(2))) + match.group(3) | 3147 line = match.group(1) + ('_' * len(match.group(2))) + match.group(3) |
| 3079 else: | 3148 else: |
| 3080 break | 3149 break |
| 3081 | 3150 |
| 3082 # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". | 3151 # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )". |
| 3083 # Otherwise not. Note we only check for non-spaces on *both* sides; | 3152 # Otherwise not. Note we only check for non-spaces on *both* sides; |
| 3084 # sometimes people put non-spaces on one side when aligning ='s among | 3153 # sometimes people put non-spaces on one side when aligning ='s among |
| 3085 # many lines (not that this is behavior that I approve of...) | 3154 # many lines (not that this is behavior that I approve of...) |
| 3086 if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line): | 3155 if ((Search(r'[\w.]=', line) or |
| 3156 Search(r'=[\w.]', line)) |
| 3157 and not Search(r'\b(if|while|for) ', line) |
| 3158 # Operators taken from [lex.operators] in C++11 standard. |
| 3159 and not Search(r'(>=|<=|==|!=|&=|\^=|\|=|\+=|\*=|\/=|\%=)', line) |
| 3160 and not Search(r'operator=', line)): |
| 3087 error(filename, linenum, 'whitespace/operators', 4, | 3161 error(filename, linenum, 'whitespace/operators', 4, |
| 3088 'Missing spaces around =') | 3162 'Missing spaces around =') |
| 3089 | 3163 |
| 3090 # It's ok not to have spaces around binary operators like + - * /, but if | 3164 # It's ok not to have spaces around binary operators like + - * /, but if |
| 3091 # there's too little whitespace, we get concerned. It's hard to tell, | 3165 # there's too little whitespace, we get concerned. It's hard to tell, |
| 3092 # though, so we punt on this one for now. TODO. | 3166 # though, so we punt on this one for now. TODO. |
| 3093 | 3167 |
| 3094 # You should always have whitespace around binary operators. | 3168 # You should always have whitespace around binary operators. |
| 3095 # | 3169 # |
| 3096 # Check <= and >= first to avoid false positives with < and >, then | 3170 # Check <= and >= first to avoid false positives with < and >, then |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3128 clean_lines, linenum, len(match.group(1))) | 3202 clean_lines, linenum, len(match.group(1))) |
| 3129 if start_pos <= -1: | 3203 if start_pos <= -1: |
| 3130 error(filename, linenum, 'whitespace/operators', 3, | 3204 error(filename, linenum, 'whitespace/operators', 3, |
| 3131 'Missing spaces around >') | 3205 'Missing spaces around >') |
| 3132 | 3206 |
| 3133 # We allow no-spaces around << when used like this: 10<<20, but | 3207 # We allow no-spaces around << when used like this: 10<<20, but |
| 3134 # not otherwise (particularly, not when used as streams) | 3208 # not otherwise (particularly, not when used as streams) |
| 3135 # | 3209 # |
| 3136 # We also allow operators following an opening parenthesis, since | 3210 # We also allow operators following an opening parenthesis, since |
| 3137 # those tend to be macros that deal with operators. | 3211 # those tend to be macros that deal with operators. |
| 3138 match = Search(r'(operator|\S)(?:L|UL|ULL|l|ul|ull)?<<([^\s,=])', line) | 3212 match = Search(r'(operator|[^\s(<])(?:L|UL|ULL|l|ul|ull)?<<([^\s,=<])', line) |
| 3139 if (match and match.group(1) != '(' and | 3213 if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and |
| 3140 not (match.group(1).isdigit() and match.group(2).isdigit()) and | |
| 3141 not (match.group(1) == 'operator' and match.group(2) == ';')): | 3214 not (match.group(1) == 'operator' and match.group(2) == ';')): |
| 3142 error(filename, linenum, 'whitespace/operators', 3, | 3215 error(filename, linenum, 'whitespace/operators', 3, |
| 3143 'Missing spaces around <<') | 3216 'Missing spaces around <<') |
| 3144 | 3217 |
| 3145 # We allow no-spaces around >> for almost anything. This is because | 3218 # We allow no-spaces around >> for almost anything. This is because |
| 3146 # C++11 allows ">>" to close nested templates, which accounts for | 3219 # C++11 allows ">>" to close nested templates, which accounts for |
| 3147 # most cases when ">>" is not followed by a space. | 3220 # most cases when ">>" is not followed by a space. |
| 3148 # | 3221 # |
| 3149 # We still warn on ">>" followed by alpha character, because that is | 3222 # We still warn on ">>" followed by alpha character, because that is |
| 3150 # likely due to ">>" being used for right shifts, e.g.: | 3223 # likely due to ">>" being used for right shifts, e.g.: |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3248 clean_lines: A CleansedLines instance containing the file. | 3321 clean_lines: A CleansedLines instance containing the file. |
| 3249 linenum: The number of the line to check. | 3322 linenum: The number of the line to check. |
| 3250 error: The function to call with any errors found. | 3323 error: The function to call with any errors found. |
| 3251 """ | 3324 """ |
| 3252 line = clean_lines.elided[linenum] | 3325 line = clean_lines.elided[linenum] |
| 3253 | 3326 |
| 3254 # Except after an opening paren, or after another opening brace (in case of | 3327 # Except after an opening paren, or after another opening brace (in case of |
| 3255 # an initializer list, for instance), you should have spaces before your | 3328 # an initializer list, for instance), you should have spaces before your |
| 3256 # braces. And since you should never have braces at the beginning of a line, | 3329 # braces. And since you should never have braces at the beginning of a line, |
| 3257 # this is an easy test. | 3330 # this is an easy test. |
| 3258 match = Match(r'^(.*[^ ({]){', line) | 3331 match = Match(r'^(.*[^ ({>]){', line) |
| 3259 if match: | 3332 if match: |
| 3260 # Try a bit harder to check for brace initialization. This | 3333 # Try a bit harder to check for brace initialization. This |
| 3261 # happens in one of the following forms: | 3334 # happens in one of the following forms: |
| 3262 # Constructor() : initializer_list_{} { ... } | 3335 # Constructor() : initializer_list_{} { ... } |
| 3263 # Constructor{}.MemberFunction() | 3336 # Constructor{}.MemberFunction() |
| 3264 # Type variable{}; | 3337 # Type variable{}; |
| 3265 # FunctionCall(type{}, ...); | 3338 # FunctionCall(type{}, ...); |
| 3266 # LastArgument(..., type{}); | 3339 # LastArgument(..., type{}); |
| 3267 # LOG(INFO) << type{} << " ..."; | 3340 # LOG(INFO) << type{} << " ..."; |
| 3268 # map_of_type[{...}] = ...; | 3341 # map_of_type[{...}] = ...; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3348 True if this token is end of a template parameter list, False otherwise. | 3421 True if this token is end of a template parameter list, False otherwise. |
| 3349 """ | 3422 """ |
| 3350 (_, startline, startpos) = ReverseCloseExpression( | 3423 (_, startline, startpos) = ReverseCloseExpression( |
| 3351 clean_lines, linenum, column) | 3424 clean_lines, linenum, column) |
| 3352 if (startpos > -1 and | 3425 if (startpos > -1 and |
| 3353 Search(r'\btemplate\s*$', clean_lines.elided[startline][0:startpos])): | 3426 Search(r'\btemplate\s*$', clean_lines.elided[startline][0:startpos])): |
| 3354 return True | 3427 return True |
| 3355 return False | 3428 return False |
| 3356 | 3429 |
| 3357 | 3430 |
| 3358 def IsRValueType(clean_lines, nesting_state, linenum, column): | 3431 def IsRValueType(typenames, clean_lines, nesting_state, linenum, column): |
| 3359 """Check if the token ending on (linenum, column) is a type. | 3432 """Check if the token ending on (linenum, column) is a type. |
| 3360 | 3433 |
| 3361 Assumes that text to the right of the column is "&&" or a function | 3434 Assumes that text to the right of the column is "&&" or a function |
| 3362 name. | 3435 name. |
| 3363 | 3436 |
| 3364 Args: | 3437 Args: |
| 3438 typenames: set of type names from template-argument-list. |
| 3365 clean_lines: A CleansedLines instance containing the file. | 3439 clean_lines: A CleansedLines instance containing the file. |
| 3366 nesting_state: A NestingState instance which maintains information about | 3440 nesting_state: A NestingState instance which maintains information about |
| 3367 the current stack of nested blocks being parsed. | 3441 the current stack of nested blocks being parsed. |
| 3368 linenum: the number of the line to check. | 3442 linenum: the number of the line to check. |
| 3369 column: end column of the token to check. | 3443 column: end column of the token to check. |
| 3370 Returns: | 3444 Returns: |
| 3371 True if this token is a type, False if we are not sure. | 3445 True if this token is a type, False if we are not sure. |
| 3372 """ | 3446 """ |
| 3373 prefix = clean_lines.elided[linenum][0:column] | 3447 prefix = clean_lines.elided[linenum][0:column] |
| 3374 | 3448 |
| 3375 # Get one word to the left. If we failed to do so, this is most | 3449 # Get one word to the left. If we failed to do so, this is most |
| 3376 # likely not a type, since it's unlikely that the type name and "&&" | 3450 # likely not a type, since it's unlikely that the type name and "&&" |
| 3377 # would be split across multiple lines. | 3451 # would be split across multiple lines. |
| 3378 match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix) | 3452 match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix) |
| 3379 if not match: | 3453 if not match: |
| 3380 return False | 3454 return False |
| 3381 | 3455 |
| 3382 # Check text following the token. If it's "&&>" or "&&," or "&&...", it's | 3456 # Check text following the token. If it's "&&>" or "&&," or "&&...", it's |
| 3383 # most likely a rvalue reference used inside a template. | 3457 # most likely a rvalue reference used inside a template. |
| 3384 suffix = clean_lines.elided[linenum][column:] | 3458 suffix = clean_lines.elided[linenum][column:] |
| 3385 if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix): | 3459 if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix): |
| 3386 return True | 3460 return True |
| 3387 | 3461 |
| 3388 # Check for simple type and end of templates: | 3462 # Check for known types and end of templates: |
| 3389 # int&& variable | 3463 # int&& variable |
| 3390 # vector<int>&& variable | 3464 # vector<int>&& variable |
| 3391 # | 3465 # |
| 3392 # Because this function is called recursively, we also need to | 3466 # Because this function is called recursively, we also need to |
| 3393 # recognize pointer and reference types: | 3467 # recognize pointer and reference types: |
| 3394 # int* Function() | 3468 # int* Function() |
| 3395 # int& Function() | 3469 # int& Function() |
| 3396 if match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool', | 3470 if (match.group(2) in typenames or |
| 3397 'short', 'int', 'long', 'signed', 'unsigned', | 3471 match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool', |
| 3398 'float', 'double', 'void', 'auto', '>', '*', '&']: | 3472 'short', 'int', 'long', 'signed', 'unsigned', |
| 3473 'float', 'double', 'void', 'auto', '>', '*', '&']): |
| 3399 return True | 3474 return True |
| 3400 | 3475 |
| 3401 # If we see a close parenthesis, look for decltype on the other side. | 3476 # If we see a close parenthesis, look for decltype on the other side. |
| 3402 # decltype would unambiguously identify a type, anything else is | 3477 # decltype would unambiguously identify a type, anything else is |
| 3403 # probably a parenthesized expression and not a type. | 3478 # probably a parenthesized expression and not a type. |
| 3404 if match.group(2) == ')': | 3479 if match.group(2) == ')': |
| 3405 return IsDecltype( | 3480 return IsDecltype( |
| 3406 clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1) | 3481 clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1) |
| 3407 | 3482 |
| 3408 # Check for casts and cv-qualifiers. | 3483 # Check for casts and cv-qualifiers. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3521 # ( FunctionCall(expression && | 3596 # ( FunctionCall(expression && |
| 3522 # + FunctionCall(expression && | 3597 # + FunctionCall(expression && |
| 3523 # + (expression && | 3598 # + (expression && |
| 3524 # | 3599 # |
| 3525 # The last '+' represents operators such as '+' and '-'. | 3600 # The last '+' represents operators such as '+' and '-'. |
| 3526 if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text): | 3601 if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text): |
| 3527 return False | 3602 return False |
| 3528 | 3603 |
| 3529 # Something else. Check that tokens to the left look like | 3604 # Something else. Check that tokens to the left look like |
| 3530 # return_type function_name | 3605 # return_type function_name |
| 3531 match_func = Match(r'^(.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', | 3606 match_func = Match(r'^(.*\S.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', |
| 3532 match_symbol.group(1)) | 3607 match_symbol.group(1)) |
| 3533 if match_func: | 3608 if match_func: |
| 3534 # Check for constructors, which don't have return types. | 3609 # Check for constructors, which don't have return types. |
| 3535 if Search(r'\b(?:explicit|inline)$', match_func.group(1)): | 3610 if Search(r'\b(?:explicit|inline)$', match_func.group(1)): |
| 3536 return True | 3611 return True |
| 3537 implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix) | 3612 implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix) |
| 3538 if (implicit_constructor and | 3613 if (implicit_constructor and |
| 3539 implicit_constructor.group(1) == implicit_constructor.group(2)): | 3614 implicit_constructor.group(1) == implicit_constructor.group(2)): |
| 3540 return True | 3615 return True |
| 3541 return IsRValueType(clean_lines, nesting_state, linenum, | 3616 return IsRValueType(typenames, clean_lines, nesting_state, linenum, |
| 3542 len(match_func.group(1))) | 3617 len(match_func.group(1))) |
| 3543 | 3618 |
| 3544 # Nothing before the function name. If this is inside a block scope, | 3619 # Nothing before the function name. If this is inside a block scope, |
| 3545 # this is probably a function call. | 3620 # this is probably a function call. |
| 3546 return not (nesting_state.previous_stack_top and | 3621 return not (nesting_state.previous_stack_top and |
| 3547 nesting_state.previous_stack_top.IsBlockInfo()) | 3622 nesting_state.previous_stack_top.IsBlockInfo()) |
| 3548 | 3623 |
| 3549 if match_symbol.group(2) == '>': | 3624 if match_symbol.group(2) == '>': |
| 3550 # Possibly a closing bracket, check that what's on the other side | 3625 # Possibly a closing bracket, check that what's on the other side |
| 3551 # looks like the start of a template. | 3626 # looks like the start of a template. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 3569 open_paren = clean_lines.elided[linenum].find('(') | 3644 open_paren = clean_lines.elided[linenum].find('(') |
| 3570 if open_paren < 0: | 3645 if open_paren < 0: |
| 3571 return False | 3646 return False |
| 3572 (close_line, _, close_paren) = CloseExpression( | 3647 (close_line, _, close_paren) = CloseExpression( |
| 3573 clean_lines, linenum, open_paren) | 3648 clean_lines, linenum, open_paren) |
| 3574 if close_paren < 0: | 3649 if close_paren < 0: |
| 3575 return False | 3650 return False |
| 3576 return Match(r'\s*=\s*(?:delete|default)\b', close_line[close_paren:]) | 3651 return Match(r'\s*=\s*(?:delete|default)\b', close_line[close_paren:]) |
| 3577 | 3652 |
| 3578 | 3653 |
| 3579 def IsRValueAllowed(clean_lines, linenum): | 3654 def IsRValueAllowed(clean_lines, linenum, typenames): |
| 3580 """Check if RValue reference is allowed on a particular line. | 3655 """Check if RValue reference is allowed on a particular line. |
| 3581 | 3656 |
| 3582 Args: | 3657 Args: |
| 3583 clean_lines: A CleansedLines instance containing the file. | 3658 clean_lines: A CleansedLines instance containing the file. |
| 3584 linenum: The number of the line to check. | 3659 linenum: The number of the line to check. |
| 3660 typenames: set of type names from template-argument-list. |
| 3585 Returns: | 3661 Returns: |
| 3586 True if line is within the region where RValue references are allowed. | 3662 True if line is within the region where RValue references are allowed. |
| 3587 """ | 3663 """ |
| 3588 # Allow region marked by PUSH/POP macros | 3664 # Allow region marked by PUSH/POP macros |
| 3589 for i in xrange(linenum, 0, -1): | 3665 for i in xrange(linenum, 0, -1): |
| 3590 line = clean_lines.elided[i] | 3666 line = clean_lines.elided[i] |
| 3591 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): | 3667 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): |
| 3592 if not line.endswith('PUSH'): | 3668 if not line.endswith('PUSH'): |
| 3593 return False | 3669 return False |
| 3594 for j in xrange(linenum, clean_lines.NumLines(), 1): | 3670 for j in xrange(linenum, clean_lines.NumLines(), 1): |
| 3595 line = clean_lines.elided[j] | 3671 line = clean_lines.elided[j] |
| 3596 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): | 3672 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): |
| 3597 return line.endswith('POP') | 3673 return line.endswith('POP') |
| 3598 | 3674 |
| 3599 # Allow operator= | 3675 # Allow operator= |
| 3600 line = clean_lines.elided[linenum] | 3676 line = clean_lines.elided[linenum] |
| 3601 if Search(r'\boperator\s*=\s*\(', line): | 3677 if Search(r'\boperator\s*=\s*\(', line): |
| 3602 return IsDeletedOrDefault(clean_lines, linenum) | 3678 return IsDeletedOrDefault(clean_lines, linenum) |
| 3603 | 3679 |
| 3604 # Allow constructors | 3680 # Allow constructors |
| 3605 match = Match(r'\s*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line) | 3681 match = Match(r'\s*(?:[\w<>]+::)*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line) |
| 3606 if match and match.group(1) == match.group(2): | 3682 if match and match.group(1) == match.group(2): |
| 3607 return IsDeletedOrDefault(clean_lines, linenum) | 3683 return IsDeletedOrDefault(clean_lines, linenum) |
| 3608 if Search(r'\b(?:explicit|inline)\s+[\w<>]+\s*\(', line): | 3684 if Search(r'\b(?:explicit|inline)\s+[\w<>]+\s*\(', line): |
| 3609 return IsDeletedOrDefault(clean_lines, linenum) | 3685 return IsDeletedOrDefault(clean_lines, linenum) |
| 3610 | 3686 |
| 3611 if Match(r'\s*[\w<>]+\s*\(', line): | 3687 if Match(r'\s*[\w<>]+\s*\(', line): |
| 3612 previous_line = 'ReturnType' | 3688 previous_line = 'ReturnType' |
| 3613 if linenum > 0: | 3689 if linenum > 0: |
| 3614 previous_line = clean_lines.elided[linenum - 1] | 3690 previous_line = clean_lines.elided[linenum - 1] |
| 3615 if Match(r'^\s*$', previous_line) or Search(r'[{}:;]\s*$', previous_line): | 3691 if Match(r'^\s*$', previous_line) or Search(r'[{}:;]\s*$', previous_line): |
| 3616 return IsDeletedOrDefault(clean_lines, linenum) | 3692 return IsDeletedOrDefault(clean_lines, linenum) |
| 3617 | 3693 |
| 3618 return False | 3694 # Reject types not mentioned in template-argument-list |
| 3695 while line: |
| 3696 match = Match(r'^.*?(\w+)\s*&&(.*)$', line) |
| 3697 if not match: |
| 3698 break |
| 3699 if match.group(1) not in typenames: |
| 3700 return False |
| 3701 line = match.group(2) |
| 3702 |
| 3703 # All RValue types that were in template-argument-list should have |
| 3704 # been removed by now. Those were allowed, assuming that they will |
| 3705 # be forwarded. |
| 3706 # |
| 3707 # If there are no remaining RValue types left (i.e. types that were |
| 3708 # not found in template-argument-list), flag those as not allowed. |
| 3709 return line.find('&&') < 0 |
| 3710 |
| 3711 |
| 3712 def GetTemplateArgs(clean_lines, linenum): |
| 3713 """Find list of template arguments associated with this function declaration. |
| 3714 |
| 3715 Args: |
| 3716 clean_lines: A CleansedLines instance containing the file. |
| 3717 linenum: Line number containing the start of the function declaration, |
| 3718 usually one line after the end of the template-argument-list. |
| 3719 Returns: |
| 3720 Set of type names, or empty set if this does not appear to have |
| 3721 any template parameters. |
| 3722 """ |
| 3723 # Find start of function |
| 3724 func_line = linenum |
| 3725 while func_line > 0: |
| 3726 line = clean_lines.elided[func_line] |
| 3727 if Match(r'^\s*$', line): |
| 3728 return set() |
| 3729 if line.find('(') >= 0: |
| 3730 break |
| 3731 func_line -= 1 |
| 3732 if func_line == 0: |
| 3733 return set() |
| 3734 |
| 3735 # Collapse template-argument-list into a single string |
| 3736 argument_list = '' |
| 3737 match = Match(r'^(\s*template\s*)<', clean_lines.elided[func_line]) |
| 3738 if match: |
| 3739 # template-argument-list on the same line as function name |
| 3740 start_col = len(match.group(1)) |
| 3741 _, end_line, end_col = CloseExpression(clean_lines, func_line, start_col) |
| 3742 if end_col > -1 and end_line == func_line: |
| 3743 start_col += 1 # Skip the opening bracket |
| 3744 argument_list = clean_lines.elided[func_line][start_col:end_col] |
| 3745 |
| 3746 elif func_line > 1: |
| 3747 # template-argument-list one line before function name |
| 3748 match = Match(r'^(.*)>\s*$', clean_lines.elided[func_line - 1]) |
| 3749 if match: |
| 3750 end_col = len(match.group(1)) |
| 3751 _, start_line, start_col = ReverseCloseExpression( |
| 3752 clean_lines, func_line - 1, end_col) |
| 3753 if start_col > -1: |
| 3754 start_col += 1 # Skip the opening bracket |
| 3755 while start_line < func_line - 1: |
| 3756 argument_list += clean_lines.elided[start_line][start_col:] |
| 3757 start_col = 0 |
| 3758 start_line += 1 |
| 3759 argument_list += clean_lines.elided[func_line - 1][start_col:end_col] |
| 3760 |
| 3761 if not argument_list: |
| 3762 return set() |
| 3763 |
| 3764 # Extract type names |
| 3765 typenames = set() |
| 3766 while True: |
| 3767 match = Match(r'^[,\s]*(?:typename|class)(?:\.\.\.)?\s+(\w+)(.*)$', |
| 3768 argument_list) |
| 3769 if not match: |
| 3770 break |
| 3771 typenames.add(match.group(1)) |
| 3772 argument_list = match.group(2) |
| 3773 return typenames |
| 3619 | 3774 |
| 3620 | 3775 |
| 3621 def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): | 3776 def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): |
| 3622 """Check for rvalue references. | 3777 """Check for rvalue references. |
| 3623 | 3778 |
| 3624 Args: | 3779 Args: |
| 3625 filename: The name of the current file. | 3780 filename: The name of the current file. |
| 3626 clean_lines: A CleansedLines instance containing the file. | 3781 clean_lines: A CleansedLines instance containing the file. |
| 3627 linenum: The number of the line to check. | 3782 linenum: The number of the line to check. |
| 3628 nesting_state: A NestingState instance which maintains information about | 3783 nesting_state: A NestingState instance which maintains information about |
| 3629 the current stack of nested blocks being parsed. | 3784 the current stack of nested blocks being parsed. |
| 3630 error: The function to call with any errors found. | 3785 error: The function to call with any errors found. |
| 3631 """ | 3786 """ |
| 3632 # Find lines missing spaces around &&. | 3787 # Find lines missing spaces around &&. |
| 3633 # TODO(unknown): currently we don't check for rvalue references | 3788 # TODO(unknown): currently we don't check for rvalue references |
| 3634 # with spaces surrounding the && to avoid false positives with | 3789 # with spaces surrounding the && to avoid false positives with |
| 3635 # boolean expressions. | 3790 # boolean expressions. |
| 3636 line = clean_lines.elided[linenum] | 3791 line = clean_lines.elided[linenum] |
| 3637 match = Match(r'^(.*\S)&&', line) | 3792 match = Match(r'^(.*\S)&&', line) |
| 3638 if not match: | 3793 if not match: |
| 3639 match = Match(r'(.*)&&\S', line) | 3794 match = Match(r'(.*)&&\S', line) |
| 3640 if (not match) or '(&&)' in line or Search(r'\boperator\s*$', match.group(1)): | 3795 if (not match) or '(&&)' in line or Search(r'\boperator\s*$', match.group(1)): |
| 3641 return | 3796 return |
| 3642 | 3797 |
| 3643 # Either poorly formed && or an rvalue reference, check the context | 3798 # Either poorly formed && or an rvalue reference, check the context |
| 3644 # to get a more accurate error message. Mostly we want to determine | 3799 # to get a more accurate error message. Mostly we want to determine |
| 3645 # if what's to the left of "&&" is a type or not. | 3800 # if what's to the left of "&&" is a type or not. |
| 3801 typenames = GetTemplateArgs(clean_lines, linenum) |
| 3646 and_pos = len(match.group(1)) | 3802 and_pos = len(match.group(1)) |
| 3647 if IsRValueType(clean_lines, nesting_state, linenum, and_pos): | 3803 if IsRValueType(typenames, clean_lines, nesting_state, linenum, and_pos): |
| 3648 if not IsRValueAllowed(clean_lines, linenum): | 3804 if not IsRValueAllowed(clean_lines, linenum, typenames): |
| 3649 error(filename, linenum, 'build/c++11', 3, | 3805 error(filename, linenum, 'build/c++11', 3, |
| 3650 'RValue references are an unapproved C++ feature.') | 3806 'RValue references are an unapproved C++ feature.') |
| 3651 else: | 3807 else: |
| 3652 error(filename, linenum, 'whitespace/operators', 3, | 3808 error(filename, linenum, 'whitespace/operators', 3, |
| 3653 'Missing spaces around &&') | 3809 'Missing spaces around &&') |
| 3654 | 3810 |
| 3655 | 3811 |
| 3656 def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): | 3812 def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): |
| 3657 """Checks for additional blank line issues related to sections. | 3813 """Checks for additional blank line issues related to sections. |
| 3658 | 3814 |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3919 # - INTERFACE_DEF | 4075 # - INTERFACE_DEF |
| 3920 # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: | 4076 # - EXCLUSIVE_LOCKS_REQUIRED, SHARED_LOCKS_REQUIRED, LOCKS_EXCLUDED: |
| 3921 # | 4077 # |
| 3922 # We implement a whitelist of safe macros instead of a blacklist of | 4078 # We implement a whitelist of safe macros instead of a blacklist of |
| 3923 # unsafe macros, even though the latter appears less frequently in | 4079 # unsafe macros, even though the latter appears less frequently in |
| 3924 # google code and would have been easier to implement. This is because | 4080 # google code and would have been easier to implement. This is because |
| 3925 # the downside for getting the whitelist wrong means some extra | 4081 # the downside for getting the whitelist wrong means some extra |
| 3926 # semicolons, while the downside for getting the blacklist wrong | 4082 # semicolons, while the downside for getting the blacklist wrong |
| 3927 # would result in compile errors. | 4083 # would result in compile errors. |
| 3928 # | 4084 # |
| 3929 # In addition to macros, we also don't want to warn on compound | 4085 # In addition to macros, we also don't want to warn on |
| 3930 # literals and lambdas. | 4086 # - Compound literals |
| 4087 # - Lambdas |
| 4088 # - alignas specifier with anonymous structs: |
| 3931 closing_brace_pos = match.group(1).rfind(')') | 4089 closing_brace_pos = match.group(1).rfind(')') |
| 3932 opening_parenthesis = ReverseCloseExpression( | 4090 opening_parenthesis = ReverseCloseExpression( |
| 3933 clean_lines, linenum, closing_brace_pos) | 4091 clean_lines, linenum, closing_brace_pos) |
| 3934 if opening_parenthesis[2] > -1: | 4092 if opening_parenthesis[2] > -1: |
| 3935 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] | 4093 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] |
| 3936 macro = Search(r'\b([A-Z_]+)\s*$', line_prefix) | 4094 macro = Search(r'\b([A-Z_]+)\s*$', line_prefix) |
| 3937 func = Match(r'^(.*\])\s*$', line_prefix) | 4095 func = Match(r'^(.*\])\s*$', line_prefix) |
| 3938 if ((macro and | 4096 if ((macro and |
| 3939 macro.group(1) not in ( | 4097 macro.group(1) not in ( |
| 3940 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', | 4098 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', |
| 3941 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', | 4099 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', |
| 3942 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or | 4100 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or |
| 3943 (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or | 4101 (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or |
| 4102 Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or |
| 3944 Search(r'\s+=\s*$', line_prefix)): | 4103 Search(r'\s+=\s*$', line_prefix)): |
| 3945 match = None | 4104 match = None |
| 3946 if (match and | 4105 if (match and |
| 3947 opening_parenthesis[1] > 1 and | 4106 opening_parenthesis[1] > 1 and |
| 3948 Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): | 4107 Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): |
| 3949 # Multi-line lambda-expression | 4108 # Multi-line lambda-expression |
| 3950 match = None | 4109 match = None |
| 3951 | 4110 |
| 3952 else: | 4111 else: |
| 3953 # Try matching cases 2-3. | 4112 # Try matching cases 2-3. |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4477 # not. | 4636 # not. |
| 4478 match = _RE_PATTERN_INCLUDE.search(line) | 4637 match = _RE_PATTERN_INCLUDE.search(line) |
| 4479 if match: | 4638 if match: |
| 4480 include = match.group(2) | 4639 include = match.group(2) |
| 4481 is_system = (match.group(1) == '<') | 4640 is_system = (match.group(1) == '<') |
| 4482 duplicate_line = include_state.FindHeader(include) | 4641 duplicate_line = include_state.FindHeader(include) |
| 4483 if duplicate_line >= 0: | 4642 if duplicate_line >= 0: |
| 4484 error(filename, linenum, 'build/include', 4, | 4643 error(filename, linenum, 'build/include', 4, |
| 4485 '"%s" already included at %s:%s' % | 4644 '"%s" already included at %s:%s' % |
| 4486 (include, filename, duplicate_line)) | 4645 (include, filename, duplicate_line)) |
| 4646 elif (include.endswith('.cc') and |
| 4647 os.path.dirname(fileinfo.RepositoryName()) != os.path.dirname(include)
): |
| 4648 error(filename, linenum, 'build/include', 4, |
| 4649 'Do not include .cc files from other packages') |
| 4487 elif not _THIRD_PARTY_HEADERS_PATTERN.match(include): | 4650 elif not _THIRD_PARTY_HEADERS_PATTERN.match(include): |
| 4488 include_state.include_list[-1].append((include, linenum)) | 4651 include_state.include_list[-1].append((include, linenum)) |
| 4489 | 4652 |
| 4490 # We want to ensure that headers appear in the right order: | 4653 # We want to ensure that headers appear in the right order: |
| 4491 # 1) for foo.cc, foo.h (preferred location) | 4654 # 1) for foo.cc, foo.h (preferred location) |
| 4492 # 2) c system files | 4655 # 2) c system files |
| 4493 # 3) cpp system files | 4656 # 3) cpp system files |
| 4494 # 4) for foo.cc, foo.h (deprecated location) | 4657 # 4) for foo.cc, foo.h (deprecated location) |
| 4495 # 5) other google headers | 4658 # 5) other google headers |
| 4496 # | 4659 # |
| 4497 # We classify each include statement as one of those 5 types | 4660 # We classify each include statement as one of those 5 types |
| 4498 # using a number of techniques. The include_state object keeps | 4661 # using a number of techniques. The include_state object keeps |
| 4499 # track of the highest type seen, and complains if we see a | 4662 # track of the highest type seen, and complains if we see a |
| 4500 # lower type after that. | 4663 # lower type after that. |
| 4501 error_message = include_state.CheckNextIncludeOrder( | 4664 error_message = include_state.CheckNextIncludeOrder( |
| 4502 _ClassifyInclude(fileinfo, include, is_system)) | 4665 _ClassifyInclude(fileinfo, include, is_system)) |
| 4503 if error_message: | 4666 if error_message: |
| 4504 error(filename, linenum, 'build/include_order', 4, | 4667 error(filename, linenum, 'build/include_order', 4, |
| 4505 '%s. Should be: %s.h, c system, c++ system, other.' % | 4668 '%s. Should be: %s.h, c system, c++ system, other.' % |
| 4506 (error_message, fileinfo.BaseName())) | 4669 (error_message, fileinfo.BaseName())) |
| 4507 canonical_include = include_state.CanonicalizeAlphabeticalOrder(include) | 4670 canonical_include = include_state.CanonicalizeAlphabeticalOrder(include) |
| 4508 if not include_state.IsInAlphabeticalOrder( | 4671 if not include_state.IsInAlphabeticalOrder( |
| 4509 clean_lines, linenum, canonical_include): | 4672 clean_lines, linenum, canonical_include): |
| 4510 error(filename, linenum, 'build/include_alpha', 4, | 4673 error(filename, linenum, 'build/include_alpha', 4, |
| 4511 'Include "%s" not in alphabetical order' % include) | 4674 'Include "%s" not in alphabetical order' % include) |
| 4512 include_state.SetLastHeader(canonical_include) | 4675 include_state.SetLastHeader(canonical_include) |
| 4513 | 4676 |
| 4514 # Look for any of the stream classes that are part of standard C++. | |
| 4515 match = _RE_PATTERN_INCLUDE.match(line) | |
| 4516 if match: | |
| 4517 include = match.group(2) | |
| 4518 if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include): | |
| 4519 # Many unit tests use cout, so we exempt them. | |
| 4520 if not _IsTestFilename(filename): | |
| 4521 # Suggest a different header for ostream | |
| 4522 if include == 'ostream': | |
| 4523 error(filename, linenum, 'readability/streams', 3, | |
| 4524 'For logging, include "base/logging.h" instead of <ostream>.') | |
| 4525 else: | |
| 4526 error(filename, linenum, 'readability/streams', 3, | |
| 4527 'Streams are highly discouraged.') | |
| 4528 | 4677 |
| 4529 | 4678 |
| 4530 def _GetTextInside(text, start_pattern): | 4679 def _GetTextInside(text, start_pattern): |
| 4531 r"""Retrieves all the text between matching open and close parentheses. | 4680 r"""Retrieves all the text between matching open and close parentheses. |
| 4532 | 4681 |
| 4533 Given a string of lines and a regular expression string, retrieve all the text | 4682 Given a string of lines and a regular expression string, retrieve all the text |
| 4534 following the expression and between opening punctuation symbols like | 4683 following the expression and between opening punctuation symbols like |
| 4535 (, [, or {, and the matching close-punctuation symbol. This properly nested | 4684 (, [, or {, and the matching close-punctuation symbol. This properly nested |
| 4536 occurrences of the punctuations, so for the text like | 4685 occurrences of the punctuations, so for the text like |
| 4537 printf(a(), b(c())); | 4686 printf(a(), b(c())); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4748 if tok.startswith('sizeof'): | 4897 if tok.startswith('sizeof'): |
| 4749 skip_next = True | 4898 skip_next = True |
| 4750 continue | 4899 continue |
| 4751 is_const = False | 4900 is_const = False |
| 4752 break | 4901 break |
| 4753 if not is_const: | 4902 if not is_const: |
| 4754 error(filename, linenum, 'runtime/arrays', 1, | 4903 error(filename, linenum, 'runtime/arrays', 1, |
| 4755 'Do not use variable-length arrays. Use an appropriately named ' | 4904 'Do not use variable-length arrays. Use an appropriately named ' |
| 4756 "('k' followed by CamelCase) compile-time constant for the size.") | 4905 "('k' followed by CamelCase) compile-time constant for the size.") |
| 4757 | 4906 |
| 4758 # If DISALLOW_COPY_AND_ASSIGN DISALLOW_IMPLICIT_CONSTRUCTORS is present, | |
| 4759 # then it should be the last thing in the class declaration. | |
| 4760 match = Match( | |
| 4761 (r'\s*' | |
| 4762 r'(DISALLOW_(COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))' | |
| 4763 r'\(.*\);$'), | |
| 4764 line) | |
| 4765 if match and linenum + 1 < clean_lines.NumLines(): | |
| 4766 next_line = clean_lines.elided[linenum + 1] | |
| 4767 # We allow some, but not all, declarations of variables to be present | |
| 4768 # in the statement that defines the class. The [\w\*,\s]* fragment of | |
| 4769 # the regular expression below allows users to declare instances of | |
| 4770 # the class or pointers to instances, but not less common types such | |
| 4771 # as function pointers or arrays. It's a tradeoff between allowing | |
| 4772 # reasonable code and avoiding trying to parse more C++ using regexps. | |
| 4773 if not Search(r'^\s*}[\w\*,\s]*;', next_line): | |
| 4774 error(filename, linenum, 'readability/constructors', 3, | |
| 4775 match.group(1) + ' should be the last thing in the class') | |
| 4776 | |
| 4777 # Check for use of unnamed namespaces in header files. Registration | 4907 # Check for use of unnamed namespaces in header files. Registration |
| 4778 # macros are typically OK, so we allow use of "namespace {" on lines | 4908 # macros are typically OK, so we allow use of "namespace {" on lines |
| 4779 # that end with backslashes. | 4909 # that end with backslashes. |
| 4780 if (file_extension == 'h' | 4910 if (file_extension == 'h' |
| 4781 and Search(r'\bnamespace\s*{', line) | 4911 and Search(r'\bnamespace\s*{', line) |
| 4782 and line[-1] != '\\'): | 4912 and line[-1] != '\\'): |
| 4783 error(filename, linenum, 'build/namespaces', 4, | 4913 error(filename, linenum, 'build/namespaces', 4, |
| 4784 'Do not use unnamed namespaces in header files. See ' | 4914 'Do not use unnamed namespaces in header files. See ' |
| 4785 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp
aces' | 4915 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp
aces' |
| 4786 ' for more information.') | 4916 ' for more information.') |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4882 match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) | 5012 match = Match(r'^([^()]*\w+)\(', clean_lines.elided[i]) |
| 4883 if match: | 5013 if match: |
| 4884 # Look for "override" after the matching closing parenthesis | 5014 # Look for "override" after the matching closing parenthesis |
| 4885 line, _, closing_paren = CloseExpression( | 5015 line, _, closing_paren = CloseExpression( |
| 4886 clean_lines, i, len(match.group(1))) | 5016 clean_lines, i, len(match.group(1))) |
| 4887 return (closing_paren >= 0 and | 5017 return (closing_paren >= 0 and |
| 4888 Search(r'\boverride\b', line[closing_paren:])) | 5018 Search(r'\boverride\b', line[closing_paren:])) |
| 4889 return False | 5019 return False |
| 4890 | 5020 |
| 4891 | 5021 |
| 5022 def IsOutOfLineMethodDefinition(clean_lines, linenum): |
| 5023 """Check if current line contains an out-of-line method definition. |
| 5024 |
| 5025 Args: |
| 5026 clean_lines: A CleansedLines instance containing the file. |
| 5027 linenum: The number of the line to check. |
| 5028 Returns: |
| 5029 True if current line contains an out-of-line method definition. |
| 5030 """ |
| 5031 # Scan back a few lines for start of current function |
| 5032 for i in xrange(linenum, max(-1, linenum - 10), -1): |
| 5033 if Match(r'^([^()]*\w+)\(', clean_lines.elided[i]): |
| 5034 return Match(r'^[^()]*\w+::\w+\(', clean_lines.elided[i]) is not None |
| 5035 return False |
| 5036 |
| 5037 |
| 4892 def IsInitializerList(clean_lines, linenum): | 5038 def IsInitializerList(clean_lines, linenum): |
| 4893 """Check if current line is inside constructor initializer list. | 5039 """Check if current line is inside constructor initializer list. |
| 4894 | 5040 |
| 4895 Args: | 5041 Args: |
| 4896 clean_lines: A CleansedLines instance containing the file. | 5042 clean_lines: A CleansedLines instance containing the file. |
| 4897 linenum: The number of the line to check. | 5043 linenum: The number of the line to check. |
| 4898 Returns: | 5044 Returns: |
| 4899 True if current line appears to be inside constructor initializer | 5045 True if current line appears to be inside constructor initializer |
| 4900 list, False otherwise. | 5046 list, False otherwise. |
| 4901 """ | 5047 """ |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4950 line = clean_lines.elided[linenum] | 5096 line = clean_lines.elided[linenum] |
| 4951 if '&' not in line: | 5097 if '&' not in line: |
| 4952 return | 5098 return |
| 4953 | 5099 |
| 4954 # If a function is inherited, current function doesn't have much of | 5100 # If a function is inherited, current function doesn't have much of |
| 4955 # a choice, so any non-const references should not be blamed on | 5101 # a choice, so any non-const references should not be blamed on |
| 4956 # derived function. | 5102 # derived function. |
| 4957 if IsDerivedFunction(clean_lines, linenum): | 5103 if IsDerivedFunction(clean_lines, linenum): |
| 4958 return | 5104 return |
| 4959 | 5105 |
| 5106 # Don't warn on out-of-line method definitions, as we would warn on the |
| 5107 # in-line declaration, if it isn't marked with 'override'. |
| 5108 if IsOutOfLineMethodDefinition(clean_lines, linenum): |
| 5109 return |
| 5110 |
| 4960 # Long type names may be broken across multiple lines, usually in one | 5111 # Long type names may be broken across multiple lines, usually in one |
| 4961 # of these forms: | 5112 # of these forms: |
| 4962 # LongType | 5113 # LongType |
| 4963 # ::LongTypeContinued &identifier | 5114 # ::LongTypeContinued &identifier |
| 4964 # LongType:: | 5115 # LongType:: |
| 4965 # LongTypeContinued &identifier | 5116 # LongTypeContinued &identifier |
| 4966 # LongType< | 5117 # LongType< |
| 4967 # ...>::LongTypeContinued &identifier | 5118 # ...>::LongTypeContinued &identifier |
| 4968 # | 5119 # |
| 4969 # If we detected a type split across two lines, join the previous | 5120 # If we detected a type split across two lines, join the previous |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5145 # point where you think. | 5296 # point where you think. |
| 5146 # | 5297 # |
| 5147 # Some non-identifier character is required before the '&' for the | 5298 # Some non-identifier character is required before the '&' for the |
| 5148 # expression to be recognized as a cast. These are casts: | 5299 # expression to be recognized as a cast. These are casts: |
| 5149 # expression = &static_cast<int*>(temporary()); | 5300 # expression = &static_cast<int*>(temporary()); |
| 5150 # function(&(int*)(temporary())); | 5301 # function(&(int*)(temporary())); |
| 5151 # | 5302 # |
| 5152 # This is not a cast: | 5303 # This is not a cast: |
| 5153 # reference_type&(int* function_param); | 5304 # reference_type&(int* function_param); |
| 5154 match = Search( | 5305 match = Search( |
| 5155 r'(?:[^\w]&\(([^)]+)\)[\w(])|' | 5306 r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|' |
| 5156 r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line) | 5307 r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line) |
| 5157 if match and match.group(1) != '*': | 5308 if match: |
| 5158 # Try a better error message when the & is bound to something | 5309 # Try a better error message when the & is bound to something |
| 5159 # dereferenced by the casted pointer, as opposed to the casted | 5310 # dereferenced by the casted pointer, as opposed to the casted |
| 5160 # pointer itself. | 5311 # pointer itself. |
| 5161 parenthesis_error = False | 5312 parenthesis_error = False |
| 5162 match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) | 5313 match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line) |
| 5163 if match: | 5314 if match: |
| 5164 _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) | 5315 _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1))) |
| 5165 if x1 >= 0 and clean_lines.elided[y1][x1] == '(': | 5316 if x1 >= 0 and clean_lines.elided[y1][x1] == '(': |
| 5166 _, y2, x2 = CloseExpression(clean_lines, y1, x1) | 5317 _, y2, x2 = CloseExpression(clean_lines, y1, x1) |
| 5167 if x2 >= 0: | 5318 if x2 >= 0: |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5228 # | 5379 # |
| 5229 # These are things that we want warnings for, since the style guide | 5380 # These are things that we want warnings for, since the style guide |
| 5230 # explicitly require all parameters to be named: | 5381 # explicitly require all parameters to be named: |
| 5231 # Function(int); | 5382 # Function(int); |
| 5232 # Function(int) { | 5383 # Function(int) { |
| 5233 # ConstMember(int) const; | 5384 # ConstMember(int) const; |
| 5234 # ConstMember(int) const { | 5385 # ConstMember(int) const { |
| 5235 # ExceptionMember(int) throw (...); | 5386 # ExceptionMember(int) throw (...); |
| 5236 # ExceptionMember(int) throw (...) { | 5387 # ExceptionMember(int) throw (...) { |
| 5237 # PureVirtual(int) = 0; | 5388 # PureVirtual(int) = 0; |
| 5389 # [](int) -> bool { |
| 5238 # | 5390 # |
| 5239 # These are functions of some sort, where the compiler would be fine | 5391 # These are functions of some sort, where the compiler would be fine |
| 5240 # if they had named parameters, but people often omit those | 5392 # if they had named parameters, but people often omit those |
| 5241 # identifiers to reduce clutter: | 5393 # identifiers to reduce clutter: |
| 5242 # (FunctionPointer)(int); | 5394 # (FunctionPointer)(int); |
| 5243 # (FunctionPointer)(int) = value; | 5395 # (FunctionPointer)(int) = value; |
| 5244 # Function((function_pointer_arg)(int)) | 5396 # Function((function_pointer_arg)(int)) |
| 5245 # Function((function_pointer_arg)(int), int param) | 5397 # Function((function_pointer_arg)(int), int param) |
| 5246 # <TemplateArgument(int)>; | 5398 # <TemplateArgument(int)>; |
| 5247 # <(FunctionPointerTemplateArgument)(int)>; | 5399 # <(FunctionPointerTemplateArgument)(int)>; |
| 5248 remainder = line[match.end(0):] | 5400 remainder = line[match.end(0):] |
| 5249 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),])', | 5401 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', |
| 5250 remainder): | 5402 remainder): |
| 5251 # Looks like an unnamed parameter. | 5403 # Looks like an unnamed parameter. |
| 5252 | 5404 |
| 5253 # Don't warn on any kind of template arguments. | 5405 # Don't warn on any kind of template arguments. |
| 5254 if Match(r'^\s*>', remainder): | 5406 if Match(r'^\s*>', remainder): |
| 5255 return False | 5407 return False |
| 5256 | 5408 |
| 5257 # Don't warn on assignments to function pointers, but keep warnings for | 5409 # Don't warn on assignments to function pointers, but keep warnings for |
| 5258 # unnamed parameters to pure virtual functions. Note that this pattern | 5410 # unnamed parameters to pure virtual functions. Note that this pattern |
| 5259 # will also pass on assignments of "0" to function pointers, but the | 5411 # will also pass on assignments of "0" to function pointers, but the |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5328 'mem_fun_ref', | 5480 'mem_fun_ref', |
| 5329 )), | 5481 )), |
| 5330 ('<limits>', ('numeric_limits',)), | 5482 ('<limits>', ('numeric_limits',)), |
| 5331 ('<list>', ('list',)), | 5483 ('<list>', ('list',)), |
| 5332 ('<map>', ('map', 'multimap',)), | 5484 ('<map>', ('map', 'multimap',)), |
| 5333 ('<memory>', ('allocator',)), | 5485 ('<memory>', ('allocator',)), |
| 5334 ('<queue>', ('queue', 'priority_queue',)), | 5486 ('<queue>', ('queue', 'priority_queue',)), |
| 5335 ('<set>', ('set', 'multiset',)), | 5487 ('<set>', ('set', 'multiset',)), |
| 5336 ('<stack>', ('stack',)), | 5488 ('<stack>', ('stack',)), |
| 5337 ('<string>', ('char_traits', 'basic_string',)), | 5489 ('<string>', ('char_traits', 'basic_string',)), |
| 5490 ('<tuple>', ('tuple',)), |
| 5338 ('<utility>', ('pair',)), | 5491 ('<utility>', ('pair',)), |
| 5339 ('<vector>', ('vector',)), | 5492 ('<vector>', ('vector',)), |
| 5340 | 5493 |
| 5341 # gcc extensions. | 5494 # gcc extensions. |
| 5342 # Note: std::hash is their hash, ::hash is our hash | 5495 # Note: std::hash is their hash, ::hash is our hash |
| 5343 ('<hash_map>', ('hash_map', 'hash_multimap',)), | 5496 ('<hash_map>', ('hash_map', 'hash_multimap',)), |
| 5344 ('<hash_set>', ('hash_set', 'hash_multiset',)), | 5497 ('<hash_set>', ('hash_set', 'hash_multiset',)), |
| 5345 ('<slist>', ('slist',)), | 5498 ('<slist>', ('slist',)), |
| 5346 ) | 5499 ) |
| 5347 | 5500 |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5595 """Check if line contains a redundant "virtual" function-specifier. | 5748 """Check if line contains a redundant "virtual" function-specifier. |
| 5596 | 5749 |
| 5597 Args: | 5750 Args: |
| 5598 filename: The name of the current file. | 5751 filename: The name of the current file. |
| 5599 clean_lines: A CleansedLines instance containing the file. | 5752 clean_lines: A CleansedLines instance containing the file. |
| 5600 linenum: The number of the line to check. | 5753 linenum: The number of the line to check. |
| 5601 error: The function to call with any errors found. | 5754 error: The function to call with any errors found. |
| 5602 """ | 5755 """ |
| 5603 # Look for "virtual" on current line. | 5756 # Look for "virtual" on current line. |
| 5604 line = clean_lines.elided[linenum] | 5757 line = clean_lines.elided[linenum] |
| 5605 virtual = Match(r'^(.*\bvirtual\b)', line) | 5758 virtual = Match(r'^(.*)(\bvirtual\b)(.*)$', line) |
| 5606 if not virtual: return | 5759 if not virtual: return |
| 5607 | 5760 |
| 5761 # Ignore "virtual" keywords that are near access-specifiers. These |
| 5762 # are only used in class base-specifier and do not apply to member |
| 5763 # functions. |
| 5764 if (Search(r'\b(public|protected|private)\s+$', virtual.group(1)) or |
| 5765 Match(r'^\s+(public|protected|private)\b', virtual.group(3))): |
| 5766 return |
| 5767 |
| 5768 # Ignore the "virtual" keyword from virtual base classes. Usually |
| 5769 # there is a column on the same line in these cases (virtual base |
| 5770 # classes are rare in google3 because multiple inheritance is rare). |
| 5771 if Match(r'^.*[^:]:[^:].*$', line): return |
| 5772 |
| 5608 # Look for the next opening parenthesis. This is the start of the | 5773 # Look for the next opening parenthesis. This is the start of the |
| 5609 # parameter list (possibly on the next line shortly after virtual). | 5774 # parameter list (possibly on the next line shortly after virtual). |
| 5610 # TODO(unknown): doesn't work if there are virtual functions with | 5775 # TODO(unknown): doesn't work if there are virtual functions with |
| 5611 # decltype() or other things that use parentheses, but csearch suggests | 5776 # decltype() or other things that use parentheses, but csearch suggests |
| 5612 # that this is rare. | 5777 # that this is rare. |
| 5613 end_col = -1 | 5778 end_col = -1 |
| 5614 end_line = -1 | 5779 end_line = -1 |
| 5615 start_col = len(virtual.group(1)) | 5780 start_col = len(virtual.group(2)) |
| 5616 for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): | 5781 for start_line in xrange(linenum, min(linenum + 3, clean_lines.NumLines())): |
| 5617 line = clean_lines.elided[start_line][start_col:] | 5782 line = clean_lines.elided[start_line][start_col:] |
| 5618 parameter_list = Match(r'^([^(]*)\(', line) | 5783 parameter_list = Match(r'^([^(]*)\(', line) |
| 5619 if parameter_list: | 5784 if parameter_list: |
| 5620 # Match parentheses to find the end of the parameter list | 5785 # Match parentheses to find the end of the parameter list |
| 5621 (_, end_line, end_col) = CloseExpression( | 5786 (_, end_line, end_col) = CloseExpression( |
| 5622 clean_lines, start_line, start_col + len(parameter_list.group(1))) | 5787 clean_lines, start_line, start_col + len(parameter_list.group(1))) |
| 5623 break | 5788 break |
| 5624 start_col = 0 | 5789 start_col = 0 |
| 5625 | 5790 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 5645 | 5810 |
| 5646 def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error): | 5811 def CheckRedundantOverrideOrFinal(filename, clean_lines, linenum, error): |
| 5647 """Check if line contains a redundant "override" or "final" virt-specifier. | 5812 """Check if line contains a redundant "override" or "final" virt-specifier. |
| 5648 | 5813 |
| 5649 Args: | 5814 Args: |
| 5650 filename: The name of the current file. | 5815 filename: The name of the current file. |
| 5651 clean_lines: A CleansedLines instance containing the file. | 5816 clean_lines: A CleansedLines instance containing the file. |
| 5652 linenum: The number of the line to check. | 5817 linenum: The number of the line to check. |
| 5653 error: The function to call with any errors found. | 5818 error: The function to call with any errors found. |
| 5654 """ | 5819 """ |
| 5820 # Look for closing parenthesis nearby. We need one to confirm where |
| 5821 # the declarator ends and where the virt-specifier starts to avoid |
| 5822 # false positives. |
| 5823 line = clean_lines.elided[linenum] |
| 5824 declarator_end = line.rfind(')') |
| 5825 if declarator_end >= 0: |
| 5826 fragment = line[declarator_end:] |
| 5827 else: |
| 5828 if linenum > 1 and clean_lines.elided[linenum - 1].rfind(')') >= 0: |
| 5829 fragment = line |
| 5830 else: |
| 5831 return |
| 5832 |
| 5655 # Check that at most one of "override" or "final" is present, not both | 5833 # Check that at most one of "override" or "final" is present, not both |
| 5656 line = clean_lines.elided[linenum] | 5834 if Search(r'\boverride\b', fragment) and Search(r'\bfinal\b', fragment): |
| 5657 if Search(r'\boverride\b', line) and Search(r'\bfinal\b', line): | |
| 5658 error(filename, linenum, 'readability/inheritance', 4, | 5835 error(filename, linenum, 'readability/inheritance', 4, |
| 5659 ('"override" is redundant since function is ' | 5836 ('"override" is redundant since function is ' |
| 5660 'already declared as "final"')) | 5837 'already declared as "final"')) |
| 5661 | 5838 |
| 5662 | 5839 |
| 5663 | 5840 |
| 5664 | 5841 |
| 5665 # Returns true if we are at a new block, and it is directly | 5842 # Returns true if we are at a new block, and it is directly |
| 5666 # inside of a namespace. | 5843 # inside of a namespace. |
| 5667 def IsBlockInNameSpace(nesting_state, is_forward_declaration): | 5844 def IsBlockInNameSpace(nesting_state, is_forward_declaration): |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5802 # features in preprocessor directives is in macro definitions. | 5979 # features in preprocessor directives is in macro definitions. |
| 5803 if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return | 5980 if Match(r'\s*#', line) and not Match(r'\s*#\s*define\b', line): return |
| 5804 | 5981 |
| 5805 # These are classes and free functions. The classes are always | 5982 # These are classes and free functions. The classes are always |
| 5806 # mentioned as std::*, but we only catch the free functions if | 5983 # mentioned as std::*, but we only catch the free functions if |
| 5807 # they're not found by ADL. They're alphabetical by header. | 5984 # they're not found by ADL. They're alphabetical by header. |
| 5808 for top_name in ( | 5985 for top_name in ( |
| 5809 # type_traits | 5986 # type_traits |
| 5810 'alignment_of', | 5987 'alignment_of', |
| 5811 'aligned_union', | 5988 'aligned_union', |
| 5812 | |
| 5813 # utility | |
| 5814 'forward', | |
| 5815 ): | 5989 ): |
| 5816 if Search(r'\bstd::%s\b' % top_name, line): | 5990 if Search(r'\bstd::%s\b' % top_name, line): |
| 5817 error(filename, linenum, 'build/c++11', 5, | 5991 error(filename, linenum, 'build/c++11', 5, |
| 5818 ('std::%s is an unapproved C++11 class or function. Send c-style ' | 5992 ('std::%s is an unapproved C++11 class or function. Send c-style ' |
| 5819 'an example of where it would make your code more readable, and ' | 5993 'an example of where it would make your code more readable, and ' |
| 5820 'they may let you use it.') % top_name) | 5994 'they may let you use it.') % top_name) |
| 5821 | 5995 |
| 5822 | 5996 |
| 5823 def ProcessFileData(filename, file_extension, lines, error, | 5997 def ProcessFileData(filename, file_extension, lines, error, |
| 5824 extra_check_functions=[]): | 5998 extra_check_functions=[]): |
| (...skipping 14 matching lines...) Expand all Loading... |
| 5839 ['// marker so line numbers end in a known way']) | 6013 ['// marker so line numbers end in a known way']) |
| 5840 | 6014 |
| 5841 include_state = _IncludeState() | 6015 include_state = _IncludeState() |
| 5842 function_state = _FunctionState() | 6016 function_state = _FunctionState() |
| 5843 nesting_state = NestingState() | 6017 nesting_state = NestingState() |
| 5844 | 6018 |
| 5845 ResetNolintSuppressions() | 6019 ResetNolintSuppressions() |
| 5846 | 6020 |
| 5847 CheckForCopyright(filename, lines, error) | 6021 CheckForCopyright(filename, lines, error) |
| 5848 | 6022 |
| 5849 if file_extension == 'h': | |
| 5850 CheckForHeaderGuard(filename, lines, error) | |
| 5851 | |
| 5852 RemoveMultiLineComments(filename, lines, error) | 6023 RemoveMultiLineComments(filename, lines, error) |
| 5853 clean_lines = CleansedLines(lines) | 6024 clean_lines = CleansedLines(lines) |
| 6025 |
| 6026 if file_extension == 'h': |
| 6027 CheckForHeaderGuard(filename, clean_lines, error) |
| 6028 |
| 5854 for line in xrange(clean_lines.NumLines()): | 6029 for line in xrange(clean_lines.NumLines()): |
| 5855 ProcessLine(filename, file_extension, clean_lines, line, | 6030 ProcessLine(filename, file_extension, clean_lines, line, |
| 5856 include_state, function_state, nesting_state, error, | 6031 include_state, function_state, nesting_state, error, |
| 5857 extra_check_functions) | 6032 extra_check_functions) |
| 5858 FlagCxx11Features(filename, clean_lines, line, error) | 6033 FlagCxx11Features(filename, clean_lines, line, error) |
| 5859 nesting_state.CheckCompletedBlocks(filename, error) | 6034 nesting_state.CheckCompletedBlocks(filename, error) |
| 5860 | 6035 |
| 5861 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) | 6036 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) |
| 6037 |
| 6038 # Check that the .cc file has included its header if it exists. |
| 6039 if file_extension == 'cc': |
| 6040 CheckHeaderFileIncluded(filename, include_state, error) |
| 5862 | 6041 |
| 5863 # We check here rather than inside ProcessLine so that we see raw | 6042 # We check here rather than inside ProcessLine so that we see raw |
| 5864 # lines rather than "cleaned" lines. | 6043 # lines rather than "cleaned" lines. |
| 5865 CheckForBadCharacters(filename, lines, error) | 6044 CheckForBadCharacters(filename, lines, error) |
| 5866 | 6045 |
| 5867 CheckForNewlineAtEOF(filename, lines, error) | 6046 CheckForNewlineAtEOF(filename, lines, error) |
| 5868 | 6047 |
| 5869 def ProcessConfigOverrides(filename): | 6048 def ProcessConfigOverrides(filename): |
| 5870 """ Loads the configuration files and processes the config overrides. | 6049 """ Loads the configuration files and processes the config overrides. |
| 5871 | 6050 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6135 _cpplint_state.ResetErrorCounts() | 6314 _cpplint_state.ResetErrorCounts() |
| 6136 for filename in filenames: | 6315 for filename in filenames: |
| 6137 ProcessFile(filename, _cpplint_state.verbose_level) | 6316 ProcessFile(filename, _cpplint_state.verbose_level) |
| 6138 _cpplint_state.PrintErrorCounts() | 6317 _cpplint_state.PrintErrorCounts() |
| 6139 | 6318 |
| 6140 sys.exit(_cpplint_state.error_count > 0) | 6319 sys.exit(_cpplint_state.error_count > 0) |
| 6141 | 6320 |
| 6142 | 6321 |
| 6143 if __name__ == '__main__': | 6322 if __name__ == '__main__': |
| 6144 main() | 6323 main() |
| OLD | NEW |