Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: mojo/public/tools/bindings/generators/mojom_cpp_generator.py

Issue 2864543002: Mojo code generator: makes the filters member methods of generator if necessary. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | mojo/public/tools/bindings/generators/mojom_java_generator.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 14 matching lines...) Expand all
25 } 25 }
26 26
27 _kind_to_cpp_literal_suffix = { 27 _kind_to_cpp_literal_suffix = {
28 mojom.UINT8: "U", 28 mojom.UINT8: "U",
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
36 # generator library code so that filters can use the generator as context.
37 _current_typemap = {}
38 _for_blink = False
39 # TODO(rockot, yzshen): The variant handling is kind of a hack currently. Make
40 # it right.
41 _variant = None
42 _export_attribute = None
43
44 35
45 class _NameFormatter(object): 36 class _NameFormatter(object):
46 """A formatter for the names of kinds or values.""" 37 """A formatter for the names of kinds or values."""
47 38
48 def __init__(self, token, variant): 39 def __init__(self, token, variant):
49 self._token = token 40 self._token = token
50 self._variant = variant 41 self._variant = variant
51 42
52 def Format(self, separator, prefixed=False, internal=False, 43 def Format(self, separator, prefixed=False, internal=False,
53 include_variant=False, add_same_module_namespaces=False, 44 include_variant=False, add_same_module_namespaces=False,
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 return add_same_module_namespaces or self._token.imported_from 114 return add_same_module_namespaces or self._token.imported_from
124 115
125 def _GetNamespace(self): 116 def _GetNamespace(self):
126 if self._token.imported_from: 117 if self._token.imported_from:
127 return NamespaceToArray(self._token.imported_from["namespace"]) 118 return NamespaceToArray(self._token.imported_from["namespace"])
128 elif hasattr(self._token, "module"): 119 elif hasattr(self._token, "module"):
129 return NamespaceToArray(self._token.module.namespace) 120 return NamespaceToArray(self._token.module.namespace)
130 return [] 121 return []
131 122
132 123
133 def ConstantValue(constant):
134 return ExpressionToText(constant.value, kind=constant.kind)
135
136 # TODO(yzshen): Revisit the default value feature. It was designed prior to
137 # custom type mapping.
138 def DefaultValue(field):
139 if field.default:
140 if mojom.IsStructKind(field.kind):
141 assert field.default == "default"
142 if not IsTypemappedKind(field.kind):
143 return "%s::New()" % GetNameForKind(field.kind)
144 return ExpressionToText(field.default, kind=field.kind)
145 return ""
146
147 def NamespaceToArray(namespace): 124 def NamespaceToArray(namespace):
148 return namespace.split(".") if namespace else [] 125 return namespace.split(".") if namespace else []
149 126
150 def GetNameForKind(kind, internal=False, flatten_nested_kind=False,
151 add_same_module_namespaces=False):
152 return _NameFormatter(kind, _variant).FormatForCpp(
153 internal=internal, flatten_nested_kind=flatten_nested_kind,
154 add_same_module_namespaces=add_same_module_namespaces)
155
156 def GetQualifiedNameForKind(kind, internal=False, flatten_nested_kind=False,
157 include_variant=True):
158 return _NameFormatter(
159 kind, _variant if include_variant else None).FormatForCpp(
160 internal=internal, add_same_module_namespaces=True,
161 flatten_nested_kind=flatten_nested_kind)
162
163 127
164 def GetWtfHashFnNameForEnum(enum): 128 def GetWtfHashFnNameForEnum(enum):
165 return _NameFormatter( 129 return _NameFormatter(
166 enum, None).Format("_", internal=True, add_same_module_namespaces=True, 130 enum, None).Format("_", internal=True, add_same_module_namespaces=True,
167 flatten_nested_kind=True) + "HashFn" 131 flatten_nested_kind=True) + "HashFn"
168 132
169 133
170 def GetFullMojomNameForKind(kind):
171 return _NameFormatter(kind, _variant).FormatForMojom()
172
173 def IsTypemappedKind(kind):
174 return hasattr(kind, "name") and \
175 GetFullMojomNameForKind(kind) in _current_typemap
176
177 def IsNativeOnlyKind(kind): 134 def IsNativeOnlyKind(kind):
178 return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \ 135 return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
179 kind.native_only 136 kind.native_only
180 137
181 138
182 def IsHashableKind(kind):
183 """Check if the kind can be hashed.
184
185 Args:
186 kind: {Kind} The kind to check.
187
188 Returns:
189 {bool} True if a value of this kind can be hashed.
190 """
191 checked = set()
192 def Check(kind):
193 if kind.spec in checked:
194 return True
195 checked.add(kind.spec)
196 if mojom.IsNullableKind(kind):
197 return False
198 elif mojom.IsStructKind(kind):
199 if (IsTypemappedKind(kind) and
200 not _current_typemap[GetFullMojomNameForKind(kind)]["hashable"]):
201 return False
202 return all(Check(field.kind) for field in kind.fields)
203 elif mojom.IsEnumKind(kind):
204 return not IsTypemappedKind(kind) or _current_typemap[
205 GetFullMojomNameForKind(kind)]["hashable"]
206 elif mojom.IsUnionKind(kind):
207 return all(Check(field.kind) for field in kind.fields)
208 elif mojom.IsAnyHandleKind(kind):
209 return False
210 elif mojom.IsAnyInterfaceKind(kind):
211 return False
212 # TODO(tibell): Arrays and maps could be made hashable. We just don't have a
213 # use case yet.
214 elif mojom.IsArrayKind(kind):
215 return False
216 elif mojom.IsMapKind(kind):
217 return False
218 else:
219 return True
220 return Check(kind)
221
222
223 def AllEnumValues(enum): 139 def AllEnumValues(enum):
224 """Return all enum values associated with an enum. 140 """Return all enum values associated with an enum.
225 141
226 Args: 142 Args:
227 enum: {mojom.Enum} The enum type. 143 enum: {mojom.Enum} The enum type.
228 144
229 Returns: 145 Returns:
230 {Set[int]} The values. 146 {Set[int]} The values.
231 """ 147 """
232 return set(field.numeric_value for field in enum.fields) 148 return set(field.numeric_value for field in enum.fields)
233 149
234 150
235 def GetNativeTypeName(typemapped_kind):
236 return _current_typemap[GetFullMojomNameForKind(typemapped_kind)]["typename"]
237
238 def GetCppPodType(kind): 151 def GetCppPodType(kind):
239 return _kind_to_cpp_type[kind] 152 return _kind_to_cpp_type[kind]
240 153
241 def FormatConstantDeclaration(constant, nested=False):
242 if mojom.IsStringKind(constant.kind):
243 if nested:
244 return "const char %s[]" % constant.name
245 return "%sextern const char %s[]" % \
246 ((_export_attribute + " ") if _export_attribute else "", constant.name)
247 return "constexpr %s %s = %s" % (GetCppPodType(constant.kind), constant.name,
248 ConstantValue(constant))
249
250 def GetCppWrapperType(kind, add_same_module_namespaces=False):
251 def _AddOptional(type_name):
252 pattern = "WTF::Optional<%s>" if _for_blink else "base::Optional<%s>"
253 return pattern % type_name
254
255 if IsTypemappedKind(kind):
256 type_name = GetNativeTypeName(kind)
257 if (mojom.IsNullableKind(kind) and
258 not _current_typemap[GetFullMojomNameForKind(kind)][
259 "nullable_is_same_type"]):
260 type_name = _AddOptional(type_name)
261 return type_name
262 if mojom.IsEnumKind(kind):
263 return GetNameForKind(
264 kind, add_same_module_namespaces=add_same_module_namespaces)
265 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
266 return "%sPtr" % GetNameForKind(
267 kind, add_same_module_namespaces=add_same_module_namespaces)
268 if mojom.IsArrayKind(kind):
269 pattern = "WTF::Vector<%s>" if _for_blink else "std::vector<%s>"
270 if mojom.IsNullableKind(kind):
271 pattern = _AddOptional(pattern)
272 return pattern % GetCppWrapperType(
273 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
274 if mojom.IsMapKind(kind):
275 pattern = ("WTF::HashMap<%s, %s>" if _for_blink else
276 "std::unordered_map<%s, %s>")
277 if mojom.IsNullableKind(kind):
278 pattern = _AddOptional(pattern)
279 return pattern % (
280 GetCppWrapperType(
281 kind.key_kind,
282 add_same_module_namespaces=add_same_module_namespaces),
283 GetCppWrapperType(
284 kind.value_kind,
285 add_same_module_namespaces=add_same_module_namespaces))
286 if mojom.IsInterfaceKind(kind):
287 return "%sPtr" % GetNameForKind(
288 kind, add_same_module_namespaces=add_same_module_namespaces)
289 if mojom.IsInterfaceRequestKind(kind):
290 return "%sRequest" % GetNameForKind(
291 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
292 if mojom.IsAssociatedInterfaceKind(kind):
293 return "%sAssociatedPtrInfo" % GetNameForKind(
294 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
295 if mojom.IsAssociatedInterfaceRequestKind(kind):
296 return "%sAssociatedRequest" % GetNameForKind(
297 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
298 if mojom.IsStringKind(kind):
299 if _for_blink:
300 return "WTF::String"
301 type_name = "std::string"
302 return _AddOptional(type_name) if mojom.IsNullableKind(kind) else type_name
303 if mojom.IsGenericHandleKind(kind):
304 return "mojo::ScopedHandle"
305 if mojom.IsDataPipeConsumerKind(kind):
306 return "mojo::ScopedDataPipeConsumerHandle"
307 if mojom.IsDataPipeProducerKind(kind):
308 return "mojo::ScopedDataPipeProducerHandle"
309 if mojom.IsMessagePipeKind(kind):
310 return "mojo::ScopedMessagePipeHandle"
311 if mojom.IsSharedBufferKind(kind):
312 return "mojo::ScopedSharedBufferHandle"
313 if not kind in _kind_to_cpp_type:
314 raise Exception("Unrecognized kind %s" % kind.spec)
315 return _kind_to_cpp_type[kind]
316
317 def IsMoveOnlyKind(kind):
318 if IsTypemappedKind(kind):
319 if mojom.IsEnumKind(kind):
320 return False
321 return _current_typemap[GetFullMojomNameForKind(kind)]["move_only"]
322 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
323 return True
324 if mojom.IsArrayKind(kind):
325 return IsMoveOnlyKind(kind.kind)
326 if mojom.IsMapKind(kind):
327 return IsMoveOnlyKind(kind.value_kind)
328 if mojom.IsAnyHandleOrInterfaceKind(kind):
329 return True
330 return False
331
332 def IsCopyablePassByValue(kind):
333 if not IsTypemappedKind(kind):
334 return False
335 return _current_typemap[GetFullMojomNameForKind(kind)][
336 "copyable_pass_by_value"]
337
338 def ShouldPassParamByValue(kind):
339 return ((not mojom.IsReferenceKind(kind)) or IsMoveOnlyKind(kind) or
340 IsCopyablePassByValue(kind))
341
342 def GetCppWrapperParamType(kind):
343 cpp_wrapper_type = GetCppWrapperType(kind)
344 return (cpp_wrapper_type if ShouldPassParamByValue(kind)
345 else "const %s&" % cpp_wrapper_type)
346
347 def GetCppFieldType(kind):
348 if mojom.IsStructKind(kind):
349 return ("mojo::internal::Pointer<%s>" %
350 GetNameForKind(kind, internal=True))
351 if mojom.IsUnionKind(kind):
352 return "%s" % GetNameForKind(kind, internal=True)
353 if mojom.IsArrayKind(kind):
354 return ("mojo::internal::Pointer<mojo::internal::Array_Data<%s>>" %
355 GetCppFieldType(kind.kind))
356 if mojom.IsMapKind(kind):
357 return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" %
358 (GetCppFieldType(kind.key_kind), GetCppFieldType(kind.value_kind)))
359 if mojom.IsInterfaceKind(kind):
360 return "mojo::internal::Interface_Data"
361 if mojom.IsInterfaceRequestKind(kind):
362 return "mojo::internal::Handle_Data"
363 if mojom.IsAssociatedInterfaceKind(kind):
364 return "mojo::internal::AssociatedInterface_Data"
365 if mojom.IsAssociatedInterfaceRequestKind(kind):
366 return "mojo::internal::AssociatedEndpointHandle_Data"
367 if mojom.IsEnumKind(kind):
368 return "int32_t"
369 if mojom.IsStringKind(kind):
370 return "mojo::internal::Pointer<mojo::internal::String_Data>"
371 if mojom.IsAnyHandleKind(kind):
372 return "mojo::internal::Handle_Data"
373 return _kind_to_cpp_type[kind]
374
375 def GetCppUnionFieldType(kind):
376 if mojom.IsUnionKind(kind):
377 return ("mojo::internal::Pointer<%s>" % GetNameForKind(kind, internal=True))
378 return GetCppFieldType(kind)
379
380 def GetUnionGetterReturnType(kind):
381 if mojom.IsReferenceKind(kind):
382 return "%s&" % GetCppWrapperType(kind)
383 return GetCppWrapperType(kind)
384
385 def GetUnionTraitGetterReturnType(kind):
386 """Get field type used in UnionTraits template specialization.
387
388 The type may be qualified as UnionTraits specializations live outside the
389 namespace where e.g. structs are defined.
390
391 Args:
392 kind: {Kind} The type of the field.
393
394 Returns:
395 {str} The C++ type to use for the field.
396 """
397 if mojom.IsReferenceKind(kind):
398 return "%s&" % GetCppWrapperType(kind, add_same_module_namespaces=True)
399 return GetCppWrapperType(kind, add_same_module_namespaces=True)
400 154
401 def GetCppDataViewType(kind, qualified=False): 155 def GetCppDataViewType(kind, qualified=False):
402 def _GetName(input_kind): 156 def _GetName(input_kind):
403 return _NameFormatter(input_kind, None).FormatForCpp( 157 return _NameFormatter(input_kind, None).FormatForCpp(
404 add_same_module_namespaces=qualified, flatten_nested_kind=True) 158 add_same_module_namespaces=qualified, flatten_nested_kind=True)
405 159
406 if mojom.IsEnumKind(kind): 160 if mojom.IsEnumKind(kind):
407 return _GetName(kind) 161 return _GetName(kind)
408 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): 162 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
409 return "%sDataView" % _GetName(kind) 163 return "%sDataView" % _GetName(kind)
(...skipping 18 matching lines...) Expand all
428 if mojom.IsDataPipeConsumerKind(kind): 182 if mojom.IsDataPipeConsumerKind(kind):
429 return "mojo::ScopedDataPipeConsumerHandle" 183 return "mojo::ScopedDataPipeConsumerHandle"
430 if mojom.IsDataPipeProducerKind(kind): 184 if mojom.IsDataPipeProducerKind(kind):
431 return "mojo::ScopedDataPipeProducerHandle" 185 return "mojo::ScopedDataPipeProducerHandle"
432 if mojom.IsMessagePipeKind(kind): 186 if mojom.IsMessagePipeKind(kind):
433 return "mojo::ScopedMessagePipeHandle" 187 return "mojo::ScopedMessagePipeHandle"
434 if mojom.IsSharedBufferKind(kind): 188 if mojom.IsSharedBufferKind(kind):
435 return "mojo::ScopedSharedBufferHandle" 189 return "mojo::ScopedSharedBufferHandle"
436 return _kind_to_cpp_type[kind] 190 return _kind_to_cpp_type[kind]
437 191
192
438 def GetUnmappedTypeForSerializer(kind): 193 def GetUnmappedTypeForSerializer(kind):
439 return GetCppDataViewType(kind, qualified=True) 194 return GetCppDataViewType(kind, qualified=True)
440 195
441 def TranslateConstants(token, kind):
442 if isinstance(token, mojom.NamedValue):
443 return GetNameForKind(token, flatten_nested_kind=True)
444
445 if isinstance(token, mojom.BuiltinValue):
446 if token.value == "double.INFINITY":
447 return "std::numeric_limits<double>::infinity()"
448 if token.value == "float.INFINITY":
449 return "std::numeric_limits<float>::infinity()"
450 if token.value == "double.NEGATIVE_INFINITY":
451 return "-std::numeric_limits<double>::infinity()"
452 if token.value == "float.NEGATIVE_INFINITY":
453 return "-std::numeric_limits<float>::infinity()"
454 if token.value == "double.NAN":
455 return "std::numeric_limits<double>::quiet_NaN()"
456 if token.value == "float.NAN":
457 return "std::numeric_limits<float>::quiet_NaN()"
458
459 if (kind is not None and mojom.IsFloatKind(kind)):
460 return token if token.isdigit() else token + "f";
461
462 # Per C++11, 2.14.2, the type of an integer literal is the first of the
463 # corresponding list in Table 6 in which its value can be represented. In this
464 # case, the list for decimal constants with no suffix is:
465 # int, long int, long long int
466 # The standard considers a program ill-formed if it contains an integer
467 # literal that cannot be represented by any of the allowed types.
468 #
469 # As it turns out, MSVC doesn't bother trying to fall back to long long int,
470 # so the integral constant -2147483648 causes it grief: it decides to
471 # represent 2147483648 as an unsigned integer, and then warns that the unary
472 # minus operator doesn't make sense on unsigned types. Doh!
473 if kind == mojom.INT32 and token == "-2147483648":
474 return "(-%d - 1) /* %s */" % (
475 2**31 - 1, "Workaround for MSVC bug; see https://crbug.com/445618")
476
477 return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, ""))
478
479 def ExpressionToText(value, kind=None):
480 return TranslateConstants(value, kind)
481 196
482 def RequiresContextForDataView(kind): 197 def RequiresContextForDataView(kind):
483 for field in kind.fields: 198 for field in kind.fields:
484 if mojom.IsReferenceKind(field.kind): 199 if mojom.IsReferenceKind(field.kind):
485 return True 200 return True
486 return False 201 return False
487 202
203
488 def ShouldInlineStruct(struct): 204 def ShouldInlineStruct(struct):
489 # TODO(darin): Base this on the size of the wrapper class. 205 # TODO(darin): Base this on the size of the wrapper class.
490 if len(struct.fields) > 4: 206 if len(struct.fields) > 4:
491 return False 207 return False
492 for field in struct.fields: 208 for field in struct.fields:
493 if mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind): 209 if mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind):
494 return False 210 return False
495 return True 211 return True
496 212
497 def ContainsMoveOnlyMembers(struct):
498 for field in struct.fields:
499 if IsMoveOnlyKind(field.kind):
500 return True
501 return False
502 213
503 def ShouldInlineUnion(union): 214 def ShouldInlineUnion(union):
504 return not any( 215 return not any(
505 mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind) 216 mojom.IsReferenceKind(field.kind) and not mojom.IsStringKind(field.kind)
506 for field in union.fields) 217 for field in union.fields)
507 218
508 219
509 class StructConstructor(object): 220 class StructConstructor(object):
510 """Represents a constructor for a generated struct. 221 """Represents a constructor for a generated struct.
511 222
512 Fields: 223 Fields:
513 fields: {[Field]} All struct fields in order. 224 fields: {[Field]} All struct fields in order.
514 params: {[Field]} The fields that are passed as params. 225 params: {[Field]} The fields that are passed as params.
515 """ 226 """
516 227
517 def __init__(self, fields, params): 228 def __init__(self, fields, params):
518 self._fields = fields 229 self._fields = fields
519 self._params = set(params) 230 self._params = set(params)
520 231
521 @property 232 @property
522 def params(self): 233 def params(self):
523 return [field for field in self._fields if field in self._params] 234 return [field for field in self._fields if field in self._params]
524 235
525 @property 236 @property
526 def fields(self): 237 def fields(self):
527 for field in self._fields: 238 for field in self._fields:
528 yield (field, field in self._params) 239 yield (field, field in self._params)
529 240
530 241
531 def GetStructConstructors(struct): 242 class Generator(generator.Generator):
532 """Returns a list of constructors for a struct. 243 def __init__(self, *args, **kwargs):
244 super(Generator, self).__init__(*args, **kwargs)
533 245
534 Params: 246 def _GetExtraTraitsHeaders(self):
535 struct: {Struct} The struct to return constructors for.
536
537 Returns:
538 {[StructConstructor]} A list of StructConstructors that should be generated
539 for |struct|.
540 """
541 if not mojom.IsStructKind(struct):
542 raise TypeError
543 # Types that are neither copyable nor movable can't be passed to a struct
544 # constructor so only generate a default constructor.
545 if any(IsTypemappedKind(field.kind) and _current_typemap[
546 GetFullMojomNameForKind(field.kind)]["non_copyable_non_movable"]
547 for field in struct.fields):
548 return [StructConstructor(struct.fields, [])]
549
550 param_counts = [0]
551 for version in struct.versions:
552 if param_counts[-1] != version.num_fields:
553 param_counts.append(version.num_fields)
554
555 ordinal_fields = sorted(struct.fields, key=lambda field: field.ordinal)
556 return (StructConstructor(struct.fields, ordinal_fields[:param_count])
557 for param_count in param_counts)
558
559
560 def GetContainerValidateParamsCtorArgs(kind):
561 if mojom.IsStringKind(kind):
562 expected_num_elements = 0
563 element_is_nullable = False
564 key_validate_params = "nullptr"
565 element_validate_params = "nullptr"
566 enum_validate_func = "nullptr"
567 elif mojom.IsMapKind(kind):
568 expected_num_elements = 0
569 element_is_nullable = False
570 key_validate_params = GetNewContainerValidateParams(mojom.Array(
571 kind=kind.key_kind))
572 element_validate_params = GetNewContainerValidateParams(mojom.Array(
573 kind=kind.value_kind))
574 enum_validate_func = "nullptr"
575 else: # mojom.IsArrayKind(kind)
576 expected_num_elements = generator.ExpectedArraySize(kind) or 0
577 element_is_nullable = mojom.IsNullableKind(kind.kind)
578 key_validate_params = "nullptr"
579 element_validate_params = GetNewContainerValidateParams(kind.kind)
580 if mojom.IsEnumKind(kind.kind):
581 enum_validate_func = ("%s::Validate" %
582 GetQualifiedNameForKind(kind.kind, internal=True,
583 flatten_nested_kind=True))
584 else:
585 enum_validate_func = "nullptr"
586
587 if enum_validate_func == "nullptr":
588 if key_validate_params == "nullptr":
589 return "%d, %s, %s" % (expected_num_elements,
590 "true" if element_is_nullable else "false",
591 element_validate_params)
592 else:
593 return "%s, %s" % (key_validate_params, element_validate_params)
594 else:
595 return "%d, %s" % (expected_num_elements, enum_validate_func)
596
597 def GetNewContainerValidateParams(kind):
598 if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and
599 not mojom.IsStringKind(kind)):
600 return "nullptr"
601
602 return "new mojo::internal::ContainerValidateParams(%s)" % (
603 GetContainerValidateParamsCtorArgs(kind))
604
605 class Generator(generator.Generator):
606
607 cpp_filters = {
608 "all_enum_values": AllEnumValues,
609 "constant_value": ConstantValue,
610 "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
611 "contains_move_only_members": ContainsMoveOnlyMembers,
612 "cpp_wrapper_param_type": GetCppWrapperParamType,
613 "cpp_data_view_type": GetCppDataViewType,
614 "cpp_field_type": GetCppFieldType,
615 "cpp_union_field_type": GetCppUnionFieldType,
616 "cpp_pod_type": GetCppPodType,
617 "cpp_union_getter_return_type": GetUnionGetterReturnType,
618 "cpp_union_trait_getter_return_type": GetUnionTraitGetterReturnType,
619 "cpp_wrapper_type": GetCppWrapperType,
620 "default_value": DefaultValue,
621 "expression_to_text": ExpressionToText,
622 "format_constant_declaration": FormatConstantDeclaration,
623 "get_container_validate_params_ctor_args":
624 GetContainerValidateParamsCtorArgs,
625 "get_name_for_kind": GetNameForKind,
626 "get_pad": pack.GetPad,
627 "get_qualified_name_for_kind": GetQualifiedNameForKind,
628 "has_callbacks": mojom.HasCallbacks,
629 "has_sync_methods": mojom.HasSyncMethods,
630 "requires_context_for_data_view": RequiresContextForDataView,
631 "should_inline": ShouldInlineStruct,
632 "should_inline_union": ShouldInlineUnion,
633 "is_array_kind": mojom.IsArrayKind,
634 "is_enum_kind": mojom.IsEnumKind,
635 "is_integral_kind": mojom.IsIntegralKind,
636 "is_native_only_kind": IsNativeOnlyKind,
637 "is_any_handle_kind": mojom.IsAnyHandleKind,
638 "is_any_interface_kind": mojom.IsAnyInterfaceKind,
639 "is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind,
640 "is_associated_kind": mojom.IsAssociatedKind,
641 "is_hashable": IsHashableKind,
642 "is_map_kind": mojom.IsMapKind,
643 "is_nullable_kind": mojom.IsNullableKind,
644 "is_object_kind": mojom.IsObjectKind,
645 "is_reference_kind": mojom.IsReferenceKind,
646 "is_string_kind": mojom.IsStringKind,
647 "is_struct_kind": mojom.IsStructKind,
648 "is_typemapped_kind": IsTypemappedKind,
649 "is_union_kind": mojom.IsUnionKind,
650 "passes_associated_kinds": mojom.PassesAssociatedKinds,
651 "struct_constructors": GetStructConstructors,
652 "stylize_method": generator.StudlyCapsToCamel,
653 "under_to_camel": generator.UnderToCamel,
654 "unmapped_type_for_serializer": GetUnmappedTypeForSerializer,
655 "wtf_hash_fn_name_for_enum": GetWtfHashFnNameForEnum,
656 }
657
658 def GetExtraTraitsHeaders(self):
659 extra_headers = set() 247 extra_headers = set()
660 for typemap in self._GetAllUsedTypemaps(): 248 for typemap in self._GetAllUsedTypemaps():
661 extra_headers.update(typemap.get("traits_headers", [])) 249 extra_headers.update(typemap.get("traits_headers", []))
662 return sorted(extra_headers) 250 return sorted(extra_headers)
663 251
664 def _GetAllUsedTypemaps(self): 252 def _GetAllUsedTypemaps(self):
665 """Returns the typemaps for types needed for serialization in this module. 253 """Returns the typemaps for types needed for serialization in this module.
666 254
667 A type is needed for serialization if it is contained by a struct or union 255 A type is needed for serialization if it is contained by a struct or union
668 defined in this module, is a parameter of a message in an interface in 256 defined in this module, is a parameter of a message in an interface in
669 this module or is contained within another type needed for serialization. 257 this module or is contained within another type needed for serialization.
670 """ 258 """
671 used_typemaps = [] 259 used_typemaps = []
672 seen_types = set() 260 seen_types = set()
673 def AddKind(kind): 261 def AddKind(kind):
674 if (mojom.IsIntegralKind(kind) or mojom.IsStringKind(kind) or 262 if (mojom.IsIntegralKind(kind) or mojom.IsStringKind(kind) or
675 mojom.IsDoubleKind(kind) or mojom.IsFloatKind(kind) or 263 mojom.IsDoubleKind(kind) or mojom.IsFloatKind(kind) or
676 mojom.IsAnyHandleKind(kind) or 264 mojom.IsAnyHandleKind(kind) or
677 mojom.IsInterfaceKind(kind) or 265 mojom.IsInterfaceKind(kind) or
678 mojom.IsInterfaceRequestKind(kind) or 266 mojom.IsInterfaceRequestKind(kind) or
679 mojom.IsAssociatedKind(kind)): 267 mojom.IsAssociatedKind(kind)):
680 pass 268 pass
681 elif mojom.IsArrayKind(kind): 269 elif mojom.IsArrayKind(kind):
682 AddKind(kind.kind) 270 AddKind(kind.kind)
683 elif mojom.IsMapKind(kind): 271 elif mojom.IsMapKind(kind):
684 AddKind(kind.key_kind) 272 AddKind(kind.key_kind)
685 AddKind(kind.value_kind) 273 AddKind(kind.value_kind)
686 else: 274 else:
687 name = GetFullMojomNameForKind(kind) 275 name = self._GetFullMojomNameForKind(kind)
688 if name in seen_types: 276 if name in seen_types:
689 return 277 return
690 seen_types.add(name) 278 seen_types.add(name)
691 279
692 typemap = _current_typemap.get(name, None) 280 typemap = self.typemap.get(name, None)
693 if typemap: 281 if typemap:
694 used_typemaps.append(typemap) 282 used_typemaps.append(typemap)
695 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind): 283 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
696 for field in kind.fields: 284 for field in kind.fields:
697 AddKind(field.kind) 285 AddKind(field.kind)
698 286
699 for kind in self.module.structs + self.module.unions: 287 for kind in self.module.structs + self.module.unions:
700 for field in kind.fields: 288 for field in kind.fields:
701 AddKind(field.kind) 289 AddKind(field.kind)
702 290
703 for interface in self.module.interfaces: 291 for interface in self.module.interfaces:
704 for method in interface.methods: 292 for method in interface.methods:
705 for parameter in method.parameters + (method.response_parameters or []): 293 for parameter in method.parameters + (method.response_parameters or []):
706 AddKind(parameter.kind) 294 AddKind(parameter.kind)
707 295
708 return used_typemaps 296 return used_typemaps
709 297
710 def GetExtraPublicHeaders(self): 298 def _GetExtraPublicHeaders(self):
711 all_enums = list(self.module.enums) 299 all_enums = list(self.module.enums)
712 for struct in self.module.structs: 300 for struct in self.module.structs:
713 all_enums.extend(struct.enums) 301 all_enums.extend(struct.enums)
714 for interface in self.module.interfaces: 302 for interface in self.module.interfaces:
715 all_enums.extend(interface.enums) 303 all_enums.extend(interface.enums)
716 304
717 types = set(GetFullMojomNameForKind(typename) 305 types = set(self._GetFullMojomNameForKind(typename)
718 for typename in 306 for typename in
719 self.module.structs + all_enums + self.module.unions) 307 self.module.structs + all_enums + self.module.unions)
720 headers = set() 308 headers = set()
721 for typename, typemap in self.typemap.iteritems(): 309 for typename, typemap in self.typemap.iteritems():
722 if typename in types: 310 if typename in types:
723 headers.update(typemap.get("public_headers", [])) 311 headers.update(typemap.get("public_headers", []))
724 return sorted(headers) 312 return sorted(headers)
725 313
726 def _GetDirectlyUsedKinds(self): 314 def _GetDirectlyUsedKinds(self):
727 for struct in self.module.structs + self.module.unions: 315 for struct in self.module.structs + self.module.unions:
728 for field in struct.fields: 316 for field in struct.fields:
729 yield field.kind 317 yield field.kind
730 318
731 for interface in self.module.interfaces: 319 for interface in self.module.interfaces:
732 for method in interface.methods: 320 for method in interface.methods:
733 for param in method.parameters + (method.response_parameters or []): 321 for param in method.parameters + (method.response_parameters or []):
734 yield param.kind 322 yield param.kind
735 323
736 def GetJinjaExports(self): 324 def _GetJinjaExports(self):
737 structs = self.GetStructs() 325 structs = self.GetStructs()
738 interfaces = self.GetInterfaces() 326 interfaces = self.GetInterfaces()
739 all_enums = list(self.module.enums) 327 all_enums = list(self.module.enums)
740 for struct in structs: 328 for struct in structs:
741 all_enums.extend(struct.enums) 329 all_enums.extend(struct.enums)
742 for interface in interfaces: 330 for interface in interfaces:
743 all_enums.extend(interface.enums) 331 all_enums.extend(interface.enums)
744 332
745 return { 333 return {
746 "module": self.module, 334 "module": self.module,
747 "namespace": self.module.namespace, 335 "namespace": self.module.namespace,
748 "namespaces_as_array": NamespaceToArray(self.module.namespace), 336 "namespaces_as_array": NamespaceToArray(self.module.namespace),
749 "imports": self.module.imports, 337 "imports": self.module.imports,
750 "kinds": self.module.kinds, 338 "kinds": self.module.kinds,
751 "enums": self.module.enums, 339 "enums": self.module.enums,
752 "all_enums": all_enums, 340 "all_enums": all_enums,
753 "structs": structs, 341 "structs": structs,
754 "unions": self.GetUnions(), 342 "unions": self.GetUnions(),
755 "interfaces": interfaces, 343 "interfaces": interfaces,
756 "variant": self.variant, 344 "variant": self.variant,
757 "extra_traits_headers": self.GetExtraTraitsHeaders(), 345 "extra_traits_headers": self._GetExtraTraitsHeaders(),
758 "extra_public_headers": self.GetExtraPublicHeaders(), 346 "extra_public_headers": self._GetExtraPublicHeaders(),
759 "for_blink": self.for_blink, 347 "for_blink": self.for_blink,
760 "use_once_callback": self.use_once_callback, 348 "use_once_callback": self.use_once_callback,
761 "export_attribute": self.export_attribute, 349 "export_attribute": self.export_attribute,
762 "export_header": self.export_header, 350 "export_header": self.export_header,
763 } 351 }
764 352
765 @staticmethod 353 @staticmethod
766 def GetTemplatePrefix(): 354 def GetTemplatePrefix():
767 return "cpp_templates" 355 return "cpp_templates"
768 356
769 @classmethod 357 def GetFilters(self):
770 def GetFilters(cls): 358 cpp_filters = {
771 return cls.cpp_filters 359 "all_enum_values": AllEnumValues,
360 "constant_value": self._ConstantValue,
361 "contains_handles_or_interfaces": mojom.ContainsHandlesOrInterfaces,
362 "contains_move_only_members": self._ContainsMoveOnlyMembers,
363 "cpp_wrapper_param_type": self._GetCppWrapperParamType,
364 "cpp_data_view_type": GetCppDataViewType,
365 "cpp_field_type": self._GetCppFieldType,
366 "cpp_union_field_type": self._GetCppUnionFieldType,
367 "cpp_pod_type": GetCppPodType,
368 "cpp_union_getter_return_type": self._GetUnionGetterReturnType,
369 "cpp_union_trait_getter_return_type": self._GetUnionTraitGetterReturnType,
370 "cpp_wrapper_type": self._GetCppWrapperType,
371 "default_value": self._DefaultValue,
372 "expression_to_text": self._ExpressionToText,
373 "format_constant_declaration": self._FormatConstantDeclaration,
374 "get_container_validate_params_ctor_args":
375 self._GetContainerValidateParamsCtorArgs,
376 "get_name_for_kind": self._GetNameForKind,
377 "get_pad": pack.GetPad,
378 "get_qualified_name_for_kind": self._GetQualifiedNameForKind,
379 "has_callbacks": mojom.HasCallbacks,
380 "has_sync_methods": mojom.HasSyncMethods,
381 "requires_context_for_data_view": RequiresContextForDataView,
382 "should_inline": ShouldInlineStruct,
383 "should_inline_union": ShouldInlineUnion,
384 "is_array_kind": mojom.IsArrayKind,
385 "is_enum_kind": mojom.IsEnumKind,
386 "is_integral_kind": mojom.IsIntegralKind,
387 "is_native_only_kind": IsNativeOnlyKind,
388 "is_any_handle_kind": mojom.IsAnyHandleKind,
389 "is_any_interface_kind": mojom.IsAnyInterfaceKind,
390 "is_any_handle_or_interface_kind": mojom.IsAnyHandleOrInterfaceKind,
391 "is_associated_kind": mojom.IsAssociatedKind,
392 "is_hashable": self._IsHashableKind,
393 "is_map_kind": mojom.IsMapKind,
394 "is_nullable_kind": mojom.IsNullableKind,
395 "is_object_kind": mojom.IsObjectKind,
396 "is_reference_kind": mojom.IsReferenceKind,
397 "is_string_kind": mojom.IsStringKind,
398 "is_struct_kind": mojom.IsStructKind,
399 "is_typemapped_kind": self._IsTypemappedKind,
400 "is_union_kind": mojom.IsUnionKind,
401 "passes_associated_kinds": mojom.PassesAssociatedKinds,
402 "struct_constructors": self._GetStructConstructors,
403 "under_to_camel": generator.UnderToCamel,
404 "unmapped_type_for_serializer": GetUnmappedTypeForSerializer,
405 "wtf_hash_fn_name_for_enum": GetWtfHashFnNameForEnum,
406 }
407 return cpp_filters
772 408
773 @UseJinja("module.h.tmpl") 409 @UseJinja("module.h.tmpl")
774 def GenerateModuleHeader(self): 410 def _GenerateModuleHeader(self):
775 return self.GetJinjaExports() 411 return self._GetJinjaExports()
776 412
777 @UseJinja("module.cc.tmpl") 413 @UseJinja("module.cc.tmpl")
778 def GenerateModuleSource(self): 414 def _GenerateModuleSource(self):
779 return self.GetJinjaExports() 415 return self._GetJinjaExports()
780 416
781 @UseJinja("module-shared.h.tmpl") 417 @UseJinja("module-shared.h.tmpl")
782 def GenerateModuleSharedHeader(self): 418 def _GenerateModuleSharedHeader(self):
783 return self.GetJinjaExports() 419 return self._GetJinjaExports()
784 420
785 @UseJinja("module-shared-internal.h.tmpl") 421 @UseJinja("module-shared-internal.h.tmpl")
786 def GenerateModuleSharedInternalHeader(self): 422 def _GenerateModuleSharedInternalHeader(self):
787 return self.GetJinjaExports() 423 return self._GetJinjaExports()
788 424
789 @UseJinja("module-shared.cc.tmpl") 425 @UseJinja("module-shared.cc.tmpl")
790 def GenerateModuleSharedSource(self): 426 def _GenerateModuleSharedSource(self):
791 return self.GetJinjaExports() 427 return self._GetJinjaExports()
792 428
793 def GenerateFiles(self, args): 429 def GenerateFiles(self, args):
794 if self.generate_non_variant_code: 430 if self.generate_non_variant_code:
795 self.Write(self.GenerateModuleSharedHeader(), 431 self.Write(self._GenerateModuleSharedHeader(),
796 self.MatchMojomFilePath("%s-shared.h" % self.module.name)) 432 self.MatchMojomFilePath("%s-shared.h" % self.module.name))
797 self.Write( 433 self.Write(
798 self.GenerateModuleSharedInternalHeader(), 434 self._GenerateModuleSharedInternalHeader(),
799 self.MatchMojomFilePath("%s-shared-internal.h" % self.module.name)) 435 self.MatchMojomFilePath("%s-shared-internal.h" % self.module.name))
800 self.Write(self.GenerateModuleSharedSource(), 436 self.Write(self._GenerateModuleSharedSource(),
801 self.MatchMojomFilePath("%s-shared.cc" % self.module.name)) 437 self.MatchMojomFilePath("%s-shared.cc" % self.module.name))
802 else: 438 else:
803 global _current_typemap
804 _current_typemap = self.typemap
805 global _for_blink
806 _for_blink = self.for_blink
807 global _use_once_callback
808 _use_once_callback = self.use_once_callback
809 global _variant
810 _variant = self.variant
811 global _export_attribute
812 _export_attribute = self.export_attribute
813 suffix = "-%s" % self.variant if self.variant else "" 439 suffix = "-%s" % self.variant if self.variant else ""
814 self.Write(self.GenerateModuleHeader(), 440 self.Write(self._GenerateModuleHeader(),
815 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) 441 self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix)))
816 self.Write( 442 self.Write(
817 self.GenerateModuleSource(), 443 self._GenerateModuleSource(),
818 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) 444 self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix)))
445
446 def _ConstantValue(self, constant):
447 return self._ExpressionToText(constant.value, kind=constant.kind)
448
449 # TODO(yzshen): Revisit the default value feature. It was designed prior to
450 # custom type mapping.
451 def _DefaultValue(self, field):
452 if field.default:
453 if mojom.IsStructKind(field.kind):
454 assert field.default == "default"
455 if not self._IsTypemappedKind(field.kind):
456 return "%s::New()" % self._GetNameForKind(field.kind)
457 return self._ExpressionToText(field.default, kind=field.kind)
458 return ""
459
460 def _GetNameForKind(self, kind, internal=False, flatten_nested_kind=False,
461 add_same_module_namespaces=False):
462 return _NameFormatter(kind, self.variant).FormatForCpp(
463 internal=internal, flatten_nested_kind=flatten_nested_kind,
464 add_same_module_namespaces=add_same_module_namespaces)
465
466 def _GetQualifiedNameForKind(self, kind, internal=False,
467 flatten_nested_kind=False, include_variant=True):
468 return _NameFormatter(
469 kind, self.variant if include_variant else None).FormatForCpp(
470 internal=internal, add_same_module_namespaces=True,
471 flatten_nested_kind=flatten_nested_kind)
472
473 def _GetFullMojomNameForKind(self, kind):
474 return _NameFormatter(kind, self.variant).FormatForMojom()
475
476 def _IsTypemappedKind(self, kind):
477 return hasattr(kind, "name") and \
478 self._GetFullMojomNameForKind(kind) in self.typemap
479
480 def _IsHashableKind(self, kind):
481 """Check if the kind can be hashed.
482
483 Args:
484 kind: {Kind} The kind to check.
485
486 Returns:
487 {bool} True if a value of this kind can be hashed.
488 """
489 checked = set()
490 def Check(kind):
491 if kind.spec in checked:
492 return True
493 checked.add(kind.spec)
494 if mojom.IsNullableKind(kind):
495 return False
496 elif mojom.IsStructKind(kind):
497 if (self._IsTypemappedKind(kind) and
498 not self.typemap[self._GetFullMojomNameForKind(kind)]["hashable"]):
499 return False
500 return all(Check(field.kind) for field in kind.fields)
501 elif mojom.IsEnumKind(kind):
502 return not self._IsTypemappedKind(kind) or self.typemap[
503 self._GetFullMojomNameForKind(kind)]["hashable"]
504 elif mojom.IsUnionKind(kind):
505 return all(Check(field.kind) for field in kind.fields)
506 elif mojom.IsAnyHandleKind(kind):
507 return False
508 elif mojom.IsAnyInterfaceKind(kind):
509 return False
510 # TODO(tibell): Arrays and maps could be made hashable. We just don't have
511 # a use case yet.
512 elif mojom.IsArrayKind(kind):
513 return False
514 elif mojom.IsMapKind(kind):
515 return False
516 else:
517 return True
518 return Check(kind)
519
520 def _GetNativeTypeName(self, typemapped_kind):
521 return self.typemap[self._GetFullMojomNameForKind(typemapped_kind)][
522 "typename"]
523
524 def _FormatConstantDeclaration(self, constant, nested=False):
525 if mojom.IsStringKind(constant.kind):
526 if nested:
527 return "const char %s[]" % constant.name
528 return "%sextern const char %s[]" % \
529 ((self.export_attribute + " ") if self.export_attribute else "",
530 constant.name)
531 return "constexpr %s %s = %s" % (
532 GetCppPodType(constant.kind), constant.name,
533 self._ConstantValue(constant))
534
535 def _GetCppWrapperType(self, kind, add_same_module_namespaces=False):
536 def _AddOptional(type_name):
537 pattern = "WTF::Optional<%s>" if self.for_blink else "base::Optional<%s>"
538 return pattern % type_name
539
540 if self._IsTypemappedKind(kind):
541 type_name = self._GetNativeTypeName(kind)
542 if (mojom.IsNullableKind(kind) and
543 not self.typemap[self._GetFullMojomNameForKind(kind)][
544 "nullable_is_same_type"]):
545 type_name = _AddOptional(type_name)
546 return type_name
547 if mojom.IsEnumKind(kind):
548 return self._GetNameForKind(
549 kind, add_same_module_namespaces=add_same_module_namespaces)
550 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
551 return "%sPtr" % self._GetNameForKind(
552 kind, add_same_module_namespaces=add_same_module_namespaces)
553 if mojom.IsArrayKind(kind):
554 pattern = "WTF::Vector<%s>" if self.for_blink else "std::vector<%s>"
555 if mojom.IsNullableKind(kind):
556 pattern = _AddOptional(pattern)
557 return pattern % self._GetCppWrapperType(
558 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
559 if mojom.IsMapKind(kind):
560 pattern = ("WTF::HashMap<%s, %s>" if self.for_blink else
561 "std::unordered_map<%s, %s>")
562 if mojom.IsNullableKind(kind):
563 pattern = _AddOptional(pattern)
564 return pattern % (
565 self._GetCppWrapperType(
566 kind.key_kind,
567 add_same_module_namespaces=add_same_module_namespaces),
568 self._GetCppWrapperType(
569 kind.value_kind,
570 add_same_module_namespaces=add_same_module_namespaces))
571 if mojom.IsInterfaceKind(kind):
572 return "%sPtr" % self._GetNameForKind(
573 kind, add_same_module_namespaces=add_same_module_namespaces)
574 if mojom.IsInterfaceRequestKind(kind):
575 return "%sRequest" % self._GetNameForKind(
576 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
577 if mojom.IsAssociatedInterfaceKind(kind):
578 return "%sAssociatedPtrInfo" % self._GetNameForKind(
579 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
580 if mojom.IsAssociatedInterfaceRequestKind(kind):
581 return "%sAssociatedRequest" % self._GetNameForKind(
582 kind.kind, add_same_module_namespaces=add_same_module_namespaces)
583 if mojom.IsStringKind(kind):
584 if self.for_blink:
585 return "WTF::String"
586 type_name = "std::string"
587 return (_AddOptional(type_name) if mojom.IsNullableKind(kind)
588 else type_name)
589 if mojom.IsGenericHandleKind(kind):
590 return "mojo::ScopedHandle"
591 if mojom.IsDataPipeConsumerKind(kind):
592 return "mojo::ScopedDataPipeConsumerHandle"
593 if mojom.IsDataPipeProducerKind(kind):
594 return "mojo::ScopedDataPipeProducerHandle"
595 if mojom.IsMessagePipeKind(kind):
596 return "mojo::ScopedMessagePipeHandle"
597 if mojom.IsSharedBufferKind(kind):
598 return "mojo::ScopedSharedBufferHandle"
599 if not kind in _kind_to_cpp_type:
600 raise Exception("Unrecognized kind %s" % kind.spec)
601 return _kind_to_cpp_type[kind]
602
603 def _IsMoveOnlyKind(self, kind):
604 if self._IsTypemappedKind(kind):
605 if mojom.IsEnumKind(kind):
606 return False
607 return self.typemap[self._GetFullMojomNameForKind(kind)]["move_only"]
608 if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
609 return True
610 if mojom.IsArrayKind(kind):
611 return self._IsMoveOnlyKind(kind.kind)
612 if mojom.IsMapKind(kind):
613 return self._IsMoveOnlyKind(kind.value_kind)
614 if mojom.IsAnyHandleOrInterfaceKind(kind):
615 return True
616 return False
617
618 def _IsCopyablePassByValue(self, kind):
619 if not self._IsTypemappedKind(kind):
620 return False
621 return self.typemap[self._GetFullMojomNameForKind(kind)][
622 "copyable_pass_by_value"]
623
624 def _ShouldPassParamByValue(self, kind):
625 return ((not mojom.IsReferenceKind(kind)) or self._IsMoveOnlyKind(kind) or
626 self._IsCopyablePassByValue(kind))
627
628 def _GetCppWrapperParamType(self, kind):
629 cpp_wrapper_type = self._GetCppWrapperType(kind)
630 return (cpp_wrapper_type if self._ShouldPassParamByValue(kind)
631 else "const %s&" % cpp_wrapper_type)
632
633 def _GetCppFieldType(self, kind):
634 if mojom.IsStructKind(kind):
635 return ("mojo::internal::Pointer<%s>" %
636 self._GetNameForKind(kind, internal=True))
637 if mojom.IsUnionKind(kind):
638 return "%s" % self._GetNameForKind(kind, internal=True)
639 if mojom.IsArrayKind(kind):
640 return ("mojo::internal::Pointer<mojo::internal::Array_Data<%s>>" %
641 self._GetCppFieldType(kind.kind))
642 if mojom.IsMapKind(kind):
643 return ("mojo::internal::Pointer<mojo::internal::Map_Data<%s, %s>>" %
644 (self._GetCppFieldType(kind.key_kind),
645 self._GetCppFieldType(kind.value_kind)))
646 if mojom.IsInterfaceKind(kind):
647 return "mojo::internal::Interface_Data"
648 if mojom.IsInterfaceRequestKind(kind):
649 return "mojo::internal::Handle_Data"
650 if mojom.IsAssociatedInterfaceKind(kind):
651 return "mojo::internal::AssociatedInterface_Data"
652 if mojom.IsAssociatedInterfaceRequestKind(kind):
653 return "mojo::internal::AssociatedEndpointHandle_Data"
654 if mojom.IsEnumKind(kind):
655 return "int32_t"
656 if mojom.IsStringKind(kind):
657 return "mojo::internal::Pointer<mojo::internal::String_Data>"
658 if mojom.IsAnyHandleKind(kind):
659 return "mojo::internal::Handle_Data"
660 return _kind_to_cpp_type[kind]
661
662 def _GetCppUnionFieldType(self, kind):
663 if mojom.IsUnionKind(kind):
664 return ("mojo::internal::Pointer<%s>" %
665 self._GetNameForKind(kind, internal=True))
666 return self._GetCppFieldType(kind)
667
668 def _GetUnionGetterReturnType(self, kind):
669 if mojom.IsReferenceKind(kind):
670 return "%s&" % self._GetCppWrapperType(kind)
671 return self._GetCppWrapperType(kind)
672
673 def _GetUnionTraitGetterReturnType(self, kind):
674 """Get field type used in UnionTraits template specialization.
675
676 The type may be qualified as UnionTraits specializations live outside the
677 namespace where e.g. structs are defined.
678
679 Args:
680 kind: {Kind} The type of the field.
681
682 Returns:
683 {str} The C++ type to use for the field.
684 """
685 if mojom.IsReferenceKind(kind):
686 return "%s&" % self._GetCppWrapperType(kind,
687 add_same_module_namespaces=True)
688 return self._GetCppWrapperType(kind, add_same_module_namespaces=True)
689
690 def _TranslateConstants(self, token, kind):
691 if isinstance(token, mojom.NamedValue):
692 return self._GetNameForKind(token, flatten_nested_kind=True)
693
694 if isinstance(token, mojom.BuiltinValue):
695 if token.value == "double.INFINITY":
696 return "std::numeric_limits<double>::infinity()"
697 if token.value == "float.INFINITY":
698 return "std::numeric_limits<float>::infinity()"
699 if token.value == "double.NEGATIVE_INFINITY":
700 return "-std::numeric_limits<double>::infinity()"
701 if token.value == "float.NEGATIVE_INFINITY":
702 return "-std::numeric_limits<float>::infinity()"
703 if token.value == "double.NAN":
704 return "std::numeric_limits<double>::quiet_NaN()"
705 if token.value == "float.NAN":
706 return "std::numeric_limits<float>::quiet_NaN()"
707
708 if (kind is not None and mojom.IsFloatKind(kind)):
709 return token if token.isdigit() else token + "f";
710
711 # Per C++11, 2.14.2, the type of an integer literal is the first of the
712 # corresponding list in Table 6 in which its value can be represented. In
713 # this case, the list for decimal constants with no suffix is:
714 # int, long int, long long int
715 # The standard considers a program ill-formed if it contains an integer
716 # literal that cannot be represented by any of the allowed types.
717 #
718 # As it turns out, MSVC doesn't bother trying to fall back to long long int,
719 # so the integral constant -2147483648 causes it grief: it decides to
720 # represent 2147483648 as an unsigned integer, and then warns that the unary
721 # minus operator doesn't make sense on unsigned types. Doh!
722 if kind == mojom.INT32 and token == "-2147483648":
723 return "(-%d - 1) /* %s */" % (
724 2**31 - 1, "Workaround for MSVC bug; see https://crbug.com/445618")
725
726 return "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, ""))
727
728 def _ExpressionToText(self, value, kind=None):
729 return self._TranslateConstants(value, kind)
730
731 def _ContainsMoveOnlyMembers(self, struct):
732 for field in struct.fields:
733 if self._IsMoveOnlyKind(field.kind):
734 return True
735 return False
736
737 def _GetStructConstructors(self, struct):
738 """Returns a list of constructors for a struct.
739
740 Params:
741 struct: {Struct} The struct to return constructors for.
742
743 Returns:
744 {[StructConstructor]} A list of StructConstructors that should be
745 generated for |struct|.
746 """
747 if not mojom.IsStructKind(struct):
748 raise TypeError
749 # Types that are neither copyable nor movable can't be passed to a struct
750 # constructor so only generate a default constructor.
751 if any(self._IsTypemappedKind(field.kind) and self.typemap[
752 self._GetFullMojomNameForKind(field.kind)]["non_copyable_non_movable"]
753 for field in struct.fields):
754 return [StructConstructor(struct.fields, [])]
755
756 param_counts = [0]
757 for version in struct.versions:
758 if param_counts[-1] != version.num_fields:
759 param_counts.append(version.num_fields)
760
761 ordinal_fields = sorted(struct.fields, key=lambda field: field.ordinal)
762 return (StructConstructor(struct.fields, ordinal_fields[:param_count])
763 for param_count in param_counts)
764
765 def _GetContainerValidateParamsCtorArgs(self, kind):
766 if mojom.IsStringKind(kind):
767 expected_num_elements = 0
768 element_is_nullable = False
769 key_validate_params = "nullptr"
770 element_validate_params = "nullptr"
771 enum_validate_func = "nullptr"
772 elif mojom.IsMapKind(kind):
773 expected_num_elements = 0
774 element_is_nullable = False
775 key_validate_params = self._GetNewContainerValidateParams(mojom.Array(
776 kind=kind.key_kind))
777 element_validate_params = self._GetNewContainerValidateParams(mojom.Array(
778 kind=kind.value_kind))
779 enum_validate_func = "nullptr"
780 else: # mojom.IsArrayKind(kind)
781 expected_num_elements = generator.ExpectedArraySize(kind) or 0
782 element_is_nullable = mojom.IsNullableKind(kind.kind)
783 key_validate_params = "nullptr"
784 element_validate_params = self._GetNewContainerValidateParams(kind.kind)
785 if mojom.IsEnumKind(kind.kind):
786 enum_validate_func = ("%s::Validate" %
787 self._GetQualifiedNameForKind(kind.kind, internal=True,
788 flatten_nested_kind=True))
789 else:
790 enum_validate_func = "nullptr"
791
792 if enum_validate_func == "nullptr":
793 if key_validate_params == "nullptr":
794 return "%d, %s, %s" % (expected_num_elements,
795 "true" if element_is_nullable else "false",
796 element_validate_params)
797 else:
798 return "%s, %s" % (key_validate_params, element_validate_params)
799 else:
800 return "%d, %s" % (expected_num_elements, enum_validate_func)
801
802 def _GetNewContainerValidateParams(self, kind):
803 if (not mojom.IsArrayKind(kind) and not mojom.IsMapKind(kind) and
804 not mojom.IsStringKind(kind)):
805 return "nullptr"
806
807 return "new mojo::internal::ContainerValidateParams(%s)" % (
808 self._GetContainerValidateParamsCtorArgs(kind))
OLDNEW
« no previous file with comments | « no previous file | mojo/public/tools/bindings/generators/mojom_java_generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698