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

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