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 collections import defaultdict |
7 from itertools import chain | 8 from itertools import chain |
8 import os | 9 import os |
9 import re | 10 import re |
10 | 11 |
11 from mojom.generate.template_expander import UseJinja | 12 from mojom.generate.template_expander import UseJinja |
12 | 13 |
13 import mojom.generate.generator as generator | 14 import mojom.generate.generator as generator |
14 import mojom.generate.module as mojom | 15 import mojom.generate.module as mojom |
15 import mojom.generate.pack as pack | 16 import mojom.generate.pack as pack |
16 | 17 |
| 18 GENERATOR_PREFIX = 'go' |
| 19 |
17 class KindInfo(object): | 20 class KindInfo(object): |
18 def __init__(self, go_type, encode_suffix, decode_suffix, bit_size): | 21 def __init__(self, go_type, encode_suffix, decode_suffix, bit_size): |
19 self.go_type = go_type | 22 self.go_type = go_type |
20 self.encode_suffix = encode_suffix | 23 self.encode_suffix = encode_suffix |
21 self.decode_suffix = decode_suffix | 24 self.decode_suffix = decode_suffix |
22 self.bit_size = bit_size | 25 self.bit_size = bit_size |
23 | 26 |
24 _kind_infos = { | 27 _kind_infos = { |
25 mojom.BOOL: KindInfo('bool', 'Bool', 'Bool', 1), | 28 mojom.BOOL: KindInfo('bool', 'Bool', 'Bool', 1), |
26 mojom.INT8: KindInfo('int8', 'Int8', 'Int8', 8), | 29 mojom.INT8: KindInfo('int8', 'Int8', 'Int8', 8), |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 return | 292 return |
290 path = GetPackagePath(imported['module']) | 293 path = GetPackagePath(imported['module']) |
291 if path in _imports: | 294 if path in _imports: |
292 return | 295 return |
293 name = GetPackageName(imported['module']) | 296 name = GetPackageName(imported['module']) |
294 while name in _imports.values(): # This avoids repeated names. | 297 while name in _imports.values(): # This avoids repeated names. |
295 name += '_' | 298 name += '_' |
296 _imports[path] = name | 299 _imports[path] = name |
297 _mojom_imports[path] = name | 300 _mojom_imports[path] = name |
298 | 301 |
299 # The identifier cache is used by the Type generator to determine if a type has | 302 # The identifier_store tracks identifiers that have been used so that code |
300 # already been generated or not. This prevents over-generation of the same type | 303 # generation can avoid over-generating code for the same identifier. |
301 # when it is referred to in multiple ways. | 304 identifier_store = defaultdict(bool) |
302 identifier_cache = {} | |
303 def GetIdentifier(kind): | 305 def GetIdentifier(kind): |
304 # Use the kind's module to determine the package name. | 306 # Use the kind's module to determine the package and name. |
| 307 # Note: InterfaceRequestKind's should use the Interface inside them. |
305 if hasattr(kind, 'module'): | 308 if hasattr(kind, 'module'): |
306 package = GetPackageName(kind.module) | 309 package = GetPackageName(kind.module) |
| 310 name = kind.name |
307 elif mojom.IsInterfaceRequestKind(kind): | 311 elif mojom.IsInterfaceRequestKind(kind): |
308 package = GetPackageName(kind.kind.module) | 312 package = GetPackageName(kind.kind.module) |
| 313 name = kind.kind.name |
309 else: | 314 else: |
| 315 # This is for a type that should not be stored. Return an empty identifier. |
310 return '' | 316 return '' |
311 | 317 |
312 # Most kinds have a name, but those that don't should rely on their spec. | 318 return '%s_%s' % (package, name) |
313 # Since spec can have : and ? characters, these must be replaced. Since ? is | |
314 # replaced with '', the caller must keep track of optionality on its own. | |
315 name_or_spec = (kind.name if hasattr(kind, 'name') else kind.spec) | |
316 package_unique = name_or_spec.replace(':', '_').replace('?', '') | |
317 return '%s_%s' % (package, package_unique) | |
318 | 319 |
319 def StoreIdentifier(identifier, cache_name): | 320 def StoreIdentifier(identifier): |
320 if not cache_name in identifier_cache: | 321 identifier_store[identifier] = True |
321 identifier_cache[cache_name] = {} | |
322 identifier_cache[cache_name][identifier] = True | |
323 return '' | 322 return '' |
324 | 323 |
325 def CheckIdentifier(identifier, cache_name): | 324 def CheckIdentifier(identifier): |
326 if not cache_name in identifier_cache: | 325 return identifier in identifier_store |
327 identifier_cache[cache_name] = {} | |
328 return identifier in identifier_cache[cache_name] | |
329 | 326 |
330 # Get the mojom type's identifier suffix. | 327 # Get the mojom type's identifier suffix. |
331 def GetMojomTypeIdentifier(kind): | 328 def GetMojomTypeIdentifier(kind): |
332 # 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. |
333 return "%s__" % GetIdentifier(kind) | 330 return "%s__" % GetIdentifier(kind) |
334 | 331 |
335 class Generator(generator.Generator): | 332 class Generator(generator.Generator): |
336 go_filters = { | 333 go_filters = { |
337 'array': lambda kind: mojom.Array(kind), | 334 'array': lambda kind: mojom.Array(kind), |
338 'bit_size': GetBitSize, | 335 'bit_size': GetBitSize, |
(...skipping 19 matching lines...) Expand all Loading... |
358 'is_union': mojom.IsUnionKind, | 355 'is_union': mojom.IsUnionKind, |
359 'qualified': GetQualifiedName, | 356 'qualified': GetQualifiedName, |
360 'mojom_type': GetMojomTypeValue, | 357 'mojom_type': GetMojomTypeValue, |
361 'mojom_type_identifier': GetMojomTypeIdentifier, | 358 'mojom_type_identifier': GetMojomTypeIdentifier, |
362 'name': GetNameForElement, | 359 'name': GetNameForElement, |
363 'unqualified_name': GetUnqualifiedNameForElement, | 360 'unqualified_name': GetUnqualifiedNameForElement, |
364 'package': GetPackageNameForElement, | 361 'package': GetPackageNameForElement, |
365 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) | 362 'tab_indent': lambda s, size = 1: ('\n' + '\t' * size).join(s.splitlines()) |
366 } | 363 } |
367 | 364 |
368 # TODO: This value should be settable via arguments. If False, then mojom type | 365 # If set to True, then mojom type information will be generated. |
369 # information will not be generated. | 366 should_gen_mojom_types = False |
370 should_gen_mojom_types = True | |
371 | 367 |
372 def GetParameters(self): | 368 def GetParameters(self): |
373 package = GetPackageName(self.module) | 369 package = GetPackageName(self.module) |
374 return { | 370 return { |
375 'enums': GetAllEnums(self.module), | 371 'enums': GetAllEnums(self.module), |
376 'imports': self.GetImports()[0], | 372 'imports': self.GetImports()[0], |
377 'interfaces': self.GetInterfaces(), | 373 'interfaces': self.GetInterfaces(), |
378 'mojom_imports': self.GetMojomImports(), | 374 'mojom_imports': self.GetMojomImports(), |
379 'package': package, | 375 'package': package, |
380 'structs': self.GetStructs(), | 376 'structs': self.GetStructs(), |
381 'descpkg': '%s.' % _service_describer_pkg_short \ | 377 'descpkg': '%s.' % _service_describer_pkg_short \ |
382 if package != _service_describer_pkg_short else '', | 378 if package != _service_describer_pkg_short else '', |
383 'typepkg': '%s.' % _mojom_types_pkg_short \ | 379 'typepkg': '%s.' % _mojom_types_pkg_short \ |
384 if package != _mojom_types_pkg_short else '', | 380 if package != _mojom_types_pkg_short else '', |
385 'unions': self.GetUnions() | 381 'unions': self.GetUnions() |
386 } | 382 } |
387 | 383 |
388 @UseJinja('go_templates/source.tmpl', filters=go_filters) | 384 @UseJinja('go_templates/source.tmpl', filters=go_filters) |
389 def GenerateSource(self): | 385 def GenerateSource(self): |
390 return self.GetParameters() | 386 return self.GetParameters() |
391 | 387 |
392 def GenerateFiles(self, args): | 388 def GenerateFiles(self, args): |
| 389 if "--go_gen_types" in args: |
| 390 self.should_gen_mojom_types = True |
| 391 |
393 self.Write(self.GenerateSource(), os.path.join("go", "src", | 392 self.Write(self.GenerateSource(), os.path.join("go", "src", |
394 GetPackagePath(self.module), "%s.go" % self.module.name)) | 393 GetPackagePath(self.module), "%s.go" % self.module.name)) |
395 | 394 |
396 def GetJinjaParameters(self): | 395 def GetJinjaParameters(self): |
397 return { | 396 return { |
398 'lstrip_blocks': True, | 397 'lstrip_blocks': True, |
399 'trim_blocks': True, | 398 'trim_blocks': True, |
400 } | 399 } |
401 | 400 |
402 def GetGlobals(self): | 401 def GetGlobals(self): |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 # Overrides the implementation from the base class in order to customize the | 493 # Overrides the implementation from the base class in order to customize the |
495 # struct and field names. | 494 # struct and field names. |
496 def _GetResponseStructFromMethod(self, method): | 495 def _GetResponseStructFromMethod(self, method): |
497 params_class = "%s_%s_ResponseParams" % ( | 496 params_class = "%s_%s_ResponseParams" % ( |
498 GetNameForElement(method.interface), GetNameForElement(method)) | 497 GetNameForElement(method.interface), GetNameForElement(method)) |
499 struct = mojom.Struct(params_class, module=method.interface.module) | 498 struct = mojom.Struct(params_class, module=method.interface.module) |
500 for param in method.response_parameters: | 499 for param in method.response_parameters: |
501 struct.AddField("out%s" % GetNameForElement(param), | 500 struct.AddField("out%s" % GetNameForElement(param), |
502 param.kind, param.ordinal, attributes=param.attributes) | 501 param.kind, param.ordinal, attributes=param.attributes) |
503 return self._AddStructComputedData(False, struct) | 502 return self._AddStructComputedData(False, struct) |
OLD | NEW |