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

Side by Side Diff: PRESUBMIT.py

Issue 2598173002: Add a Presubmit to check if a file must be included or imported.
Patch Set: feedback Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | PRESUBMIT_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # 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 depot_tools. 8 for more details about the presubmit API built into depot_tools.
9 """ 9 """
10 10
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 ) 51 )
52 52
53 53
54 _TEST_ONLY_WARNING = ( 54 _TEST_ONLY_WARNING = (
55 'You might be calling functions intended only for testing from\n' 55 'You might be calling functions intended only for testing from\n'
56 'production code. It is OK to ignore this warning if you know what\n' 56 'production code. It is OK to ignore this warning if you know what\n'
57 'you are doing, as the heuristics used to detect the situation are\n' 57 'you are doing, as the heuristics used to detect the situation are\n'
58 'not perfect. The commit queue will not block on this warning.') 58 'not perfect. The commit queue will not block on this warning.')
59 59
60 60
61 _INCLUDE_IMPORT_WARNING = (
62 'You are including ObjC headers or importing C++ headers. Remember to use '
63 'the right #include/#import directive.')
64
65
61 _INCLUDE_ORDER_WARNING = ( 66 _INCLUDE_ORDER_WARNING = (
62 'Your #include order seems to be broken. Remember to use the right ' 67 'Your #include order seems to be broken. Remember to use the right '
63 'collation (LC_COLLATE=C) and check\nhttps://google.github.io/styleguide/' 68 'collation (LC_COLLATE=C) and check\nhttps://google.github.io/styleguide/'
64 'cppguide.html#Names_and_Order_of_Includes') 69 'cppguide.html#Names_and_Order_of_Includes')
65 70
66 71
67 _BANNED_OBJC_FUNCTIONS = ( 72 _BANNED_OBJC_FUNCTIONS = (
68 ( 73 (
69 'addTrackingRect:', 74 'addTrackingRect:',
70 ( 75 (
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 if pattern.match(line): 788 if pattern.match(line):
784 errors.append(' %s:%d' % (f.LocalPath(), line_num)) 789 errors.append(' %s:%d' % (f.LocalPath(), line_num))
785 790
786 results = [] 791 results = []
787 if errors: 792 if errors:
788 results.append(output_api.PresubmitError( 793 results.append(output_api.PresubmitError(
789 'Header files should not include ui/aura/window_property.h', errors)) 794 'Header files should not include ui/aura/window_property.h', errors))
790 return results 795 return results
791 796
792 797
798 def _CheckHeaderIsObjectiveC(input_api, included_file, included_file_content):
799 """Checks if f is a C++ or an Objective-C header.
800
801 An Objective-C header is a header with a line starting with
802 - #import
803 - @class
804 - @interface
805 - @implementation
806 - @protocol
807 - @end
808
809 or with the two lines
810 #if !defined(__OBJC__)
811 #error ...
812
813 Returns a pair of booleans.
814 - First is true if the determination of Objective-C could be done without
815 error
816 - Second is true if the file has been determined as Objective-C header.
817 """
818 file_path_ios_mac_pattern = input_api.re.compile(
819 r'(?:.*[_./])?(?:ios|mac)[_./].*')
820 if not file_path_ios_mac_pattern.match(included_file):
821 return (False, False)
822 guard_noobjc_pattern = input_api.re.compile(
823 r'\s*#if !defined\(__OBJC__\).*')
824 guard_objc_pattern = input_api.re.compile(
825 r'\s*#if defined\(__OBJC__\).*')
826 error_pattern = input_api.re.compile(
827 r'\s*#error .*')
828 block_pattern = input_api.re.compile(
829 r'\s*typedef.*\(\^.*')
830 objc_pattern = input_api.re.compile(
831 r'\s*(@class|@interface|@end|@implementation|@protocol|#import).*')
832 lines = included_file_content.NewContents()
833 previous_was_noobjc_define = False
834 for included_line in lines:
835 if guard_noobjc_pattern.match(included_line):
836 previous_was_noobjc_define = True
837 continue
838 if previous_was_noobjc_define:
839 # Found No Objc Guard. The next line must be check to see if it is
840 # throwing an error.
841 if error_pattern.match(included_line):
842 # There is an error thrown if the file is compiled without ObjC.
843 # Header is Objective-C.
844 return (True, True)
845 else:
846 # There are ifdefs about Objective-C, file can likely be imported or
847 # included.
848 return (False, False)
849 previous_was_noobjc_define = False
850 if guard_objc_pattern.match(included_line):
851 # Found ObjcGuard. This file can be included or imported.
852 return (False, False)
853 if objc_pattern.match(included_line) or block_pattern.match(included_line):
854 # Found an Objective-C keyword. File is an Objective-C header.
855 return (True, True)
856 # No Objective-C clue, file must be C++.
857 return (True, False)
858
859
860 def _CheckIncludeImportInFile(input_api, f):
861 """Checks the include/import coherence in file f."""
862 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
863 custom_import_pattern = input_api.re.compile(r'\s*#import "(?P<FILE>.*)"')
864 contents = f.NewContents()
865 warnings = []
866 for (line_num, line) in enumerate(contents):
867 is_imported = False
868 included_file = ""
869 match_cpp = custom_include_pattern.match(line)
870 if match_cpp:
871 match_dict = match_cpp.groupdict()
872 included_file = match_dict['FILE']
873 match_objc = custom_import_pattern.match(line)
874 if match_objc:
875 match_dict = match_objc.groupdict()
876 included_file = match_dict['FILE']
877 is_imported = True
878 if included_file == "":
879 continue
880 included_absolute_path = input_api.os_path.join(
881 input_api.change.RepositoryRoot(), included_file)
882 if not input_api.os_path.isfile(included_absolute_path):
883 # Included file may need a custom -I flag.
884 # Ignore it.
885 continue
886 included_file_content = input_api.ReadFile(included_absolute_path)
887 (detection_ok, has_objc) = \
888 _CheckHeaderIsObjectiveC(input_api,
889 included_file,
890 included_file_content)
891 if not detection_ok:
892 # There is an Objective-C guard, the file is internded to be included or
893 # imported.
894 continue
895 if is_imported and f.LocalPath().endswith('.cc'):
896 warnings.append('%s:%d %s' % (f.LocalPath(), line_num, line))
897 warnings.append('Header is imported in a C++ file.')
898 if has_objc and not is_imported:
899 warnings.append('%s:%d %s' % (f.LocalPath(), line_num, line))
900 warnings.append('Header is included but has Objective-C instructions.')
901 if not has_objc and is_imported:
902 warnings.append('%s:%d %s' % (f.LocalPath(), line_num, line))
903 warnings.append('Header is imported but has no Objective-C instructions.')
904 return warnings
905
906
907 def _CheckIncludeImport(input_api, output_api):
908 """Checks that C++ headers are included, Objective-C headers imported.
909 """
910 def FileFilterIncludeImport(affected_file):
911 black_list = (_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST)
912 return input_api.FilterSourceFile(affected_file, black_list=black_list)
913
914 warnings = []
915 for f in input_api.AffectedFiles(file_filter=FileFilterIncludeImport):
916 warnings.extend(_CheckIncludeImportInFile(input_api, f))
917
918 results = []
919 if warnings:
920 results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_IMPORT_WARNING,
921 warnings))
922 return results
923
924
793 def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums): 925 def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
794 """Checks that the lines in scope occur in the right order. 926 """Checks that the lines in scope occur in the right order.
795 927
796 1. C system files in alphabetical order 928 1. C system files in alphabetical order
797 2. C++ system files in alphabetical order 929 2. C++ system files in alphabetical order
798 3. Project's .h files 930 3. Project's .h files
799 """ 931 """
800 932
801 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>') 933 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
802 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>') 934 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
(...skipping 1278 matching lines...) Expand 10 before | Expand all | Expand 10 after
2081 results.extend(_CheckDCHECK_IS_ONHasBraces(input_api, output_api)) 2213 results.extend(_CheckDCHECK_IS_ONHasBraces(input_api, output_api))
2082 results.extend(_CheckNoNewWStrings(input_api, output_api)) 2214 results.extend(_CheckNoNewWStrings(input_api, output_api))
2083 results.extend(_CheckNoDEPSGIT(input_api, output_api)) 2215 results.extend(_CheckNoDEPSGIT(input_api, output_api))
2084 results.extend(_CheckNoBannedFunctions(input_api, output_api)) 2216 results.extend(_CheckNoBannedFunctions(input_api, output_api))
2085 results.extend(_CheckNoPragmaOnce(input_api, output_api)) 2217 results.extend(_CheckNoPragmaOnce(input_api, output_api))
2086 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api)) 2218 results.extend(_CheckNoTrinaryTrueFalse(input_api, output_api))
2087 results.extend(_CheckUnwantedDependencies(input_api, output_api)) 2219 results.extend(_CheckUnwantedDependencies(input_api, output_api))
2088 results.extend(_CheckFilePermissions(input_api, output_api)) 2220 results.extend(_CheckFilePermissions(input_api, output_api))
2089 results.extend(_CheckTeamTags(input_api, output_api)) 2221 results.extend(_CheckTeamTags(input_api, output_api))
2090 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) 2222 results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api))
2223 results.extend(_CheckIncludeImport(input_api, output_api))
2091 results.extend(_CheckIncludeOrder(input_api, output_api)) 2224 results.extend(_CheckIncludeOrder(input_api, output_api))
2092 results.extend(_CheckForVersionControlConflicts(input_api, output_api)) 2225 results.extend(_CheckForVersionControlConflicts(input_api, output_api))
2093 results.extend(_CheckPatchFiles(input_api, output_api)) 2226 results.extend(_CheckPatchFiles(input_api, output_api))
2094 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api)) 2227 results.extend(_CheckHardcodedGoogleHostsInLowerLayers(input_api, output_api))
2095 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api)) 2228 results.extend(_CheckNoAbbreviationInPngFileName(input_api, output_api))
2096 results.extend(_CheckForInvalidOSMacros(input_api, output_api)) 2229 results.extend(_CheckForInvalidOSMacros(input_api, output_api))
2097 results.extend(_CheckForInvalidIfDefinedMacros(input_api, output_api)) 2230 results.extend(_CheckForInvalidIfDefinedMacros(input_api, output_api))
2098 results.extend(_CheckFlakyTestUsage(input_api, output_api)) 2231 results.extend(_CheckFlakyTestUsage(input_api, output_api))
2099 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api)) 2232 results.extend(_CheckAddedDepsHaveTargetApprovals(input_api, output_api))
2100 results.extend( 2233 results.extend(
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2367 results.extend(input_api.canned_checks.CheckTreeIsOpen( 2500 results.extend(input_api.canned_checks.CheckTreeIsOpen(
2368 input_api, 2501 input_api,
2369 output_api, 2502 output_api,
2370 json_url='http://chromium-status.appspot.com/current?format=json')) 2503 json_url='http://chromium-status.appspot.com/current?format=json'))
2371 2504
2372 results.extend(input_api.canned_checks.CheckChangeHasBugField( 2505 results.extend(input_api.canned_checks.CheckChangeHasBugField(
2373 input_api, output_api)) 2506 input_api, output_api))
2374 results.extend(input_api.canned_checks.CheckChangeHasDescription( 2507 results.extend(input_api.canned_checks.CheckChangeHasDescription(
2375 input_api, output_api)) 2508 input_api, output_api))
2376 return results 2509 return results
OLDNEW
« no previous file with comments | « no previous file | PRESUBMIT_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698