OLD | NEW |
---|---|
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 Go source files from a mojom.Module.''' | 5 '''Generates Go source files from a mojom.Module.''' |
6 | 6 |
7 from itertools import chain | 7 from itertools import chain |
8 import os | 8 import os |
9 import re | 9 import re |
10 | 10 |
11 from mojom.generate.template_expander import UseJinja | 11 from mojom.generate.template_expander import UseJinja |
12 | 12 |
13 import mojom.generate.generator as generator | 13 import mojom.generate.generator as generator |
14 import mojom.generate.module as mojom | 14 import mojom.generate.module as mojom |
15 import mojom.generate.pack as pack | 15 import mojom.generate.pack as pack |
16 | 16 |
17 GENERATOR_PREFIX = 'go' | |
18 | |
17 class KindInfo(object): | 19 class KindInfo(object): |
18 def __init__(self, go_type, encode_suffix, decode_suffix, bit_size): | 20 def __init__(self, go_type, encode_suffix, decode_suffix, bit_size): |
19 self.go_type = go_type | 21 self.go_type = go_type |
20 self.encode_suffix = encode_suffix | 22 self.encode_suffix = encode_suffix |
21 self.decode_suffix = decode_suffix | 23 self.decode_suffix = decode_suffix |
22 self.bit_size = bit_size | 24 self.bit_size = bit_size |
23 | 25 |
24 _kind_infos = { | 26 _kind_infos = { |
25 mojom.BOOL: KindInfo('bool', 'Bool', 'Bool', 1), | 27 mojom.BOOL: KindInfo('bool', 'Bool', 'Bool', 1), |
26 mojom.INT8: KindInfo('int8', 'Int8', 'Int8', 8), | 28 mojom.INT8: KindInfo('int8', 'Int8', 'Int8', 8), |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 path = GetPackagePath(imported['module']) | 302 path = GetPackagePath(imported['module']) |
301 if path in imports: | 303 if path in imports: |
302 return | 304 return |
303 name = GetPackageName(imported['module']) | 305 name = GetPackageName(imported['module']) |
304 while name in imports.values(): # This avoids repeated names. | 306 while name in imports.values(): # This avoids repeated names. |
305 name += '_' | 307 name += '_' |
306 imported['go_name'] = name | 308 imported['go_name'] = name |
307 imports[path] = name | 309 imports[path] = name |
308 mojom_imports[path] = name | 310 mojom_imports[path] = name |
309 | 311 |
310 # The identifier cache is used by the Type generator to determine if a type has | |
311 # already been generated or not. This prevents over-generation of the same type | |
312 # when it is referred to in multiple ways. | |
313 identifier_cache = {} | |
314 def GetIdentifier(kind): | 312 def GetIdentifier(kind): |
315 # Use the kind's module to determine the package name. | 313 # Use the kind's module to determine the package and name. |
314 # Note: InterfaceRequestKind's should use the Interface inside them. | |
azani
2015/12/10 23:16:18
The type is just InterfaceRequest.
alexfandrianto
2015/12/11 01:26:57
Done.
| |
316 if hasattr(kind, 'module'): | 315 if hasattr(kind, 'module'): |
317 package = GetPackageName(kind.module) | 316 package = GetPackageName(kind.module) |
317 name = kind.name | |
318 elif mojom.IsInterfaceRequestKind(kind): | 318 elif mojom.IsInterfaceRequestKind(kind): |
319 package = GetPackageName(kind.kind.module) | 319 package = GetPackageName(kind.kind.module) |
320 name = kind.kind.name | |
320 else: | 321 else: |
322 # This is for a type that should not be stored. Return an empty identifier. | |
321 return '' | 323 return '' |
322 | 324 |
323 # Most kinds have a name, but those that don't should rely on their spec. | 325 return '%s_%s' % (package, name) |
324 # Since spec can have : and ? characters, these must be replaced. Since ? is | |
325 # replaced with '', the caller must keep track of optionality on its own. | |
326 name_or_spec = (kind.name if hasattr(kind, 'name') else kind.spec) | |
327 package_unique = name_or_spec.replace(':', '_').replace('?', '') | |
328 return '%s_%s' % (package, package_unique) | |
329 | |
330 def StoreIdentifier(identifier, cache_name): | |
331 if not cache_name in identifier_cache: | |
332 identifier_cache[cache_name] = {} | |
333 identifier_cache[cache_name][identifier] = True | |
334 return '' | |
335 | |
336 def CheckIdentifier(identifier, cache_name): | |
337 if not cache_name in identifier_cache: | |
338 identifier_cache[cache_name] = {} | |
339 return identifier in identifier_cache[cache_name] | |
340 | 326 |
341 # Get the mojom type's identifier suffix. | 327 # Get the mojom type's identifier suffix. |
342 def GetMojomTypeIdentifier(kind): | 328 def GetMojomTypeIdentifier(kind): |
343 # Since this should be unique, it is based on the type's identifier. | 329 # Since this should be unique, it is based on the type's identifier. |
344 return "%s__" % GetIdentifier(kind) | 330 return "%s__" % GetIdentifier(kind) |
345 | 331 |
346 class Generator(generator.Generator): | 332 class Generator(generator.Generator): |
347 go_filters = { | 333 go_filters = { |
348 'array': lambda kind: mojom.Array(kind), | 334 'array': lambda kind: mojom.Array(kind), |
349 'bit_size': GetBitSize, | 335 'bit_size': GetBitSize, |
350 'decode_suffix': DecodeSuffix, | 336 'decode_suffix': DecodeSuffix, |
351 'encode_suffix': EncodeSuffix, | 337 'encode_suffix': EncodeSuffix, |
352 'go_type': GetGoType, | 338 'go_type': GetGoType, |
353 'expression_to_text': ExpressionToText, | 339 'expression_to_text': ExpressionToText, |
354 'has_response': lambda method: method.response_parameters is not None, | 340 'has_response': lambda method: method.response_parameters is not None, |
355 'identifier': GetIdentifier, | 341 'identifier': GetIdentifier, |
356 'identifier_check': CheckIdentifier, | |
357 'identifier_store': StoreIdentifier, | |
358 'is_array': mojom.IsArrayKind, | 342 'is_array': mojom.IsArrayKind, |
359 'is_enum': mojom.IsEnumKind, | 343 'is_enum': mojom.IsEnumKind, |
360 'is_handle': mojom.IsAnyHandleKind, | 344 'is_handle': mojom.IsAnyHandleKind, |
361 'is_interface': mojom.IsInterfaceKind, | 345 'is_interface': mojom.IsInterfaceKind, |
362 'is_interface_request': mojom.IsInterfaceRequestKind, | 346 'is_interface_request': mojom.IsInterfaceRequestKind, |
363 'is_map': mojom.IsMapKind, | 347 'is_map': mojom.IsMapKind, |
364 'is_none_or_empty': lambda array: array is None or len(array) == 0, | 348 'is_none_or_empty': lambda array: array is None or len(array) == 0, |
365 'is_nullable': mojom.IsNullableKind, | 349 'is_nullable': mojom.IsNullableKind, |
366 'is_pointer': IsPointer, | 350 'is_pointer': IsPointer, |
367 'is_object': mojom.IsObjectKind, | 351 'is_object': mojom.IsObjectKind, |
368 'is_struct': mojom.IsStructKind, | 352 'is_struct': mojom.IsStructKind, |
369 'is_union': mojom.IsUnionKind, | 353 'is_union': mojom.IsUnionKind, |
370 'qualified': GetQualifiedName, | 354 'qualified': GetQualifiedName, |
371 'fullidentifier': GetFullIdentifier, | 355 'fullidentifier': GetFullIdentifier, |
372 'mojom_type': GetMojomTypeValue, | 356 'mojom_type': GetMojomTypeValue, |
373 'mojom_type_identifier': GetMojomTypeIdentifier, | 357 'mojom_type_identifier': GetMojomTypeIdentifier, |
374 'name': GetNameForElement, | 358 'name': GetNameForElement, |
375 'unqualified_name': GetUnqualifiedNameForElement, | 359 'unqualified_name': GetUnqualifiedNameForElement, |
376 'package': GetPackageNameForElement, | 360 'package': GetPackageNameForElement, |
377 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) | 361 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) |
378 } | 362 } |
379 | 363 |
380 # TODO: This value should be settable via arguments. If False, then mojom type | 364 # If set to True, then mojom type information will be generated. |
381 # information will not be generated. | 365 should_gen_mojom_types = False |
382 should_gen_mojom_types = True | |
383 | 366 |
384 def GetParameters(self): | 367 def GetParameters(self): |
385 package = GetPackageName(self.module) | 368 package = GetPackageName(self.module) |
386 imports, mojom_imports = self.GetImports() | 369 imports, mojom_imports = self.GetImports() |
387 return { | 370 return { |
388 'enums': GetAllEnums(self.module), | 371 'enums': GetAllEnums(self.module), |
389 'imports': imports, | 372 'imports': imports, |
390 'interfaces': self.GetInterfaces(), | 373 'interfaces': self.GetInterfaces(), |
391 'mojom_imports': mojom_imports, | 374 'mojom_imports': mojom_imports, |
392 'package': package, | 375 'package': package, |
393 'structs': self.GetStructs(), | 376 'structs': self.GetStructs(), |
394 'descpkg': '%s.' % _service_describer_pkg_short \ | 377 'descpkg': '%s.' % _service_describer_pkg_short \ |
395 if package != _service_describer_pkg_short else '', | 378 if package != _service_describer_pkg_short else '', |
396 'typepkg': '%s.' % _mojom_types_pkg_short \ | 379 'typepkg': '%s.' % _mojom_types_pkg_short \ |
397 if package != _mojom_types_pkg_short else '', | 380 if package != _mojom_types_pkg_short else '', |
398 'unions': self.GetUnions() | 381 'unions': self.GetUnions() |
399 } | 382 } |
400 | 383 |
401 @UseJinja('go_templates/source.tmpl', filters=go_filters) | 384 @UseJinja('go_templates/source.tmpl', filters=go_filters) |
402 def GenerateSource(self): | 385 def GenerateSource(self): |
403 return self.GetParameters() | 386 return self.GetParameters() |
404 | 387 |
405 def GenerateFiles(self, args): | 388 def GenerateFiles(self, args): |
389 if "--go_gen_types" in args: | |
azani
2015/12/10 23:16:18
Let's have a single flag control type generation i
alexfandrianto
2015/12/11 01:26:57
I very much agree, but I am having issues with lin
rudominer
2015/12/14 21:29:57
Let's just leave it as you have it for now. We can
azani
2015/12/14 22:20:01
I just chatted with Mitch and we came up with a so
alexfandrianto
2015/12/15 20:53:40
Thanks, that was very helpful. I added --generate_
| |
390 self.should_gen_mojom_types = True | |
391 | |
406 self.Write(self.GenerateSource(), os.path.join("go", "src", | 392 self.Write(self.GenerateSource(), os.path.join("go", "src", |
407 GetPackagePath(self.module), "%s.go" % self.module.name)) | 393 GetPackagePath(self.module), "%s.go" % self.module.name)) |
408 | 394 |
409 def GetJinjaParameters(self): | 395 def GetJinjaParameters(self): |
410 return { | 396 return { |
411 'lstrip_blocks': True, | 397 'lstrip_blocks': True, |
412 'trim_blocks': True, | 398 'trim_blocks': True, |
413 } | 399 } |
414 | 400 |
415 def GetGlobals(self): | 401 def GetGlobals(self): |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
504 # Overrides the implementation from the base class in order to customize the | 490 # Overrides the implementation from the base class in order to customize the |
505 # struct and field names. | 491 # struct and field names. |
506 def _GetResponseStructFromMethod(self, method): | 492 def _GetResponseStructFromMethod(self, method): |
507 params_class = "%s_%s_ResponseParams" % ( | 493 params_class = "%s_%s_ResponseParams" % ( |
508 GetNameForElement(method.interface), GetNameForElement(method)) | 494 GetNameForElement(method.interface), GetNameForElement(method)) |
509 struct = mojom.Struct(params_class, module=method.interface.module) | 495 struct = mojom.Struct(params_class, module=method.interface.module) |
510 for param in method.response_parameters: | 496 for param in method.response_parameters: |
511 struct.AddField("out%s" % GetNameForElement(param), | 497 struct.AddField("out%s" % GetNameForElement(param), |
512 param.kind, param.ordinal, attributes=param.attributes) | 498 param.kind, param.ordinal, attributes=param.attributes) |
513 return self._AddStructComputedData(False, struct) | 499 return self._AddStructComputedData(False, struct) |
OLD | NEW |