Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 """Generates C++ source files from a mojom.Module.""" | 5 """Generates C++ source files from a mojom.Module.""" |
| 6 | 6 |
| 7 import mojom.generate.generator as generator | 7 import mojom.generate.generator as generator |
| 8 import mojom.generate.module as mojom | 8 import mojom.generate.module as mojom |
| 9 import mojom.generate.pack as pack | 9 import mojom.generate.pack as pack |
| 10 from mojom.generate.template_expander import UseJinja | 10 from mojom.generate.template_expander import UseJinja |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 """ | 180 """ |
| 181 checked = set() | 181 checked = set() |
| 182 def Check(kind): | 182 def Check(kind): |
| 183 if kind.spec in checked: | 183 if kind.spec in checked: |
| 184 return True | 184 return True |
| 185 checked.add(kind.spec) | 185 checked.add(kind.spec) |
| 186 if mojom.IsNullableKind(kind): | 186 if mojom.IsNullableKind(kind): |
| 187 return False | 187 return False |
| 188 elif mojom.IsStructKind(kind): | 188 elif mojom.IsStructKind(kind): |
| 189 if (IsTypemappedKind(kind) and | 189 if (IsTypemappedKind(kind) and |
| 190 not _current_typemap[GetFullMojomNameForKind(kind)]["hashable"]): | 190 not _current_typemap[ GetFullMojomNameForKind(kind)]["hashable"]): |
|
yzshen1
2017/02/03 00:31:45
nit: the empty space is not needed.
Sam McNally
2017/02/03 02:28:32
Done.
| |
| 191 return False | 191 return False |
| 192 return all(Check(field.kind) for field in kind.fields) | 192 return all(Check(field.kind) for field in kind.fields) |
| 193 elif mojom.IsEnumKind(kind): | 193 elif mojom.IsEnumKind(kind): |
| 194 if (IsTypemappedKind(kind) and | 194 return not (IsTypemappedKind(kind) and not _current_typemap[ |
|
yzshen1
2017/02/03 00:31:45
It seems a little easier to read with
"return not
Sam McNally
2017/02/03 02:28:32
Done.
| |
| 195 not _current_typemap[GetFullMojomNameForKind(kind)]["hashable"]): | 195 GetFullMojomNameForKind(kind)]["hashable"]) |
| 196 return False | |
| 197 return True | |
| 198 elif mojom.IsUnionKind(kind): | 196 elif mojom.IsUnionKind(kind): |
| 199 return all(Check(field.kind) for field in kind.fields) | 197 return all(Check(field.kind) for field in kind.fields) |
| 200 elif mojom.IsAnyHandleKind(kind): | 198 elif mojom.IsAnyHandleKind(kind): |
| 201 return False | 199 return False |
| 202 elif mojom.IsAnyInterfaceKind(kind): | 200 elif mojom.IsAnyInterfaceKind(kind): |
| 203 return False | 201 return False |
| 204 # TODO(tibell): Arrays and maps could be made hashable. We just don't have a | 202 # TODO(tibell): Arrays and maps could be made hashable. We just don't have a |
| 205 # use case yet. | 203 # use case yet. |
| 206 elif mojom.IsArrayKind(kind): | 204 elif mojom.IsArrayKind(kind): |
| 207 return False | 205 return False |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 412 return "mojo::ScopedMessagePipeHandle" | 410 return "mojo::ScopedMessagePipeHandle" |
| 413 if mojom.IsSharedBufferKind(kind): | 411 if mojom.IsSharedBufferKind(kind): |
| 414 return "mojo::ScopedSharedBufferHandle" | 412 return "mojo::ScopedSharedBufferHandle" |
| 415 return _kind_to_cpp_type[kind] | 413 return _kind_to_cpp_type[kind] |
| 416 | 414 |
| 417 def GetUnmappedTypeForSerializer(kind): | 415 def GetUnmappedTypeForSerializer(kind): |
| 418 return GetCppDataViewType(kind, qualified=True) | 416 return GetCppDataViewType(kind, qualified=True) |
| 419 | 417 |
| 420 def TranslateConstants(token, kind): | 418 def TranslateConstants(token, kind): |
| 421 if isinstance(token, mojom.NamedValue): | 419 if isinstance(token, mojom.NamedValue): |
| 422 return _NameFormatter(token, _variant).FormatForCpp( | 420 return GetNameForKind(token, flatten_nested_kind=True) |
| 423 flatten_nested_kind=True) | |
| 424 | 421 |
| 425 if isinstance(token, mojom.BuiltinValue): | 422 if isinstance(token, mojom.BuiltinValue): |
| 426 if token.value == "double.INFINITY": | 423 if token.value == "double.INFINITY": |
| 427 return "std::numeric_limits<double>::infinity()" | 424 return "std::numeric_limits<double>::infinity()" |
| 428 if token.value == "float.INFINITY": | 425 if token.value == "float.INFINITY": |
| 429 return "std::numeric_limits<float>::infinity()" | 426 return "std::numeric_limits<float>::infinity()" |
| 430 if token.value == "double.NEGATIVE_INFINITY": | 427 if token.value == "double.NEGATIVE_INFINITY": |
| 431 return "-std::numeric_limits<double>::infinity()" | 428 return "-std::numeric_limits<double>::infinity()" |
| 432 if token.value == "float.NEGATIVE_INFINITY": | 429 if token.value == "float.NEGATIVE_INFINITY": |
| 433 return "-std::numeric_limits<float>::infinity()" | 430 return "-std::numeric_limits<float>::infinity()" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 return "%d, %s" % (expected_num_elements, enum_validate_func) | 520 return "%d, %s" % (expected_num_elements, enum_validate_func) |
| 524 | 521 |
| 525 def GetNewContainerValidateParams(kind): | 522 def GetNewContainerValidateParams(kind): |
| 526 if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and | 523 if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and |
| 527 not mojom.IsStringKind(kind)): | 524 not mojom.IsStringKind(kind)): |
| 528 return "nullptr" | 525 return "nullptr" |
| 529 | 526 |
| 530 return "new mojo::internal::ContainerValidateParams(%s)" % ( | 527 return "new mojo::internal::ContainerValidateParams(%s)" % ( |
| 531 GetContainerValidateParamsCtorArgs(kind)) | 528 GetContainerValidateParamsCtorArgs(kind)) |
| 532 | 529 |
| 530 | |
| 531 def QuoteHeader(header): | |
| 532 if header[0] == '<': | |
| 533 return header | |
| 534 return '"%s"' % header | |
| 535 | |
| 536 | |
| 537 def QuoteAndSortHeaders(headers): | |
| 538 return (QuoteHeader(header) for header in sorted(headers)) | |
| 539 | |
| 540 | |
| 541 CHROMIUM_HEADERS = { | |
| 542 "array": ["<vector>"], | |
|
yzshen1
2017/02/02 22:33:58
(Not saying that I have a strong preference, just
Sam McNally
2017/02/03 02:28:32
Perf-wise, probably not too much. Including a .moj
| |
| 543 "interface": [ | |
| 544 "base/callback.h", | |
| 545 "mojo/public/cpp/bindings/associated_interface_ptr.h", | |
| 546 "mojo/public/cpp/bindings/associated_interface_ptr_info.h", | |
| 547 "mojo/public/cpp/bindings/associated_interface_request.h", | |
| 548 "mojo/public/cpp/bindings/interface_ptr.h", | |
| 549 "mojo/public/cpp/bindings/interface_request.h", | |
| 550 "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h", | |
| 551 "mojo/public/cpp/bindings/thread_safe_interface_ptr.h", | |
| 552 ], | |
| 553 "map": ["<unordered_map>"], | |
| 554 "native_enum": ["mojo/public/cpp/bindings/native_enum.h"], | |
| 555 "native_struct": ["mojo/public/cpp/bindings/native_struct.h"], | |
| 556 "optional": ["base/optional.h"], | |
| 557 "string": ["<string>"], | |
| 558 "struct": [ | |
| 559 "<vector>", | |
| 560 "mojo/public/cpp/bindings/lib/clone_equals_util.h", | |
| 561 "mojo/public/cpp/bindings/lib/hash_util.h", | |
| 562 "mojo/public/cpp/bindings/struct_ptr.h", | |
| 563 "mojo/public/cpp/bindings/struct_traits.h", | |
| 564 ], | |
| 565 "union": [ | |
| 566 "<vector>", | |
| 567 "mojo/public/cpp/bindings/lib/union_accessor.h", | |
| 568 "mojo/public/cpp/bindings/union_traits.h", | |
| 569 ], | |
| 570 } | |
| 571 | |
| 572 BLINK_HEADERS = { | |
| 573 "array": ["third_party/WebKit/Source/wtf/Vector.h"], | |
| 574 "interface": [ | |
| 575 "base/callback.h", | |
| 576 "mojo/public/cpp/bindings/associated_interface_ptr.h", | |
| 577 "mojo/public/cpp/bindings/associated_interface_ptr_info.h", | |
| 578 "mojo/public/cpp/bindings/associated_interface_request.h", | |
| 579 "mojo/public/cpp/bindings/interface_ptr.h", | |
| 580 "mojo/public/cpp/bindings/interface_request.h", | |
| 581 "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h", | |
| 582 "mojo/public/cpp/bindings/thread_safe_interface_ptr.h", | |
| 583 ], | |
| 584 "map": ["third_party/WebKit/Source/wtf/HashMap.h"], | |
| 585 "native_enum": ["mojo/public/cpp/bindings/native_enum.h"], | |
| 586 "native_struct": ["mojo/public/cpp/bindings/native_struct.h"], | |
| 587 "optional": ["third_party/WebKit/Source/wtf/Optional.h"], | |
| 588 "string": ["third_party/WebKit/Source/wtf/text/WTFString.h"], | |
| 589 "struct": [ | |
| 590 "third_party/WebKit/Source/wtf/Vector.h", | |
| 591 "mojo/public/cpp/bindings/struct_ptr.h", | |
| 592 "mojo/public/cpp/bindings/struct_traits.h", | |
| 593 "mojo/public/cpp/bindings/lib/wtf_clone_equals_util.h", | |
| 594 "mojo/public/cpp/bindings/lib/wtf_hash_util.h", | |
| 595 ], | |
| 596 "union": [ | |
| 597 "mojo/public/cpp/bindings/lib/union_accessor.h", | |
| 598 "mojo/public/cpp/bindings/union_traits.h", | |
| 599 "third_party/WebKit/Source/wtf/Vector.h", | |
| 600 ], | |
| 601 } | |
| 602 | |
| 603 SHARED_HEADERS = { | |
| 604 "array": ["mojo/public/cpp/bindings/array_data_view.h"], | |
| 605 "enum": ["mojo/public/cpp/bindings/enum_traits.h"], | |
| 606 "interface": ["mojo/public/cpp/bindings/interface_data_view.h"], | |
| 607 "map": ["mojo/public/cpp/bindings/map_data_view.h"], | |
| 608 "native_enum": ["mojo/public/cpp/bindings/native_enum.h"], | |
| 609 "native_struct": ["mojo/public/cpp/bindings/native_struct_data_view.h"], | |
| 610 "non_native_enum": ["<ostream>"], | |
| 611 "string": ["mojo/public/cpp/bindings/string_data_view.h"], | |
| 612 } | |
| 613 | |
| 614 | |
| 533 class Generator(generator.Generator): | 615 class Generator(generator.Generator): |
| 534 | 616 |
| 535 cpp_filters = { | 617 cpp_filters = { |
| 536 "constant_value": ConstantValue, | 618 "constant_value": ConstantValue, |
| 537 "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces, | 619 "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces, |
| 538 "contains_move_only_members": ContainsMoveOnlyMembers, | 620 "contains_move_only_members": ContainsMoveOnlyMembers, |
| 539 "cpp_wrapper_param_type": GetCppWrapperParamType, | 621 "cpp_wrapper_param_type": GetCppWrapperParamType, |
| 540 "cpp_data_view_type": GetCppDataViewType, | 622 "cpp_data_view_type": GetCppDataViewType, |
| 541 "cpp_field_type": GetCppFieldType, | 623 "cpp_field_type": GetCppFieldType, |
| 542 "cpp_union_field_type": GetCppUnionFieldType, | 624 "cpp_union_field_type": GetCppUnionFieldType, |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 568 "is_hashable": IsHashableKind, | 650 "is_hashable": IsHashableKind, |
| 569 "is_map_kind": mojom.IsMapKind, | 651 "is_map_kind": mojom.IsMapKind, |
| 570 "is_nullable_kind": mojom.IsNullableKind, | 652 "is_nullable_kind": mojom.IsNullableKind, |
| 571 "is_object_kind": mojom.IsObjectKind, | 653 "is_object_kind": mojom.IsObjectKind, |
| 572 "is_reference_kind": mojom.IsReferenceKind, | 654 "is_reference_kind": mojom.IsReferenceKind, |
| 573 "is_string_kind": mojom.IsStringKind, | 655 "is_string_kind": mojom.IsStringKind, |
| 574 "is_struct_kind": mojom.IsStructKind, | 656 "is_struct_kind": mojom.IsStructKind, |
| 575 "is_typemapped_kind": IsTypemappedKind, | 657 "is_typemapped_kind": IsTypemappedKind, |
| 576 "is_union_kind": mojom.IsUnionKind, | 658 "is_union_kind": mojom.IsUnionKind, |
| 577 "passes_associated_kinds": mojom.PassesAssociatedKinds, | 659 "passes_associated_kinds": mojom.PassesAssociatedKinds, |
| 578 "struct_size": lambda ps: ps.GetTotalSize() + _HEADER_SIZE, | |
| 579 "stylize_method": generator.StudlyCapsToCamel, | 660 "stylize_method": generator.StudlyCapsToCamel, |
| 580 "under_to_camel": generator.UnderToCamel, | 661 "under_to_camel": generator.UnderToCamel, |
| 581 "unmapped_type_for_serializer": GetUnmappedTypeForSerializer, | 662 "unmapped_type_for_serializer": GetUnmappedTypeForSerializer, |
| 582 } | 663 } |
| 583 | 664 |
| 584 def GetExtraTraitsHeaders(self): | 665 def GetExtraTraitsHeaders(self): |
| 585 extra_headers = set() | 666 extra_headers = set() |
| 586 for entry in self.typemap.itervalues(): | 667 for typemap in self._GetAllUsedTypemaps(): |
| 587 extra_headers.update(entry.get("traits_headers", [])) | 668 extra_headers.update(typemap.get("traits_headers", [])) |
| 588 return list(extra_headers) | 669 return QuoteAndSortHeaders(extra_headers) |
| 589 | 670 |
| 590 def GetExtraPublicHeaders(self): | 671 def _GetAllUsedTypemaps(self): |
| 591 extra_headers = set() | 672 used_typemaps = [] |
| 592 for entry in self.typemap.itervalues(): | 673 seen_types = set() |
| 593 extra_headers.update(entry.get("public_headers", [])) | 674 def AddKind(kind): |
| 594 return list(extra_headers) | 675 if (mojom.IsIntegralKind(kind) or mojom.IsStringKind(kind) or |
| 676 mojom.IsDoubleKind(kind) or mojom.IsFloatKind(kind) or | |
| 677 mojom.IsAnyHandleKind(kind) or | |
| 678 mojom.IsInterfaceKind(kind) or | |
| 679 mojom.IsInterfaceRequestKind(kind) or | |
| 680 mojom.IsAssociatedKind(kind)): | |
| 681 pass | |
| 682 elif mojom.IsArrayKind(kind): | |
| 683 AddKind(kind.kind) | |
| 684 elif mojom.IsMapKind(kind): | |
| 685 AddKind(kind.key_kind) | |
| 686 AddKind(kind.value_kind) | |
| 687 else: | |
| 688 name = GetFullMojomNameForKind(kind) | |
| 689 if name in seen_types: | |
| 690 return | |
| 691 seen_types.add(name) | |
| 692 | |
| 693 typemap = _current_typemap.get(name, None) | |
| 694 if typemap: | |
| 695 used_typemaps.append(typemap) | |
| 696 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): | |
| 697 for field in kind.fields: | |
| 698 AddKind(field.kind) | |
| 699 | |
| 700 for kind in self.module.structs + self.module.unions: | |
|
yzshen1
2017/02/03 00:31:45
We should also consider enum typemapping, right? E
Sam McNally
2017/02/03 02:28:32
This is used to generate the list of traits header
| |
| 701 for field in kind.fields: | |
| 702 AddKind(field.kind) | |
| 703 | |
| 704 for interface in self.module.interfaces: | |
| 705 for method in interface.methods: | |
| 706 for parameter in method.parameters + (method.response_parameters or []): | |
| 707 AddKind(parameter.kind) | |
| 708 | |
| 709 return used_typemaps | |
| 710 | |
| 711 def _GetPublicHeadersImpl(self, header_type_to_headers): | |
| 712 header_types = set() | |
| 713 headers = set() | |
| 714 | |
| 715 if self.module.structs: | |
| 716 header_types.add('struct') | |
| 717 if self.module.unions: | |
| 718 header_types.add('union') | |
| 719 if self.module.interfaces: | |
| 720 header_types.add('interface') | |
| 721 | |
| 722 all_enums = list(self.module.enums) | |
| 723 for struct in self.module.structs: | |
| 724 all_enums.extend(struct.enums) | |
| 725 for interface in self.module.interfaces: | |
| 726 all_enums.extend(interface.enums) | |
| 727 | |
| 728 potential_types = set(GetFullMojomNameForKind(typename) | |
| 729 for typename in | |
| 730 self.module.structs + all_enums + self.module.unions) | |
| 731 for key, entry in self.typemap.iteritems(): | |
| 732 if key in potential_types: | |
| 733 headers.update(entry.get("public_headers", [])) | |
| 734 if all_enums: | |
| 735 header_types.add('enum') | |
| 736 native_enums = [enum.native_only for enum in all_enums] | |
| 737 if native_enums: | |
| 738 header_types.add('native_enum') | |
| 739 if len(native_enums) != len(all_enums): | |
| 740 header_types.add('non_native_enum') | |
| 741 | |
| 742 if any(struct.native_only for struct in self.module.structs): | |
| 743 header_types.add('native_struct') | |
| 744 for kind in self._GetDirectlyUsedKinds(): | |
| 745 if hasattr(kind, 'is_nullable') and kind.is_nullable: | |
| 746 header_types.add('optional') | |
| 747 if mojom.IsStringKind(kind): | |
| 748 header_types.add('string') | |
| 749 elif mojom.IsArrayKind(kind): | |
| 750 header_types.add('array') | |
| 751 elif mojom.IsMapKind(kind): | |
| 752 header_types.add('map') | |
| 753 for header_type in header_types: | |
| 754 headers.update(header_type_to_headers.get(header_type, [])) | |
| 755 return QuoteAndSortHeaders(headers) | |
| 756 | |
| 757 def GetPublicHeaders(self): | |
| 758 return self._GetPublicHeadersImpl( | |
| 759 BLINK_HEADERS if self.for_blink else CHROMIUM_HEADERS) | |
| 760 | |
| 761 def GetPublicSharedHeaders(self): | |
| 762 return self._GetPublicHeadersImpl(SHARED_HEADERS) | |
| 763 | |
| 764 def _GetDirectlyUsedKinds(self): | |
| 765 for struct in self.module.structs + self.module.unions: | |
| 766 for field in struct.fields: | |
| 767 yield field.kind | |
| 768 | |
| 769 for interface in self.module.interfaces: | |
| 770 for method in interface.methods: | |
| 771 for param in method.parameters + (method.response_parameters or []): | |
| 772 yield param.kind | |
| 595 | 773 |
| 596 def GetJinjaExports(self): | 774 def GetJinjaExports(self): |
| 597 structs = self.GetStructs() | 775 structs = self.GetStructs() |
| 598 interfaces = self.GetInterfaces() | 776 interfaces = self.GetInterfaces() |
| 599 all_enums = list(self.module.enums) | 777 all_enums = list(self.module.enums) |
| 600 for struct in structs: | 778 for struct in structs: |
| 601 all_enums.extend(struct.enums) | 779 all_enums.extend(struct.enums) |
| 602 for interface in interfaces: | 780 for interface in interfaces: |
| 603 all_enums.extend(interface.enums) | 781 all_enums.extend(interface.enums) |
| 604 | 782 |
| 605 return { | 783 return { |
| 606 "module": self.module, | 784 "module": self.module, |
| 607 "namespace": self.module.namespace, | 785 "namespace": self.module.namespace, |
| 608 "namespaces_as_array": NamespaceToArray(self.module.namespace), | 786 "namespaces_as_array": NamespaceToArray(self.module.namespace), |
| 609 "imports": self.module.imports, | 787 "imports": self.module.imports, |
| 610 "kinds": self.module.kinds, | 788 "kinds": self.module.kinds, |
| 611 "enums": self.module.enums, | 789 "enums": self.module.enums, |
| 612 "all_enums": all_enums, | 790 "all_enums": all_enums, |
| 613 "structs": structs, | 791 "structs": structs, |
| 614 "unions": self.GetUnions(), | 792 "unions": self.GetUnions(), |
| 615 "interfaces": interfaces, | 793 "interfaces": interfaces, |
| 616 "variant": self.variant, | 794 "variant": self.variant, |
| 617 "extra_traits_headers": self.GetExtraTraitsHeaders(), | 795 "extra_traits_headers": self.GetExtraTraitsHeaders(), |
| 618 "extra_public_headers": self.GetExtraPublicHeaders(), | 796 "public_headers": self.GetPublicHeaders(), |
| 797 "public_shared_headers": self.GetPublicSharedHeaders(), | |
| 619 "for_blink": self.for_blink, | 798 "for_blink": self.for_blink, |
| 620 "use_once_callback": self.use_once_callback, | 799 "use_once_callback": self.use_once_callback, |
| 621 "export_attribute": self.export_attribute, | 800 "export_attribute": self.export_attribute, |
| 622 "export_header": self.export_header, | 801 "export_header": self.export_header, |
| 623 } | 802 } |
| 624 | 803 |
| 625 @staticmethod | 804 @staticmethod |
| 626 def GetTemplatePrefix(): | 805 def GetTemplatePrefix(): |
| 627 return "cpp_templates" | 806 return "cpp_templates" |
| 628 | 807 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 global _use_once_callback | 846 global _use_once_callback |
| 668 _use_once_callback = self.use_once_callback | 847 _use_once_callback = self.use_once_callback |
| 669 global _variant | 848 global _variant |
| 670 _variant = self.variant | 849 _variant = self.variant |
| 671 suffix = "-%s" % self.variant if self.variant else "" | 850 suffix = "-%s" % self.variant if self.variant else "" |
| 672 self.Write(self.GenerateModuleHeader(), | 851 self.Write(self.GenerateModuleHeader(), |
| 673 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) | 852 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) |
| 674 self.Write( | 853 self.Write( |
| 675 self.GenerateModuleSource(), | 854 self.GenerateModuleSource(), |
| 676 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) | 855 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) |
| OLD | NEW |