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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 | 43 |
44 | 44 |
45 class _NameFormatter(object): | 45 class _NameFormatter(object): |
46 """A formatter for the names of kinds or values.""" | 46 """A formatter for the names of kinds or values.""" |
47 | 47 |
48 def __init__(self, token, variant): | 48 def __init__(self, token, variant): |
49 self._token = token | 49 self._token = token |
50 self._variant = variant | 50 self._variant = variant |
51 | 51 |
52 def Format(self, separator, prefixed=False, internal=False, | 52 def Format(self, separator, prefixed=False, internal=False, |
53 include_variant=False, add_same_module_namespaces=False): | 53 include_variant=False, add_same_module_namespaces=False, |
| 54 flatten_nested_kind=False): |
| 55 """Formats the name according to the given configuration. |
| 56 |
| 57 Args: |
| 58 separator: Separator between different parts of the name. |
| 59 prefixed: Whether a leading separator should be added. |
| 60 internal: Returns the name in the "internal" namespace. |
| 61 include_variant: Whether to include variant as namespace. If |internal| is |
| 62 True, then this flag is ignored and variant is not included. |
| 63 add_same_module_namespaces: Includes all namespaces even if the token is |
| 64 from the same module as the current mojom file. |
| 65 flatten_nested_kind: It is allowed to define enums inside structs and |
| 66 interfaces. If this flag is set to True, this method concatenates the |
| 67 parent kind and the nested kind with '_', instead of treating the |
| 68 parent kind as a scope.""" |
| 69 |
54 parts = [] | 70 parts = [] |
55 if self._ShouldIncludeNamespace(add_same_module_namespaces): | 71 if self._ShouldIncludeNamespace(add_same_module_namespaces): |
56 if prefixed: | 72 if prefixed: |
57 parts.append("") | 73 parts.append("") |
58 parts.extend(self._GetNamespace()) | 74 parts.extend(self._GetNamespace()) |
59 if include_variant and self._variant: | 75 if include_variant and self._variant and not internal: |
60 parts.append(self._variant) | 76 parts.append(self._variant) |
61 parts.extend(self._GetName(internal)) | 77 parts.extend(self._GetName(internal, flatten_nested_kind)) |
62 return separator.join(parts) | 78 return separator.join(parts) |
63 | 79 |
64 def FormatForCpp(self, add_same_module_namespaces=False, internal=False): | 80 def FormatForCpp(self, add_same_module_namespaces=False, internal=False, |
| 81 flatten_nested_kind=False): |
65 return self.Format( | 82 return self.Format( |
66 "::", prefixed=True, | 83 "::", prefixed=True, |
67 add_same_module_namespaces=add_same_module_namespaces, | 84 add_same_module_namespaces=add_same_module_namespaces, |
68 internal=internal, include_variant=True) | 85 internal=internal, include_variant=True, |
| 86 flatten_nested_kind=flatten_nested_kind) |
69 | 87 |
70 def FormatForMojom(self): | 88 def FormatForMojom(self): |
71 return self.Format(".", add_same_module_namespaces=True) | 89 return self.Format(".", add_same_module_namespaces=True) |
72 | 90 |
73 def _MapKindName(self, token, internal): | 91 def _MapKindName(self, token, internal): |
74 if not internal: | 92 if not internal: |
75 return token.name | 93 return token.name |
76 if (mojom.IsStructKind(token) or mojom.IsUnionKind(token) or | 94 if (mojom.IsStructKind(token) or mojom.IsUnionKind(token) or |
77 mojom.IsInterfaceKind(token) or mojom.IsEnumKind(token)): | 95 mojom.IsEnumKind(token)): |
78 return token.name + "_Data" | 96 return token.name + "_Data" |
79 return token.name | 97 return token.name |
80 | 98 |
81 def _GetName(self, internal): | 99 def _GetName(self, internal, flatten_nested_kind): |
82 name = [] | 100 if isinstance(self._token, mojom.EnumValue): |
| 101 name_parts = _NameFormatter(self._token.enum, self._variant)._GetName( |
| 102 internal, flatten_nested_kind) |
| 103 name_parts.append(self._token.name) |
| 104 return name_parts |
| 105 |
| 106 name_parts = [] |
83 if internal: | 107 if internal: |
84 name.append("internal") | 108 name_parts.append("internal") |
| 109 |
| 110 if (flatten_nested_kind and mojom.IsEnumKind(self._token) and |
| 111 self._token.parent_kind): |
| 112 name = "%s_%s" % (self._token.parent_kind.name, |
| 113 self._MapKindName(self._token, internal)) |
| 114 name_parts.append(name) |
| 115 return name_parts |
| 116 |
85 if self._token.parent_kind: | 117 if self._token.parent_kind: |
86 name.append(self._MapKindName(self._token.parent_kind, internal)) | 118 name_parts.append(self._MapKindName(self._token.parent_kind, internal)) |
87 # Both variable and enum constants are constructed like: | 119 name_parts.append(self._MapKindName(self._token, internal)) |
88 # Namespace::Struct::CONSTANT_NAME | 120 return name_parts |
89 # For enums, CONSTANT_NAME is EnumName::ENUM_VALUE. | |
90 if isinstance(self._token, mojom.EnumValue): | |
91 name.extend([self._token.enum.name, self._token.name]) | |
92 else: | |
93 name.append(self._MapKindName(self._token, internal)) | |
94 return name | |
95 | 121 |
96 def _ShouldIncludeNamespace(self, add_same_module_namespaces): | 122 def _ShouldIncludeNamespace(self, add_same_module_namespaces): |
97 return add_same_module_namespaces or self._token.imported_from | 123 return add_same_module_namespaces or self._token.imported_from |
98 | 124 |
99 def _GetNamespace(self): | 125 def _GetNamespace(self): |
100 if self._token.imported_from: | 126 if self._token.imported_from: |
101 return NamespaceToArray(self._token.imported_from["namespace"]) | 127 return NamespaceToArray(self._token.imported_from["namespace"]) |
102 elif hasattr(self._token, "module"): | 128 elif hasattr(self._token, "module"): |
103 return NamespaceToArray(self._token.module.namespace) | 129 return NamespaceToArray(self._token.module.namespace) |
104 return [] | 130 return [] |
(...skipping 14 matching lines...) Expand all Loading... |
119 if not _use_new_wrapper_types: | 145 if not _use_new_wrapper_types: |
120 if mojom.IsArrayKind(field.kind) or mojom.IsMapKind(field.kind): | 146 if mojom.IsArrayKind(field.kind) or mojom.IsMapKind(field.kind): |
121 return "nullptr"; | 147 return "nullptr"; |
122 if mojom.IsStringKind(field.kind): | 148 if mojom.IsStringKind(field.kind): |
123 return "" if _for_blink else "nullptr" | 149 return "" if _for_blink else "nullptr" |
124 return "" | 150 return "" |
125 | 151 |
126 def NamespaceToArray(namespace): | 152 def NamespaceToArray(namespace): |
127 return namespace.split(".") if namespace else [] | 153 return namespace.split(".") if namespace else [] |
128 | 154 |
129 def GetNameForKind(kind, internal=False): | 155 def GetNameForKind(kind, internal=False, flatten_nested_kind=False): |
130 return _NameFormatter(kind, _variant).FormatForCpp(internal=internal) | 156 return _NameFormatter(kind, _variant).FormatForCpp( |
| 157 internal=internal, flatten_nested_kind=flatten_nested_kind) |
131 | 158 |
132 def GetQualifiedNameForKind(kind, internal=False): | 159 def GetQualifiedNameForKind(kind, internal=False, flatten_nested_kind=False): |
133 return _NameFormatter(kind, _variant).FormatForCpp( | 160 return _NameFormatter(kind, _variant).FormatForCpp( |
134 internal=internal, add_same_module_namespaces=True) | 161 internal=internal, add_same_module_namespaces=True, |
| 162 flatten_nested_kind=flatten_nested_kind) |
135 | 163 |
136 def GetFullMojomNameForKind(kind): | 164 def GetFullMojomNameForKind(kind): |
137 return _NameFormatter(kind, _variant).FormatForMojom() | 165 return _NameFormatter(kind, _variant).FormatForMojom() |
138 | 166 |
139 def IsTypemappedKind(kind): | 167 def IsTypemappedKind(kind): |
140 return hasattr(kind, "name") and \ | 168 return hasattr(kind, "name") and \ |
141 GetFullMojomNameForKind(kind) in _current_typemap | 169 GetFullMojomNameForKind(kind) in _current_typemap |
142 | 170 |
143 def IsNativeOnlyKind(kind): | 171 def IsNativeOnlyKind(kind): |
144 return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \ | 172 return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \ |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 if mojom.IsDataPipeProducerKind(kind): | 355 if mojom.IsDataPipeProducerKind(kind): |
328 return "mojo::ScopedDataPipeProducerHandle" | 356 return "mojo::ScopedDataPipeProducerHandle" |
329 if mojom.IsMessagePipeKind(kind): | 357 if mojom.IsMessagePipeKind(kind): |
330 return "mojo::ScopedMessagePipeHandle" | 358 return "mojo::ScopedMessagePipeHandle" |
331 if mojom.IsSharedBufferKind(kind): | 359 if mojom.IsSharedBufferKind(kind): |
332 return "mojo::ScopedSharedBufferHandle" | 360 return "mojo::ScopedSharedBufferHandle" |
333 return _kind_to_cpp_type[kind] | 361 return _kind_to_cpp_type[kind] |
334 | 362 |
335 def TranslateConstants(token, kind): | 363 def TranslateConstants(token, kind): |
336 if isinstance(token, mojom.NamedValue): | 364 if isinstance(token, mojom.NamedValue): |
337 return _NameFormatter(token, _variant).FormatForCpp() | 365 return _NameFormatter(token, _variant).FormatForCpp( |
| 366 flatten_nested_kind=True) |
338 | 367 |
339 if isinstance(token, mojom.BuiltinValue): | 368 if isinstance(token, mojom.BuiltinValue): |
340 if token.value == "double.INFINITY" or token.value == "float.INFINITY": | 369 if token.value == "double.INFINITY" or token.value == "float.INFINITY": |
341 return "INFINITY"; | 370 return "INFINITY"; |
342 if token.value == "double.NEGATIVE_INFINITY" or \ | 371 if token.value == "double.NEGATIVE_INFINITY" or \ |
343 token.value == "float.NEGATIVE_INFINITY": | 372 token.value == "float.NEGATIVE_INFINITY": |
344 return "-INFINITY"; | 373 return "-INFINITY"; |
345 if token.value == "double.NAN" or token.value == "float.NAN": | 374 if token.value == "double.NAN" or token.value == "float.NAN": |
346 return "NAN"; | 375 return "NAN"; |
347 | 376 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 element_validate_params = GetNewContainerValidateParams(mojom.Array( | 432 element_validate_params = GetNewContainerValidateParams(mojom.Array( |
404 kind=kind.value_kind)) | 433 kind=kind.value_kind)) |
405 enum_validate_func = "nullptr" | 434 enum_validate_func = "nullptr" |
406 else: # mojom.IsArrayKind(kind) | 435 else: # mojom.IsArrayKind(kind) |
407 expected_num_elements = generator.ExpectedArraySize(kind) or 0 | 436 expected_num_elements = generator.ExpectedArraySize(kind) or 0 |
408 element_is_nullable = mojom.IsNullableKind(kind.kind) | 437 element_is_nullable = mojom.IsNullableKind(kind.kind) |
409 key_validate_params = "nullptr" | 438 key_validate_params = "nullptr" |
410 element_validate_params = GetNewContainerValidateParams(kind.kind) | 439 element_validate_params = GetNewContainerValidateParams(kind.kind) |
411 if mojom.IsEnumKind(kind.kind): | 440 if mojom.IsEnumKind(kind.kind): |
412 enum_validate_func = ("%s::Validate" % | 441 enum_validate_func = ("%s::Validate" % |
413 GetQualifiedNameForKind(kind.kind, internal=True)) | 442 GetQualifiedNameForKind(kind.kind, internal=True, |
| 443 flatten_nested_kind=True)) |
414 else: | 444 else: |
415 enum_validate_func = "nullptr" | 445 enum_validate_func = "nullptr" |
416 | 446 |
417 if enum_validate_func == "nullptr": | 447 if enum_validate_func == "nullptr": |
418 if key_validate_params == "nullptr": | 448 if key_validate_params == "nullptr": |
419 return "%d, %s, %s" % (expected_num_elements, | 449 return "%d, %s, %s" % (expected_num_elements, |
420 "true" if element_is_nullable else "false", | 450 "true" if element_is_nullable else "false", |
421 element_validate_params) | 451 element_validate_params) |
422 else: | 452 else: |
423 return "%s, %s" % (key_validate_params, element_validate_params) | 453 return "%s, %s" % (key_validate_params, element_validate_params) |
(...skipping 15 matching lines...) Expand all Loading... |
439 "cpp_wrapper_param_type": GetCppWrapperParamType, | 469 "cpp_wrapper_param_type": GetCppWrapperParamType, |
440 "cpp_data_view_type": GetCppDataViewType, | 470 "cpp_data_view_type": GetCppDataViewType, |
441 "cpp_field_type": GetCppFieldType, | 471 "cpp_field_type": GetCppFieldType, |
442 "cpp_union_field_type": GetCppUnionFieldType, | 472 "cpp_union_field_type": GetCppUnionFieldType, |
443 "cpp_pod_type": GetCppPodType, | 473 "cpp_pod_type": GetCppPodType, |
444 "cpp_union_getter_return_type": GetUnionGetterReturnType, | 474 "cpp_union_getter_return_type": GetUnionGetterReturnType, |
445 "cpp_wrapper_type": GetCppWrapperType, | 475 "cpp_wrapper_type": GetCppWrapperType, |
446 "default_value": DefaultValue, | 476 "default_value": DefaultValue, |
447 "expression_to_text": ExpressionToText, | 477 "expression_to_text": ExpressionToText, |
448 "get_container_validate_params_ctor_args": | 478 "get_container_validate_params_ctor_args": |
449 GetContainerValidateParamsCtorArgs, | 479 GetContainerValidateParamsCtorArgs, |
450 "get_name_for_kind": GetNameForKind, | 480 "get_name_for_kind": GetNameForKind, |
451 "get_pad": pack.GetPad, | 481 "get_pad": pack.GetPad, |
452 "get_qualified_name_for_kind": GetQualifiedNameForKind, | 482 "get_qualified_name_for_kind": GetQualifiedNameForKind, |
453 "has_callbacks": mojom.HasCallbacks, | 483 "has_callbacks": mojom.HasCallbacks, |
454 "has_sync_methods": mojom.HasSyncMethods, | 484 "has_sync_methods": mojom.HasSyncMethods, |
455 "requires_context_for_data_view": RequiresContextForDataView, | 485 "requires_context_for_data_view": RequiresContextForDataView, |
456 "should_inline": ShouldInlineStruct, | 486 "should_inline": ShouldInlineStruct, |
457 "should_inline_union": ShouldInlineUnion, | 487 "should_inline_union": ShouldInlineUnion, |
458 "is_array_kind": mojom.IsArrayKind, | 488 "is_array_kind": mojom.IsArrayKind, |
459 "is_enum_kind": mojom.IsEnumKind, | 489 "is_enum_kind": mojom.IsEnumKind, |
(...skipping 21 matching lines...) Expand all Loading... |
481 extra_headers.update(entry.get("traits_headers", [])) | 511 extra_headers.update(entry.get("traits_headers", [])) |
482 return list(extra_headers) | 512 return list(extra_headers) |
483 | 513 |
484 def GetExtraPublicHeaders(self): | 514 def GetExtraPublicHeaders(self): |
485 extra_headers = set() | 515 extra_headers = set() |
486 for entry in self.typemap.itervalues(): | 516 for entry in self.typemap.itervalues(): |
487 extra_headers.update(entry.get("public_headers", [])) | 517 extra_headers.update(entry.get("public_headers", [])) |
488 return list(extra_headers) | 518 return list(extra_headers) |
489 | 519 |
490 def GetJinjaExports(self): | 520 def GetJinjaExports(self): |
| 521 structs = self.GetStructs() |
| 522 interfaces = self.GetInterfaces() |
| 523 all_enums = list(self.module.enums) |
| 524 for struct in structs: |
| 525 all_enums.extend(struct.enums) |
| 526 for interface in interfaces: |
| 527 all_enums.extend(interface.enums) |
| 528 |
491 return { | 529 return { |
492 "module": self.module, | 530 "module": self.module, |
493 "namespace": self.module.namespace, | 531 "namespace": self.module.namespace, |
494 "namespaces_as_array": NamespaceToArray(self.module.namespace), | 532 "namespaces_as_array": NamespaceToArray(self.module.namespace), |
495 "imports": self.module.imports, | 533 "imports": self.module.imports, |
496 "kinds": self.module.kinds, | 534 "kinds": self.module.kinds, |
497 "enums": self.module.enums, | 535 "enums": self.module.enums, |
498 "structs": self.GetStructs(), | 536 "all_enums": all_enums, |
| 537 "structs": structs, |
499 "unions": self.GetUnions(), | 538 "unions": self.GetUnions(), |
500 "interfaces": self.GetInterfaces(), | 539 "interfaces": interfaces, |
501 "variant": self.variant, | 540 "variant": self.variant, |
502 "extra_traits_headers": self.GetExtraTraitsHeaders(), | 541 "extra_traits_headers": self.GetExtraTraitsHeaders(), |
503 "extra_public_headers": self.GetExtraPublicHeaders(), | 542 "extra_public_headers": self.GetExtraPublicHeaders(), |
504 "for_blink": self.for_blink, | 543 "for_blink": self.for_blink, |
505 "use_new_wrapper_types": self.use_new_wrapper_types, | 544 "use_new_wrapper_types": self.use_new_wrapper_types, |
506 "export_attribute": self.export_attribute, | 545 "export_attribute": self.export_attribute, |
507 "export_header": self.export_header, | 546 "export_header": self.export_header, |
508 } | 547 } |
509 | 548 |
510 @staticmethod | 549 @staticmethod |
511 def GetTemplatePrefix(): | 550 def GetTemplatePrefix(): |
512 return "cpp_templates" | 551 return "cpp_templates" |
513 | 552 |
514 @classmethod | 553 @classmethod |
515 def GetFilters(cls): | 554 def GetFilters(cls): |
516 return cls.cpp_filters | 555 return cls.cpp_filters |
517 | 556 |
518 @UseJinja("module.h.tmpl") | 557 @UseJinja("module.h.tmpl") |
519 def GenerateModuleHeader(self): | 558 def GenerateModuleHeader(self): |
520 return self.GetJinjaExports() | 559 return self.GetJinjaExports() |
521 | 560 |
522 @UseJinja("module-internal.h.tmpl") | |
523 def GenerateModuleInternalHeader(self): | |
524 return self.GetJinjaExports() | |
525 | |
526 @UseJinja("module.cc.tmpl") | 561 @UseJinja("module.cc.tmpl") |
527 def GenerateModuleSource(self): | 562 def GenerateModuleSource(self): |
528 return self.GetJinjaExports() | 563 return self.GetJinjaExports() |
529 | 564 |
530 @UseJinja("module-shared.h.tmpl") | 565 @UseJinja("module-shared.h.tmpl") |
531 def GenerateModuleSharedHeader(self): | 566 def GenerateModuleSharedHeader(self): |
532 return self.GetJinjaExports() | 567 return self.GetJinjaExports() |
533 | 568 |
534 @UseJinja("module-shared-internal.h.tmpl") | 569 @UseJinja("module-shared-internal.h.tmpl") |
535 def GenerateModuleSharedInternalHeader(self): | 570 def GenerateModuleSharedInternalHeader(self): |
(...skipping 17 matching lines...) Expand all Loading... |
553 _current_typemap = self.typemap | 588 _current_typemap = self.typemap |
554 global _for_blink | 589 global _for_blink |
555 _for_blink = self.for_blink | 590 _for_blink = self.for_blink |
556 global _use_new_wrapper_types | 591 global _use_new_wrapper_types |
557 _use_new_wrapper_types = self.use_new_wrapper_types | 592 _use_new_wrapper_types = self.use_new_wrapper_types |
558 global _variant | 593 global _variant |
559 _variant = self.variant | 594 _variant = self.variant |
560 suffix = "-%s" % self.variant if self.variant else "" | 595 suffix = "-%s" % self.variant if self.variant else "" |
561 self.Write(self.GenerateModuleHeader(), | 596 self.Write(self.GenerateModuleHeader(), |
562 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) | 597 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) |
563 self.Write(self.GenerateModuleInternalHeader(), | |
564 self.MatchMojomFilePath("%s%s-internal.h" % | |
565 (self.module.name, suffix))) | |
566 self.Write( | 598 self.Write( |
567 self.GenerateModuleSource(), | 599 self.GenerateModuleSource(), |
568 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) | 600 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) |
OLD | NEW |