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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 import unicodedata | 53 import unicodedata |
54 | 54 |
55 | 55 |
56 _USAGE = """ | 56 _USAGE = """ |
57 Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] | 57 Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...] |
58 [--counting=total|toplevel|detailed] [--root=subdir] | 58 [--counting=total|toplevel|detailed] [--root=subdir] |
59 [--linelength=digits] | 59 [--linelength=digits] |
60 <file> [file] ... | 60 <file> [file] ... |
61 | 61 |
62 The style guidelines this tries to follow are those in | 62 The style guidelines this tries to follow are those in |
63 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml | 63 https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml |
64 | 64 |
65 Every problem is given a confidence score from 1-5, with 5 meaning we are | 65 Every problem is given a confidence score from 1-5, with 5 meaning we are |
66 certain of the problem, and 1 meaning it could be a legitimate construct. | 66 certain of the problem, and 1 meaning it could be a legitimate construct. |
67 This will miss some errors, and is not a substitute for a code review. | 67 This will miss some errors, and is not a substitute for a code review. |
68 | 68 |
69 To suppress false-positive errors of a certain category, add a | 69 To suppress false-positive errors of a certain category, add a |
70 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) | 70 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*) |
71 suppresses errors of all categories on that line. | 71 suppresses errors of all categories on that line. |
72 | 72 |
73 The files passed in will be linted; at least one file must be provided. | 73 The files passed in will be linted; at least one file must be provided. |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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/c++14', |
| 181 'build/c++tr1', |
180 'build/deprecated', | 182 'build/deprecated', |
181 'build/endif_comment', | 183 'build/endif_comment', |
182 'build/explicit_make_pair', | 184 'build/explicit_make_pair', |
183 'build/forward_decl', | 185 'build/forward_decl', |
184 'build/header_guard', | 186 'build/header_guard', |
185 'build/include', | 187 'build/include', |
186 'build/include_alpha', | 188 'build/include_alpha', |
187 'build/include_order', | 189 'build/include_order', |
188 'build/include_what_you_use', | 190 'build/include_what_you_use', |
189 'build/namespaces', | 191 'build/namespaces', |
190 'build/printf_format', | 192 'build/printf_format', |
191 'build/storage_class', | 193 'build/storage_class', |
192 'legal/copyright', | 194 'legal/copyright', |
193 'readability/alt_tokens', | 195 'readability/alt_tokens', |
194 'readability/braces', | 196 'readability/braces', |
195 'readability/casting', | 197 'readability/casting', |
196 'readability/check', | 198 'readability/check', |
197 'readability/constructors', | 199 'readability/constructors', |
198 'readability/fn_size', | 200 'readability/fn_size', |
199 'readability/function', | |
200 'readability/inheritance', | 201 'readability/inheritance', |
201 'readability/multiline_comment', | 202 'readability/multiline_comment', |
202 'readability/multiline_string', | 203 'readability/multiline_string', |
203 'readability/namespace', | 204 'readability/namespace', |
204 'readability/nolint', | 205 'readability/nolint', |
205 'readability/nul', | 206 'readability/nul', |
206 'readability/strings', | 207 'readability/strings', |
207 'readability/todo', | 208 'readability/todo', |
208 'readability/utf8', | 209 'readability/utf8', |
209 'runtime/arrays', | 210 'runtime/arrays', |
(...skipping 10 matching lines...) Expand all Loading... |
220 'runtime/printf_format', | 221 'runtime/printf_format', |
221 'runtime/references', | 222 'runtime/references', |
222 'runtime/string', | 223 'runtime/string', |
223 'runtime/threadsafe_fn', | 224 'runtime/threadsafe_fn', |
224 'runtime/vlog', | 225 'runtime/vlog', |
225 'whitespace/blank_line', | 226 'whitespace/blank_line', |
226 'whitespace/braces', | 227 'whitespace/braces', |
227 'whitespace/comma', | 228 'whitespace/comma', |
228 'whitespace/comments', | 229 'whitespace/comments', |
229 'whitespace/empty_conditional_body', | 230 'whitespace/empty_conditional_body', |
| 231 'whitespace/empty_if_body', |
230 'whitespace/empty_loop_body', | 232 'whitespace/empty_loop_body', |
231 'whitespace/end_of_line', | 233 'whitespace/end_of_line', |
232 'whitespace/ending_newline', | 234 'whitespace/ending_newline', |
233 'whitespace/forcolon', | 235 'whitespace/forcolon', |
234 'whitespace/indent', | 236 'whitespace/indent', |
235 'whitespace/line_length', | 237 'whitespace/line_length', |
236 'whitespace/newline', | 238 'whitespace/newline', |
237 'whitespace/operators', | 239 'whitespace/operators', |
238 'whitespace/parens', | 240 'whitespace/parens', |
239 'whitespace/semicolon', | 241 'whitespace/semicolon', |
240 'whitespace/tab', | 242 'whitespace/tab', |
241 'whitespace/todo', | 243 'whitespace/todo', |
242 ] | 244 ] |
243 | 245 |
244 # These error categories are no longer enforced by cpplint, but for backwards- | 246 # These error categories are no longer enforced by cpplint, but for backwards- |
245 # compatibility they may still appear in NOLINT comments. | 247 # compatibility they may still appear in NOLINT comments. |
246 _LEGACY_ERROR_CATEGORIES = [ | 248 _LEGACY_ERROR_CATEGORIES = [ |
247 'readability/streams', | 249 'readability/streams', |
| 250 'readability/function', |
248 ] | 251 ] |
249 | 252 |
250 # The default state of the category filter. This is overridden by the --filter= | 253 # The default state of the category filter. This is overridden by the --filter= |
251 # flag. By default all errors are on, so only add here categories that should be | 254 # flag. By default all errors are on, so only add here categories that should be |
252 # off by default (i.e., categories that must be enabled by the --filter= flags). | 255 # off by default (i.e., categories that must be enabled by the --filter= flags). |
253 # All entries here should start with a '-' or '+', as in the --filter= flag. | 256 # All entries here should start with a '-' or '+', as in the --filter= flag. |
254 _DEFAULT_FILTERS = ['-build/include_alpha'] | 257 _DEFAULT_FILTERS = ['-build/include_alpha'] |
255 | 258 |
| 259 # The default list of categories suppressed for C (not C++) files. |
| 260 _DEFAULT_C_SUPPRESSED_CATEGORIES = [ |
| 261 'readability/casting', |
| 262 ] |
| 263 |
| 264 # The default list of categories suppressed for Linux Kernel files. |
| 265 _DEFAULT_KERNEL_SUPPRESSED_CATEGORIES = [ |
| 266 'whitespace/tab', |
| 267 ] |
| 268 |
256 # We used to check for high-bit characters, but after much discussion we | 269 # We used to check for high-bit characters, but after much discussion we |
257 # decided those were OK, as long as they were in UTF-8 and didn't represent | 270 # decided those were OK, as long as they were in UTF-8 and didn't represent |
258 # hard-coded international strings, which belong in a separate i18n file. | 271 # hard-coded international strings, which belong in a separate i18n file. |
259 | 272 |
260 # C++ headers | 273 # C++ headers |
261 _CPP_HEADERS = frozenset([ | 274 _CPP_HEADERS = frozenset([ |
262 # Legacy | 275 # Legacy |
263 'algobase.h', | 276 'algobase.h', |
264 'algo.h', | 277 'algo.h', |
265 'alloc.h', | 278 'alloc.h', |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 'map', | 352 'map', |
340 'memory', | 353 'memory', |
341 'mutex', | 354 'mutex', |
342 'new', | 355 'new', |
343 'numeric', | 356 'numeric', |
344 'ostream', | 357 'ostream', |
345 'queue', | 358 'queue', |
346 'random', | 359 'random', |
347 'ratio', | 360 'ratio', |
348 'regex', | 361 'regex', |
| 362 'scoped_allocator', |
349 'set', | 363 'set', |
350 'sstream', | 364 'sstream', |
351 'stack', | 365 'stack', |
352 'stdexcept', | 366 'stdexcept', |
353 'streambuf', | 367 'streambuf', |
354 'string', | 368 'string', |
355 'strstream', | 369 'strstream', |
356 'system_error', | 370 'system_error', |
357 'thread', | 371 'thread', |
358 'tuple', | 372 'tuple', |
(...skipping 27 matching lines...) Expand all Loading... |
386 'cstdio', | 400 'cstdio', |
387 'cstdlib', | 401 'cstdlib', |
388 'cstring', | 402 'cstring', |
389 'ctgmath', | 403 'ctgmath', |
390 'ctime', | 404 'ctime', |
391 'cuchar', | 405 'cuchar', |
392 'cwchar', | 406 'cwchar', |
393 'cwctype', | 407 'cwctype', |
394 ]) | 408 ]) |
395 | 409 |
| 410 # Type names |
| 411 _TYPES = re.compile( |
| 412 r'^(?:' |
| 413 # [dcl.type.simple] |
| 414 r'(char(16_t|32_t)?)|wchar_t|' |
| 415 r'bool|short|int|long|signed|unsigned|float|double|' |
| 416 # [support.types] |
| 417 r'(ptrdiff_t|size_t|max_align_t|nullptr_t)|' |
| 418 # [cstdint.syn] |
| 419 r'(u?int(_fast|_least)?(8|16|32|64)_t)|' |
| 420 r'(u?int(max|ptr)_t)|' |
| 421 r')$') |
| 422 |
396 | 423 |
397 # These headers are excluded from [build/include] and [build/include_order] | 424 # These headers are excluded from [build/include] and [build/include_order] |
398 # checks: | 425 # checks: |
399 # - Anything not following google file name conventions (containing an | 426 # - Anything not following google file name conventions (containing an |
400 # uppercase character, such as Python.h or nsStringAPI.h, for example). | 427 # uppercase character, such as Python.h or nsStringAPI.h, for example). |
401 # - Lua headers. | 428 # - Lua headers. |
402 _THIRD_PARTY_HEADERS_PATTERN = re.compile( | 429 _THIRD_PARTY_HEADERS_PATTERN = re.compile( |
403 r'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$') | 430 r'^(?:[^/]*[A-Z][^/]*\.h|lua\.h|lauxlib\.h|lualib\.h)$') |
404 | 431 |
| 432 # Pattern for matching FileInfo.BaseName() against test file name |
| 433 _TEST_FILE_SUFFIX = r'(_test|_unittest|_regtest)$' |
| 434 |
| 435 # Pattern that matches only complete whitespace, possibly across multiple lines. |
| 436 _EMPTY_CONDITIONAL_BODY_PATTERN = re.compile(r'^\s*$', re.DOTALL) |
405 | 437 |
406 # Assertion macros. These are defined in base/logging.h and | 438 # Assertion macros. These are defined in base/logging.h and |
407 # testing/base/gunit.h. Note that the _M versions need to come first | 439 # testing/base/public/gunit.h. |
408 # for substring matching to work. | |
409 _CHECK_MACROS = [ | 440 _CHECK_MACROS = [ |
410 'DCHECK', 'CHECK', | 441 'DCHECK', 'CHECK', |
411 'EXPECT_TRUE_M', 'EXPECT_TRUE', | 442 'EXPECT_TRUE', 'ASSERT_TRUE', |
412 'ASSERT_TRUE_M', 'ASSERT_TRUE', | 443 'EXPECT_FALSE', 'ASSERT_FALSE', |
413 'EXPECT_FALSE_M', 'EXPECT_FALSE', | |
414 'ASSERT_FALSE_M', 'ASSERT_FALSE', | |
415 ] | 444 ] |
416 | 445 |
417 # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE | 446 # Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE |
418 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) | 447 _CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS]) |
419 | 448 |
420 for op, replacement in [('==', 'EQ'), ('!=', 'NE'), | 449 for op, replacement in [('==', 'EQ'), ('!=', 'NE'), |
421 ('>=', 'GE'), ('>', 'GT'), | 450 ('>=', 'GE'), ('>', 'GT'), |
422 ('<=', 'LE'), ('<', 'LT')]: | 451 ('<=', 'LE'), ('<', 'LT')]: |
423 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement | 452 _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement |
424 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement | 453 _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement |
425 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement | 454 _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement |
426 _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement | 455 _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement |
427 _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement | |
428 _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement | |
429 | 456 |
430 for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), | 457 for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'), |
431 ('>=', 'LT'), ('>', 'LE'), | 458 ('>=', 'LT'), ('>', 'LE'), |
432 ('<=', 'GT'), ('<', 'GE')]: | 459 ('<=', 'GT'), ('<', 'GE')]: |
433 _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement | 460 _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement |
434 _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement | 461 _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement |
435 _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement | |
436 _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement | |
437 | 462 |
438 # Alternative tokens and their replacements. For full list, see section 2.5 | 463 # Alternative tokens and their replacements. For full list, see section 2.5 |
439 # Alternative tokens [lex.digraph] in the C++ standard. | 464 # Alternative tokens [lex.digraph] in the C++ standard. |
440 # | 465 # |
441 # Digraphs (such as '%:') are not included here since it's a mess to | 466 # Digraphs (such as '%:') are not included here since it's a mess to |
442 # match those on a word boundary. | 467 # match those on a word boundary. |
443 _ALT_TOKEN_REPLACEMENT = { | 468 _ALT_TOKEN_REPLACEMENT = { |
444 'and': '&&', | 469 'and': '&&', |
445 'bitor': '|', | 470 'bitor': '|', |
446 'or': '||', | 471 'or': '||', |
(...skipping 28 matching lines...) Expand all Loading... |
475 _NO_ASM = 0 # Outside of inline assembly block | 500 _NO_ASM = 0 # Outside of inline assembly block |
476 _INSIDE_ASM = 1 # Inside inline assembly block | 501 _INSIDE_ASM = 1 # Inside inline assembly block |
477 _END_ASM = 2 # Last line of inline assembly block | 502 _END_ASM = 2 # Last line of inline assembly block |
478 _BLOCK_ASM = 3 # The whole block is an inline assembly block | 503 _BLOCK_ASM = 3 # The whole block is an inline assembly block |
479 | 504 |
480 # Match start of assembly blocks | 505 # Match start of assembly blocks |
481 _MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' | 506 _MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)' |
482 r'(?:\s+(volatile|__volatile__))?' | 507 r'(?:\s+(volatile|__volatile__))?' |
483 r'\s*[{(]') | 508 r'\s*[{(]') |
484 | 509 |
| 510 # Match strings that indicate we're working on a C (not C++) file. |
| 511 _SEARCH_C_FILE = re.compile(r'\b(?:LINT_C_FILE|' |
| 512 r'vim?:\s*.*(\s*|:)filetype=c(\s*|:|$))') |
| 513 |
| 514 # Match string that indicates we're working on a Linux Kernel file. |
| 515 _SEARCH_KERNEL_FILE = re.compile(r'\b(?:LINT_KERNEL_FILE)') |
485 | 516 |
486 _regexp_compile_cache = {} | 517 _regexp_compile_cache = {} |
487 | 518 |
488 # {str, set(int)}: a map from error categories to sets of linenumbers | 519 # {str, set(int)}: a map from error categories to sets of linenumbers |
489 # on which those errors are expected and should be suppressed. | 520 # on which those errors are expected and should be suppressed. |
490 _error_suppressions = {} | 521 _error_suppressions = {} |
491 | 522 |
492 # The root directory used for deriving header guard CPP variable. | 523 # The root directory used for deriving header guard CPP variable. |
493 # This is set by --root flag. | 524 # This is set by --root flag. |
494 _root = None | 525 _root = None |
495 | 526 |
496 # The allowed line length of files. | 527 # The allowed line length of files. |
497 # This is set by --linelength flag. | 528 # This is set by --linelength flag. |
498 _line_length = 80 | 529 _line_length = 80 |
499 | 530 |
500 # The allowed extensions for file names | 531 # The allowed extensions for file names |
501 # This is set by --extensions flag. | 532 # This is set by --extensions flag. |
502 _valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) | 533 _valid_extensions = set(['cc', 'h', 'cpp', 'cu', 'cuh']) |
503 | 534 |
| 535 # {str, bool}: a map from error categories to booleans which indicate if the |
| 536 # category should be suppressed for every line. |
| 537 _global_error_suppressions = {} |
| 538 |
| 539 |
504 def ParseNolintSuppressions(filename, raw_line, linenum, error): | 540 def ParseNolintSuppressions(filename, raw_line, linenum, error): |
505 """Updates the global list of error-suppressions. | 541 """Updates the global list of line error-suppressions. |
506 | 542 |
507 Parses any NOLINT comments on the current line, updating the global | 543 Parses any NOLINT comments on the current line, updating the global |
508 error_suppressions store. Reports an error if the NOLINT comment | 544 error_suppressions store. Reports an error if the NOLINT comment |
509 was malformed. | 545 was malformed. |
510 | 546 |
511 Args: | 547 Args: |
512 filename: str, the name of the input file. | 548 filename: str, the name of the input file. |
513 raw_line: str, the line of input text, with comments. | 549 raw_line: str, the line of input text, with comments. |
514 linenum: int, the number of the current line. | 550 linenum: int, the number of the current line. |
515 error: function, an error handler. | 551 error: function, an error handler. |
(...skipping 10 matching lines...) Expand all Loading... |
526 else: | 562 else: |
527 if category.startswith('(') and category.endswith(')'): | 563 if category.startswith('(') and category.endswith(')'): |
528 category = category[1:-1] | 564 category = category[1:-1] |
529 if category in _ERROR_CATEGORIES: | 565 if category in _ERROR_CATEGORIES: |
530 _error_suppressions.setdefault(category, set()).add(suppressed_line) | 566 _error_suppressions.setdefault(category, set()).add(suppressed_line) |
531 elif category not in _LEGACY_ERROR_CATEGORIES: | 567 elif category not in _LEGACY_ERROR_CATEGORIES: |
532 error(filename, linenum, 'readability/nolint', 5, | 568 error(filename, linenum, 'readability/nolint', 5, |
533 'Unknown NOLINT error category: %s' % category) | 569 'Unknown NOLINT error category: %s' % category) |
534 | 570 |
535 | 571 |
| 572 def ProcessGlobalSuppresions(lines): |
| 573 """Updates the list of global error suppressions. |
| 574 |
| 575 Parses any lint directives in the file that have global effect. |
| 576 |
| 577 Args: |
| 578 lines: An array of strings, each representing a line of the file, with the |
| 579 last element being empty if the file is terminated with a newline. |
| 580 """ |
| 581 for line in lines: |
| 582 if _SEARCH_C_FILE.search(line): |
| 583 for category in _DEFAULT_C_SUPPRESSED_CATEGORIES: |
| 584 _global_error_suppressions[category] = True |
| 585 if _SEARCH_KERNEL_FILE.search(line): |
| 586 for category in _DEFAULT_KERNEL_SUPPRESSED_CATEGORIES: |
| 587 _global_error_suppressions[category] = True |
| 588 |
| 589 |
536 def ResetNolintSuppressions(): | 590 def ResetNolintSuppressions(): |
537 """Resets the set of NOLINT suppressions to empty.""" | 591 """Resets the set of NOLINT suppressions to empty.""" |
538 _error_suppressions.clear() | 592 _error_suppressions.clear() |
| 593 _global_error_suppressions.clear() |
539 | 594 |
540 | 595 |
541 def IsErrorSuppressedByNolint(category, linenum): | 596 def IsErrorSuppressedByNolint(category, linenum): |
542 """Returns true if the specified error category is suppressed on this line. | 597 """Returns true if the specified error category is suppressed on this line. |
543 | 598 |
544 Consults the global error_suppressions map populated by | 599 Consults the global error_suppressions map populated by |
545 ParseNolintSuppressions/ResetNolintSuppressions. | 600 ParseNolintSuppressions/ProcessGlobalSuppresions/ResetNolintSuppressions. |
546 | 601 |
547 Args: | 602 Args: |
548 category: str, the category of the error. | 603 category: str, the category of the error. |
549 linenum: int, the current line number. | 604 linenum: int, the current line number. |
550 Returns: | 605 Returns: |
551 bool, True iff the error should be suppressed due to a NOLINT comment. | 606 bool, True iff the error should be suppressed due to a NOLINT comment or |
| 607 global suppression. |
552 """ | 608 """ |
553 return (linenum in _error_suppressions.get(category, set()) or | 609 return (_global_error_suppressions.get(category, False) or |
| 610 linenum in _error_suppressions.get(category, set()) or |
554 linenum in _error_suppressions.get(None, set())) | 611 linenum in _error_suppressions.get(None, set())) |
555 | 612 |
556 | 613 |
557 def Match(pattern, s): | 614 def Match(pattern, s): |
558 """Matches the string with the pattern, caching the compiled regexp.""" | 615 """Matches the string with the pattern, caching the compiled regexp.""" |
559 # The regexp compilation caching is inlined in both Match and Search for | 616 # The regexp compilation caching is inlined in both Match and Search for |
560 # performance reasons; factoring it out into a separate function turns out | 617 # performance reasons; factoring it out into a separate function turns out |
561 # to be noticeably expensive. | 618 # to be noticeably expensive. |
562 if pattern not in _regexp_compile_cache: | 619 if pattern not in _regexp_compile_cache: |
563 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) | 620 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) |
(...skipping 18 matching lines...) Expand all Loading... |
582 return _regexp_compile_cache[pattern].sub(rep, s) | 639 return _regexp_compile_cache[pattern].sub(rep, s) |
583 | 640 |
584 | 641 |
585 def Search(pattern, s): | 642 def Search(pattern, s): |
586 """Searches the string for the pattern, caching the compiled regexp.""" | 643 """Searches the string for the pattern, caching the compiled regexp.""" |
587 if pattern not in _regexp_compile_cache: | 644 if pattern not in _regexp_compile_cache: |
588 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) | 645 _regexp_compile_cache[pattern] = sre_compile.compile(pattern) |
589 return _regexp_compile_cache[pattern].search(s) | 646 return _regexp_compile_cache[pattern].search(s) |
590 | 647 |
591 | 648 |
| 649 def _IsSourceExtension(s): |
| 650 """File extension (excluding dot) matches a source file extension.""" |
| 651 return s in ('c', 'cc', 'cpp', 'cxx') |
| 652 |
| 653 |
592 class _IncludeState(object): | 654 class _IncludeState(object): |
593 """Tracks line numbers for includes, and the order in which includes appear. | 655 """Tracks line numbers for includes, and the order in which includes appear. |
594 | 656 |
595 include_list contains list of lists of (header, line number) pairs. | 657 include_list contains list of lists of (header, line number) pairs. |
596 It's a lists of lists rather than just one flat list to make it | 658 It's a lists of lists rather than just one flat list to make it |
597 easier to update across preprocessor boundaries. | 659 easier to update across preprocessor boundaries. |
598 | 660 |
599 Call CheckNextIncludeOrder() once for each header in the file, passing | 661 Call CheckNextIncludeOrder() once for each header in the file, passing |
600 in the type constants defined above. Calls in an illegal order will | 662 in the type constants defined above. Calls in an illegal order will |
601 raise an _IncludeError with an appropriate error message. | 663 raise an _IncludeError with an appropriate error message. |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
937 self.lines_in_function += 1 | 999 self.lines_in_function += 1 |
938 | 1000 |
939 def Check(self, error, filename, linenum): | 1001 def Check(self, error, filename, linenum): |
940 """Report if too many lines in function body. | 1002 """Report if too many lines in function body. |
941 | 1003 |
942 Args: | 1004 Args: |
943 error: The function to call with any errors found. | 1005 error: The function to call with any errors found. |
944 filename: The name of the current file. | 1006 filename: The name of the current file. |
945 linenum: The number of the line to check. | 1007 linenum: The number of the line to check. |
946 """ | 1008 """ |
| 1009 if not self.in_a_function: |
| 1010 return |
| 1011 |
947 if Match(r'T(EST|est)', self.current_function): | 1012 if Match(r'T(EST|est)', self.current_function): |
948 base_trigger = self._TEST_TRIGGER | 1013 base_trigger = self._TEST_TRIGGER |
949 else: | 1014 else: |
950 base_trigger = self._NORMAL_TRIGGER | 1015 base_trigger = self._NORMAL_TRIGGER |
951 trigger = base_trigger * 2**_VerboseLevel() | 1016 trigger = base_trigger * 2**_VerboseLevel() |
952 | 1017 |
953 if self.lines_in_function > trigger: | 1018 if self.lines_in_function > trigger: |
954 error_level = int(math.log(self.lines_in_function / base_trigger, 2)) | 1019 error_level = int(math.log(self.lines_in_function / base_trigger, 2)) |
955 # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... | 1020 # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ... |
956 if error_level > 5: | 1021 if error_level > 5: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 def Extension(self): | 1116 def Extension(self): |
1052 """File extension - text following the final period.""" | 1117 """File extension - text following the final period.""" |
1053 return self.Split()[2] | 1118 return self.Split()[2] |
1054 | 1119 |
1055 def NoExtension(self): | 1120 def NoExtension(self): |
1056 """File has no source file extension.""" | 1121 """File has no source file extension.""" |
1057 return '/'.join(self.Split()[0:2]) | 1122 return '/'.join(self.Split()[0:2]) |
1058 | 1123 |
1059 def IsSource(self): | 1124 def IsSource(self): |
1060 """File has a source file extension.""" | 1125 """File has a source file extension.""" |
1061 return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx') | 1126 return _IsSourceExtension(self.Extension()[1:]) |
1062 | 1127 |
1063 | 1128 |
1064 def _ShouldPrintError(category, confidence, linenum): | 1129 def _ShouldPrintError(category, confidence, linenum): |
1065 """If confidence >= verbose, category passes filter and is not suppressed.""" | 1130 """If confidence >= verbose, category passes filter and is not suppressed.""" |
1066 | 1131 |
1067 # There are three ways we might decide not to print an error message: | 1132 # There are three ways we might decide not to print an error message: |
1068 # a "NOLINT(category)" comment appears in the source, | 1133 # a "NOLINT(category)" comment appears in the source, |
1069 # the verbosity level isn't high enough, or the filters filter it out. | 1134 # the verbosity level isn't high enough, or the filters filter it out. |
1070 if IsErrorSuppressedByNolint(category, linenum): | 1135 if IsErrorSuppressedByNolint(category, linenum): |
1071 return False | 1136 return False |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 else: | 1262 else: |
1198 # Haven't found the end yet, append a blank line. | 1263 # Haven't found the end yet, append a blank line. |
1199 line = '""' | 1264 line = '""' |
1200 | 1265 |
1201 # Look for beginning of a raw string, and replace them with | 1266 # Look for beginning of a raw string, and replace them with |
1202 # empty strings. This is done in a loop to handle multiple raw | 1267 # empty strings. This is done in a loop to handle multiple raw |
1203 # strings on the same line. | 1268 # strings on the same line. |
1204 while delimiter is None: | 1269 while delimiter is None: |
1205 # Look for beginning of a raw string. | 1270 # Look for beginning of a raw string. |
1206 # See 2.14.15 [lex.string] for syntax. | 1271 # See 2.14.15 [lex.string] for syntax. |
1207 matched = Match(r'^(.*)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) | 1272 # |
1208 if matched: | 1273 # Once we have matched a raw string, we check the prefix of the |
| 1274 # line to make sure that the line is not part of a single line |
| 1275 # comment. It's done this way because we remove raw strings |
| 1276 # before removing comments as opposed to removing comments |
| 1277 # before removing raw strings. This is because there are some |
| 1278 # cpplint checks that requires the comments to be preserved, but |
| 1279 # we don't want to check comments that are inside raw strings. |
| 1280 matched = Match(r'^(.*?)\b(?:R|u8R|uR|UR|LR)"([^\s\\()]*)\((.*)$', line) |
| 1281 if (matched and |
| 1282 not Match(r'^([^\'"]|\'(\\.|[^\'])*\'|"(\\.|[^"])*")*//', |
| 1283 matched.group(1))): |
1209 delimiter = ')' + matched.group(2) + '"' | 1284 delimiter = ')' + matched.group(2) + '"' |
1210 | 1285 |
1211 end = matched.group(3).find(delimiter) | 1286 end = matched.group(3).find(delimiter) |
1212 if end >= 0: | 1287 if end >= 0: |
1213 # Raw string ended on same line | 1288 # Raw string ended on same line |
1214 line = (matched.group(1) + '""' + | 1289 line = (matched.group(1) + '""' + |
1215 matched.group(3)[end + len(delimiter):]) | 1290 matched.group(3)[end + len(delimiter):]) |
1216 delimiter = None | 1291 delimiter = None |
1217 else: | 1292 else: |
1218 # Start of a multi-line raw string | 1293 # Start of a multi-line raw string |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 | 1844 |
1770 # Didn't find anything | 1845 # Didn't find anything |
1771 error(filename, endif_linenum, 'build/header_guard', 5, | 1846 error(filename, endif_linenum, 'build/header_guard', 5, |
1772 '#endif line should be "#endif // %s"' % cppvar) | 1847 '#endif line should be "#endif // %s"' % cppvar) |
1773 | 1848 |
1774 | 1849 |
1775 def CheckHeaderFileIncluded(filename, include_state, error): | 1850 def CheckHeaderFileIncluded(filename, include_state, error): |
1776 """Logs an error if a .cc file does not include its header.""" | 1851 """Logs an error if a .cc file does not include its header.""" |
1777 | 1852 |
1778 # Do not check test files | 1853 # Do not check test files |
1779 if filename.endswith('_test.cc') or filename.endswith('_unittest.cc'): | 1854 fileinfo = FileInfo(filename) |
| 1855 if Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()): |
1780 return | 1856 return |
1781 | 1857 |
1782 fileinfo = FileInfo(filename) | 1858 headerfile = filename[0:len(filename) - len(fileinfo.Extension())] + '.h' |
1783 headerfile = filename[0:len(filename) - 2] + 'h' | |
1784 if not os.path.exists(headerfile): | 1859 if not os.path.exists(headerfile): |
1785 return | 1860 return |
1786 headername = FileInfo(headerfile).RepositoryName() | 1861 headername = FileInfo(headerfile).RepositoryName() |
1787 first_include = 0 | 1862 first_include = 0 |
1788 for section_list in include_state.include_list: | 1863 for section_list in include_state.include_list: |
1789 for f in section_list: | 1864 for f in section_list: |
1790 if headername in f[0] or f[0] in headername: | 1865 if headername in f[0] or f[0] in headername: |
1791 return | 1866 return |
1792 if not first_include: | 1867 if not first_include: |
1793 first_include = f[1] | 1868 first_include = f[1] |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1990 return False | 2065 return False |
1991 | 2066 |
1992 | 2067 |
1993 def IsForwardClassDeclaration(clean_lines, linenum): | 2068 def IsForwardClassDeclaration(clean_lines, linenum): |
1994 return Match(r'^\s*(\btemplate\b)*.*class\s+\w+;\s*$', clean_lines[linenum]) | 2069 return Match(r'^\s*(\btemplate\b)*.*class\s+\w+;\s*$', clean_lines[linenum]) |
1995 | 2070 |
1996 | 2071 |
1997 class _BlockInfo(object): | 2072 class _BlockInfo(object): |
1998 """Stores information about a generic block of code.""" | 2073 """Stores information about a generic block of code.""" |
1999 | 2074 |
2000 def __init__(self, seen_open_brace): | 2075 def __init__(self, linenum, seen_open_brace): |
| 2076 self.starting_linenum = linenum |
2001 self.seen_open_brace = seen_open_brace | 2077 self.seen_open_brace = seen_open_brace |
2002 self.open_parentheses = 0 | 2078 self.open_parentheses = 0 |
2003 self.inline_asm = _NO_ASM | 2079 self.inline_asm = _NO_ASM |
2004 self.check_namespace_indentation = False | 2080 self.check_namespace_indentation = False |
2005 | 2081 |
2006 def CheckBegin(self, filename, clean_lines, linenum, error): | 2082 def CheckBegin(self, filename, clean_lines, linenum, error): |
2007 """Run checks that applies to text up to the opening brace. | 2083 """Run checks that applies to text up to the opening brace. |
2008 | 2084 |
2009 This is mostly for checking the text after the class identifier | 2085 This is mostly for checking the text after the class identifier |
2010 and the "{", usually where the base class is specified. For other | 2086 and the "{", usually where the base class is specified. For other |
(...skipping 28 matching lines...) Expand all Loading... |
2039 | 2115 |
2040 Returns: | 2116 Returns: |
2041 True for this class, False for derived classes. | 2117 True for this class, False for derived classes. |
2042 """ | 2118 """ |
2043 return self.__class__ == _BlockInfo | 2119 return self.__class__ == _BlockInfo |
2044 | 2120 |
2045 | 2121 |
2046 class _ExternCInfo(_BlockInfo): | 2122 class _ExternCInfo(_BlockInfo): |
2047 """Stores information about an 'extern "C"' block.""" | 2123 """Stores information about an 'extern "C"' block.""" |
2048 | 2124 |
2049 def __init__(self): | 2125 def __init__(self, linenum): |
2050 _BlockInfo.__init__(self, True) | 2126 _BlockInfo.__init__(self, linenum, True) |
2051 | 2127 |
2052 | 2128 |
2053 class _ClassInfo(_BlockInfo): | 2129 class _ClassInfo(_BlockInfo): |
2054 """Stores information about a class.""" | 2130 """Stores information about a class.""" |
2055 | 2131 |
2056 def __init__(self, name, class_or_struct, clean_lines, linenum): | 2132 def __init__(self, name, class_or_struct, clean_lines, linenum): |
2057 _BlockInfo.__init__(self, False) | 2133 _BlockInfo.__init__(self, linenum, False) |
2058 self.name = name | 2134 self.name = name |
2059 self.starting_linenum = linenum | |
2060 self.is_derived = False | 2135 self.is_derived = False |
2061 self.check_namespace_indentation = True | 2136 self.check_namespace_indentation = True |
2062 if class_or_struct == 'struct': | 2137 if class_or_struct == 'struct': |
2063 self.access = 'public' | 2138 self.access = 'public' |
2064 self.is_struct = True | 2139 self.is_struct = True |
2065 else: | 2140 else: |
2066 self.access = 'private' | 2141 self.access = 'private' |
2067 self.is_struct = False | 2142 self.is_struct = False |
2068 | 2143 |
2069 # Remember initial indentation level for this class. Using raw_lines here | 2144 # Remember initial indentation level for this class. Using raw_lines here |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2117 else: | 2192 else: |
2118 parent = 'class ' + self.name | 2193 parent = 'class ' + self.name |
2119 error(filename, linenum, 'whitespace/indent', 3, | 2194 error(filename, linenum, 'whitespace/indent', 3, |
2120 'Closing brace should be aligned with beginning of %s' % parent) | 2195 'Closing brace should be aligned with beginning of %s' % parent) |
2121 | 2196 |
2122 | 2197 |
2123 class _NamespaceInfo(_BlockInfo): | 2198 class _NamespaceInfo(_BlockInfo): |
2124 """Stores information about a namespace.""" | 2199 """Stores information about a namespace.""" |
2125 | 2200 |
2126 def __init__(self, name, linenum): | 2201 def __init__(self, name, linenum): |
2127 _BlockInfo.__init__(self, False) | 2202 _BlockInfo.__init__(self, linenum, False) |
2128 self.name = name or '' | 2203 self.name = name or '' |
2129 self.starting_linenum = linenum | |
2130 self.check_namespace_indentation = True | 2204 self.check_namespace_indentation = True |
2131 | 2205 |
2132 def CheckEnd(self, filename, clean_lines, linenum, error): | 2206 def CheckEnd(self, filename, clean_lines, linenum, error): |
2133 """Check end of namespace comments.""" | 2207 """Check end of namespace comments.""" |
2134 line = clean_lines.raw_lines[linenum] | 2208 line = clean_lines.raw_lines[linenum] |
2135 | 2209 |
2136 # Check how many lines is enclosed in this namespace. Don't issue | 2210 # Check how many lines is enclosed in this namespace. Don't issue |
2137 # warning for missing namespace comments if there aren't enough | 2211 # warning for missing namespace comments if there aren't enough |
2138 # lines. However, do apply checks if there is already an end of | 2212 # lines. However, do apply checks if there is already an end of |
2139 # namespace comment and it's incorrect. | 2213 # namespace comment and it's incorrect. |
2140 # | 2214 # |
2141 # TODO(unknown): We always want to check end of namespace comments | 2215 # TODO(unknown): We always want to check end of namespace comments |
2142 # if a namespace is large, but sometimes we also want to apply the | 2216 # if a namespace is large, but sometimes we also want to apply the |
2143 # check if a short namespace contained nontrivial things (something | 2217 # check if a short namespace contained nontrivial things (something |
2144 # other than forward declarations). There is currently no logic on | 2218 # other than forward declarations). There is currently no logic on |
2145 # deciding what these nontrivial things are, so this check is | 2219 # deciding what these nontrivial things are, so this check is |
2146 # triggered by namespace size only, which works most of the time. | 2220 # triggered by namespace size only, which works most of the time. |
2147 if (linenum - self.starting_linenum < 10 | 2221 if (linenum - self.starting_linenum < 10 |
2148 and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)): | 2222 and not Match(r'^\s*};*\s*(//|/\*).*\bnamespace\b', line)): |
2149 return | 2223 return |
2150 | 2224 |
2151 # Look for matching comment at end of namespace. | 2225 # Look for matching comment at end of namespace. |
2152 # | 2226 # |
2153 # Note that we accept C style "/* */" comments for terminating | 2227 # Note that we accept C style "/* */" comments for terminating |
2154 # namespaces, so that code that terminate namespaces inside | 2228 # namespaces, so that code that terminate namespaces inside |
2155 # preprocessor macros can be cpplint clean. | 2229 # preprocessor macros can be cpplint clean. |
2156 # | 2230 # |
2157 # We also accept stuff like "// end of namespace <name>." with the | 2231 # We also accept stuff like "// end of namespace <name>." with the |
2158 # period at the end. | 2232 # period at the end. |
2159 # | 2233 # |
2160 # Besides these, we don't accept anything else, otherwise we might | 2234 # Besides these, we don't accept anything else, otherwise we might |
2161 # get false negatives when existing comment is a substring of the | 2235 # get false negatives when existing comment is a substring of the |
2162 # expected namespace. | 2236 # expected namespace. |
2163 if self.name: | 2237 if self.name: |
2164 # Named namespace | 2238 # Named namespace |
2165 if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) + | 2239 if not Match((r'^\s*};*\s*(//|/\*).*\bnamespace\s+' + |
2166 r'[\*/\.\\\s]*$'), | 2240 re.escape(self.name) + r'[\*/\.\\\s]*$'), |
2167 line): | 2241 line): |
2168 error(filename, linenum, 'readability/namespace', 5, | 2242 error(filename, linenum, 'readability/namespace', 5, |
2169 'Namespace should be terminated with "// namespace %s"' % | 2243 'Namespace should be terminated with "// namespace %s"' % |
2170 self.name) | 2244 self.name) |
2171 else: | 2245 else: |
2172 # Anonymous namespace | 2246 # Anonymous namespace |
2173 if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): | 2247 if not Match(r'^\s*};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line): |
2174 # If "// namespace anonymous" or "// anonymous namespace (more text)", | 2248 # If "// namespace anonymous" or "// anonymous namespace (more text)", |
2175 # mention "// anonymous namespace" as an acceptable form | 2249 # mention "// anonymous namespace" as an acceptable form |
2176 if Match(r'}.*\b(namespace anonymous|anonymous namespace)\b', line): | 2250 if Match(r'^\s*}.*\b(namespace anonymous|anonymous namespace)\b', line): |
2177 error(filename, linenum, 'readability/namespace', 5, | 2251 error(filename, linenum, 'readability/namespace', 5, |
2178 'Anonymous namespace should be terminated with "// namespace"' | 2252 'Anonymous namespace should be terminated with "// namespace"' |
2179 ' or "// anonymous namespace"') | 2253 ' or "// anonymous namespace"') |
2180 else: | 2254 else: |
2181 error(filename, linenum, 'readability/namespace', 5, | 2255 error(filename, linenum, 'readability/namespace', 5, |
2182 'Anonymous namespace should be terminated with "// namespace"') | 2256 'Anonymous namespace should be terminated with "// namespace"') |
2183 | 2257 |
2184 | 2258 |
2185 class _PreprocessorInfo(object): | 2259 class _PreprocessorInfo(object): |
2186 """Stores checkpoints of nesting stacks when #if/#else is seen.""" | 2260 """Stores checkpoints of nesting stacks when #if/#else is seen.""" |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2505 break | 2579 break |
2506 | 2580 |
2507 token = matched.group(1) | 2581 token = matched.group(1) |
2508 if token == '{': | 2582 if token == '{': |
2509 # If namespace or class hasn't seen a opening brace yet, mark | 2583 # If namespace or class hasn't seen a opening brace yet, mark |
2510 # namespace/class head as complete. Push a new block onto the | 2584 # namespace/class head as complete. Push a new block onto the |
2511 # stack otherwise. | 2585 # stack otherwise. |
2512 if not self.SeenOpenBrace(): | 2586 if not self.SeenOpenBrace(): |
2513 self.stack[-1].seen_open_brace = True | 2587 self.stack[-1].seen_open_brace = True |
2514 elif Match(r'^extern\s*"[^"]*"\s*\{', line): | 2588 elif Match(r'^extern\s*"[^"]*"\s*\{', line): |
2515 self.stack.append(_ExternCInfo()) | 2589 self.stack.append(_ExternCInfo(linenum)) |
2516 else: | 2590 else: |
2517 self.stack.append(_BlockInfo(True)) | 2591 self.stack.append(_BlockInfo(linenum, True)) |
2518 if _MATCH_ASM.match(line): | 2592 if _MATCH_ASM.match(line): |
2519 self.stack[-1].inline_asm = _BLOCK_ASM | 2593 self.stack[-1].inline_asm = _BLOCK_ASM |
2520 | 2594 |
2521 elif token == ';' or token == ')': | 2595 elif token == ';' or token == ')': |
2522 # If we haven't seen an opening brace yet, but we already saw | 2596 # If we haven't seen an opening brace yet, but we already saw |
2523 # a semicolon, this is probably a forward declaration. Pop | 2597 # a semicolon, this is probably a forward declaration. Pop |
2524 # the stack for these. | 2598 # the stack for these. |
2525 # | 2599 # |
2526 # Similarly, if we haven't seen an opening brace yet, but we | 2600 # Similarly, if we haven't seen an opening brace yet, but we |
2527 # already saw a closing parenthesis, then these are probably | 2601 # already saw a closing parenthesis, then these are probably |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 | 2693 |
2620 # For the rest, work with both comments and strings removed. | 2694 # For the rest, work with both comments and strings removed. |
2621 line = clean_lines.elided[linenum] | 2695 line = clean_lines.elided[linenum] |
2622 | 2696 |
2623 if Search(r'\b(const|volatile|void|char|short|int|long' | 2697 if Search(r'\b(const|volatile|void|char|short|int|long' |
2624 r'|float|double|signed|unsigned' | 2698 r'|float|double|signed|unsigned' |
2625 r'|schar|u?int8|u?int16|u?int32|u?int64)' | 2699 r'|schar|u?int8|u?int16|u?int32|u?int64)' |
2626 r'\s+(register|static|extern|typedef)\b', | 2700 r'\s+(register|static|extern|typedef)\b', |
2627 line): | 2701 line): |
2628 error(filename, linenum, 'build/storage_class', 5, | 2702 error(filename, linenum, 'build/storage_class', 5, |
2629 'Storage class (static, extern, typedef, etc) should be first.') | 2703 'Storage-class specifier (static, extern, typedef, etc) should be ' |
| 2704 'at the beginning of the declaration.') |
2630 | 2705 |
2631 if Match(r'\s*#\s*endif\s*[^/\s]+', line): | 2706 if Match(r'\s*#\s*endif\s*[^/\s]+', line): |
2632 error(filename, linenum, 'build/endif_comment', 5, | 2707 error(filename, linenum, 'build/endif_comment', 5, |
2633 'Uncommented text after #endif is non-standard. Use a comment.') | 2708 'Uncommented text after #endif is non-standard. Use a comment.') |
2634 | 2709 |
2635 if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line): | 2710 if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line): |
2636 error(filename, linenum, 'build/forward_decl', 5, | 2711 error(filename, linenum, 'build/forward_decl', 5, |
2637 'Inner-style forward declarations are invalid. Remove this line.') | 2712 'Inner-style forward declarations are invalid. Remove this line.') |
2638 | 2713 |
2639 if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', | 2714 if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?', |
(...skipping 18 matching lines...) Expand all Loading... |
2658 # the class head is not completed yet. | 2733 # the class head is not completed yet. |
2659 classinfo = nesting_state.InnermostClass() | 2734 classinfo = nesting_state.InnermostClass() |
2660 if not classinfo or not classinfo.seen_open_brace: | 2735 if not classinfo or not classinfo.seen_open_brace: |
2661 return | 2736 return |
2662 | 2737 |
2663 # The class may have been declared with namespace or classname qualifiers. | 2738 # The class may have been declared with namespace or classname qualifiers. |
2664 # The constructor and destructor will not have those qualifiers. | 2739 # The constructor and destructor will not have those qualifiers. |
2665 base_classname = classinfo.name.split('::')[-1] | 2740 base_classname = classinfo.name.split('::')[-1] |
2666 | 2741 |
2667 # Look for single-argument constructors that aren't marked explicit. | 2742 # Look for single-argument constructors that aren't marked explicit. |
2668 # Technically a valid construct, but against style. Also look for | 2743 # Technically a valid construct, but against style. |
2669 # non-single-argument constructors which are also technically valid, but | |
2670 # strongly suggest something is wrong. | |
2671 explicit_constructor_match = Match( | 2744 explicit_constructor_match = Match( |
2672 r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*' | 2745 r'\s+(?:inline\s+)?(explicit\s+)?(?:inline\s+)?%s\s*' |
2673 r'\(((?:[^()]|\([^()]*\))*)\)' | 2746 r'\(((?:[^()]|\([^()]*\))*)\)' |
2674 % re.escape(base_classname), | 2747 % re.escape(base_classname), |
2675 line) | 2748 line) |
2676 | 2749 |
2677 if explicit_constructor_match: | 2750 if explicit_constructor_match: |
2678 is_marked_explicit = explicit_constructor_match.group(1) | 2751 is_marked_explicit = explicit_constructor_match.group(1) |
2679 | 2752 |
2680 if not explicit_constructor_match.group(2): | 2753 if not explicit_constructor_match.group(2): |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2721 error(filename, linenum, 'runtime/explicit', 5, | 2794 error(filename, linenum, 'runtime/explicit', 5, |
2722 'Constructors callable with one argument ' | 2795 'Constructors callable with one argument ' |
2723 'should be marked explicit.') | 2796 'should be marked explicit.') |
2724 else: | 2797 else: |
2725 error(filename, linenum, 'runtime/explicit', 5, | 2798 error(filename, linenum, 'runtime/explicit', 5, |
2726 'Single-parameter constructors should be marked explicit.') | 2799 'Single-parameter constructors should be marked explicit.') |
2727 elif is_marked_explicit and not onearg_constructor: | 2800 elif is_marked_explicit and not onearg_constructor: |
2728 if noarg_constructor: | 2801 if noarg_constructor: |
2729 error(filename, linenum, 'runtime/explicit', 5, | 2802 error(filename, linenum, 'runtime/explicit', 5, |
2730 'Zero-parameter constructors should not be marked explicit.') | 2803 'Zero-parameter constructors should not be marked explicit.') |
2731 else: | |
2732 error(filename, linenum, 'runtime/explicit', 0, | |
2733 'Constructors that require multiple arguments ' | |
2734 'should not be marked explicit.') | |
2735 | 2804 |
2736 | 2805 |
2737 def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): | 2806 def CheckSpacingForFunctionCall(filename, clean_lines, linenum, error): |
2738 """Checks for the correctness of various spacing around function calls. | 2807 """Checks for the correctness of various spacing around function calls. |
2739 | 2808 |
2740 Args: | 2809 Args: |
2741 filename: The name of the current file. | 2810 filename: The name of the current file. |
2742 clean_lines: A CleansedLines instance containing the file. | 2811 clean_lines: A CleansedLines instance containing the file. |
2743 linenum: The number of the line to check. | 2812 linenum: The number of the line to check. |
2744 error: The function to call with any errors found. | 2813 error: The function to call with any errors found. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2779 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and | 2848 not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and |
2780 # Ignore pointers/references to arrays. | 2849 # Ignore pointers/references to arrays. |
2781 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): | 2850 not Search(r' \([^)]+\)\[[^\]]+\]', fncall)): |
2782 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call | 2851 if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call |
2783 error(filename, linenum, 'whitespace/parens', 4, | 2852 error(filename, linenum, 'whitespace/parens', 4, |
2784 'Extra space after ( in function call') | 2853 'Extra space after ( in function call') |
2785 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): | 2854 elif Search(r'\(\s+(?!(\s*\\)|\()', fncall): |
2786 error(filename, linenum, 'whitespace/parens', 2, | 2855 error(filename, linenum, 'whitespace/parens', 2, |
2787 'Extra space after (') | 2856 'Extra space after (') |
2788 if (Search(r'\w\s+\(', fncall) and | 2857 if (Search(r'\w\s+\(', fncall) and |
| 2858 not Search(r'_{0,2}asm_{0,2}\s+_{0,2}volatile_{0,2}\s+\(', fncall) and |
2789 not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and | 2859 not Search(r'#\s*define|typedef|using\s+\w+\s*=', fncall) and |
2790 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and | 2860 not Search(r'\w\s+\((\w+::)*\*\w+\)\(', fncall) and |
2791 not Search(r'\bcase\s+\(', fncall)): | 2861 not Search(r'\bcase\s+\(', fncall)): |
2792 # TODO(unknown): Space after an operator function seem to be a common | 2862 # TODO(unknown): Space after an operator function seem to be a common |
2793 # error, silence those for now by restricting them to highest verbosity. | 2863 # error, silence those for now by restricting them to highest verbosity. |
2794 if Search(r'\boperator_*\b', line): | 2864 if Search(r'\boperator_*\b', line): |
2795 error(filename, linenum, 'whitespace/parens', 0, | 2865 error(filename, linenum, 'whitespace/parens', 0, |
2796 'Extra space before ( in function call') | 2866 'Extra space before ( in function call') |
2797 else: | 2867 else: |
2798 error(filename, linenum, 'whitespace/parens', 4, | 2868 error(filename, linenum, 'whitespace/parens', 4, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2837 clean_lines.elided, line): | 2907 clean_lines.elided, line): |
2838 CheckItemIndentationInNamespace(filename, clean_lines.elided, | 2908 CheckItemIndentationInNamespace(filename, clean_lines.elided, |
2839 line, error) | 2909 line, error) |
2840 | 2910 |
2841 | 2911 |
2842 def CheckForFunctionLengths(filename, clean_lines, linenum, | 2912 def CheckForFunctionLengths(filename, clean_lines, linenum, |
2843 function_state, error): | 2913 function_state, error): |
2844 """Reports for long function bodies. | 2914 """Reports for long function bodies. |
2845 | 2915 |
2846 For an overview why this is done, see: | 2916 For an overview why this is done, see: |
2847 http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Fun
ctions | 2917 https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Fu
nctions |
2848 | 2918 |
2849 Uses a simplistic algorithm assuming other style guidelines | 2919 Uses a simplistic algorithm assuming other style guidelines |
2850 (especially spacing) are followed. | 2920 (especially spacing) are followed. |
2851 Only checks unindented functions, so class members are unchecked. | 2921 Only checks unindented functions, so class members are unchecked. |
2852 Trivial bodies are unchecked, so constructors with huge initializer lists | 2922 Trivial bodies are unchecked, so constructors with huge initializer lists |
2853 may be missed. | 2923 may be missed. |
2854 Blank/comment lines are not counted so as to avoid encouraging the removal | 2924 Blank/comment lines are not counted so as to avoid encouraging the removal |
2855 of vertical space and comments just to get through a lint check. | 2925 of vertical space and comments just to get through a lint check. |
2856 NOLINT *on the last line of a function* disables this check. | 2926 NOLINT *on the last line of a function* disables this check. |
2857 | 2927 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2916 Args: | 2986 Args: |
2917 line: The line in question. | 2987 line: The line in question. |
2918 filename: The name of the current file. | 2988 filename: The name of the current file. |
2919 linenum: The number of the line to check. | 2989 linenum: The number of the line to check. |
2920 next_line_start: The first non-whitespace column of the next line. | 2990 next_line_start: The first non-whitespace column of the next line. |
2921 error: The function to call with any errors found. | 2991 error: The function to call with any errors found. |
2922 """ | 2992 """ |
2923 commentpos = line.find('//') | 2993 commentpos = line.find('//') |
2924 if commentpos != -1: | 2994 if commentpos != -1: |
2925 # Check if the // may be in quotes. If so, ignore it | 2995 # Check if the // may be in quotes. If so, ignore it |
2926 # Comparisons made explicit for clarity -- pylint: disable=g-explicit-bool-c
omparison | 2996 if re.sub(r'\\.', '', line[0:commentpos]).count('"') % 2 == 0: |
2927 if (line.count('"', 0, commentpos) - | |
2928 line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes | |
2929 # Allow one space for new scopes, two spaces otherwise: | 2997 # Allow one space for new scopes, two spaces otherwise: |
2930 if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and | 2998 if (not (Match(r'^.*{ *//', line) and next_line_start == commentpos) and |
2931 ((commentpos >= 1 and | 2999 ((commentpos >= 1 and |
2932 line[commentpos-1] not in string.whitespace) or | 3000 line[commentpos-1] not in string.whitespace) or |
2933 (commentpos >= 2 and | 3001 (commentpos >= 2 and |
2934 line[commentpos-2] not in string.whitespace))): | 3002 line[commentpos-2] not in string.whitespace))): |
2935 error(filename, linenum, 'whitespace/comments', 2, | 3003 error(filename, linenum, 'whitespace/comments', 2, |
2936 'At least two spaces is best between code and comments') | 3004 'At least two spaces is best between code and comments') |
2937 | 3005 |
2938 # Checks for common mistakes in TODO comments. | 3006 # Checks for common mistakes in TODO comments. |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3167 | 3235 |
3168 # You should always have whitespace around binary operators. | 3236 # You should always have whitespace around binary operators. |
3169 # | 3237 # |
3170 # Check <= and >= first to avoid false positives with < and >, then | 3238 # Check <= and >= first to avoid false positives with < and >, then |
3171 # check non-include lines for spacing around < and >. | 3239 # check non-include lines for spacing around < and >. |
3172 # | 3240 # |
3173 # If the operator is followed by a comma, assume it's be used in a | 3241 # If the operator is followed by a comma, assume it's be used in a |
3174 # macro context and don't do any checks. This avoids false | 3242 # macro context and don't do any checks. This avoids false |
3175 # positives. | 3243 # positives. |
3176 # | 3244 # |
3177 # Note that && is not included here. Those are checked separately | 3245 # Note that && is not included here. This is because there are too |
3178 # in CheckRValueReference | 3246 # many false positives due to RValue references. |
3179 match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line) | 3247 match = Search(r'[^<>=!\s](==|!=|<=|>=|\|\|)[^<>=!\s,;\)]', line) |
3180 if match: | 3248 if match: |
3181 error(filename, linenum, 'whitespace/operators', 3, | 3249 error(filename, linenum, 'whitespace/operators', 3, |
3182 'Missing spaces around %s' % match.group(1)) | 3250 'Missing spaces around %s' % match.group(1)) |
3183 elif not Match(r'#.*include', line): | 3251 elif not Match(r'#.*include', line): |
3184 # Look for < that is not surrounded by spaces. This is only | 3252 # Look for < that is not surrounded by spaces. This is only |
3185 # triggered if both sides are missing spaces, even though | 3253 # triggered if both sides are missing spaces, even though |
3186 # technically should should flag if at least one side is missing a | 3254 # technically should should flag if at least one side is missing a |
3187 # space. This is done to avoid some false positives with shifts. | 3255 # space. This is done to avoid some false positives with shifts. |
3188 match = Match(r'^(.*[^\s<])<[^\s=<,]', line) | 3256 match = Match(r'^(.*[^\s<])<[^\s=<,]', line) |
(...skipping 13 matching lines...) Expand all Loading... |
3202 clean_lines, linenum, len(match.group(1))) | 3270 clean_lines, linenum, len(match.group(1))) |
3203 if start_pos <= -1: | 3271 if start_pos <= -1: |
3204 error(filename, linenum, 'whitespace/operators', 3, | 3272 error(filename, linenum, 'whitespace/operators', 3, |
3205 'Missing spaces around >') | 3273 'Missing spaces around >') |
3206 | 3274 |
3207 # We allow no-spaces around << when used like this: 10<<20, but | 3275 # We allow no-spaces around << when used like this: 10<<20, but |
3208 # not otherwise (particularly, not when used as streams) | 3276 # not otherwise (particularly, not when used as streams) |
3209 # | 3277 # |
3210 # We also allow operators following an opening parenthesis, since | 3278 # We also allow operators following an opening parenthesis, since |
3211 # those tend to be macros that deal with operators. | 3279 # those tend to be macros that deal with operators. |
3212 match = Search(r'(operator|[^\s(<])(?:L|UL|ULL|l|ul|ull)?<<([^\s,=<])', line) | 3280 match = Search(r'(operator|[^\s(<])(?:L|UL|LL|ULL|l|ul|ll|ull)?<<([^\s,=<])',
line) |
3213 if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and | 3281 if (match and not (match.group(1).isdigit() and match.group(2).isdigit()) and |
3214 not (match.group(1) == 'operator' and match.group(2) == ';')): | 3282 not (match.group(1) == 'operator' and match.group(2) == ';')): |
3215 error(filename, linenum, 'whitespace/operators', 3, | 3283 error(filename, linenum, 'whitespace/operators', 3, |
3216 'Missing spaces around <<') | 3284 'Missing spaces around <<') |
3217 | 3285 |
3218 # We allow no-spaces around >> for almost anything. This is because | 3286 # We allow no-spaces around >> for almost anything. This is because |
3219 # C++11 allows ">>" to close nested templates, which accounts for | 3287 # C++11 allows ">>" to close nested templates, which accounts for |
3220 # most cases when ">>" is not followed by a space. | 3288 # most cases when ">>" is not followed by a space. |
3221 # | 3289 # |
3222 # We still warn on ">>" followed by alpha character, because that is | 3290 # We still warn on ">>" followed by alpha character, because that is |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3306 | 3374 |
3307 # You should always have a space after a semicolon | 3375 # You should always have a space after a semicolon |
3308 # except for few corner cases | 3376 # except for few corner cases |
3309 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more | 3377 # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more |
3310 # space after ; | 3378 # space after ; |
3311 if Search(r';[^\s};\\)/]', line): | 3379 if Search(r';[^\s};\\)/]', line): |
3312 error(filename, linenum, 'whitespace/semicolon', 3, | 3380 error(filename, linenum, 'whitespace/semicolon', 3, |
3313 'Missing space after ;') | 3381 'Missing space after ;') |
3314 | 3382 |
3315 | 3383 |
3316 def CheckBracesSpacing(filename, clean_lines, linenum, error): | 3384 def _IsType(clean_lines, nesting_state, expr): |
| 3385 """Check if expression looks like a type name, returns true if so. |
| 3386 |
| 3387 Args: |
| 3388 clean_lines: A CleansedLines instance containing the file. |
| 3389 nesting_state: A NestingState instance which maintains information about |
| 3390 the current stack of nested blocks being parsed. |
| 3391 expr: The expression to check. |
| 3392 Returns: |
| 3393 True, if token looks like a type. |
| 3394 """ |
| 3395 # Keep only the last token in the expression |
| 3396 last_word = Match(r'^.*(\b\S+)$', expr) |
| 3397 if last_word: |
| 3398 token = last_word.group(1) |
| 3399 else: |
| 3400 token = expr |
| 3401 |
| 3402 # Match native types and stdint types |
| 3403 if _TYPES.match(token): |
| 3404 return True |
| 3405 |
| 3406 # Try a bit harder to match templated types. Walk up the nesting |
| 3407 # stack until we find something that resembles a typename |
| 3408 # declaration for what we are looking for. |
| 3409 typename_pattern = (r'\b(?:typename|class|struct)\s+' + re.escape(token) + |
| 3410 r'\b') |
| 3411 block_index = len(nesting_state.stack) - 1 |
| 3412 while block_index >= 0: |
| 3413 if isinstance(nesting_state.stack[block_index], _NamespaceInfo): |
| 3414 return False |
| 3415 |
| 3416 # Found where the opening brace is. We want to scan from this |
| 3417 # line up to the beginning of the function, minus a few lines. |
| 3418 # template <typename Type1, // stop scanning here |
| 3419 # ...> |
| 3420 # class C |
| 3421 # : public ... { // start scanning here |
| 3422 last_line = nesting_state.stack[block_index].starting_linenum |
| 3423 |
| 3424 next_block_start = 0 |
| 3425 if block_index > 0: |
| 3426 next_block_start = nesting_state.stack[block_index - 1].starting_linenum |
| 3427 first_line = last_line |
| 3428 while first_line >= next_block_start: |
| 3429 if clean_lines.elided[first_line].find('template') >= 0: |
| 3430 break |
| 3431 first_line -= 1 |
| 3432 if first_line < next_block_start: |
| 3433 # Didn't find any "template" keyword before reaching the next block, |
| 3434 # there are probably no template things to check for this block |
| 3435 block_index -= 1 |
| 3436 continue |
| 3437 |
| 3438 # Look for typename in the specified range |
| 3439 for i in xrange(first_line, last_line + 1, 1): |
| 3440 if Search(typename_pattern, clean_lines.elided[i]): |
| 3441 return True |
| 3442 block_index -= 1 |
| 3443 |
| 3444 return False |
| 3445 |
| 3446 |
| 3447 def CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error): |
3317 """Checks for horizontal spacing near commas. | 3448 """Checks for horizontal spacing near commas. |
3318 | 3449 |
3319 Args: | 3450 Args: |
3320 filename: The name of the current file. | 3451 filename: The name of the current file. |
3321 clean_lines: A CleansedLines instance containing the file. | 3452 clean_lines: A CleansedLines instance containing the file. |
3322 linenum: The number of the line to check. | 3453 linenum: The number of the line to check. |
| 3454 nesting_state: A NestingState instance which maintains information about |
| 3455 the current stack of nested blocks being parsed. |
3323 error: The function to call with any errors found. | 3456 error: The function to call with any errors found. |
3324 """ | 3457 """ |
3325 line = clean_lines.elided[linenum] | 3458 line = clean_lines.elided[linenum] |
3326 | 3459 |
3327 # Except after an opening paren, or after another opening brace (in case of | 3460 # Except after an opening paren, or after another opening brace (in case of |
3328 # an initializer list, for instance), you should have spaces before your | 3461 # an initializer list, for instance), you should have spaces before your |
3329 # braces. And since you should never have braces at the beginning of a line, | 3462 # braces when they are delimiting blocks, classes, namespaces etc. |
3330 # this is an easy test. | 3463 # And since you should never have braces at the beginning of a line, |
| 3464 # this is an easy test. Except that braces used for initialization don't |
| 3465 # follow the same rule; we often don't want spaces before those. |
3331 match = Match(r'^(.*[^ ({>]){', line) | 3466 match = Match(r'^(.*[^ ({>]){', line) |
| 3467 |
3332 if match: | 3468 if match: |
3333 # Try a bit harder to check for brace initialization. This | 3469 # Try a bit harder to check for brace initialization. This |
3334 # happens in one of the following forms: | 3470 # happens in one of the following forms: |
3335 # Constructor() : initializer_list_{} { ... } | 3471 # Constructor() : initializer_list_{} { ... } |
3336 # Constructor{}.MemberFunction() | 3472 # Constructor{}.MemberFunction() |
3337 # Type variable{}; | 3473 # Type variable{}; |
3338 # FunctionCall(type{}, ...); | 3474 # FunctionCall(type{}, ...); |
3339 # LastArgument(..., type{}); | 3475 # LastArgument(..., type{}); |
3340 # LOG(INFO) << type{} << " ..."; | 3476 # LOG(INFO) << type{} << " ..."; |
3341 # map_of_type[{...}] = ...; | 3477 # map_of_type[{...}] = ...; |
3342 # ternary = expr ? new type{} : nullptr; | 3478 # ternary = expr ? new type{} : nullptr; |
3343 # OuterTemplate<InnerTemplateConstructor<Type>{}> | 3479 # OuterTemplate<InnerTemplateConstructor<Type>{}> |
3344 # | 3480 # |
3345 # We check for the character following the closing brace, and | 3481 # We check for the character following the closing brace, and |
3346 # silence the warning if it's one of those listed above, i.e. | 3482 # silence the warning if it's one of those listed above, i.e. |
3347 # "{.;,)<>]:". | 3483 # "{.;,)<>]:". |
3348 # | 3484 # |
3349 # To account for nested initializer list, we allow any number of | 3485 # To account for nested initializer list, we allow any number of |
3350 # closing braces up to "{;,)<". We can't simply silence the | 3486 # closing braces up to "{;,)<". We can't simply silence the |
3351 # warning on first sight of closing brace, because that would | 3487 # warning on first sight of closing brace, because that would |
3352 # cause false negatives for things that are not initializer lists. | 3488 # cause false negatives for things that are not initializer lists. |
3353 # Silence this: But not this: | 3489 # Silence this: But not this: |
3354 # Outer{ if (...) { | 3490 # Outer{ if (...) { |
3355 # Inner{...} if (...){ // Missing space before { | 3491 # Inner{...} if (...){ // Missing space before { |
3356 # }; } | 3492 # }; } |
3357 # | 3493 # |
3358 # There is a false negative with this approach if people inserted | 3494 # There is a false negative with this approach if people inserted |
3359 # spurious semicolons, e.g. "if (cond){};", but we will catch the | 3495 # spurious semicolons, e.g. "if (cond){};", but we will catch the |
3360 # spurious semicolon with a separate check. | 3496 # spurious semicolon with a separate check. |
| 3497 leading_text = match.group(1) |
3361 (endline, endlinenum, endpos) = CloseExpression( | 3498 (endline, endlinenum, endpos) = CloseExpression( |
3362 clean_lines, linenum, len(match.group(1))) | 3499 clean_lines, linenum, len(match.group(1))) |
3363 trailing_text = '' | 3500 trailing_text = '' |
3364 if endpos > -1: | 3501 if endpos > -1: |
3365 trailing_text = endline[endpos:] | 3502 trailing_text = endline[endpos:] |
3366 for offset in xrange(endlinenum + 1, | 3503 for offset in xrange(endlinenum + 1, |
3367 min(endlinenum + 3, clean_lines.NumLines() - 1)): | 3504 min(endlinenum + 3, clean_lines.NumLines() - 1)): |
3368 trailing_text += clean_lines.elided[offset] | 3505 trailing_text += clean_lines.elided[offset] |
3369 if not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text): | 3506 # We also suppress warnings for `uint64_t{expression}` etc., as the style |
| 3507 # guide recommends brace initialization for integral types to avoid |
| 3508 # overflow/truncation. |
| 3509 if (not Match(r'^[\s}]*[{.;,)<>\]:]', trailing_text) |
| 3510 and not _IsType(clean_lines, nesting_state, leading_text)): |
3370 error(filename, linenum, 'whitespace/braces', 5, | 3511 error(filename, linenum, 'whitespace/braces', 5, |
3371 'Missing space before {') | 3512 'Missing space before {') |
3372 | 3513 |
3373 # Make sure '} else {' has spaces. | 3514 # Make sure '} else {' has spaces. |
3374 if Search(r'}else', line): | 3515 if Search(r'}else', line): |
3375 error(filename, linenum, 'whitespace/braces', 5, | 3516 error(filename, linenum, 'whitespace/braces', 5, |
3376 'Missing space before else') | 3517 'Missing space before else') |
3377 | 3518 |
3378 # You shouldn't have a space before a semicolon at the end of the line. | 3519 # You shouldn't have a space before a semicolon at the end of the line. |
3379 # There's a special case for "for" since the style guide allows space before | 3520 # There's a special case for "for" since the style guide allows space before |
(...skipping 23 matching lines...) Expand all Loading... |
3403 True if this token is decltype() expression, False otherwise. | 3544 True if this token is decltype() expression, False otherwise. |
3404 """ | 3545 """ |
3405 (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column) | 3546 (text, _, start_col) = ReverseCloseExpression(clean_lines, linenum, column) |
3406 if start_col < 0: | 3547 if start_col < 0: |
3407 return False | 3548 return False |
3408 if Search(r'\bdecltype\s*$', text[0:start_col]): | 3549 if Search(r'\bdecltype\s*$', text[0:start_col]): |
3409 return True | 3550 return True |
3410 return False | 3551 return False |
3411 | 3552 |
3412 | 3553 |
3413 def IsTemplateParameterList(clean_lines, linenum, column): | |
3414 """Check if the token ending on (linenum, column) is the end of template<>. | |
3415 | |
3416 Args: | |
3417 clean_lines: A CleansedLines instance containing the file. | |
3418 linenum: the number of the line to check. | |
3419 column: end column of the token to check. | |
3420 Returns: | |
3421 True if this token is end of a template parameter list, False otherwise. | |
3422 """ | |
3423 (_, startline, startpos) = ReverseCloseExpression( | |
3424 clean_lines, linenum, column) | |
3425 if (startpos > -1 and | |
3426 Search(r'\btemplate\s*$', clean_lines.elided[startline][0:startpos])): | |
3427 return True | |
3428 return False | |
3429 | |
3430 | |
3431 def IsRValueType(typenames, clean_lines, nesting_state, linenum, column): | |
3432 """Check if the token ending on (linenum, column) is a type. | |
3433 | |
3434 Assumes that text to the right of the column is "&&" or a function | |
3435 name. | |
3436 | |
3437 Args: | |
3438 typenames: set of type names from template-argument-list. | |
3439 clean_lines: A CleansedLines instance containing the file. | |
3440 nesting_state: A NestingState instance which maintains information about | |
3441 the current stack of nested blocks being parsed. | |
3442 linenum: the number of the line to check. | |
3443 column: end column of the token to check. | |
3444 Returns: | |
3445 True if this token is a type, False if we are not sure. | |
3446 """ | |
3447 prefix = clean_lines.elided[linenum][0:column] | |
3448 | |
3449 # Get one word to the left. If we failed to do so, this is most | |
3450 # likely not a type, since it's unlikely that the type name and "&&" | |
3451 # would be split across multiple lines. | |
3452 match = Match(r'^(.*)(\b\w+|[>*)&])\s*$', prefix) | |
3453 if not match: | |
3454 return False | |
3455 | |
3456 # Check text following the token. If it's "&&>" or "&&," or "&&...", it's | |
3457 # most likely a rvalue reference used inside a template. | |
3458 suffix = clean_lines.elided[linenum][column:] | |
3459 if Match(r'&&\s*(?:[>,]|\.\.\.)', suffix): | |
3460 return True | |
3461 | |
3462 # Check for known types and end of templates: | |
3463 # int&& variable | |
3464 # vector<int>&& variable | |
3465 # | |
3466 # Because this function is called recursively, we also need to | |
3467 # recognize pointer and reference types: | |
3468 # int* Function() | |
3469 # int& Function() | |
3470 if (match.group(2) in typenames or | |
3471 match.group(2) in ['char', 'char16_t', 'char32_t', 'wchar_t', 'bool', | |
3472 'short', 'int', 'long', 'signed', 'unsigned', | |
3473 'float', 'double', 'void', 'auto', '>', '*', '&']): | |
3474 return True | |
3475 | |
3476 # If we see a close parenthesis, look for decltype on the other side. | |
3477 # decltype would unambiguously identify a type, anything else is | |
3478 # probably a parenthesized expression and not a type. | |
3479 if match.group(2) == ')': | |
3480 return IsDecltype( | |
3481 clean_lines, linenum, len(match.group(1)) + len(match.group(2)) - 1) | |
3482 | |
3483 # Check for casts and cv-qualifiers. | |
3484 # match.group(1) remainder | |
3485 # -------------- --------- | |
3486 # const_cast< type&& | |
3487 # const type&& | |
3488 # type const&& | |
3489 if Search(r'\b(?:const_cast\s*<|static_cast\s*<|dynamic_cast\s*<|' | |
3490 r'reinterpret_cast\s*<|\w+\s)\s*$', | |
3491 match.group(1)): | |
3492 return True | |
3493 | |
3494 # Look for a preceding symbol that might help differentiate the context. | |
3495 # These are the cases that would be ambiguous: | |
3496 # match.group(1) remainder | |
3497 # -------------- --------- | |
3498 # Call ( expression && | |
3499 # Declaration ( type&& | |
3500 # sizeof ( type&& | |
3501 # if ( expression && | |
3502 # while ( expression && | |
3503 # for ( type&& | |
3504 # for( ; expression && | |
3505 # statement ; type&& | |
3506 # block { type&& | |
3507 # constructor { expression && | |
3508 start = linenum | |
3509 line = match.group(1) | |
3510 match_symbol = None | |
3511 while start >= 0: | |
3512 # We want to skip over identifiers and commas to get to a symbol. | |
3513 # Commas are skipped so that we can find the opening parenthesis | |
3514 # for function parameter lists. | |
3515 match_symbol = Match(r'^(.*)([^\w\s,])[\w\s,]*$', line) | |
3516 if match_symbol: | |
3517 break | |
3518 start -= 1 | |
3519 line = clean_lines.elided[start] | |
3520 | |
3521 if not match_symbol: | |
3522 # Probably the first statement in the file is an rvalue reference | |
3523 return True | |
3524 | |
3525 if match_symbol.group(2) == '}': | |
3526 # Found closing brace, probably an indicate of this: | |
3527 # block{} type&& | |
3528 return True | |
3529 | |
3530 if match_symbol.group(2) == ';': | |
3531 # Found semicolon, probably one of these: | |
3532 # for(; expression && | |
3533 # statement; type&& | |
3534 | |
3535 # Look for the previous 'for(' in the previous lines. | |
3536 before_text = match_symbol.group(1) | |
3537 for i in xrange(start - 1, max(start - 6, 0), -1): | |
3538 before_text = clean_lines.elided[i] + before_text | |
3539 if Search(r'for\s*\([^{};]*$', before_text): | |
3540 # This is the condition inside a for-loop | |
3541 return False | |
3542 | |
3543 # Did not find a for-init-statement before this semicolon, so this | |
3544 # is probably a new statement and not a condition. | |
3545 return True | |
3546 | |
3547 if match_symbol.group(2) == '{': | |
3548 # Found opening brace, probably one of these: | |
3549 # block{ type&& = ... ; } | |
3550 # constructor{ expression && expression } | |
3551 | |
3552 # Look for a closing brace or a semicolon. If we see a semicolon | |
3553 # first, this is probably a rvalue reference. | |
3554 line = clean_lines.elided[start][0:len(match_symbol.group(1)) + 1] | |
3555 end = start | |
3556 depth = 1 | |
3557 while True: | |
3558 for ch in line: | |
3559 if ch == ';': | |
3560 return True | |
3561 elif ch == '{': | |
3562 depth += 1 | |
3563 elif ch == '}': | |
3564 depth -= 1 | |
3565 if depth == 0: | |
3566 return False | |
3567 end += 1 | |
3568 if end >= clean_lines.NumLines(): | |
3569 break | |
3570 line = clean_lines.elided[end] | |
3571 # Incomplete program? | |
3572 return False | |
3573 | |
3574 if match_symbol.group(2) == '(': | |
3575 # Opening parenthesis. Need to check what's to the left of the | |
3576 # parenthesis. Look back one extra line for additional context. | |
3577 before_text = match_symbol.group(1) | |
3578 if linenum > 1: | |
3579 before_text = clean_lines.elided[linenum - 1] + before_text | |
3580 before_text = match_symbol.group(1) | |
3581 | |
3582 # Patterns that are likely to be types: | |
3583 # [](type&& | |
3584 # for (type&& | |
3585 # sizeof(type&& | |
3586 # operator=(type&& | |
3587 # | |
3588 if Search(r'(?:\]|\bfor|\bsizeof|\boperator\s*\S+\s*)\s*$', before_text): | |
3589 return True | |
3590 | |
3591 # Patterns that are likely to be expressions: | |
3592 # if (expression && | |
3593 # while (expression && | |
3594 # : initializer(expression && | |
3595 # , initializer(expression && | |
3596 # ( FunctionCall(expression && | |
3597 # + FunctionCall(expression && | |
3598 # + (expression && | |
3599 # | |
3600 # The last '+' represents operators such as '+' and '-'. | |
3601 if Search(r'(?:\bif|\bwhile|[-+=%^(<!?:,&*]\s*)$', before_text): | |
3602 return False | |
3603 | |
3604 # Something else. Check that tokens to the left look like | |
3605 # return_type function_name | |
3606 match_func = Match(r'^(.*\S.*)\s+\w(?:\w|::)*(?:<[^<>]*>)?\s*$', | |
3607 match_symbol.group(1)) | |
3608 if match_func: | |
3609 # Check for constructors, which don't have return types. | |
3610 if Search(r'\b(?:explicit|inline)$', match_func.group(1)): | |
3611 return True | |
3612 implicit_constructor = Match(r'\s*(\w+)\((?:const\s+)?(\w+)', prefix) | |
3613 if (implicit_constructor and | |
3614 implicit_constructor.group(1) == implicit_constructor.group(2)): | |
3615 return True | |
3616 return IsRValueType(typenames, clean_lines, nesting_state, linenum, | |
3617 len(match_func.group(1))) | |
3618 | |
3619 # Nothing before the function name. If this is inside a block scope, | |
3620 # this is probably a function call. | |
3621 return not (nesting_state.previous_stack_top and | |
3622 nesting_state.previous_stack_top.IsBlockInfo()) | |
3623 | |
3624 if match_symbol.group(2) == '>': | |
3625 # Possibly a closing bracket, check that what's on the other side | |
3626 # looks like the start of a template. | |
3627 return IsTemplateParameterList( | |
3628 clean_lines, start, len(match_symbol.group(1))) | |
3629 | |
3630 # Some other symbol, usually something like "a=b&&c". This is most | |
3631 # likely not a type. | |
3632 return False | |
3633 | |
3634 | |
3635 def IsDeletedOrDefault(clean_lines, linenum): | |
3636 """Check if current constructor or operator is deleted or default. | |
3637 | |
3638 Args: | |
3639 clean_lines: A CleansedLines instance containing the file. | |
3640 linenum: The number of the line to check. | |
3641 Returns: | |
3642 True if this is a deleted or default constructor. | |
3643 """ | |
3644 open_paren = clean_lines.elided[linenum].find('(') | |
3645 if open_paren < 0: | |
3646 return False | |
3647 (close_line, _, close_paren) = CloseExpression( | |
3648 clean_lines, linenum, open_paren) | |
3649 if close_paren < 0: | |
3650 return False | |
3651 return Match(r'\s*=\s*(?:delete|default)\b', close_line[close_paren:]) | |
3652 | |
3653 | |
3654 def IsRValueAllowed(clean_lines, linenum, typenames): | |
3655 """Check if RValue reference is allowed on a particular line. | |
3656 | |
3657 Args: | |
3658 clean_lines: A CleansedLines instance containing the file. | |
3659 linenum: The number of the line to check. | |
3660 typenames: set of type names from template-argument-list. | |
3661 Returns: | |
3662 True if line is within the region where RValue references are allowed. | |
3663 """ | |
3664 # Allow region marked by PUSH/POP macros | |
3665 for i in xrange(linenum, 0, -1): | |
3666 line = clean_lines.elided[i] | |
3667 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): | |
3668 if not line.endswith('PUSH'): | |
3669 return False | |
3670 for j in xrange(linenum, clean_lines.NumLines(), 1): | |
3671 line = clean_lines.elided[j] | |
3672 if Match(r'GOOGLE_ALLOW_RVALUE_REFERENCES_(?:PUSH|POP)', line): | |
3673 return line.endswith('POP') | |
3674 | |
3675 # Allow operator= | |
3676 line = clean_lines.elided[linenum] | |
3677 if Search(r'\boperator\s*=\s*\(', line): | |
3678 return IsDeletedOrDefault(clean_lines, linenum) | |
3679 | |
3680 # Allow constructors | |
3681 match = Match(r'\s*(?:[\w<>]+::)*([\w<>]+)\s*::\s*([\w<>]+)\s*\(', line) | |
3682 if match and match.group(1) == match.group(2): | |
3683 return IsDeletedOrDefault(clean_lines, linenum) | |
3684 if Search(r'\b(?:explicit|inline)\s+[\w<>]+\s*\(', line): | |
3685 return IsDeletedOrDefault(clean_lines, linenum) | |
3686 | |
3687 if Match(r'\s*[\w<>]+\s*\(', line): | |
3688 previous_line = 'ReturnType' | |
3689 if linenum > 0: | |
3690 previous_line = clean_lines.elided[linenum - 1] | |
3691 if Match(r'^\s*$', previous_line) or Search(r'[{}:;]\s*$', previous_line): | |
3692 return IsDeletedOrDefault(clean_lines, linenum) | |
3693 | |
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 | |
3774 | |
3775 | |
3776 def CheckRValueReference(filename, clean_lines, linenum, nesting_state, error): | |
3777 """Check for rvalue references. | |
3778 | |
3779 Args: | |
3780 filename: The name of the current file. | |
3781 clean_lines: A CleansedLines instance containing the file. | |
3782 linenum: The number of the line to check. | |
3783 nesting_state: A NestingState instance which maintains information about | |
3784 the current stack of nested blocks being parsed. | |
3785 error: The function to call with any errors found. | |
3786 """ | |
3787 # Find lines missing spaces around &&. | |
3788 # TODO(unknown): currently we don't check for rvalue references | |
3789 # with spaces surrounding the && to avoid false positives with | |
3790 # boolean expressions. | |
3791 line = clean_lines.elided[linenum] | |
3792 match = Match(r'^(.*\S)&&', line) | |
3793 if not match: | |
3794 match = Match(r'(.*)&&\S', line) | |
3795 if (not match) or '(&&)' in line or Search(r'\boperator\s*$', match.group(1)): | |
3796 return | |
3797 | |
3798 # Either poorly formed && or an rvalue reference, check the context | |
3799 # to get a more accurate error message. Mostly we want to determine | |
3800 # if what's to the left of "&&" is a type or not. | |
3801 typenames = GetTemplateArgs(clean_lines, linenum) | |
3802 and_pos = len(match.group(1)) | |
3803 if IsRValueType(typenames, clean_lines, nesting_state, linenum, and_pos): | |
3804 if not IsRValueAllowed(clean_lines, linenum, typenames): | |
3805 error(filename, linenum, 'build/c++11', 3, | |
3806 'RValue references are an unapproved C++ feature.') | |
3807 else: | |
3808 error(filename, linenum, 'whitespace/operators', 3, | |
3809 'Missing spaces around &&') | |
3810 | |
3811 | |
3812 def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): | 3554 def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error): |
3813 """Checks for additional blank line issues related to sections. | 3555 """Checks for additional blank line issues related to sections. |
3814 | 3556 |
3815 Currently the only thing checked here is blank line before protected/private. | 3557 Currently the only thing checked here is blank line before protected/private. |
3816 | 3558 |
3817 Args: | 3559 Args: |
3818 filename: The name of the current file. | 3560 filename: The name of the current file. |
3819 clean_lines: A CleansedLines instance containing the file. | 3561 clean_lines: A CleansedLines instance containing the file. |
3820 class_info: A _ClassInfo objects. | 3562 class_info: A _ClassInfo objects. |
3821 linenum: The number of the line to check. | 3563 linenum: The number of the line to check. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3899 | 3641 |
3900 line = clean_lines.elided[linenum] # get rid of comments and strings | 3642 line = clean_lines.elided[linenum] # get rid of comments and strings |
3901 | 3643 |
3902 if Match(r'\s*{\s*$', line): | 3644 if Match(r'\s*{\s*$', line): |
3903 # We allow an open brace to start a line in the case where someone is using | 3645 # We allow an open brace to start a line in the case where someone is using |
3904 # braces in a block to explicitly create a new scope, which is commonly used | 3646 # braces in a block to explicitly create a new scope, which is commonly used |
3905 # to control the lifetime of stack-allocated variables. Braces are also | 3647 # to control the lifetime of stack-allocated variables. Braces are also |
3906 # used for brace initializers inside function calls. We don't detect this | 3648 # used for brace initializers inside function calls. We don't detect this |
3907 # perfectly: we just don't complain if the last non-whitespace character on | 3649 # perfectly: we just don't complain if the last non-whitespace character on |
3908 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the | 3650 # the previous non-blank line is ',', ';', ':', '(', '{', or '}', or if the |
3909 # previous line starts a preprocessor block. | 3651 # previous line starts a preprocessor block. We also allow a brace on the |
| 3652 # following line if it is part of an array initialization and would not fit |
| 3653 # within the 80 character limit of the preceding line. |
3910 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] | 3654 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] |
3911 if (not Search(r'[,;:}{(]\s*$', prevline) and | 3655 if (not Search(r'[,;:}{(]\s*$', prevline) and |
3912 not Match(r'\s*#', prevline)): | 3656 not Match(r'\s*#', prevline) and |
| 3657 not (GetLineWidth(prevline) > _line_length - 2 and '[]' in prevline)): |
3913 error(filename, linenum, 'whitespace/braces', 4, | 3658 error(filename, linenum, 'whitespace/braces', 4, |
3914 '{ should almost always be at the end of the previous line') | 3659 '{ should almost always be at the end of the previous line') |
3915 | 3660 |
3916 # An else clause should be on the same line as the preceding closing brace. | 3661 # An else clause should be on the same line as the preceding closing brace. |
3917 if Match(r'\s*else\b\s*(?:if\b|\{|$)', line): | 3662 if Match(r'\s*else\b\s*(?:if\b|\{|$)', line): |
3918 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] | 3663 prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0] |
3919 if Match(r'\s*}\s*$', prevline): | 3664 if Match(r'\s*}\s*$', prevline): |
3920 error(filename, linenum, 'whitespace/newline', 4, | 3665 error(filename, linenum, 'whitespace/newline', 4, |
3921 'An else should appear on the same line as the preceding }') | 3666 'An else should appear on the same line as the preceding }') |
3922 | 3667 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4078 # We implement a whitelist of safe macros instead of a blacklist of | 3823 # We implement a whitelist of safe macros instead of a blacklist of |
4079 # unsafe macros, even though the latter appears less frequently in | 3824 # unsafe macros, even though the latter appears less frequently in |
4080 # google code and would have been easier to implement. This is because | 3825 # google code and would have been easier to implement. This is because |
4081 # the downside for getting the whitelist wrong means some extra | 3826 # the downside for getting the whitelist wrong means some extra |
4082 # semicolons, while the downside for getting the blacklist wrong | 3827 # semicolons, while the downside for getting the blacklist wrong |
4083 # would result in compile errors. | 3828 # would result in compile errors. |
4084 # | 3829 # |
4085 # In addition to macros, we also don't want to warn on | 3830 # In addition to macros, we also don't want to warn on |
4086 # - Compound literals | 3831 # - Compound literals |
4087 # - Lambdas | 3832 # - Lambdas |
4088 # - alignas specifier with anonymous structs: | 3833 # - alignas specifier with anonymous structs |
| 3834 # - decltype |
4089 closing_brace_pos = match.group(1).rfind(')') | 3835 closing_brace_pos = match.group(1).rfind(')') |
4090 opening_parenthesis = ReverseCloseExpression( | 3836 opening_parenthesis = ReverseCloseExpression( |
4091 clean_lines, linenum, closing_brace_pos) | 3837 clean_lines, linenum, closing_brace_pos) |
4092 if opening_parenthesis[2] > -1: | 3838 if opening_parenthesis[2] > -1: |
4093 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] | 3839 line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] |
4094 macro = Search(r'\b([A-Z_]+)\s*$', line_prefix) | 3840 macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix) |
4095 func = Match(r'^(.*\])\s*$', line_prefix) | 3841 func = Match(r'^(.*\])\s*$', line_prefix) |
4096 if ((macro and | 3842 if ((macro and |
4097 macro.group(1) not in ( | 3843 macro.group(1) not in ( |
4098 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', | 3844 'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', |
4099 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', | 3845 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', |
4100 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or | 3846 'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or |
4101 (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or | 3847 (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or |
4102 Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or | 3848 Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or |
| 3849 Search(r'\bdecltype$', line_prefix) or |
4103 Search(r'\s+=\s*$', line_prefix)): | 3850 Search(r'\s+=\s*$', line_prefix)): |
4104 match = None | 3851 match = None |
4105 if (match and | 3852 if (match and |
4106 opening_parenthesis[1] > 1 and | 3853 opening_parenthesis[1] > 1 and |
4107 Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): | 3854 Search(r'\]\s*$', clean_lines.elided[opening_parenthesis[1] - 1])): |
4108 # Multi-line lambda-expression | 3855 # Multi-line lambda-expression |
4109 match = None | 3856 match = None |
4110 | 3857 |
4111 else: | 3858 else: |
4112 # Try matching cases 2-3. | 3859 # Try matching cases 2-3. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4152 | 3899 |
4153 # Search for loop keywords at the beginning of the line. Because only | 3900 # Search for loop keywords at the beginning of the line. Because only |
4154 # whitespaces are allowed before the keywords, this will also ignore most | 3901 # whitespaces are allowed before the keywords, this will also ignore most |
4155 # do-while-loops, since those lines should start with closing brace. | 3902 # do-while-loops, since those lines should start with closing brace. |
4156 # | 3903 # |
4157 # We also check "if" blocks here, since an empty conditional block | 3904 # We also check "if" blocks here, since an empty conditional block |
4158 # is likely an error. | 3905 # is likely an error. |
4159 line = clean_lines.elided[linenum] | 3906 line = clean_lines.elided[linenum] |
4160 matched = Match(r'\s*(for|while|if)\s*\(', line) | 3907 matched = Match(r'\s*(for|while|if)\s*\(', line) |
4161 if matched: | 3908 if matched: |
4162 # Find the end of the conditional expression | 3909 # Find the end of the conditional expression. |
4163 (end_line, end_linenum, end_pos) = CloseExpression( | 3910 (end_line, end_linenum, end_pos) = CloseExpression( |
4164 clean_lines, linenum, line.find('(')) | 3911 clean_lines, linenum, line.find('(')) |
4165 | 3912 |
4166 # Output warning if what follows the condition expression is a semicolon. | 3913 # Output warning if what follows the condition expression is a semicolon. |
4167 # No warning for all other cases, including whitespace or newline, since we | 3914 # No warning for all other cases, including whitespace or newline, since we |
4168 # have a separate check for semicolons preceded by whitespace. | 3915 # have a separate check for semicolons preceded by whitespace. |
4169 if end_pos >= 0 and Match(r';', end_line[end_pos:]): | 3916 if end_pos >= 0 and Match(r';', end_line[end_pos:]): |
4170 if matched.group(1) == 'if': | 3917 if matched.group(1) == 'if': |
4171 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, | 3918 error(filename, end_linenum, 'whitespace/empty_conditional_body', 5, |
4172 'Empty conditional bodies should use {}') | 3919 'Empty conditional bodies should use {}') |
4173 else: | 3920 else: |
4174 error(filename, end_linenum, 'whitespace/empty_loop_body', 5, | 3921 error(filename, end_linenum, 'whitespace/empty_loop_body', 5, |
4175 'Empty loop bodies should use {} or continue') | 3922 'Empty loop bodies should use {} or continue') |
4176 | 3923 |
| 3924 # Check for if statements that have completely empty bodies (no comments) |
| 3925 # and no else clauses. |
| 3926 if end_pos >= 0 and matched.group(1) == 'if': |
| 3927 # Find the position of the opening { for the if statement. |
| 3928 # Return without logging an error if it has no brackets. |
| 3929 opening_linenum = end_linenum |
| 3930 opening_line_fragment = end_line[end_pos:] |
| 3931 # Loop until EOF or find anything that's not whitespace or opening {. |
| 3932 while not Search(r'^\s*\{', opening_line_fragment): |
| 3933 if Search(r'^(?!\s*$)', opening_line_fragment): |
| 3934 # Conditional has no brackets. |
| 3935 return |
| 3936 opening_linenum += 1 |
| 3937 if opening_linenum == len(clean_lines.elided): |
| 3938 # Couldn't find conditional's opening { or any code before EOF. |
| 3939 return |
| 3940 opening_line_fragment = clean_lines.elided[opening_linenum] |
| 3941 # Set opening_line (opening_line_fragment may not be entire opening line). |
| 3942 opening_line = clean_lines.elided[opening_linenum] |
| 3943 |
| 3944 # Find the position of the closing }. |
| 3945 opening_pos = opening_line_fragment.find('{') |
| 3946 if opening_linenum == end_linenum: |
| 3947 # We need to make opening_pos relative to the start of the entire line. |
| 3948 opening_pos += end_pos |
| 3949 (closing_line, closing_linenum, closing_pos) = CloseExpression( |
| 3950 clean_lines, opening_linenum, opening_pos) |
| 3951 if closing_pos < 0: |
| 3952 return |
| 3953 |
| 3954 # Now construct the body of the conditional. This consists of the portion |
| 3955 # of the opening line after the {, all lines until the closing line, |
| 3956 # and the portion of the closing line before the }. |
| 3957 if (clean_lines.raw_lines[opening_linenum] != |
| 3958 CleanseComments(clean_lines.raw_lines[opening_linenum])): |
| 3959 # Opening line ends with a comment, so conditional isn't empty. |
| 3960 return |
| 3961 if closing_linenum > opening_linenum: |
| 3962 # Opening line after the {. Ignore comments here since we checked above. |
| 3963 body = list(opening_line[opening_pos+1:]) |
| 3964 # All lines until closing line, excluding closing line, with comments. |
| 3965 body.extend(clean_lines.raw_lines[opening_linenum+1:closing_linenum]) |
| 3966 # Closing line before the }. Won't (and can't) have comments. |
| 3967 body.append(clean_lines.elided[closing_linenum][:closing_pos-1]) |
| 3968 body = '\n'.join(body) |
| 3969 else: |
| 3970 # If statement has brackets and fits on a single line. |
| 3971 body = opening_line[opening_pos+1:closing_pos-1] |
| 3972 |
| 3973 # Check if the body is empty |
| 3974 if not _EMPTY_CONDITIONAL_BODY_PATTERN.search(body): |
| 3975 return |
| 3976 # The body is empty. Now make sure there's not an else clause. |
| 3977 current_linenum = closing_linenum |
| 3978 current_line_fragment = closing_line[closing_pos:] |
| 3979 # Loop until EOF or find anything that's not whitespace or else clause. |
| 3980 while Search(r'^\s*$|^(?=\s*else)', current_line_fragment): |
| 3981 if Search(r'^(?=\s*else)', current_line_fragment): |
| 3982 # Found an else clause, so don't log an error. |
| 3983 return |
| 3984 current_linenum += 1 |
| 3985 if current_linenum == len(clean_lines.elided): |
| 3986 break |
| 3987 current_line_fragment = clean_lines.elided[current_linenum] |
| 3988 |
| 3989 # The body is empty and there's no else clause until EOF or other code. |
| 3990 error(filename, end_linenum, 'whitespace/empty_if_body', 4, |
| 3991 ('If statement had no body and no else clause')) |
| 3992 |
4177 | 3993 |
4178 def FindCheckMacro(line): | 3994 def FindCheckMacro(line): |
4179 """Find a replaceable CHECK-like macro. | 3995 """Find a replaceable CHECK-like macro. |
4180 | 3996 |
4181 Args: | 3997 Args: |
4182 line: line to search on. | 3998 line: line to search on. |
4183 Returns: | 3999 Returns: |
4184 (macro name, start position), or (None, -1) if no replaceable | 4000 (macro name, start position), or (None, -1) if no replaceable |
4185 macro is found. | 4001 macro is found. |
4186 """ | 4002 """ |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4386 nesting_state: A NestingState instance which maintains information about | 4202 nesting_state: A NestingState instance which maintains information about |
4387 the current stack of nested blocks being parsed. | 4203 the current stack of nested blocks being parsed. |
4388 error: The function to call with any errors found. | 4204 error: The function to call with any errors found. |
4389 """ | 4205 """ |
4390 | 4206 |
4391 # Don't use "elided" lines here, otherwise we can't check commented lines. | 4207 # Don't use "elided" lines here, otherwise we can't check commented lines. |
4392 # Don't want to use "raw" either, because we don't want to check inside C++11 | 4208 # Don't want to use "raw" either, because we don't want to check inside C++11 |
4393 # raw strings, | 4209 # raw strings, |
4394 raw_lines = clean_lines.lines_without_raw_strings | 4210 raw_lines = clean_lines.lines_without_raw_strings |
4395 line = raw_lines[linenum] | 4211 line = raw_lines[linenum] |
| 4212 prev = raw_lines[linenum - 1] if linenum > 0 else '' |
4396 | 4213 |
4397 if line.find('\t') != -1: | 4214 if line.find('\t') != -1: |
4398 error(filename, linenum, 'whitespace/tab', 1, | 4215 error(filename, linenum, 'whitespace/tab', 1, |
4399 'Tab found; better to use spaces') | 4216 'Tab found; better to use spaces') |
4400 | 4217 |
4401 # One or three blank spaces at the beginning of the line is weird; it's | 4218 # One or three blank spaces at the beginning of the line is weird; it's |
4402 # hard to reconcile that with 2-space indents. | 4219 # hard to reconcile that with 2-space indents. |
4403 # NOTE: here are the conditions rob pike used for his tests. Mine aren't | 4220 # NOTE: here are the conditions rob pike used for his tests. Mine aren't |
4404 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces | 4221 # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces |
4405 # if(RLENGTH > 20) complain = 0; | 4222 # if(RLENGTH > 20) complain = 0; |
4406 # if(match($0, " +(error|private|public|protected):")) complain = 0; | 4223 # if(match($0, " +(error|private|public|protected):")) complain = 0; |
4407 # if(match(prev, "&& *$")) complain = 0; | 4224 # if(match(prev, "&& *$")) complain = 0; |
4408 # if(match(prev, "\\|\\| *$")) complain = 0; | 4225 # if(match(prev, "\\|\\| *$")) complain = 0; |
4409 # if(match(prev, "[\",=><] *$")) complain = 0; | 4226 # if(match(prev, "[\",=><] *$")) complain = 0; |
4410 # if(match($0, " <<")) complain = 0; | 4227 # if(match($0, " <<")) complain = 0; |
4411 # if(match(prev, " +for \\(")) complain = 0; | 4228 # if(match(prev, " +for \\(")) complain = 0; |
4412 # if(prevodd && match(prevprev, " +for \\(")) complain = 0; | 4229 # if(prevodd && match(prevprev, " +for \\(")) complain = 0; |
4413 scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' | 4230 scope_or_label_pattern = r'\s*\w+\s*:\s*\\?$' |
4414 classinfo = nesting_state.InnermostClass() | 4231 classinfo = nesting_state.InnermostClass() |
4415 initial_spaces = 0 | 4232 initial_spaces = 0 |
4416 cleansed_line = clean_lines.elided[linenum] | 4233 cleansed_line = clean_lines.elided[linenum] |
4417 while initial_spaces < len(line) and line[initial_spaces] == ' ': | 4234 while initial_spaces < len(line) and line[initial_spaces] == ' ': |
4418 initial_spaces += 1 | 4235 initial_spaces += 1 |
4419 if line and line[-1].isspace(): | |
4420 error(filename, linenum, 'whitespace/end_of_line', 4, | |
4421 'Line ends in whitespace. Consider deleting these extra spaces.') | |
4422 # There are certain situations we allow one space, notably for | 4236 # There are certain situations we allow one space, notably for |
4423 # section labels, and also lines containing multi-line raw strings. | 4237 # section labels, and also lines containing multi-line raw strings. |
4424 elif ((initial_spaces == 1 or initial_spaces == 3) and | 4238 # We also don't check for lines that look like continuation lines |
4425 not Match(scope_or_label_pattern, cleansed_line) and | 4239 # (of lines ending in double quotes, commas, equals, or angle brackets) |
4426 not (clean_lines.raw_lines[linenum] != line and | 4240 # because the rules for how to indent those are non-trivial. |
4427 Match(r'^\s*""', line))): | 4241 if (not Search(r'[",=><] *$', prev) and |
| 4242 (initial_spaces == 1 or initial_spaces == 3) and |
| 4243 not Match(scope_or_label_pattern, cleansed_line) and |
| 4244 not (clean_lines.raw_lines[linenum] != line and |
| 4245 Match(r'^\s*""', line))): |
4428 error(filename, linenum, 'whitespace/indent', 3, | 4246 error(filename, linenum, 'whitespace/indent', 3, |
4429 'Weird number of spaces at line-start. ' | 4247 'Weird number of spaces at line-start. ' |
4430 'Are you using a 2-space indent?') | 4248 'Are you using a 2-space indent?') |
4431 | 4249 |
| 4250 if line and line[-1].isspace(): |
| 4251 error(filename, linenum, 'whitespace/end_of_line', 4, |
| 4252 'Line ends in whitespace. Consider deleting these extra spaces.') |
| 4253 |
4432 # Check if the line is a header guard. | 4254 # Check if the line is a header guard. |
4433 is_header_guard = False | 4255 is_header_guard = False |
4434 if file_extension == 'h': | 4256 if file_extension == 'h': |
4435 cppvar = GetHeaderGuardCPPVariable(filename) | 4257 cppvar = GetHeaderGuardCPPVariable(filename) |
4436 if (line.startswith('#ifndef %s' % cppvar) or | 4258 if (line.startswith('#ifndef %s' % cppvar) or |
4437 line.startswith('#define %s' % cppvar) or | 4259 line.startswith('#define %s' % cppvar) or |
4438 line.startswith('#endif // %s' % cppvar)): | 4260 line.startswith('#endif // %s' % cppvar)): |
4439 is_header_guard = True | 4261 is_header_guard = True |
4440 # #include lines and header guards can be long, since there's no clean way to | 4262 # #include lines and header guards can be long, since there's no clean way to |
4441 # split them. | 4263 # split them. |
4442 # | 4264 # |
4443 # URLs can be long too. It's possible to split these, but it makes them | 4265 # URLs can be long too. It's possible to split these, but it makes them |
4444 # harder to cut&paste. | 4266 # harder to cut&paste. |
4445 # | 4267 # |
4446 # The "$Id:...$" comment may also get very long without it being the | 4268 # The "$Id:...$" comment may also get very long without it being the |
4447 # developers fault. | 4269 # developers fault. |
4448 if (not line.startswith('#include') and not is_header_guard and | 4270 if (not line.startswith('#include') and not is_header_guard and |
4449 not Match(r'^\s*//.*http(s?)://\S*$', line) and | 4271 not Match(r'^\s*//.*http(s?)://\S*$', line) and |
| 4272 not Match(r'^\s*//\s*[^\s]*$', line) and |
4450 not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): | 4273 not Match(r'^// \$Id:.*#[0-9]+ \$$', line)): |
4451 line_width = GetLineWidth(line) | 4274 line_width = GetLineWidth(line) |
4452 extended_length = int((_line_length * 1.25)) | 4275 if line_width > _line_length: |
4453 if line_width > extended_length: | |
4454 error(filename, linenum, 'whitespace/line_length', 4, | |
4455 'Lines should very rarely be longer than %i characters' % | |
4456 extended_length) | |
4457 elif line_width > _line_length: | |
4458 error(filename, linenum, 'whitespace/line_length', 2, | 4276 error(filename, linenum, 'whitespace/line_length', 2, |
4459 'Lines should be <= %i characters long' % _line_length) | 4277 'Lines should be <= %i characters long' % _line_length) |
4460 | 4278 |
4461 if (cleansed_line.count(';') > 1 and | 4279 if (cleansed_line.count(';') > 1 and |
4462 # for loops are allowed two ;'s (and may run over two lines). | 4280 # for loops are allowed two ;'s (and may run over two lines). |
4463 cleansed_line.find('for') == -1 and | 4281 cleansed_line.find('for') == -1 and |
4464 (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or | 4282 (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or |
4465 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and | 4283 GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and |
4466 # It's ok to have many commands in a switch case that fits in 1 line | 4284 # It's ok to have many commands in a switch case that fits in 1 line |
4467 not ((cleansed_line.find('case ') != -1 or | 4285 not ((cleansed_line.find('case ') != -1 or |
4468 cleansed_line.find('default:') != -1) and | 4286 cleansed_line.find('default:') != -1) and |
4469 cleansed_line.find('break;') != -1)): | 4287 cleansed_line.find('break;') != -1)): |
4470 error(filename, linenum, 'whitespace/newline', 0, | 4288 error(filename, linenum, 'whitespace/newline', 0, |
4471 'More than one command on the same line') | 4289 'More than one command on the same line') |
4472 | 4290 |
4473 # Some more style checks | 4291 # Some more style checks |
4474 CheckBraces(filename, clean_lines, linenum, error) | 4292 CheckBraces(filename, clean_lines, linenum, error) |
4475 CheckTrailingSemicolon(filename, clean_lines, linenum, error) | 4293 CheckTrailingSemicolon(filename, clean_lines, linenum, error) |
4476 CheckEmptyBlockBody(filename, clean_lines, linenum, error) | 4294 CheckEmptyBlockBody(filename, clean_lines, linenum, error) |
4477 CheckAccess(filename, clean_lines, linenum, nesting_state, error) | 4295 CheckAccess(filename, clean_lines, linenum, nesting_state, error) |
4478 CheckSpacing(filename, clean_lines, linenum, nesting_state, error) | 4296 CheckSpacing(filename, clean_lines, linenum, nesting_state, error) |
4479 CheckOperatorSpacing(filename, clean_lines, linenum, error) | 4297 CheckOperatorSpacing(filename, clean_lines, linenum, error) |
4480 CheckParenthesisSpacing(filename, clean_lines, linenum, error) | 4298 CheckParenthesisSpacing(filename, clean_lines, linenum, error) |
4481 CheckCommaSpacing(filename, clean_lines, linenum, error) | 4299 CheckCommaSpacing(filename, clean_lines, linenum, error) |
4482 CheckBracesSpacing(filename, clean_lines, linenum, error) | 4300 CheckBracesSpacing(filename, clean_lines, linenum, nesting_state, error) |
4483 CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) | 4301 CheckSpacingForFunctionCall(filename, clean_lines, linenum, error) |
4484 CheckRValueReference(filename, clean_lines, linenum, nesting_state, error) | |
4485 CheckCheck(filename, clean_lines, linenum, error) | 4302 CheckCheck(filename, clean_lines, linenum, error) |
4486 CheckAltTokens(filename, clean_lines, linenum, error) | 4303 CheckAltTokens(filename, clean_lines, linenum, error) |
4487 classinfo = nesting_state.InnermostClass() | 4304 classinfo = nesting_state.InnermostClass() |
4488 if classinfo: | 4305 if classinfo: |
4489 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) | 4306 CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error) |
4490 | 4307 |
4491 | 4308 |
4492 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') | 4309 _RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$') |
4493 # Matches the first component of a filename delimited by -s and _s. That is: | 4310 # Matches the first component of a filename delimited by -s and _s. That is: |
4494 # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' | 4311 # _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo' |
(...skipping 23 matching lines...) Expand all Loading... |
4518 The filename with the common suffix removed. | 4335 The filename with the common suffix removed. |
4519 """ | 4336 """ |
4520 for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', | 4337 for suffix in ('test.cc', 'regtest.cc', 'unittest.cc', |
4521 'inl.h', 'impl.h', 'internal.h'): | 4338 'inl.h', 'impl.h', 'internal.h'): |
4522 if (filename.endswith(suffix) and len(filename) > len(suffix) and | 4339 if (filename.endswith(suffix) and len(filename) > len(suffix) and |
4523 filename[-len(suffix) - 1] in ('-', '_')): | 4340 filename[-len(suffix) - 1] in ('-', '_')): |
4524 return filename[:-len(suffix) - 1] | 4341 return filename[:-len(suffix) - 1] |
4525 return os.path.splitext(filename)[0] | 4342 return os.path.splitext(filename)[0] |
4526 | 4343 |
4527 | 4344 |
4528 def _IsTestFilename(filename): | |
4529 """Determines if the given filename has a suffix that identifies it as a test. | |
4530 | |
4531 Args: | |
4532 filename: The input filename. | |
4533 | |
4534 Returns: | |
4535 True if 'filename' looks like a test, False otherwise. | |
4536 """ | |
4537 if (filename.endswith('_test.cc') or | |
4538 filename.endswith('_unittest.cc') or | |
4539 filename.endswith('_regtest.cc')): | |
4540 return True | |
4541 else: | |
4542 return False | |
4543 | |
4544 | |
4545 def _ClassifyInclude(fileinfo, include, is_system): | 4345 def _ClassifyInclude(fileinfo, include, is_system): |
4546 """Figures out what kind of header 'include' is. | 4346 """Figures out what kind of header 'include' is. |
4547 | 4347 |
4548 Args: | 4348 Args: |
4549 fileinfo: The current file cpplint is running over. A FileInfo instance. | 4349 fileinfo: The current file cpplint is running over. A FileInfo instance. |
4550 include: The path to a #included file. | 4350 include: The path to a #included file. |
4551 is_system: True if the #include used <> rather than "". | 4351 is_system: True if the #include used <> rather than "". |
4552 | 4352 |
4553 Returns: | 4353 Returns: |
4554 One of the _XXX_HEADER constants. | 4354 One of the _XXX_HEADER constants. |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4749 r'::)+') | 4549 r'::)+') |
4750 # A call-by-reference parameter ends with '& identifier'. | 4550 # A call-by-reference parameter ends with '& identifier'. |
4751 _RE_PATTERN_REF_PARAM = re.compile( | 4551 _RE_PATTERN_REF_PARAM = re.compile( |
4752 r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*' | 4552 r'(' + _RE_PATTERN_TYPE + r'(?:\s*(?:\bconst\b|[*]))*\s*' |
4753 r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]') | 4553 r'&\s*' + _RE_PATTERN_IDENT + r')\s*(?:=[^,()]+)?[,)]') |
4754 # A call-by-const-reference parameter either ends with 'const& identifier' | 4554 # A call-by-const-reference parameter either ends with 'const& identifier' |
4755 # or looks like 'const type& identifier' when 'type' is atomic. | 4555 # or looks like 'const type& identifier' when 'type' is atomic. |
4756 _RE_PATTERN_CONST_REF_PARAM = ( | 4556 _RE_PATTERN_CONST_REF_PARAM = ( |
4757 r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT + | 4557 r'(?:.*\s*\bconst\s*&\s*' + _RE_PATTERN_IDENT + |
4758 r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')') | 4558 r'|const\s+' + _RE_PATTERN_TYPE + r'\s*&\s*' + _RE_PATTERN_IDENT + r')') |
| 4559 # Stream types. |
| 4560 _RE_PATTERN_REF_STREAM_PARAM = ( |
| 4561 r'(?:.*stream\s*&\s*' + _RE_PATTERN_IDENT + r')') |
4759 | 4562 |
4760 | 4563 |
4761 def CheckLanguage(filename, clean_lines, linenum, file_extension, | 4564 def CheckLanguage(filename, clean_lines, linenum, file_extension, |
4762 include_state, nesting_state, error): | 4565 include_state, nesting_state, error): |
4763 """Checks rules from the 'C++ language rules' section of cppguide.html. | 4566 """Checks rules from the 'C++ language rules' section of cppguide.html. |
4764 | 4567 |
4765 Some of these rules are hard to test (function overloading, using | 4568 Some of these rules are hard to test (function overloading, using |
4766 uint32 inappropriately), but we do the best we can. | 4569 uint32 inappropriately), but we do the best we can. |
4767 | 4570 |
4768 Args: | 4571 Args: |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4905 "('k' followed by CamelCase) compile-time constant for the size.") | 4708 "('k' followed by CamelCase) compile-time constant for the size.") |
4906 | 4709 |
4907 # Check for use of unnamed namespaces in header files. Registration | 4710 # Check for use of unnamed namespaces in header files. Registration |
4908 # macros are typically OK, so we allow use of "namespace {" on lines | 4711 # macros are typically OK, so we allow use of "namespace {" on lines |
4909 # that end with backslashes. | 4712 # that end with backslashes. |
4910 if (file_extension == 'h' | 4713 if (file_extension == 'h' |
4911 and Search(r'\bnamespace\s*{', line) | 4714 and Search(r'\bnamespace\s*{', line) |
4912 and line[-1] != '\\'): | 4715 and line[-1] != '\\'): |
4913 error(filename, linenum, 'build/namespaces', 4, | 4716 error(filename, linenum, 'build/namespaces', 4, |
4914 'Do not use unnamed namespaces in header files. See ' | 4717 'Do not use unnamed namespaces in header files. See ' |
4915 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namesp
aces' | 4718 'https://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Names
paces' |
4916 ' for more information.') | 4719 ' for more information.') |
4917 | 4720 |
4918 | 4721 |
4919 def CheckGlobalStatic(filename, clean_lines, linenum, error): | 4722 def CheckGlobalStatic(filename, clean_lines, linenum, error): |
4920 """Check for unsafe global or static objects. | 4723 """Check for unsafe global or static objects. |
4921 | 4724 |
4922 Args: | 4725 Args: |
4923 filename: The name of the current file. | 4726 filename: The name of the current file. |
4924 clean_lines: A CleansedLines instance containing the file. | 4727 clean_lines: A CleansedLines instance containing the file. |
4925 linenum: The number of the line to check. | 4728 linenum: The number of the line to check. |
4926 error: The function to call with any errors found. | 4729 error: The function to call with any errors found. |
4927 """ | 4730 """ |
4928 line = clean_lines.elided[linenum] | 4731 line = clean_lines.elided[linenum] |
4929 | 4732 |
4930 # Match two lines at a time to support multiline declarations | 4733 # Match two lines at a time to support multiline declarations |
4931 if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): | 4734 if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): |
4932 line += clean_lines.elided[linenum + 1].strip() | 4735 line += clean_lines.elided[linenum + 1].strip() |
4933 | 4736 |
4934 # Check for people declaring static/global STL strings at the top level. | 4737 # Check for people declaring static/global STL strings at the top level. |
4935 # This is dangerous because the C++ language does not guarantee that | 4738 # This is dangerous because the C++ language does not guarantee that |
4936 # globals with constructors are initialized before the first access. | 4739 # globals with constructors are initialized before the first access, and |
| 4740 # also because globals can be destroyed when some threads are still running. |
| 4741 # TODO(unknown): Generalize this to also find static unique_ptr instances. |
| 4742 # TODO(unknown): File bugs for clang-tidy to find these. |
4937 match = Match( | 4743 match = Match( |
4938 r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)', | 4744 r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +' |
| 4745 r'([a-zA-Z0-9_:]+)\b(.*)', |
4939 line) | 4746 line) |
4940 | 4747 |
4941 # Remove false positives: | 4748 # Remove false positives: |
4942 # - String pointers (as opposed to values). | 4749 # - String pointers (as opposed to values). |
4943 # string *pointer | 4750 # string *pointer |
4944 # const string *pointer | 4751 # const string *pointer |
4945 # string const *pointer | 4752 # string const *pointer |
4946 # string *const pointer | 4753 # string *const pointer |
4947 # | 4754 # |
4948 # - Functions and template specializations. | 4755 # - Functions and template specializations. |
4949 # string Function<Type>(... | 4756 # string Function<Type>(... |
4950 # string Class<Type>::Method(... | 4757 # string Class<Type>::Method(... |
4951 # | 4758 # |
4952 # - Operators. These are matched separately because operator names | 4759 # - Operators. These are matched separately because operator names |
4953 # cross non-word boundaries, and trying to match both operators | 4760 # cross non-word boundaries, and trying to match both operators |
4954 # and functions at the same time would decrease accuracy of | 4761 # and functions at the same time would decrease accuracy of |
4955 # matching identifiers. | 4762 # matching identifiers. |
4956 # string Class::operator*() | 4763 # string Class::operator*() |
4957 if (match and | 4764 if (match and |
4958 not Search(r'\bstring\b(\s+const)?\s*\*\s*(const\s+)?\w', line) and | 4765 not Search(r'\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w', line) and |
4959 not Search(r'\boperator\W', line) and | 4766 not Search(r'\boperator\W', line) and |
4960 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(3))): | 4767 not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(4))): |
4961 error(filename, linenum, 'runtime/string', 4, | 4768 if Search(r'\bconst\b', line): |
4962 'For a static/global string constant, use a C style string instead: ' | 4769 error(filename, linenum, 'runtime/string', 4, |
4963 '"%schar %s[]".' % | 4770 'For a static/global string constant, use a C style string ' |
4964 (match.group(1), match.group(2))) | 4771 'instead: "%schar%s %s[]".' % |
| 4772 (match.group(1), match.group(2) or '', match.group(3))) |
| 4773 else: |
| 4774 error(filename, linenum, 'runtime/string', 4, |
| 4775 'Static/global string variables are not permitted.') |
4965 | 4776 |
4966 if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line): | 4777 if (Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line) or |
| 4778 Search(r'\b([A-Za-z0-9_]*_)\(CHECK_NOTNULL\(\1\)\)', line)): |
4967 error(filename, linenum, 'runtime/init', 4, | 4779 error(filename, linenum, 'runtime/init', 4, |
4968 'You seem to be initializing a member variable with itself.') | 4780 'You seem to be initializing a member variable with itself.') |
4969 | 4781 |
4970 | 4782 |
4971 def CheckPrintf(filename, clean_lines, linenum, error): | 4783 def CheckPrintf(filename, clean_lines, linenum, error): |
4972 """Check for printf related issues. | 4784 """Check for printf related issues. |
4973 | 4785 |
4974 Args: | 4786 Args: |
4975 filename: The name of the current file. | 4787 filename: The name of the current file. |
4976 clean_lines: A CleansedLines instance containing the file. | 4788 clean_lines: A CleansedLines instance containing the file. |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5201 # Don't see a whitelisted function on this line. Actually we | 5013 # Don't see a whitelisted function on this line. Actually we |
5202 # didn't see any function name on this line, so this is likely a | 5014 # didn't see any function name on this line, so this is likely a |
5203 # multi-line parameter list. Try a bit harder to catch this case. | 5015 # multi-line parameter list. Try a bit harder to catch this case. |
5204 for i in xrange(2): | 5016 for i in xrange(2): |
5205 if (linenum > i and | 5017 if (linenum > i and |
5206 Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): | 5018 Search(whitelisted_functions, clean_lines.elided[linenum - i - 1])): |
5207 return | 5019 return |
5208 | 5020 |
5209 decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body | 5021 decls = ReplaceAll(r'{[^}]*}', ' ', line) # exclude function body |
5210 for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): | 5022 for parameter in re.findall(_RE_PATTERN_REF_PARAM, decls): |
5211 if not Match(_RE_PATTERN_CONST_REF_PARAM, parameter): | 5023 if (not Match(_RE_PATTERN_CONST_REF_PARAM, parameter) and |
| 5024 not Match(_RE_PATTERN_REF_STREAM_PARAM, parameter)): |
5212 error(filename, linenum, 'runtime/references', 2, | 5025 error(filename, linenum, 'runtime/references', 2, |
5213 'Is this a non-const reference? ' | 5026 'Is this a non-const reference? ' |
5214 'If so, make const or use a pointer: ' + | 5027 'If so, make const or use a pointer: ' + |
5215 ReplaceAll(' *<', '<', parameter)) | 5028 ReplaceAll(' *<', '<', parameter)) |
5216 | 5029 |
5217 | 5030 |
5218 def CheckCasts(filename, clean_lines, linenum, error): | 5031 def CheckCasts(filename, clean_lines, linenum, error): |
5219 """Various cast related checks. | 5032 """Various cast related checks. |
5220 | 5033 |
5221 Args: | 5034 Args: |
5222 filename: The name of the current file. | 5035 filename: The name of the current file. |
5223 clean_lines: A CleansedLines instance containing the file. | 5036 clean_lines: A CleansedLines instance containing the file. |
5224 linenum: The number of the line to check. | 5037 linenum: The number of the line to check. |
5225 error: The function to call with any errors found. | 5038 error: The function to call with any errors found. |
5226 """ | 5039 """ |
5227 line = clean_lines.elided[linenum] | 5040 line = clean_lines.elided[linenum] |
5228 | 5041 |
5229 # Check to see if they're using an conversion function cast. | 5042 # Check to see if they're using an conversion function cast. |
5230 # I just try to capture the most common basic types, though there are more. | 5043 # I just try to capture the most common basic types, though there are more. |
5231 # Parameterless conversion functions, such as bool(), are allowed as they are | 5044 # Parameterless conversion functions, such as bool(), are allowed as they are |
5232 # probably a member operator declaration or default constructor. | 5045 # probably a member operator declaration or default constructor. |
5233 match = Search( | 5046 match = Search( |
5234 r'(\bnew\s+|\S<\s*(?:const\s+)?)?\b' | 5047 r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' |
5235 r'(int|float|double|bool|char|int32|uint32|int64|uint64)' | 5048 r'(int|float|double|bool|char|int32|uint32|int64|uint64)' |
5236 r'(\([^)].*)', line) | 5049 r'(\([^)].*)', line) |
5237 expecting_function = ExpectingFunctionArgs(clean_lines, linenum) | 5050 expecting_function = ExpectingFunctionArgs(clean_lines, linenum) |
5238 if match and not expecting_function: | 5051 if match and not expecting_function: |
5239 matched_type = match.group(2) | 5052 matched_type = match.group(2) |
5240 | 5053 |
5241 # matched_new_or_template is used to silence two false positives: | 5054 # matched_new_or_template is used to silence two false positives: |
5242 # - New operators | 5055 # - New operators |
5243 # - Template arguments with function types | 5056 # - Template arguments with function types |
5244 # | 5057 # |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5365 if linenum > 0: | 5178 if linenum > 0: |
5366 for i in xrange(linenum - 1, max(0, linenum - 5), -1): | 5179 for i in xrange(linenum - 1, max(0, linenum - 5), -1): |
5367 context = clean_lines.elided[i] + context | 5180 context = clean_lines.elided[i] + context |
5368 if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): | 5181 if Match(r'.*\b[_A-Z][_A-Z0-9]*\s*\((?:\([^()]*\)|[^()])*$', context): |
5369 return False | 5182 return False |
5370 | 5183 |
5371 # operator++(int) and operator--(int) | 5184 # operator++(int) and operator--(int) |
5372 if context.endswith(' operator++') or context.endswith(' operator--'): | 5185 if context.endswith(' operator++') or context.endswith(' operator--'): |
5373 return False | 5186 return False |
5374 | 5187 |
5375 # A single unnamed argument for a function tends to look like old | 5188 # A single unnamed argument for a function tends to look like old style cast. |
5376 # style cast. If we see those, don't issue warnings for deprecated | 5189 # If we see those, don't issue warnings for deprecated casts. |
5377 # casts, instead issue warnings for unnamed arguments where | |
5378 # appropriate. | |
5379 # | |
5380 # These are things that we want warnings for, since the style guide | |
5381 # explicitly require all parameters to be named: | |
5382 # Function(int); | |
5383 # Function(int) { | |
5384 # ConstMember(int) const; | |
5385 # ConstMember(int) const { | |
5386 # ExceptionMember(int) throw (...); | |
5387 # ExceptionMember(int) throw (...) { | |
5388 # PureVirtual(int) = 0; | |
5389 # [](int) -> bool { | |
5390 # | |
5391 # These are functions of some sort, where the compiler would be fine | |
5392 # if they had named parameters, but people often omit those | |
5393 # identifiers to reduce clutter: | |
5394 # (FunctionPointer)(int); | |
5395 # (FunctionPointer)(int) = value; | |
5396 # Function((function_pointer_arg)(int)) | |
5397 # Function((function_pointer_arg)(int), int param) | |
5398 # <TemplateArgument(int)>; | |
5399 # <(FunctionPointerTemplateArgument)(int)>; | |
5400 remainder = line[match.end(0):] | 5190 remainder = line[match.end(0):] |
5401 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', | 5191 if Match(r'^\s*(?:;|const\b|throw\b|final\b|override\b|[=>{),]|->)', |
5402 remainder): | 5192 remainder): |
5403 # Looks like an unnamed parameter. | 5193 return False |
5404 | |
5405 # Don't warn on any kind of template arguments. | |
5406 if Match(r'^\s*>', remainder): | |
5407 return False | |
5408 | |
5409 # Don't warn on assignments to function pointers, but keep warnings for | |
5410 # unnamed parameters to pure virtual functions. Note that this pattern | |
5411 # will also pass on assignments of "0" to function pointers, but the | |
5412 # preferred values for those would be "nullptr" or "NULL". | |
5413 matched_zero = Match(r'^\s=\s*(\S+)\s*;', remainder) | |
5414 if matched_zero and matched_zero.group(1) != '0': | |
5415 return False | |
5416 | |
5417 # Don't warn on function pointer declarations. For this we need | |
5418 # to check what came before the "(type)" string. | |
5419 if Match(r'.*\)\s*$', line[0:match.start(0)]): | |
5420 return False | |
5421 | |
5422 # Don't warn if the parameter is named with block comments, e.g.: | |
5423 # Function(int /*unused_param*/); | |
5424 raw_line = clean_lines.raw_lines[linenum] | |
5425 if '/*' in raw_line: | |
5426 return False | |
5427 | |
5428 # Passed all filters, issue warning here. | |
5429 error(filename, linenum, 'readability/function', 3, | |
5430 'All parameters should be named in a function') | |
5431 return True | |
5432 | 5194 |
5433 # At this point, all that should be left is actual casts. | 5195 # At this point, all that should be left is actual casts. |
5434 error(filename, linenum, 'readability/casting', 4, | 5196 error(filename, linenum, 'readability/casting', 4, |
5435 'Using C-style cast. Use %s<%s>(...) instead' % | 5197 'Using C-style cast. Use %s<%s>(...) instead' % |
5436 (cast_type, match.group(1))) | 5198 (cast_type, match.group(1))) |
5437 | 5199 |
5438 return True | 5200 return True |
5439 | 5201 |
5440 | 5202 |
5441 def ExpectingFunctionArgs(clean_lines, linenum): | 5203 def ExpectingFunctionArgs(clean_lines, linenum): |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5550 Args: | 5312 Args: |
5551 filename_cc: is the path for the .cc file | 5313 filename_cc: is the path for the .cc file |
5552 filename_h: is the path for the header path | 5314 filename_h: is the path for the header path |
5553 | 5315 |
5554 Returns: | 5316 Returns: |
5555 Tuple with a bool and a string: | 5317 Tuple with a bool and a string: |
5556 bool: True if filename_cc and filename_h belong to the same module. | 5318 bool: True if filename_cc and filename_h belong to the same module. |
5557 string: the additional prefix needed to open the header file. | 5319 string: the additional prefix needed to open the header file. |
5558 """ | 5320 """ |
5559 | 5321 |
5560 if not filename_cc.endswith('.cc'): | 5322 fileinfo = FileInfo(filename_cc) |
| 5323 if not fileinfo.IsSource(): |
5561 return (False, '') | 5324 return (False, '') |
5562 filename_cc = filename_cc[:-len('.cc')] | 5325 filename_cc = filename_cc[:-len(fileinfo.Extension())] |
5563 if filename_cc.endswith('_unittest'): | 5326 matched_test_suffix = Search(_TEST_FILE_SUFFIX, fileinfo.BaseName()) |
5564 filename_cc = filename_cc[:-len('_unittest')] | 5327 if matched_test_suffix: |
5565 elif filename_cc.endswith('_test'): | 5328 filename_cc = filename_cc[:-len(matched_test_suffix.group(1))] |
5566 filename_cc = filename_cc[:-len('_test')] | |
5567 filename_cc = filename_cc.replace('/public/', '/') | 5329 filename_cc = filename_cc.replace('/public/', '/') |
5568 filename_cc = filename_cc.replace('/internal/', '/') | 5330 filename_cc = filename_cc.replace('/internal/', '/') |
5569 | 5331 |
5570 if not filename_h.endswith('.h'): | 5332 if not filename_h.endswith('.h'): |
5571 return (False, '') | 5333 return (False, '') |
5572 filename_h = filename_h[:-len('.h')] | 5334 filename_h = filename_h[:-len('.h')] |
5573 if filename_h.endswith('-inl'): | 5335 if filename_h.endswith('-inl'): |
5574 filename_h = filename_h[:-len('-inl')] | 5336 filename_h = filename_h[:-len('-inl')] |
5575 filename_h = filename_h.replace('/public/', '/') | 5337 filename_h = filename_h.replace('/public/', '/') |
5576 filename_h = filename_h.replace('/internal/', '/') | 5338 filename_h = filename_h.replace('/internal/', '/') |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5720 """ | 5482 """ |
5721 line = clean_lines.elided[linenum] | 5483 line = clean_lines.elided[linenum] |
5722 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) | 5484 match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line) |
5723 if match: | 5485 if match: |
5724 error(filename, linenum, 'build/explicit_make_pair', | 5486 error(filename, linenum, 'build/explicit_make_pair', |
5725 4, # 4 = high confidence | 5487 4, # 4 = high confidence |
5726 'For C++11-compatibility, omit template arguments from make_pair' | 5488 'For C++11-compatibility, omit template arguments from make_pair' |
5727 ' OR use pair directly OR if appropriate, construct a pair directly') | 5489 ' OR use pair directly OR if appropriate, construct a pair directly') |
5728 | 5490 |
5729 | 5491 |
5730 def CheckDefaultLambdaCaptures(filename, clean_lines, linenum, error): | |
5731 """Check that default lambda captures are not used. | |
5732 | |
5733 Args: | |
5734 filename: The name of the current file. | |
5735 clean_lines: A CleansedLines instance containing the file. | |
5736 linenum: The number of the line to check. | |
5737 error: The function to call with any errors found. | |
5738 """ | |
5739 line = clean_lines.elided[linenum] | |
5740 | |
5741 # A lambda introducer specifies a default capture if it starts with "[=" | |
5742 # or if it starts with "[&" _not_ followed by an identifier. | |
5743 match = Match(r'^(.*)\[\s*(?:=|&[^\w])', line) | |
5744 if match: | |
5745 # Found a potential error, check what comes after the lambda-introducer. | |
5746 # If it's not open parenthesis (for lambda-declarator) or open brace | |
5747 # (for compound-statement), it's not a lambda. | |
5748 line, _, pos = CloseExpression(clean_lines, linenum, len(match.group(1))) | |
5749 if pos >= 0 and Match(r'^\s*[{(]', line[pos:]): | |
5750 error(filename, linenum, 'build/c++11', | |
5751 4, # 4 = high confidence | |
5752 'Default lambda captures are an unapproved C++ feature.') | |
5753 | |
5754 | |
5755 def CheckRedundantVirtual(filename, clean_lines, linenum, error): | 5492 def CheckRedundantVirtual(filename, clean_lines, linenum, error): |
5756 """Check if line contains a redundant "virtual" function-specifier. | 5493 """Check if line contains a redundant "virtual" function-specifier. |
5757 | 5494 |
5758 Args: | 5495 Args: |
5759 filename: The name of the current file. | 5496 filename: The name of the current file. |
5760 clean_lines: A CleansedLines instance containing the file. | 5497 clean_lines: A CleansedLines instance containing the file. |
5761 linenum: The number of the line to check. | 5498 linenum: The number of the line to check. |
5762 error: The function to call with any errors found. | 5499 error: The function to call with any errors found. |
5763 """ | 5500 """ |
5764 # Look for "virtual" on current line. | 5501 # Look for "virtual" on current line. |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5943 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) | 5680 CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error) |
5944 CheckLanguage(filename, clean_lines, line, file_extension, include_state, | 5681 CheckLanguage(filename, clean_lines, line, file_extension, include_state, |
5945 nesting_state, error) | 5682 nesting_state, error) |
5946 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) | 5683 CheckForNonConstReference(filename, clean_lines, line, nesting_state, error) |
5947 CheckForNonStandardConstructs(filename, clean_lines, line, | 5684 CheckForNonStandardConstructs(filename, clean_lines, line, |
5948 nesting_state, error) | 5685 nesting_state, error) |
5949 CheckVlogArguments(filename, clean_lines, line, error) | 5686 CheckVlogArguments(filename, clean_lines, line, error) |
5950 CheckPosixThreading(filename, clean_lines, line, error) | 5687 CheckPosixThreading(filename, clean_lines, line, error) |
5951 CheckInvalidIncrement(filename, clean_lines, line, error) | 5688 CheckInvalidIncrement(filename, clean_lines, line, error) |
5952 CheckMakePairUsesDeduction(filename, clean_lines, line, error) | 5689 CheckMakePairUsesDeduction(filename, clean_lines, line, error) |
5953 CheckDefaultLambdaCaptures(filename, clean_lines, line, error) | |
5954 CheckRedundantVirtual(filename, clean_lines, line, error) | 5690 CheckRedundantVirtual(filename, clean_lines, line, error) |
5955 CheckRedundantOverrideOrFinal(filename, clean_lines, line, error) | 5691 CheckRedundantOverrideOrFinal(filename, clean_lines, line, error) |
5956 for check_fn in extra_check_functions: | 5692 for check_fn in extra_check_functions: |
5957 check_fn(filename, clean_lines, line, error) | 5693 check_fn(filename, clean_lines, line, error) |
5958 | 5694 |
5959 def FlagCxx11Features(filename, clean_lines, linenum, error): | 5695 def FlagCxx11Features(filename, clean_lines, linenum, error): |
5960 """Flag those c++11 features that we only allow in certain places. | 5696 """Flag those c++11 features that we only allow in certain places. |
5961 | 5697 |
5962 Args: | 5698 Args: |
5963 filename: The name of the current file. | 5699 filename: The name of the current file. |
5964 clean_lines: A CleansedLines instance containing the file. | 5700 clean_lines: A CleansedLines instance containing the file. |
5965 linenum: The number of the line to check. | 5701 linenum: The number of the line to check. |
5966 error: The function to call with any errors found. | 5702 error: The function to call with any errors found. |
5967 """ | 5703 """ |
5968 line = clean_lines.elided[linenum] | 5704 line = clean_lines.elided[linenum] |
5969 | 5705 |
| 5706 include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) |
| 5707 |
| 5708 # Flag unapproved C++ TR1 headers. |
| 5709 if include and include.group(1).startswith('tr1/'): |
| 5710 error(filename, linenum, 'build/c++tr1', 5, |
| 5711 ('C++ TR1 headers such as <%s> are unapproved.') % include.group(1)) |
| 5712 |
5970 # Flag unapproved C++11 headers. | 5713 # Flag unapproved C++11 headers. |
5971 include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) | |
5972 if include and include.group(1) in ('cfenv', | 5714 if include and include.group(1) in ('cfenv', |
5973 'condition_variable', | 5715 'condition_variable', |
5974 'fenv.h', | 5716 'fenv.h', |
5975 'future', | 5717 'future', |
5976 'mutex', | 5718 'mutex', |
5977 'thread', | 5719 'thread', |
5978 'chrono', | 5720 'chrono', |
5979 'ratio', | 5721 'ratio', |
5980 'regex', | 5722 'regex', |
5981 'system_error', | 5723 'system_error', |
(...skipping 13 matching lines...) Expand all Loading... |
5995 'alignment_of', | 5737 'alignment_of', |
5996 'aligned_union', | 5738 'aligned_union', |
5997 ): | 5739 ): |
5998 if Search(r'\bstd::%s\b' % top_name, line): | 5740 if Search(r'\bstd::%s\b' % top_name, line): |
5999 error(filename, linenum, 'build/c++11', 5, | 5741 error(filename, linenum, 'build/c++11', 5, |
6000 ('std::%s is an unapproved C++11 class or function. Send c-style ' | 5742 ('std::%s is an unapproved C++11 class or function. Send c-style ' |
6001 'an example of where it would make your code more readable, and ' | 5743 'an example of where it would make your code more readable, and ' |
6002 'they may let you use it.') % top_name) | 5744 'they may let you use it.') % top_name) |
6003 | 5745 |
6004 | 5746 |
| 5747 def FlagCxx14Features(filename, clean_lines, linenum, error): |
| 5748 """Flag those C++14 features that we restrict. |
| 5749 |
| 5750 Args: |
| 5751 filename: The name of the current file. |
| 5752 clean_lines: A CleansedLines instance containing the file. |
| 5753 linenum: The number of the line to check. |
| 5754 error: The function to call with any errors found. |
| 5755 """ |
| 5756 line = clean_lines.elided[linenum] |
| 5757 |
| 5758 include = Match(r'\s*#\s*include\s+[<"]([^<"]+)[">]', line) |
| 5759 |
| 5760 # Flag unapproved C++14 headers. |
| 5761 if include and include.group(1) in ('scoped_allocator', 'shared_mutex'): |
| 5762 error(filename, linenum, 'build/c++14', 5, |
| 5763 ('<%s> is an unapproved C++14 header.') % include.group(1)) |
| 5764 |
| 5765 |
6005 def ProcessFileData(filename, file_extension, lines, error, | 5766 def ProcessFileData(filename, file_extension, lines, error, |
6006 extra_check_functions=[]): | 5767 extra_check_functions=[]): |
6007 """Performs lint checks and reports any errors to the given error function. | 5768 """Performs lint checks and reports any errors to the given error function. |
6008 | 5769 |
6009 Args: | 5770 Args: |
6010 filename: Filename of the file that is being processed. | 5771 filename: Filename of the file that is being processed. |
6011 file_extension: The extension (dot not included) of the file. | 5772 file_extension: The extension (dot not included) of the file. |
6012 lines: An array of strings, each representing a line of the file, with the | 5773 lines: An array of strings, each representing a line of the file, with the |
6013 last element being empty if the file is terminated with a newline. | 5774 last element being empty if the file is terminated with a newline. |
6014 error: A callable to which errors are reported, which takes 4 arguments: | 5775 error: A callable to which errors are reported, which takes 4 arguments: |
6015 filename, line number, error level, and message | 5776 filename, line number, error level, and message |
6016 extra_check_functions: An array of additional check functions that will be | 5777 extra_check_functions: An array of additional check functions that will be |
6017 run on each source line. Each function takes 4 | 5778 run on each source line. Each function takes 4 |
6018 arguments: filename, clean_lines, line, error | 5779 arguments: filename, clean_lines, line, error |
6019 """ | 5780 """ |
6020 lines = (['// marker so line numbers and indices both start at 1'] + lines + | 5781 lines = (['// marker so line numbers and indices both start at 1'] + lines + |
6021 ['// marker so line numbers end in a known way']) | 5782 ['// marker so line numbers end in a known way']) |
6022 | 5783 |
6023 include_state = _IncludeState() | 5784 include_state = _IncludeState() |
6024 function_state = _FunctionState() | 5785 function_state = _FunctionState() |
6025 nesting_state = NestingState() | 5786 nesting_state = NestingState() |
6026 | 5787 |
6027 ResetNolintSuppressions() | 5788 ResetNolintSuppressions() |
6028 | 5789 |
6029 CheckForCopyright(filename, lines, error) | 5790 CheckForCopyright(filename, lines, error) |
6030 | 5791 ProcessGlobalSuppresions(lines) |
6031 RemoveMultiLineComments(filename, lines, error) | 5792 RemoveMultiLineComments(filename, lines, error) |
6032 clean_lines = CleansedLines(lines) | 5793 clean_lines = CleansedLines(lines) |
6033 | 5794 |
6034 if file_extension == 'h': | 5795 if file_extension == 'h': |
6035 CheckForHeaderGuard(filename, clean_lines, error) | 5796 CheckForHeaderGuard(filename, clean_lines, error) |
6036 | 5797 |
6037 for line in xrange(clean_lines.NumLines()): | 5798 for line in xrange(clean_lines.NumLines()): |
6038 ProcessLine(filename, file_extension, clean_lines, line, | 5799 ProcessLine(filename, file_extension, clean_lines, line, |
6039 include_state, function_state, nesting_state, error, | 5800 include_state, function_state, nesting_state, error, |
6040 extra_check_functions) | 5801 extra_check_functions) |
6041 FlagCxx11Features(filename, clean_lines, line, error) | 5802 FlagCxx11Features(filename, clean_lines, line, error) |
6042 nesting_state.CheckCompletedBlocks(filename, error) | 5803 nesting_state.CheckCompletedBlocks(filename, error) |
6043 | 5804 |
6044 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) | 5805 CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error) |
6045 | 5806 |
6046 # Check that the .cc file has included its header if it exists. | 5807 # Check that the .cc file has included its header if it exists. |
6047 if file_extension == 'cc': | 5808 if _IsSourceExtension(file_extension): |
6048 CheckHeaderFileIncluded(filename, include_state, error) | 5809 CheckHeaderFileIncluded(filename, include_state, error) |
6049 | 5810 |
6050 # We check here rather than inside ProcessLine so that we see raw | 5811 # We check here rather than inside ProcessLine so that we see raw |
6051 # lines rather than "cleaned" lines. | 5812 # lines rather than "cleaned" lines. |
6052 CheckForBadCharacters(filename, lines, error) | 5813 CheckForBadCharacters(filename, lines, error) |
6053 | 5814 |
6054 CheckForNewlineAtEOF(filename, lines, error) | 5815 CheckForNewlineAtEOF(filename, lines, error) |
6055 | 5816 |
6056 def ProcessConfigOverrides(filename): | 5817 def ProcessConfigOverrides(filename): |
6057 """ Loads the configuration files and processes the config overrides. | 5818 """ Loads the configuration files and processes the config overrides. |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6322 _cpplint_state.ResetErrorCounts() | 6083 _cpplint_state.ResetErrorCounts() |
6323 for filename in filenames: | 6084 for filename in filenames: |
6324 ProcessFile(filename, _cpplint_state.verbose_level) | 6085 ProcessFile(filename, _cpplint_state.verbose_level) |
6325 _cpplint_state.PrintErrorCounts() | 6086 _cpplint_state.PrintErrorCounts() |
6326 | 6087 |
6327 sys.exit(_cpplint_state.error_count > 0) | 6088 sys.exit(_cpplint_state.error_count > 0) |
6328 | 6089 |
6329 | 6090 |
6330 if __name__ == '__main__': | 6091 if __name__ == '__main__': |
6331 main() | 6092 main() |
OLD | NEW |