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

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: Code review (maruel) 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:05:14 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INC
marja 2012/11/13 18:12:48 Done.
521 C_SYSTEM_INCLUDES = 1
522 CPP_SYSTEM_INCLUCES = 2
523 CUSTOM_INCLUDES = 3
524
525 state = State.C_SYSTEM_INCLUDES
526
527 previous_line = ''
528 problem_linenums = []
529 for line_num, line in scope:
530 if c_system_include_pattern.match(line):
531 if state != State.C_SYSTEM_INCLUDES:
532 problem_linenums.append(line_num)
533 elif previous_line and previous_line > line:
534 problem_linenums.append(line_num)
535 elif cpp_system_include_pattern.match(line):
536 if state == State.C_SYSTEM_INCLUDES:
537 state = State.CPP_SYSTEM_INCLUDES
538 elif state == State.CUSTOM_INCLUDES:
539 problem_linenums.append(line_num)
540 elif previous_line and previous_line > line:
541 problem_linenums.append(line_num)
542 elif custom_include_pattern.match(line):
543 if state != State.CUSTOM_INCLUDES:
544 state = State.CUSTOM_INCLUDES
545 elif previous_line and previous_line > line:
546 problem_linenums.append(line_num)
547 else:
548 problem_linenums.append(line_num)
549 previous_line = line
550
551 warnings = []
552 for line_num in problem_linenums:
553 if line_num in changed_linenums or line_num - 1 in changed_linenums:
554 warnings.append(' %s:%d' % (file_path, line_num))
555 return warnings
556
557
558 def _CheckIncludeOrderInFile(input_api, output_api, f, is_source,
559 changed_linenums):
560 """Checks the #include order for the given file f."""
561
562 include_pattern = input_api.re.compile(r'\s*#include.*')
563 if_pattern = input_api.re.compile(r'\s*#if.*')
564 endif_pattern = input_api.re.compile(r'\s*#endif.*')
565
566 contents = f.NewContents()
567 warnings = []
568 line_num = 0
569
570 # Handle the special first include for source files.
571 if is_source:
572 for line in contents:
573 line_num += 1
574 if include_pattern.match(line):
575 wanted_line = ('#include "%s"' % f.LocalPath().replace('.cc', '.h'))
576 if line != wanted_line:
577 # Maybe there was no special first include, and that's fine. Process
578 # the line again along with the normal includes.
579 line_num -= 1
580 break
581
582 # Split into scopes: Each region between #if and #endif is its own scope.
583 scopes = []
584 current_scope = []
585 for line in contents[line_num:]:
586 line_num += 1
587 if if_pattern.match(line) or endif_pattern.match(line):
588 scopes.append(current_scope)
589 current_scope = []
590 elif include_pattern.match(line):
591 current_scope.append((line_num, line))
592 scopes.append(current_scope)
593
594 for scope in scopes:
595 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
596 changed_linenums))
597 return warnings
598
599
600 def _CheckIncludeOrder(input_api, output_api):
601 """Checks that the #include order is correct.
602
603 1. The corresponding header for source files.
604 2. C system files in alphabetical order
605 3. C++ system files in alphabetical order
606 4. Project's .h files in alphabetical order
607
608 Each region between #if and #endif follows these rules separately.
609 """
610
611 warnings = []
612 for f in input_api.AffectedFiles():
613 changed_linenums = set([line_num for line_num, _ in f.ChangedContents()])
614 if f.LocalPath().endswith('.cc'):
615 warnings = _CheckIncludeOrderInFile(input_api, output_api, f, True,
616 changed_linenums)
617 elif f.LocalPath().endswith('.h'):
618 warnings = _CheckIncludeOrderInFile(input_api, output_api, f, False,
619 changed_linenums)
620
621 results = []
622 if warnings:
623 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING,
624 warnings))
625 return results
626
627
503 def _CommonChecks(input_api, output_api): 628 def _CommonChecks(input_api, output_api):
504 """Checks common to both upload and commit.""" 629 """Checks common to both upload and commit."""
505 results = [] 630 results = []
506 results.extend(input_api.canned_checks.PanProjectChecks( 631 results.extend(input_api.canned_checks.PanProjectChecks(
507 input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) 632 input_api, output_api, excluded_paths=_EXCLUDED_PATHS))
508 results.extend(_CheckAuthorizedAuthor(input_api, output_api)) 633 results.extend(_CheckAuthorizedAuthor(input_api, output_api))
509 results.extend( 634 results.extend(
510 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) 635 _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api))
511 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api)) 636 results.extend(_CheckNoIOStreamInHeaders(input_api, output_api))
512 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api)) 637 results.extend(_CheckNoUNIT_TESTInSourceFiles(input_api, output_api))
513 results.extend(_CheckNoNewWStrings(input_api, output_api)) 638 results.extend(_CheckNoNewWStrings(input_api, output_api))
514 results.extend(_CheckNoDEPSGIT(input_api, output_api)) 639 results.extend(_CheckNoDEPSGIT(input_api, output_api))
515 results.extend(_CheckNoBannedFunctions(input_api, output_api)) 640 results.extend(_CheckNoBannedFunctions(input_api, output_api))
516 results.extend(_CheckNoPragmaOnce(input_api, output_api)) 641 results.extend(_CheckNoPragmaOnce(input_api, output_api))
517 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api)) 642 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
518 results.extend(_CheckUnwantedDependencies(input_api, output_api)) 643 results.extend(_CheckUnwantedDependencies(input_api, output_api))
519 results.extend(_CheckFilePermissions(input_api, output_api)) 644 results.extend(_CheckFilePermissions(input_api, output_api))
520 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) 645 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
646 results.extend(_CheckIncludeOrder(input_api, output_api))
521 return results 647 return results
522 648
523 649
524 def _CheckSubversionConfig(input_api, output_api): 650 def _CheckSubversionConfig(input_api, output_api):
525 """Verifies the subversion config file is correctly setup. 651 """Verifies the subversion config file is correctly setup.
526 652
527 Checks that autoprops are enabled, returns an error otherwise. 653 Checks that autoprops are enabled, returns an error otherwise.
528 """ 654 """
529 join = input_api.os_path.join 655 join = input_api.os_path.join
530 if input_api.platform == 'win32': 656 if input_api.platform == 'win32':
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 784
659 # Match things like path/aura/file.cc and path/file_aura.cc. 785 # Match things like path/aura/file.cc and path/file_aura.cc.
660 # Same for ash and chromeos. 786 # Same for ash and chromeos.
661 if any(re.search('[/_](ash|aura)', f) for f in files): 787 if any(re.search('[/_](ash|aura)', f) for f in files):
662 trybots += ['linux_chromeos_clang:compile', 'win_aura', 788 trybots += ['linux_chromeos_clang:compile', 'win_aura',
663 'linux_chromeos_asan'] 789 'linux_chromeos_asan']
664 elif any(re.search('[/_]chromeos', f) for f in files): 790 elif any(re.search('[/_]chromeos', f) for f in files):
665 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan'] 791 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan']
666 792
667 return trybots 793 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