Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: PRESUBMIT.py

Issue 11364156: PRESUBMIT.py: Check #include file order. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix (oops) & code review Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Top-level presubmit script for Chromium. 5 """Top-level presubmit script for Chromium.
6 6
7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts 7 See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
8 for more details about the presubmit API built into gcl. 8 for more details about the presubmit API built into gcl.
9 """ 9 """
10 10
(...skipping 19 matching lines...) Expand all
30 30
31 31
32 _TEST_ONLY_WARNING = ( 32 _TEST_ONLY_WARNING = (
33 'You might be calling functions intended only for testing from\n' 33 'You might be calling functions intended only for testing from\n'
34 'production code. It is OK to ignore this warning if you know what\n' 34 'production code. It is OK to ignore this warning if you know what\n'
35 'you are doing, as the heuristics used to detect the situation are\n' 35 'you are doing, as the heuristics used to detect the situation are\n'
36 'not perfect. The commit queue will not block on this warning.\n' 36 'not perfect. The commit queue will not block on this warning.\n'
37 'Email [email protected] if you have questions.') 37 'Email [email protected] if you have questions.')
38 38
39 39
40 _INCLUDE_ORDER_WARNING = (
41 'Your #include order seems to be broken. Send mail to\n'
42 '[email protected] if this is not the case.')
43
44
40 _BANNED_OBJC_FUNCTIONS = ( 45 _BANNED_OBJC_FUNCTIONS = (
41 ( 46 (
42 'addTrackingRect:', 47 'addTrackingRect:',
43 ( 48 (
44 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is' 49 'The use of -[NSView addTrackingRect:owner:userData:assumeInside:] is'
45 'prohibited. Please use CrTrackingArea instead.', 50 'prohibited. Please use CrTrackingArea instead.',
46 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts', 51 'http://dev.chromium.org/developers/coding-style/cocoa-dos-and-donts',
47 ), 52 ),
48 False, 53 False,
49 ), 54 ),
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 if pattern.match(line): 498 if pattern.match(line):
494 errors.append(' %s:%d' % (f.LocalPath(), line_num)) 499 errors.append(' %s:%d' % (f.LocalPath(), line_num))
495 500
496 results = [] 501 results = []
497 if errors: 502 if errors:
498 results.append(output_api.PresubmitError( 503 results.append(output_api.PresubmitError(
499 'Header files should not include ui/aura/window_property.h', errors)) 504 'Header files should not include ui/aura/window_property.h', errors))
500 return results 505 return results
501 506
502 507
508 def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
509 """Checks that the lines in scope occur in the right order.
510
511 1. C system files in alphabetical order
512 2. C++ system files in alphabetical order
513 3. Project's .h files
514 """
515
516 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
517 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
518 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
519
520 class State:
M-A Ruel 2012/11/13 18:18:01 No need for class State at all. It'll make the cod
marja 2012/11/13 18:24:56 Done.
521 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
522
523 state = State.C_SYSTEM_INCLUDES
524
525 previous_line = ''
526 problem_linenums = []
527 for line_num, line in scope:
528 if c_system_include_pattern.match(line):
529 if state != State.C_SYSTEM_INCLUDES:
530 problem_linenums.append(line_num)
531 elif previous_line and previous_line > line:
532 problem_linenums.append(line_num)
533 elif cpp_system_include_pattern.match(line):
534 if state == State.C_SYSTEM_INCLUDES:
535 state = State.CPP_SYSTEM_INCLUDES
536 elif state == State.CUSTOM_INCLUDES:
537 problem_linenums.append(line_num)
538 elif previous_line and previous_line > line:
539 problem_linenums.append(line_num)
540 elif custom_include_pattern.match(line):
541 if state != State.CUSTOM_INCLUDES:
542 state = State.CUSTOM_INCLUDES
543 elif previous_line and previous_line > line:
544 problem_linenums.append(line_num)
545 else:
546 problem_linenums.append(line_num)
547 previous_line = line
548
549 warnings = []
550 for line_num in problem_linenums:
551 if line_num in changed_linenums or line_num - 1 in changed_linenums:
552 warnings.append(' %s:%d' % (file_path, line_num))
553 return warnings
554
555
556 def _CheckIncludeOrderInFile(input_api, output_api, f, is_source,
557 changed_linenums):
558 """Checks the #include order for the given file f."""
559
560 include_pattern = input_api.re.compile(r'\s*#include.*')
561 if_pattern = input_api.re.compile(r'\s*#if.*')
562 endif_pattern = input_api.re.compile(r'\s*#endif.*')
563
564 contents = f.NewContents()
565 warnings = []
566 line_num = 0
567
568 # Handle the special first include for source files.
569 if is_source:
570 for line in contents:
571 line_num += 1
572 if include_pattern.match(line):
573 wanted_line = ('#include "%s"' % f.LocalPath().replace('.cc', '.h'))
M-A Ruel 2012/11/13 18:18:01 expected = '#include "%s"' % f.LocalPath().replace
marja 2012/11/13 18:24:56 Done.
574 if line != wanted_line:
575 # Maybe there was no special first include, and that's fine. Process
576 # the line again along with the normal includes.
577 line_num -= 1
578 break
579
580 # Split into scopes: Each region between #if and #endif is its own scope.
581 scopes = []
582 current_scope = []
583 for line in contents[line_num:]:
584 line_num += 1
585 if if_pattern.match(line) or endif_pattern.match(line):
586 scopes.append(current_scope)
587 current_scope = []
588 elif include_pattern.match(line):
589 current_scope.append((line_num, line))
590 scopes.append(current_scope)
591
592 for scope in scopes:
593 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
594 changed_linenums))
595 return warnings
596
597
598 def _CheckIncludeOrder(input_api, output_api):
599 """Checks that the #include order is correct.
600
601 1. The corresponding header for source files.
602 2. C system files in alphabetical order
603 3. C++ system files in alphabetical order
604 4. Project's .h files in alphabetical order
605
606 Each region between #if and #endif follows these rules separately.
607 """
608
609 warnings = []
610 for f in input_api.AffectedFiles():
611 changed_linenums = set([line_num for line_num, _ in f.ChangedContents()])
612 if f.LocalPath().endswith('.cc'):
613 warnings = _CheckIncludeOrderInFile(input_api, output_api, f, True,
614 changed_linenums)
615 elif f.LocalPath().endswith('.h'):
616 warnings = _CheckIncludeOrderInFile(input_api, output_api, f, False,
617 changed_linenums)
618
619 results = []
620 if warnings:
621 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING,
622 warnings))
623 return results
624
625
503 def _CommonChecks(input_api, output_api): 626 def _CommonChecks(input_api, output_api):
504 """Checks common to both upload and commit.""" 627 """Checks common to both upload and commit."""
505 results = [] 628 results = []
506 results.extend(input_api.canned_checks.PanProjectChecks( 629 results.extend(input_api.canned_checks.PanProjectChecks(
507 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) 630 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
508 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) 631 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
509 results.extend( 632 results.extend(
510 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) 633 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
511 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) 634 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
512 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api)) 635 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
513 results.extend(_CheckNoNewWStrings(input_api, output_api)) 636 results.extend(_CheckNoNewWStrings(input_api, output_api))
514 results.extend(_CheckNoDEPSGIT(input_api, output_api)) 637 results.extend(_CheckNoDEPSGIT(input_api, output_api))
515 results.extend(_CheckNoBannedFunctions(input_api, output_api)) 638 results.extend(_CheckNoBannedFunctions(input_api, output_api))
516 results.extend(_CheckNoPragmaOnce(input_api, output_api)) 639 results.extend(_CheckNoPragmaOnce(input_api, output_api))
517 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api)) 640 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
518 results.extend(_CheckUnwantedDependencies(input_api, output_api)) 641 results.extend(_CheckUnwantedDependencies(input_api, output_api))
519 results.extend(_CheckFilePermissions(input_api, output_api)) 642 results.extend(_CheckFilePermissions(input_api, output_api))
520 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) 643 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
644 results.extend(_CheckIncludeOrder(input_api, output_api))
521 return results 645 return results
522 646
523 647
524 def _CheckSubversionConfig(input_api, output_api): 648 def _CheckSubversionConfig(input_api, output_api):
525 """Verifies the subversion config file is correctly setup. 649 """Verifies the subversion config file is correctly setup.
526 650
527 Checks that autoprops are enabled, returns an error otherwise. 651 Checks that autoprops are enabled, returns an error otherwise.
528 """ 652 """
529 join = input_api.os_path.join 653 join = input_api.os_path.join
530 if input_api.platform == 'win32': 654 if input_api.platform == 'win32':
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 782
659 # Match things like path/aura/file.cc and path/file_aura.cc. 783 # Match things like path/aura/file.cc and path/file_aura.cc.
660 # Same for ash and chromeos. 784 # Same for ash and chromeos.
661 if any(re.search('[/_](ash|aura)', f) for f in files): 785 if any(re.search('[/_](ash|aura)', f) for f in files):
662 trybots += ['linux_chromeos_clang:compile', 'win_aura', 786 trybots += ['linux_chromeos_clang:compile', 'win_aura',
663 'linux_chromeos_asan'] 787 'linux_chromeos_asan']
664 elif any(re.search('[/_]chromeos', f) for f in files): 788 elif any(re.search('[/_]chromeos', f) for f in files):
665 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan'] 789 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan']
666 790
667 return trybots 791 return trybots
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698