Chromium Code Reviews| Index: PRESUBMIT.py |
| diff --git a/PRESUBMIT.py b/PRESUBMIT.py |
| index 32a16e1471d4f4ceca549c578b6aebae260fc88b..a622c95c93565c5bf468e715624f50028576f6fe 100644 |
| --- a/PRESUBMIT.py |
| +++ b/PRESUBMIT.py |
| @@ -58,6 +58,11 @@ _TEST_ONLY_WARNING = ( |
| 'not perfect. The commit queue will not block on this warning.') |
| +_INCLUDE_IMPORT_WARNING = ( |
| + 'You are including ObjC headers or importing C++ headers. Remember to use ' |
| + 'the right #include/#import directive.') |
| + |
| + |
| _INCLUDE_ORDER_WARNING = ( |
| 'Your #include order seems to be broken. Remember to use the right ' |
| 'collation (LC_COLLATE=C) and check\nhttps://google.github.io/styleguide/' |
| @@ -771,6 +776,82 @@ def _CheckNoAuraWindowPropertyHInHeaders(input_api, output_api): |
| return results |
| +def _CheckIncludeImportInFile(input_api, f, changed_linenums): |
| + """Checks the include/import coherence in file f.""" |
|
Eugene But (OOO till 7-30)
2016/12/23 16:25:08
Could you please document the rules, about @end/@c
Olivier
2016/12/26 14:49:29
Done.
|
| + custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"') |
| + custom_import_pattern = input_api.re.compile(r'\s*#import "(?P<FILE>.*)"') |
| + guard_pattern = input_api.re.compile( |
| + r'\s*#if !?defined\(__OBJC__\).*') |
| + objc_pattern = input_api.re.compile( |
| + r'\s*(@interface|@end|@implementation|@protocol|#import).*') |
| + contents = f.NewContents() |
| + warnings = [] |
| + line_num = 0 |
| + for line in contents: |
|
Eugene But (OOO till 7-30)
2016/12/23 16:25:08
Could you please add implementation comments. The
Olivier
2016/12/26 14:49:29
Done.
|
| + line_num += 1 |
| + is_imported = False |
| + included_file = "" |
| + match_cpp = custom_include_pattern.match(line) |
| + if match_cpp: |
| + match_dict = match_cpp.groupdict() |
| + included_file = match_dict['FILE'] |
| + match_objc = custom_import_pattern.match(line) |
| + if match_objc: |
| + match_dict = match_objc.groupdict() |
| + included_file = match_dict['FILE'] |
| + is_imported = True |
| + if included_file == "": |
| + continue |
| + included_absolute_path = input_api.os_path.join( |
| + input_api.change.RepositoryRoot(), included_file) |
| + if not input_api.os_path.isfile(included_absolute_path): |
| + # Included file may need a custom -I flag. |
| + # Ignore it. |
| + continue |
| + has_objc = False |
| + ignore_objc = False |
| + for included_line in open(included_absolute_path, 'r'): |
| + match_guard = guard_pattern.match(included_line) |
| + if match_guard: |
| + ignore_objc = True |
| + break |
| + match_objc = objc_pattern.match(included_line) |
| + if match_objc: |
| + has_objc = True |
| + break |
|
Eugene But (OOO till 7-30)
2016/12/23 16:25:09
This is a complex body with multiple loops continu
Olivier
2016/12/26 14:49:29
Done.
|
| + if ignore_objc: |
| + # There is an Objective C guard, the file is internded to be included or |
| + # imported. |
| + continue |
| + if has_objc and not is_imported: |
| + warnings.append('%s:%d %s' % (f.LocalPath(), line_num, line)) |
| + warnings.append('Header is included but has Objective C instructions.') |
| + if not has_objc and is_imported: |
| + warnings.append('%s:%d %s' % (f.LocalPath(), line_num, line)) |
| + warnings.append('Header is imported but has no Objective C instructions.') |
| + return warnings |
| + |
| + |
| +def _CheckIncludeImport(input_api, output_api): |
| + """Checks that C++ files are included, ObjC files imported |
|
Eugene But (OOO till 7-30)
2016/12/23 16:25:08
nit: s/files/headers
Olivier
2016/12/26 14:49:29
Done.
|
| + """ |
| + def FileFilterIncludeImport(affected_file): |
| + black_list = (_EXCLUDED_PATHS + input_api.DEFAULT_BLACK_LIST) |
| + return input_api.FilterSourceFile(affected_file, black_list=black_list) |
| + |
| + warnings = [] |
| + for f in input_api.AffectedFiles(file_filter=FileFilterIncludeImport): |
|
Eugene But (OOO till 7-30)
2016/12/23 16:25:08
Usage of filter is discouraged by Python Style Gui
Olivier
2016/12/26 14:49:29
All other tests use this structure and I cannot ch
|
| + if f.LocalPath().endswith(('.cc', '.h', '.mm')): |
| + changed_linenums = set(line_num for line_num, _ in f.ChangedContents()) |
| + warnings.extend(_CheckIncludeImportInFile(input_api, f, changed_linenums)) |
| + |
| + results = [] |
| + if warnings: |
| + results.append(output_api.PresubmitPromptOrNotify(_INCLUDE_IMPORT_WARNING, |
| + warnings)) |
| + return results |
| + |
| + |
| def _CheckIncludeOrderForScope(scope, input_api, file_path, changed_linenums): |
| """Checks that the lines in scope occur in the right order. |
| @@ -2046,6 +2127,7 @@ def _CommonChecks(input_api, output_api): |
| results.extend(_CheckUnwantedDependencies(input_api, output_api)) |
| results.extend(_CheckFilePermissions(input_api, output_api)) |
| results.extend(_CheckNoAuraWindowPropertyHInHeaders(input_api, output_api)) |
| + results.extend(_CheckIncludeImport(input_api, output_api)) |
| results.extend(_CheckIncludeOrder(input_api, output_api)) |
| results.extend(_CheckForVersionControlConflicts(input_api, output_api)) |
| results.extend(_CheckPatchFiles(input_api, output_api)) |