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 18 matching lines...) Expand all Loading... |
29 mojom.UINT16: "U", | 29 mojom.UINT16: "U", |
30 mojom.UINT32: "U", | 30 mojom.UINT32: "U", |
31 mojom.FLOAT: "f", | 31 mojom.FLOAT: "f", |
32 mojom.UINT64: "ULL", | 32 mojom.UINT64: "ULL", |
33 } | 33 } |
34 | 34 |
35 # TODO(rockot): Get rid of these globals. This requires some refactoring of the | 35 # TODO(rockot): Get rid of these globals. This requires some refactoring of the |
36 # generator library code so that filters can use the generator as context. | 36 # generator library code so that filters can use the generator as context. |
37 _current_typemap = {} | 37 _current_typemap = {} |
38 _for_blink = False | 38 _for_blink = False |
| 39 _use_new_wrapper_types = False |
39 # TODO(rockot, yzshen): The variant handling is kind of a hack currently. Make | 40 # TODO(rockot, yzshen): The variant handling is kind of a hack currently. Make |
40 # it right. | 41 # it right. |
41 _variant = None | 42 _variant = None |
42 | 43 |
43 | 44 |
44 class _NameFormatter(object): | 45 class _NameFormatter(object): |
45 """A formatter for the names of kinds or values.""" | 46 """A formatter for the names of kinds or values.""" |
46 | 47 |
47 def __init__(self, token, variant): | 48 def __init__(self, token, variant): |
48 self._token = token | 49 self._token = token |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 if self._token.imported_from: | 100 if self._token.imported_from: |
100 return NamespaceToArray(self._token.imported_from["namespace"]) | 101 return NamespaceToArray(self._token.imported_from["namespace"]) |
101 elif hasattr(self._token, "module"): | 102 elif hasattr(self._token, "module"): |
102 return NamespaceToArray(self._token.module.namespace) | 103 return NamespaceToArray(self._token.module.namespace) |
103 return [] | 104 return [] |
104 | 105 |
105 | 106 |
106 def ConstantValue(constant): | 107 def ConstantValue(constant): |
107 return ExpressionToText(constant.value, kind=constant.kind) | 108 return ExpressionToText(constant.value, kind=constant.kind) |
108 | 109 |
| 110 # TODO(yzshen): Revisit the default value feature. It was designed prior to |
| 111 # custom type mapping. |
109 def DefaultValue(field): | 112 def DefaultValue(field): |
110 if field.default: | 113 if field.default: |
111 if mojom.IsStructKind(field.kind): | 114 if mojom.IsStructKind(field.kind): |
112 assert field.default == "default" | 115 assert field.default == "default" |
113 return "%s::New()" % GetNameForKind(field.kind) | 116 if not IsTypemappedKind(field.kind): |
| 117 return "%s::New()" % GetNameForKind(field.kind) |
114 return ExpressionToText(field.default, kind=field.kind) | 118 return ExpressionToText(field.default, kind=field.kind) |
115 if mojom.IsArrayKind(field.kind) or mojom.IsMapKind(field.kind): | 119 if not _use_new_wrapper_types: |
116 return "nullptr"; | 120 if mojom.IsArrayKind(field.kind) or mojom.IsMapKind(field.kind): |
117 if mojom.IsStringKind(field.kind): | 121 return "nullptr"; |
118 return "" if _for_blink else "nullptr" | 122 if mojom.IsStringKind(field.kind): |
| 123 return "" if _for_blink else "nullptr" |
119 return "" | 124 return "" |
120 | 125 |
121 def NamespaceToArray(namespace): | 126 def NamespaceToArray(namespace): |
122 return namespace.split(".") if namespace else [] | 127 return namespace.split(".") if namespace else [] |
123 | 128 |
124 def GetNameForKind(kind, internal=False): | 129 def GetNameForKind(kind, internal=False): |
125 return _NameFormatter(kind, _variant).FormatForCpp(internal=internal) | 130 return _NameFormatter(kind, _variant).FormatForCpp(internal=internal) |
126 | 131 |
127 def GetQualifiedNameForKind(kind, internal=False): | 132 def GetQualifiedNameForKind(kind, internal=False): |
128 return _NameFormatter(kind, _variant).FormatForCpp( | 133 return _NameFormatter(kind, _variant).FormatForCpp( |
(...skipping 19 matching lines...) Expand all Loading... |
148 return _kind_to_cpp_type[kind] | 153 return _kind_to_cpp_type[kind] |
149 | 154 |
150 def GetCppWrapperType(kind): | 155 def GetCppWrapperType(kind): |
151 if IsTypemappedKind(kind): | 156 if IsTypemappedKind(kind): |
152 return GetNativeTypeName(kind) | 157 return GetNativeTypeName(kind) |
153 if mojom.IsEnumKind(kind): | 158 if mojom.IsEnumKind(kind): |
154 return GetNameForKind(kind) | 159 return GetNameForKind(kind) |
155 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): | 160 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): |
156 return "%sPtr" % GetNameForKind(kind) | 161 return "%sPtr" % GetNameForKind(kind) |
157 if mojom.IsArrayKind(kind): | 162 if mojom.IsArrayKind(kind): |
158 pattern = "mojo::WTFArray<%s>" if _for_blink else "mojo::Array<%s>" | 163 pattern = None |
| 164 if _use_new_wrapper_types: |
| 165 if mojom.IsNullableKind(kind): |
| 166 pattern = ("WTF::Optional<WTF::Vector<%s>>" if _for_blink else |
| 167 "base::Optional<std::vector<%s>>") |
| 168 else: |
| 169 pattern = "WTF::Vector<%s>" if _for_blink else "std::vector<%s>" |
| 170 else: |
| 171 pattern = "mojo::WTFArray<%s>" if _for_blink else "mojo::Array<%s>" |
159 return pattern % GetCppWrapperType(kind.kind) | 172 return pattern % GetCppWrapperType(kind.kind) |
160 if mojom.IsMapKind(kind): | 173 if mojom.IsMapKind(kind): |
161 pattern = "mojo::WTFMap<%s, %s>" if _for_blink else "mojo::Map<%s, %s>" | 174 pattern = None |
| 175 if _use_new_wrapper_types: |
| 176 if mojom.IsNullableKind(kind): |
| 177 pattern = ("WTF::Optional<WTF::HashMap<%s, %s>>" if _for_blink else |
| 178 "base::Optional<std::unordered_map<%s, %s>>") |
| 179 else: |
| 180 pattern = ("WTF::HashMap<%s, %s>" if _for_blink else |
| 181 "std::unordered_map<%s, %s>") |
| 182 else: |
| 183 pattern = "mojo::WTFMap<%s, %s>" if _for_blink else "mojo::Map<%s, %s>" |
162 return pattern % (GetCppWrapperType(kind.key_kind), | 184 return pattern % (GetCppWrapperType(kind.key_kind), |
163 GetCppWrapperType(kind.value_kind)) | 185 GetCppWrapperType(kind.value_kind)) |
164 if mojom.IsInterfaceKind(kind): | 186 if mojom.IsInterfaceKind(kind): |
165 return "%sPtr" % GetNameForKind(kind) | 187 return "%sPtr" % GetNameForKind(kind) |
166 if mojom.IsInterfaceRequestKind(kind): | 188 if mojom.IsInterfaceRequestKind(kind): |
167 return "%sRequest" % GetNameForKind(kind.kind) | 189 return "%sRequest" % GetNameForKind(kind.kind) |
168 if mojom.IsAssociatedInterfaceKind(kind): | 190 if mojom.IsAssociatedInterfaceKind(kind): |
169 return "%sAssociatedPtrInfo" % GetNameForKind(kind.kind) | 191 return "%sAssociatedPtrInfo" % GetNameForKind(kind.kind) |
170 if mojom.IsAssociatedInterfaceRequestKind(kind): | 192 if mojom.IsAssociatedInterfaceRequestKind(kind): |
171 return "%sAssociatedRequest" % GetNameForKind(kind.kind) | 193 return "%sAssociatedRequest" % GetNameForKind(kind.kind) |
172 if mojom.IsStringKind(kind): | 194 if mojom.IsStringKind(kind): |
173 return "WTF::String" if _for_blink else "mojo::String" | 195 if _for_blink: |
| 196 return "WTF::String" |
| 197 if not _use_new_wrapper_types: |
| 198 return "mojo::String" |
| 199 return ("base::Optional<std::string>" if mojom.IsNullableKind(kind) else |
| 200 "std::string") |
174 if mojom.IsGenericHandleKind(kind): | 201 if mojom.IsGenericHandleKind(kind): |
175 return "mojo::ScopedHandle" | 202 return "mojo::ScopedHandle" |
176 if mojom.IsDataPipeConsumerKind(kind): | 203 if mojom.IsDataPipeConsumerKind(kind): |
177 return "mojo::ScopedDataPipeConsumerHandle" | 204 return "mojo::ScopedDataPipeConsumerHandle" |
178 if mojom.IsDataPipeProducerKind(kind): | 205 if mojom.IsDataPipeProducerKind(kind): |
179 return "mojo::ScopedDataPipeProducerHandle" | 206 return "mojo::ScopedDataPipeProducerHandle" |
180 if mojom.IsMessagePipeKind(kind): | 207 if mojom.IsMessagePipeKind(kind): |
181 return "mojo::ScopedMessagePipeHandle" | 208 return "mojo::ScopedMessagePipeHandle" |
182 if mojom.IsSharedBufferKind(kind): | 209 if mojom.IsSharedBufferKind(kind): |
183 return "mojo::ScopedSharedBufferHandle" | 210 return "mojo::ScopedSharedBufferHandle" |
184 if not kind in _kind_to_cpp_type: | 211 if not kind in _kind_to_cpp_type: |
185 raise Exception("Unrecognized kind %s" % kind.spec) | 212 raise Exception("Unrecognized kind %s" % kind.spec) |
186 return _kind_to_cpp_type[kind] | 213 return _kind_to_cpp_type[kind] |
187 | 214 |
188 def ShouldPassParamByValue(kind): | 215 def IsMoveOnlyKind(kind): |
189 if IsTypemappedKind(kind): | 216 if IsTypemappedKind(kind): |
190 if mojom.IsEnumKind(kind): | 217 if mojom.IsEnumKind(kind): |
191 return True | 218 return False |
| 219 # TODO(yzshen): Change the attribute to "move_only". |
192 return _current_typemap[GetFullMojomNameForKind(kind)]["pass_by_value"] | 220 return _current_typemap[GetFullMojomNameForKind(kind)]["pass_by_value"] |
193 return not mojom.IsStringKind(kind) | 221 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): |
| 222 return True |
| 223 if mojom.IsArrayKind(kind): |
| 224 return IsMoveOnlyKind(kind.kind) if _use_new_wrapper_types else True |
| 225 if mojom.IsMapKind(kind): |
| 226 return IsMoveOnlyKind(kind.value_kind) if _use_new_wrapper_types else True |
| 227 if mojom.IsAnyHandleOrInterfaceKind(kind): |
| 228 return True |
| 229 return False |
| 230 |
| 231 def ShouldPassParamByValue(kind): |
| 232 return (not mojom.IsReferenceKind(kind)) or IsMoveOnlyKind(kind) |
194 | 233 |
195 def GetCppWrapperParamType(kind): | 234 def GetCppWrapperParamType(kind): |
196 cpp_wrapper_type = GetCppWrapperType(kind) | 235 cpp_wrapper_type = GetCppWrapperType(kind) |
197 return (cpp_wrapper_type if ShouldPassParamByValue(kind) | 236 return (cpp_wrapper_type if ShouldPassParamByValue(kind) |
198 else "const %s&" % cpp_wrapper_type) | 237 else "const %s&" % cpp_wrapper_type) |
199 | 238 |
200 def GetCppFieldType(kind): | 239 def GetCppFieldType(kind): |
201 if mojom.IsStructKind(kind): | 240 if mojom.IsStructKind(kind): |
202 return ("mojo::internal::Pointer<%s>" % | 241 return ("mojo::internal::Pointer<%s>" % |
203 GetNameForKind(kind, internal=True)) | 242 GetNameForKind(kind, internal=True)) |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, "")) | 341 return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, "")) |
303 | 342 |
304 def ExpressionToText(value, kind=None): | 343 def ExpressionToText(value, kind=None): |
305 return TranslateConstants(value, kind) | 344 return TranslateConstants(value, kind) |
306 | 345 |
307 def ShouldInlineStruct(struct): | 346 def ShouldInlineStruct(struct): |
308 # TODO(darin): Base this on the size of the wrapper class. | 347 # TODO(darin): Base this on the size of the wrapper class. |
309 if len(struct.fields) > 4: | 348 if len(struct.fields) > 4: |
310 return False | 349 return False |
311 for field in struct.fields: | 350 for field in struct.fields: |
312 if mojom.IsMoveOnlyKind(field.kind): | 351 if mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind): |
313 return False | 352 return False |
314 return True | 353 return True |
315 | 354 |
316 def ShouldInlineUnion(union): | 355 def ShouldInlineUnion(union): |
317 return not any(mojom.IsMoveOnlyKind(field.kind) for field in union.fields) | 356 return not any( |
| 357 mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind) |
| 358 for field in union.fields) |
318 | 359 |
319 def GetContainerValidateParamsCtorArgs(kind): | 360 def GetContainerValidateParamsCtorArgs(kind): |
320 if mojom.IsStringKind(kind): | 361 if mojom.IsStringKind(kind): |
321 expected_num_elements = 0 | 362 expected_num_elements = 0 |
322 element_is_nullable = False | 363 element_is_nullable = False |
323 key_validate_params = "nullptr" | 364 key_validate_params = "nullptr" |
324 element_validate_params = "nullptr" | 365 element_validate_params = "nullptr" |
325 enum_validate_func = "nullptr" | 366 enum_validate_func = "nullptr" |
326 elif mojom.IsMapKind(kind): | 367 elif mojom.IsMapKind(kind): |
327 expected_num_elements = 0 | 368 expected_num_elements = 0 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 "imports": self.module.imports, | 462 "imports": self.module.imports, |
422 "kinds": self.module.kinds, | 463 "kinds": self.module.kinds, |
423 "enums": self.module.enums, | 464 "enums": self.module.enums, |
424 "structs": self.GetStructs(), | 465 "structs": self.GetStructs(), |
425 "unions": self.GetUnions(), | 466 "unions": self.GetUnions(), |
426 "interfaces": self.GetInterfaces(), | 467 "interfaces": self.GetInterfaces(), |
427 "variant": self.variant, | 468 "variant": self.variant, |
428 "extra_traits_headers": self.GetExtraTraitsHeaders(), | 469 "extra_traits_headers": self.GetExtraTraitsHeaders(), |
429 "extra_public_headers": self.GetExtraPublicHeaders(), | 470 "extra_public_headers": self.GetExtraPublicHeaders(), |
430 "for_blink": self.for_blink, | 471 "for_blink": self.for_blink, |
| 472 "use_new_wrapper_types": self.use_new_wrapper_types, |
431 } | 473 } |
432 | 474 |
433 @staticmethod | 475 @staticmethod |
434 def GetTemplatePrefix(): | 476 def GetTemplatePrefix(): |
435 return "cpp_templates" | 477 return "cpp_templates" |
436 | 478 |
437 @classmethod | 479 @classmethod |
438 def GetFilters(cls): | 480 def GetFilters(cls): |
439 return cls.cpp_filters | 481 return cls.cpp_filters |
440 | 482 |
441 @UseJinja("module.h.tmpl") | 483 @UseJinja("module.h.tmpl") |
442 def GenerateModuleHeader(self): | 484 def GenerateModuleHeader(self): |
443 return self.GetJinjaExports() | 485 return self.GetJinjaExports() |
444 | 486 |
445 @UseJinja("module-internal.h.tmpl") | 487 @UseJinja("module-internal.h.tmpl") |
446 def GenerateModuleInternalHeader(self): | 488 def GenerateModuleInternalHeader(self): |
447 return self.GetJinjaExports() | 489 return self.GetJinjaExports() |
448 | 490 |
449 @UseJinja("module.cc.tmpl") | 491 @UseJinja("module.cc.tmpl") |
450 def GenerateModuleSource(self): | 492 def GenerateModuleSource(self): |
451 return self.GetJinjaExports() | 493 return self.GetJinjaExports() |
452 | 494 |
453 def GenerateFiles(self, args): | 495 def GenerateFiles(self, args): |
454 global _current_typemap | 496 global _current_typemap |
455 _current_typemap = self.typemap | 497 _current_typemap = self.typemap |
456 global _for_blink | 498 global _for_blink |
457 _for_blink = self.for_blink | 499 _for_blink = self.for_blink |
| 500 global _use_new_wrapper_types |
| 501 _use_new_wrapper_types = self.use_new_wrapper_types |
458 global _variant | 502 global _variant |
459 _variant = self.variant | 503 _variant = self.variant |
460 suffix = "-%s" % self.variant if self.variant else "" | 504 suffix = "-%s" % self.variant if self.variant else "" |
461 self.Write(self.GenerateModuleHeader(), | 505 self.Write(self.GenerateModuleHeader(), |
462 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) | 506 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) |
463 self.Write(self.GenerateModuleInternalHeader(), | 507 self.Write(self.GenerateModuleInternalHeader(), |
464 self.MatchMojomFilePath("%s%s-internal.h" % (self.module.name, suffix))) | 508 self.MatchMojomFilePath("%s%s-internal.h" % (self.module.name, suffix))) |
465 self.Write(self.GenerateModuleSource(), | 509 self.Write(self.GenerateModuleSource(), |
466 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) | 510 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) |
OLD | NEW |