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

Side by Side Diff: PRESUBMIT.py

Issue 2337293002: Sort include entries. (Closed)
Patch Set: Created 4 years, 3 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 | core/fpdfapi/fpdf_page/pageint.h » ('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 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 """Presubmit script for pdfium. 5 """Presubmit script for pdfium.
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 16 matching lines...) Expand all
27 '-runtime/printf', 27 '-runtime/printf',
28 # Lots of non-const references need to be fixed 28 # Lots of non-const references need to be fixed
29 '-runtime/references', 29 '-runtime/references',
30 # We are not thread safe, so this will never pass. 30 # We are not thread safe, so this will never pass.
31 '-runtime/threadsafe_fn', 31 '-runtime/threadsafe_fn',
32 # Figure out how to deal with #defines that git cl format creates. 32 # Figure out how to deal with #defines that git cl format creates.
33 '-whitespace/indent', 33 '-whitespace/indent',
34 ] 34 ]
35 35
36 36
37 _INCLUDE_ORDER_WARNING = (
38 'Your #include order seems to be broken. Remember to use the right '
39 'collation (LC_COLLATE=C) and check\nhttps://google.github.io/styleguide/'
40 'cppguide.html#Names_and_Order_of_Includes')
41
42
37 def _CheckUnwantedDependencies(input_api, output_api): 43 def _CheckUnwantedDependencies(input_api, output_api):
38 """Runs checkdeps on #include statements added in this 44 """Runs checkdeps on #include statements added in this
39 change. Breaking - rules is an error, breaking ! rules is a 45 change. Breaking - rules is an error, breaking ! rules is a
40 warning. 46 warning.
41 """ 47 """
42 import sys 48 import sys
43 # We need to wait until we have an input_api object and use this 49 # We need to wait until we have an input_api object and use this
44 # roundabout construct to import checkdeps because this file is 50 # roundabout construct to import checkdeps because this file is
45 # eval-ed and thus doesn't have __file__. 51 # eval-ed and thus doesn't have __file__.
46 original_sys_path = sys.path 52 original_sys_path = sys.path
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 error_descriptions)) 90 error_descriptions))
85 if warning_descriptions: 91 if warning_descriptions:
86 results.append(output_api.PresubmitPromptOrNotify( 92 results.append(output_api.PresubmitPromptOrNotify(
87 'You added one or more #includes of files that are temporarily\n' 93 'You added one or more #includes of files that are temporarily\n'
88 'allowed but being removed. Can you avoid introducing the\n' 94 'allowed but being removed. Can you avoid introducing the\n'
89 '#include? See relevant DEPS file(s) for details and contacts.', 95 '#include? See relevant DEPS file(s) for details and contacts.',
90 warning_descriptions)) 96 warning_descriptions))
91 return results 97 return results
92 98
93 99
100 def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums):
101 """Checks that the lines in scope occur in the right order.
102
103 1. C system files in alphabetical order
104 2. C++ system files in alphabetical order
105 3. Project's .h files
106 """
107
108 c_system_include_pattern = input_api.re.compile(r'\s*#include <.*\.h>')
109 cpp_system_include_pattern = input_api.re.compile(r'\s*#include <.*>')
110 custom_include_pattern = input_api.re.compile(r'\s*#include ".*')
111
112 C_SYSTEM_INCLUDES, CPP_SYSTEM_INCLUDES, CUSTOM_INCLUDES = range(3)
113
114 state = C_SYSTEM_INCLUDES
115
116 previous_line = ''
117 previous_line_num = 0
118 problem_linenums = []
119 out_of_order = " - line belongs before previous line"
120 for line_num, line in scope:
121 if c_system_include_pattern.match(line):
122 if state != C_SYSTEM_INCLUDES:
123 problem_linenums.append((line_num, previous_line_num,
124 " - C system include file in wrong block"))
125 elif previous_line and previous_line > line:
126 problem_linenums.append((line_num, previous_line_num,
127 out_of_order))
128 elif cpp_system_include_pattern.match(line):
129 if state == C_SYSTEM_INCLUDES:
130 state = CPP_SYSTEM_INCLUDES
131 elif state == CUSTOM_INCLUDES:
132 problem_linenums.append((line_num, previous_line_num,
133 " - c++ system include file in wrong block"))
134 elif previous_line and previous_line > line:
135 problem_linenums.append((line_num, previous_line_num, out_of_order))
136 elif custom_include_pattern.match(line):
137 if state != CUSTOM_INCLUDES:
138 state = CUSTOM_INCLUDES
139 elif previous_line and previous_line > line:
140 problem_linenums.append((line_num, previous_line_num, out_of_order))
141 else:
142 problem_linenums.append((line_num, previous_line_num,
143 "Unknown include type"))
144 previous_line = line
145 previous_line_num = line_num
146
147 warnings = []
148 for (line_num, previous_line_num, failure_type) in problem_linenums:
149 if line_num in changed_linenums or previous_line_num in changed_linenums:
150 warnings.append(' %s:%d:%s' % (file_path, line_num, failure_type))
151 return warnings
152
153
154 def _CheckIncludeOrderInFile(input_api, f, changed_linenums):
155 """Checks the #include order for the given file f."""
156
157 system_include_pattern = input_api.re.compile(r'\s*#include \<.*')
158 # Exclude the following includes from the check:
159 # 1) #include <.../...>, e.g., <sys/...> includes often need to appear in a
160 # specific order.
161 # 2) <atlbase.h>, "build/build_config.h"
162 excluded_include_pattern = input_api.re.compile(
163 r'\s*#include (\<.*/.*|\<atlbase\.h\>|"build/build_config.h")')
164 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"')
165 # Match the final or penultimate token if it is xxxtest so we can ignore it
166 # when considering the special first include.
167 test_file_tag_pattern = input_api.re.compile(
168 r'_[a-z]+test(?=(_[a-zA-Z0-9]+)?\.)')
169 if_pattern = input_api.re.compile(
170 r'\s*#\s*(if|elif|else|endif|define|undef).*')
171 # Some files need specialized order of includes; exclude such files from this
172 # check.
173 uncheckable_includes_pattern = input_api.re.compile(
174 r'\s*#include '
175 '("ipc/.*macros\.h"|<windows\.h>|".*gl.*autogen.h")\s*')
176
177 contents = f.NewContents()
178 warnings = []
179 line_num = 0
180
181 # Handle the special first include. If the first include file is
182 # some/path/file.h, the corresponding including file can be some/path/file.cc,
183 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h
184 # etc. It's also possible that no special first include exists.
185 # If the included file is some/path/file_platform.h the including file could
186 # also be some/path/file_xxxtest_platform.h.
187 including_file_base_name = test_file_tag_pattern.sub(
188 '', input_api.os_path.basename(f.LocalPath()))
189
190 for line in contents:
191 line_num += 1
192 if system_include_pattern.match(line):
193 # No special first include -> process the line again along with normal
194 # includes.
195 line_num -= 1
196 break
197 match = custom_include_pattern.match(line)
198 if match:
199 match_dict = match.groupdict()
200 header_basename = test_file_tag_pattern.sub(
201 '', input_api.os_path.basename(match_dict['FILE'])).replace('.h', '')
202
203 if header_basename not in including_file_base_name:
204 # No special first include -> process the line again along with normal
205 # includes.
206 line_num -= 1
207 break
208
209 # Split into scopes: Each region between #if and #endif is its own scope.
210 scopes = []
211 current_scope = []
212 for line in contents[line_num:]:
213 line_num += 1
214 if uncheckable_includes_pattern.match(line):
215 continue
216 if if_pattern.match(line):
217 scopes.append(current_scope)
218 current_scope = []
219 elif ((system_include_pattern.match(line) or
220 custom_include_pattern.match(line)) and
221 not excluded_include_pattern.match(line)):
222 current_scope.append((line_num, line))
223 scopes.append(current_scope)
224
225 for scope in scopes:
226 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(),
227 changed_linenums))
228 return warnings
229
230
231 def _CheckIncludeOrder(input_api, output_api):
232 """Checks that the #include order is correct.
233
234 1. The corresponding header for source files.
235 2. C system files in alphabetical order
236 3. C++ system files in alphabetical order
237 4. Project's .h files in alphabetical order
238
239 Each region separated by #if, #elif, #else, #endif, #define and #undef follows
240 these rules separately.
241 """
242 def FileFilterIncludeOrder(affected_file):
243 black_list = (input_api.DEFAULT_BLACK_LIST)
244 return input_api.FilterSourceFile(affected_file, black_list=black_list)
245
246 warnings = []
247 for f in input_api.AffectedFiles(file_filter=FileFilterIncludeOrder):
248 if f.LocalPath().endswith(('.cc', '.h', '.mm')):
249 changed_linenums = set(line_num for line_num, _ in f.ChangedContents())
250 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums))
251
252 results = []
253 if warnings:
254 results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_ORDER_WARNING,
255 warnings))
256 return results
257
258
94 def CheckChangeOnUpload(input_api, output_api): 259 def CheckChangeOnUpload(input_api, output_api):
95 results = [] 260 results = []
96 results += _CheckUnwantedDependencies(input_api, output_api) 261 results += _CheckUnwantedDependencies(input_api, output_api)
97 results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api) 262 results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api)
98 results += input_api.canned_checks.CheckChangeLintsClean( 263 results += input_api.canned_checks.CheckChangeLintsClean(
99 input_api, output_api, None, LINT_FILTERS) 264 input_api, output_api, None, LINT_FILTERS)
265 results += _CheckIncludeOrder(input_api, output_api)
100 266
101 return results 267 return results
OLDNEW
« no previous file with comments | « no previous file | core/fpdfapi/fpdf_page/pageint.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698