Checks that all user-defined constructors and assignment operators are marked V8_NOEXCEPT. This is required for standard containers to pick the right constructors. Our macros (like MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS) add this automatically. Omitting it at some places can result in weird
(input_api, output_api)
| 557 | |
| 558 | |
| 559 | def _CheckNoexceptAnnotations(input_api, output_api): |
| 560 | """ |
| 561 | Checks that all user-defined constructors and assignment operators are marked |
| 562 | V8_NOEXCEPT. |
| 563 | |
| 564 | This is required for standard containers to pick the right constructors. Our |
| 565 | macros (like MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS) add this automatically. |
| 566 | Omitting it at some places can result in weird compiler errors if this is |
| 567 | mixed with other classes that have the annotation. |
| 568 | |
| 569 | TODO(clemensb): This check should eventually be enabled for all files via |
| 570 | tools/presubmit.py (https://crbug.com/v8/8616). |
| 571 | """ |
| 572 | |
| 573 | def FilterFile(affected_file): |
| 574 | files_to_skip = _EXCLUDED_PATHS + ( |
| 575 | # Skip api.cc since we cannot easily add the 'noexcept' annotation to |
| 576 | # public methods. |
| 577 | r'src[\\\/]api[\\\/]api\.cc', |
| 578 | # Skip src/bigint/ because it's meant to be V8-independent. |
| 579 | r'src[\\\/]bigint[\\\/].*', |
| 580 | ) |
| 581 | return input_api.FilterSourceFile( |
| 582 | affected_file, |
| 583 | files_to_check=(r'src[\\\/].*\.cc', r'src[\\\/].*\.h', |
| 584 | r'test[\\\/].*\.cc', r'test[\\\/].*\.h'), |
| 585 | files_to_skip=files_to_skip) |
| 586 | |
| 587 | # matches any class name. |
| 588 | class_name = r'\b([A-Z][A-Za-z0-9_:]*)(?:::\1)?' |
| 589 | # initial class name is potentially followed by this to declare an assignment |
| 590 | # operator. |
| 591 | potential_assignment = r'(?:&\s+(?:\1::)?operator=)?\s*' |
| 592 | # matches an argument list that contains only a reference to a class named |
| 593 | # like the first capture group, potentially const. |
| 594 | single_class_ref_arg = r'\(\s*(?:const\s+)?\1(?:::\1)?&&?[^,;)]*\)' |
| 595 | # matches anything but a sequence of whitespaces followed by either |
| 596 | # V8_NOEXCEPT or "= delete". |
| 597 | not_followed_by_noexcept = r'(?!\s+(?:V8_NOEXCEPT|=\s+delete)\b)' |
| 598 | full_pattern = r'^.*?' + class_name + potential_assignment + \ |
| 599 | single_class_ref_arg + not_followed_by_noexcept + '.*?$' |
| 600 | regexp = input_api.re.compile(full_pattern, re.MULTILINE) |
| 601 | |
| 602 | errors = [] |
| 603 | for f in input_api.AffectedFiles(file_filter=FilterFile, |
| 604 | include_deletes=False): |
| 605 | with open(f.LocalPath()) as fh: |
| 606 | for match in re.finditer(regexp, fh.read()): |
| 607 | errors.append(f'in {f.LocalPath()}: {match.group().strip()}') |
| 608 | |
| 609 | if errors: |
| 610 | return [output_api.PresubmitPromptOrNotify( |
| 611 | 'Copy constructors, move constructors, copy assignment operators and ' |
| 612 | 'move assignment operators should be marked V8_NOEXCEPT.\n' |
| 613 | 'Please report false positives on https://crbug.com/v8/8616.', |
| 614 | errors)] |
| 615 | return [] |
| 616 |