Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Side by Side Diff: cpplint.py

Issue 777533005: Update cpplint.py to r141. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools@master
Patch Set: Fixed pylint issue in fix_encoding (slice index is not an int) Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | fix_encoding.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
OLDNEW
« no previous file with comments | « no previous file | fix_encoding.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698