OLD | NEW |
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 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 previous_line = line | 535 previous_line = line |
536 previous_line_num = line_num | 536 previous_line_num = line_num |
537 | 537 |
538 warnings = [] | 538 warnings = [] |
539 for (line_num, previous_line_num) in problem_linenums: | 539 for (line_num, previous_line_num) in problem_linenums: |
540 if line_num in changed_linenums or previous_line_num in changed_linenums: | 540 if line_num in changed_linenums or previous_line_num in changed_linenums: |
541 warnings.append(' %s:%d' % (file_path, line_num)) | 541 warnings.append(' %s:%d' % (file_path, line_num)) |
542 return warnings | 542 return warnings |
543 | 543 |
544 | 544 |
545 def _CheckIncludeOrderInFile(input_api, f, is_source, changed_linenums): | 545 def _CheckIncludeOrderInFile(input_api, f, changed_linenums): |
546 """Checks the #include order for the given file f.""" | 546 """Checks the #include order for the given file f.""" |
547 | 547 |
548 system_include_pattern = input_api.re.compile(r'\s*#include \<.*') | 548 system_include_pattern = input_api.re.compile(r'\s*#include \<.*') |
549 # Exclude #include <.../...> includes from the check; e.g., <sys/...> includes | 549 # Exclude #include <.../...> includes from the check; e.g., <sys/...> includes |
550 # often need to appear in a specific order. | 550 # often need to appear in a specific order. |
551 excluded_include_pattern = input_api.re.compile(r'\s*#include \<.*/.*') | 551 excluded_include_pattern = input_api.re.compile(r'\s*#include \<.*/.*') |
552 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"') | 552 custom_include_pattern = input_api.re.compile(r'\s*#include "(?P<FILE>.*)"') |
553 if_pattern = input_api.re.compile(r'\s*#\s*(if|elif|else|endif).*') | 553 if_pattern = ( |
| 554 input_api.re.compile(r'\s*#\s*(if|elif|else|endif|define|undef).*')) |
554 | 555 |
555 contents = f.NewContents() | 556 contents = f.NewContents() |
556 warnings = [] | 557 warnings = [] |
557 line_num = 0 | 558 line_num = 0 |
558 | 559 |
559 # Handle the special first include for source files. If the header file is | 560 # Handle the special first include. If the first include file is |
560 # some/path/file.h, the corresponding source file can be some/path/file.cc, | 561 # some/path/file.h, the corresponding including file can be some/path/file.cc, |
561 # some/other/path/file.cc, some/path/file_platform.cc etc. It's also possible | 562 # some/other/path/file.cc, some/path/file_platform.cc, some/path/file-suffix.h |
562 # that no special first include exists. | 563 # etc. It's also possible that no special first include exists. |
563 if is_source: | 564 for line in contents: |
564 for line in contents: | 565 line_num += 1 |
565 line_num += 1 | 566 if system_include_pattern.match(line): |
566 if system_include_pattern.match(line): | 567 # No special first include -> process the line again along with normal |
| 568 # includes. |
| 569 line_num -= 1 |
| 570 break |
| 571 match = custom_include_pattern.match(line) |
| 572 if match: |
| 573 match_dict = match.groupdict() |
| 574 header_basename = input_api.os_path.basename( |
| 575 match_dict['FILE']).replace('.h', '') |
| 576 if header_basename not in input_api.os_path.basename(f.LocalPath()): |
567 # No special first include -> process the line again along with normal | 577 # No special first include -> process the line again along with normal |
568 # includes. | 578 # includes. |
569 line_num -= 1 | 579 line_num -= 1 |
570 break | 580 break |
571 match = custom_include_pattern.match(line) | |
572 if match: | |
573 match_dict = match.groupdict() | |
574 header_basename = input_api.os_path.basename( | |
575 match_dict['FILE']).replace('.h', '') | |
576 if header_basename not in input_api.os_path.basename(f.LocalPath()): | |
577 # No special first include -> process the line again along with normal | |
578 # includes. | |
579 line_num -= 1 | |
580 break | |
581 | 581 |
582 # Split into scopes: Each region between #if and #endif is its own scope. | 582 # Split into scopes: Each region between #if and #endif is its own scope. |
583 scopes = [] | 583 scopes = [] |
584 current_scope = [] | 584 current_scope = [] |
585 for line in contents[line_num:]: | 585 for line in contents[line_num:]: |
586 line_num += 1 | 586 line_num += 1 |
587 if if_pattern.match(line): | 587 if if_pattern.match(line): |
588 scopes.append(current_scope) | 588 scopes.append(current_scope) |
589 current_scope = [] | 589 current_scope = [] |
590 elif ((system_include_pattern.match(line) or | 590 elif ((system_include_pattern.match(line) or |
591 custom_include_pattern.match(line)) and | 591 custom_include_pattern.match(line)) and |
592 not excluded_include_pattern.match(line)): | 592 not excluded_include_pattern.match(line)): |
593 current_scope.append((line_num, line)) | 593 current_scope.append((line_num, line)) |
594 scopes.append(current_scope) | 594 scopes.append(current_scope) |
595 | 595 |
596 for scope in scopes: | 596 for scope in scopes: |
597 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(), | 597 warnings.extend(_CheckIncludeOrderForScope(scope, input_api, f.LocalPath(), |
598 changed_linenums)) | 598 changed_linenums)) |
599 return warnings | 599 return warnings |
600 | 600 |
601 | 601 |
602 def _CheckIncludeOrder(input_api, output_api): | 602 def _CheckIncludeOrder(input_api, output_api): |
603 """Checks that the #include order is correct. | 603 """Checks that the #include order is correct. |
604 | 604 |
605 1. The corresponding header for source files. | 605 1. The corresponding header for source files. |
606 2. C system files in alphabetical order | 606 2. C system files in alphabetical order |
607 3. C++ system files in alphabetical order | 607 3. C++ system files in alphabetical order |
608 4. Project's .h files in alphabetical order | 608 4. Project's .h files in alphabetical order |
609 | 609 |
610 Each region between #if and #endif follows these rules separately. | 610 Each region separated by #if, #elif, #else, #endif, #define and #undef follows |
| 611 these rules separately. |
611 """ | 612 """ |
612 | 613 |
613 warnings = [] | 614 warnings = [] |
614 for f in input_api.AffectedFiles(): | 615 for f in input_api.AffectedFiles(): |
615 changed_linenums = set([line_num for line_num, _ in f.ChangedContents()]) | 616 if f.LocalPath().endswith(('.cc', '.h')): |
616 if f.LocalPath().endswith('.cc'): | 617 changed_linenums = set(line_num for line_num, _ in f.ChangedContents()) |
617 warnings.extend(_CheckIncludeOrderInFile(input_api, f, True, | 618 warnings.extend(_CheckIncludeOrderInFile(input_api, f, changed_linenums)) |
618 changed_linenums)) | |
619 elif f.LocalPath().endswith('.h'): | |
620 warnings.extend(_CheckIncludeOrderInFile(input_api, f, False, | |
621 changed_linenums)) | |
622 | 619 |
623 results = [] | 620 results = [] |
624 if warnings: | 621 if warnings: |
625 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING, | 622 results.append(output_api.PresubmitPromptWarning(_INCLUDE_ORDER_WARNING, |
626 warnings)) | 623 warnings)) |
627 return results | 624 return results |
628 | 625 |
629 | 626 |
630 def _CheckForVersionControlConflictsInFile(input_api, f): | 627 def _CheckForVersionControlConflictsInFile(input_api, f): |
631 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$') | 628 pattern = input_api.re.compile('^(?:<<<<<<<|>>>>>>>) |^=======$') |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 'win_aura', | 822 'win_aura', |
826 'win_rel', | 823 'win_rel', |
827 ] | 824 ] |
828 | 825 |
829 # Match things like path/aura/file.cc and path/file_aura.cc. | 826 # Match things like path/aura/file.cc and path/file_aura.cc. |
830 # Same for chromeos. | 827 # Same for chromeos. |
831 if any(re.search('[/_](aura|chromeos)', f) for f in files): | 828 if any(re.search('[/_](aura|chromeos)', f) for f in files): |
832 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan'] | 829 trybots += ['linux_chromeos_clang:compile', 'linux_chromeos_asan'] |
833 | 830 |
834 return trybots | 831 return trybots |
OLD | NEW |