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