Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 dart source files from a mojom.Module.""" | 5 """Generates dart source files from a mojom.Module.""" |
| 6 | 6 |
| 7 from collections import defaultdict | |
|
zra
2015/11/24 17:34:44
I'm not familiar with python conventions for impor
azani
2015/11/24 20:02:02
The prescribed style is that you import the module
alexfandrianto
2015/12/18 01:53:19
Not needed anymore. No more identifiercache
| |
| 7 import os | 8 import os |
| 8 import re | 9 import re |
| 9 import shutil | 10 import shutil |
| 10 import sys | 11 import sys |
| 11 | 12 |
| 12 import mojom.fileutil as fileutil | 13 import mojom.fileutil as fileutil |
| 13 import mojom.generate.constant_resolver as resolver | 14 import mojom.generate.constant_resolver as resolver |
| 14 import mojom.generate.generator as generator | 15 import mojom.generate.generator as generator |
| 15 import mojom.generate.module as mojom | 16 import mojom.generate.module as mojom |
| 16 import mojom.generate.pack as pack | 17 import mojom.generate.pack as pack |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 mojom.NULLABLE_DPPIPE: "core.MojoDataPipeProducer", | 64 mojom.NULLABLE_DPPIPE: "core.MojoDataPipeProducer", |
| 64 mojom.NULLABLE_MSGPIPE: "core.MojoMessagePipeEndpoint", | 65 mojom.NULLABLE_MSGPIPE: "core.MojoMessagePipeEndpoint", |
| 65 mojom.NULLABLE_SHAREDBUFFER: "core.MojoSharedBuffer", | 66 mojom.NULLABLE_SHAREDBUFFER: "core.MojoSharedBuffer", |
| 66 mojom.INT64: "int", | 67 mojom.INT64: "int", |
| 67 mojom.UINT64: "int", | 68 mojom.UINT64: "int", |
| 68 mojom.DOUBLE: "double", | 69 mojom.DOUBLE: "double", |
| 69 mojom.STRING: "String", | 70 mojom.STRING: "String", |
| 70 mojom.NULLABLE_STRING: "String" | 71 mojom.NULLABLE_STRING: "String" |
| 71 } | 72 } |
| 72 | 73 |
| 74 _kind_to_mojom_type = { | |
| 75 mojom.BOOL: "BOOL", | |
| 76 mojom.INT8: "INT8", | |
| 77 mojom.UINT8: "UINT8", | |
| 78 mojom.INT16: "INT16", | |
| 79 mojom.UINT16: "UINT16", | |
| 80 mojom.INT32: "INT32", | |
| 81 mojom.UINT32: "UINT32", | |
| 82 mojom.FLOAT: "FLOAT", | |
| 83 mojom.HANDLE: "UNSPECIFIED", | |
| 84 mojom.DCPIPE: "DATA_PIPE_CONSUMER", | |
| 85 mojom.DPPIPE: "DATA_PIPE_PRODUCER", | |
| 86 mojom.MSGPIPE: "MESSAGE_PIPE", | |
| 87 mojom.SHAREDBUFFER: "SHARED_BUFFER", | |
| 88 mojom.NULLABLE_HANDLE: "UNSPECIFIED", | |
| 89 mojom.NULLABLE_DCPIPE: "DATA_PIPE_CONSUMER", | |
| 90 mojom.NULLABLE_DPPIPE: "DATA_PIPE_PRODUCER", | |
| 91 mojom.NULLABLE_MSGPIPE: "MESSAGE_PIPE", | |
| 92 mojom.NULLABLE_SHAREDBUFFER: "SHARED_BUFFER", | |
| 93 mojom.INT64: "INT64", | |
| 94 mojom.UINT64: "UINT64", | |
| 95 mojom.DOUBLE: "DOUBLE", | |
| 96 mojom.STRING: "STRING", | |
| 97 mojom.NULLABLE_STRING: "STRING" | |
| 98 } | |
| 99 | |
| 73 _spec_to_decode_method = { | 100 _spec_to_decode_method = { |
| 74 mojom.BOOL.spec: 'decodeBool', | 101 mojom.BOOL.spec: 'decodeBool', |
| 75 mojom.DCPIPE.spec: 'decodeConsumerHandle', | 102 mojom.DCPIPE.spec: 'decodeConsumerHandle', |
| 76 mojom.DOUBLE.spec: 'decodeDouble', | 103 mojom.DOUBLE.spec: 'decodeDouble', |
| 77 mojom.DPPIPE.spec: 'decodeProducerHandle', | 104 mojom.DPPIPE.spec: 'decodeProducerHandle', |
| 78 mojom.FLOAT.spec: 'decodeFloat', | 105 mojom.FLOAT.spec: 'decodeFloat', |
| 79 mojom.HANDLE.spec: 'decodeHandle', | 106 mojom.HANDLE.spec: 'decodeHandle', |
| 80 mojom.INT16.spec: 'decodeInt16', | 107 mojom.INT16.spec: 'decodeInt16', |
| 81 mojom.INT32.spec: 'decodeInt32', | 108 mojom.INT32.spec: 'decodeInt32', |
| 82 mojom.INT64.spec: 'decodeInt64', | 109 mojom.INT64.spec: 'decodeInt64', |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 mojom.NULLABLE_SHAREDBUFFER.spec: 'encodeSharedBufferHandle', | 142 mojom.NULLABLE_SHAREDBUFFER.spec: 'encodeSharedBufferHandle', |
| 116 mojom.NULLABLE_STRING.spec: 'encodeString', | 143 mojom.NULLABLE_STRING.spec: 'encodeString', |
| 117 mojom.SHAREDBUFFER.spec: 'encodeSharedBufferHandle', | 144 mojom.SHAREDBUFFER.spec: 'encodeSharedBufferHandle', |
| 118 mojom.STRING.spec: 'encodeString', | 145 mojom.STRING.spec: 'encodeString', |
| 119 mojom.UINT16.spec: 'encodeUint16', | 146 mojom.UINT16.spec: 'encodeUint16', |
| 120 mojom.UINT32.spec: 'encodeUint32', | 147 mojom.UINT32.spec: 'encodeUint32', |
| 121 mojom.UINT64.spec: 'encodeUint64', | 148 mojom.UINT64.spec: 'encodeUint64', |
| 122 mojom.UINT8.spec: 'encodeUint8', | 149 mojom.UINT8.spec: 'encodeUint8', |
| 123 } | 150 } |
| 124 | 151 |
| 152 # The mojom_types.mojom and service_describer.mojom files are special because | |
|
zra
2015/11/24 17:34:44
It looks like you might be trying to avoid importi
alexfandrianto
2015/12/18 01:53:19
Done.
| |
| 153 # they are used to generate mojom Type's and ServiceDescription implementations. | |
| 154 _service_describer_pkg_short = "service_describer" | |
| 155 _service_describer_pkg = "package:mojo/mojo/%s.mojom.dart" % \ | |
| 156 _service_describer_pkg_short | |
| 157 _mojom_types_pkg_short = "mojom_types" | |
| 158 _mojom_types_pkg = "package:mojo/mojo/%s.mojom.dart" % \ | |
| 159 _mojom_types_pkg_short | |
| 160 | |
| 125 def GetDartType(kind): | 161 def GetDartType(kind): |
| 126 if kind.imported_from: | 162 if kind.imported_from: |
| 127 return kind.imported_from["unique_name"] + "." + GetNameForElement(kind) | 163 return kind.imported_from["unique_name"] + "." + GetNameForElement(kind) |
| 128 return GetNameForElement(kind) | 164 return GetNameForElement(kind) |
| 129 | 165 |
| 130 def DartDefaultValue(field): | 166 def DartDefaultValue(field): |
| 131 if field.default: | 167 if field.default: |
| 132 if mojom.IsStructKind(field.kind): | 168 if mojom.IsStructKind(field.kind): |
| 133 assert field.default == "default" | 169 assert field.default == "default" |
| 134 return "new %s()" % GetDartType(field.kind) | 170 return "new %s()" % GetDartType(field.kind) |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 165 if mojom.IsMapKind(kind): | 201 if mojom.IsMapKind(kind): |
| 166 key_type = DartDeclType(kind.key_kind) | 202 key_type = DartDeclType(kind.key_kind) |
| 167 value_type = DartDeclType(kind.value_kind) | 203 value_type = DartDeclType(kind.value_kind) |
| 168 return "Map<"+ key_type + ", " + value_type + ">" | 204 return "Map<"+ key_type + ", " + value_type + ">" |
| 169 if mojom.IsInterfaceKind(kind) or \ | 205 if mojom.IsInterfaceKind(kind) or \ |
| 170 mojom.IsInterfaceRequestKind(kind): | 206 mojom.IsInterfaceRequestKind(kind): |
| 171 return "Object" | 207 return "Object" |
| 172 if mojom.IsEnumKind(kind): | 208 if mojom.IsEnumKind(kind): |
| 173 return GetDartType(kind) | 209 return GetDartType(kind) |
| 174 | 210 |
| 211 def GetMojomTypeValue(kind, typepkg=''): | |
| 212 if not kind in _kind_to_mojom_type: | |
| 213 return '' | |
| 214 | |
| 215 nullable = 'true' if mojom.IsNullableKind(kind) else 'false' | |
| 216 w = _kind_to_mojom_type[kind] | |
| 217 if kind == mojom.BOOL or kind == mojom.FLOAT or kind == mojom.DOUBLE or \ | |
| 218 mojom.IsIntegralKind(kind): | |
| 219 | |
| 220 return 'new %sType()..simpleType = %sSimpleType.%s' % (typepkg, typepkg, w) | |
| 221 elif mojom.IsAnyHandleKind(kind): | |
| 222 return ('new %sType()\n..handleType = (new %sHandleType()' + | |
| 223 '\n..kind = %sHandleTypeKind.%s' + | |
| 224 '\n..nullable = %s)') % \ | |
| 225 (typepkg, typepkg, typepkg, w, nullable) | |
| 226 elif mojom.IsStringKind(kind): | |
| 227 return 'new %sType()\n..stringType = (new %sStringType()..nullable = %s)' \ | |
| 228 % (typepkg, typepkg, nullable) | |
| 229 else: | |
| 230 raise Exception('Missing case for kind: %s' % kind) | |
| 231 | |
| 175 def NameToComponent(name): | 232 def NameToComponent(name): |
| 176 # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> | 233 # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> |
| 177 # HTTP_Entry2_FooBar) | 234 # HTTP_Entry2_FooBar) |
| 178 name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name) | 235 name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name) |
| 179 # insert '_' between non upper and start of upper blocks (e.g., | 236 # insert '_' between non upper and start of upper blocks (e.g., |
| 180 # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar) | 237 # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar) |
| 181 name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name) | 238 name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name) |
| 182 return [x.lower() for x in name.split('_')] | 239 return [x.lower() for x in name.split('_')] |
| 183 | 240 |
| 184 def UpperCamelCase(name): | 241 def UpperCamelCase(name): |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 | 432 |
| 376 def IsPointerArrayKind(kind): | 433 def IsPointerArrayKind(kind): |
| 377 if not mojom.IsArrayKind(kind): | 434 if not mojom.IsArrayKind(kind): |
| 378 return False | 435 return False |
| 379 sub_kind = kind.kind | 436 sub_kind = kind.kind |
| 380 return mojom.IsObjectKind(sub_kind) | 437 return mojom.IsObjectKind(sub_kind) |
| 381 | 438 |
| 382 def IsEnumArrayKind(kind): | 439 def IsEnumArrayKind(kind): |
| 383 return mojom.IsArrayKind(kind) and mojom.IsEnumKind(kind.kind) | 440 return mojom.IsArrayKind(kind) and mojom.IsEnumKind(kind.kind) |
| 384 | 441 |
| 442 def IsImportedKind(kind): | |
| 443 return hasattr(kind, 'imported_from') and kind.imported_from | |
| 444 | |
| 385 def ParseStringAttribute(attribute): | 445 def ParseStringAttribute(attribute): |
| 386 assert isinstance(attribute, basestring) | 446 assert isinstance(attribute, basestring) |
| 387 return attribute | 447 return attribute |
| 388 | 448 |
| 389 def GetPackage(module): | 449 def GetPackage(module): |
| 390 if module.attributes and 'DartPackage' in module.attributes: | 450 if module.attributes and 'DartPackage' in module.attributes: |
| 391 return ParseStringAttribute(module.attributes['DartPackage']) | 451 return ParseStringAttribute(module.attributes['DartPackage']) |
| 392 # Default package. | 452 # Default package. |
| 393 return 'mojom' | 453 return 'mojom' |
| 394 | 454 |
| 455 def GetPackageName(module): | |
| 456 return module.name.split('.')[0] | |
| 457 | |
| 395 def GetImportUri(module): | 458 def GetImportUri(module): |
| 396 package = GetPackage(module); | 459 package = GetPackage(module); |
| 397 elements = module.namespace.split('.') | 460 elements = module.namespace.split('.') |
| 398 elements.append("%s" % module.name) | 461 elements.append("%s" % module.name) |
| 399 return os.path.join(package, *elements) | 462 return os.path.join(package, *elements) |
| 400 | 463 |
| 464 # The identifier_store tracks identifiers that have been used so that code | |
|
zra
2015/11/24 17:34:44
Is this needed for the new code generation you're
alexfandrianto
2015/12/18 01:53:19
Removed
| |
| 465 # generation can avoid over-generating code for the same identifier. | |
| 466 identifier_store = defaultdict(bool) | |
| 467 def GetIdentifier(kind): | |
| 468 # Use the kind's module to determine the package and name. | |
| 469 # Note: InterfaceRequestKind's should use the Interface inside them. | |
| 470 if hasattr(kind, 'module'): | |
| 471 package = GetPackageName(kind.module) | |
| 472 name = kind.name | |
| 473 elif mojom.IsInterfaceRequestKind(kind): | |
| 474 package = GetPackageName(kind.kind.module) | |
| 475 name = kind.kind.name | |
| 476 else: | |
| 477 # This is for a type that should not be stored. Return an empty identifier. | |
| 478 return '' | |
| 479 | |
| 480 return '%s_%s' % (package, name) | |
| 481 | |
| 482 def StoreIdentifier(identifier): | |
| 483 identifier_store[identifier] = True | |
| 484 return '' | |
| 485 | |
| 486 def CheckIdentifier(identifier): | |
| 487 return identifier in identifier_store | |
| 488 | |
| 489 def GetMojomTypeIdentifier(kind): | |
| 490 """Get the mojom type's identifier suffix.""" | |
| 491 # Since this should be unique, it is based on the type's identifier. | |
| 492 return "_%s__" % GetIdentifier(kind) | |
| 493 | |
| 401 class Generator(generator.Generator): | 494 class Generator(generator.Generator): |
| 402 | 495 |
| 403 dart_filters = { | 496 dart_filters = { |
| 404 'array_expected_length': GetArrayExpectedLength, | 497 'array_expected_length': GetArrayExpectedLength, |
| 405 'array': GetArrayKind, | 498 'array': GetArrayKind, |
| 406 'decode_method': DecodeMethod, | 499 'decode_method': DecodeMethod, |
| 407 'default_value': DartDefaultValue, | 500 'default_value': DartDefaultValue, |
| 408 'encode_method': EncodeMethod, | 501 'encode_method': EncodeMethod, |
| 409 'expression_to_text': ExpressionToText, | 502 'expression_to_text': ExpressionToText, |
| 503 'identifier': GetIdentifier, | |
| 504 'identifier_check': CheckIdentifier, | |
| 505 'identifier_store': StoreIdentifier, | |
| 506 'mojom_type_value': GetMojomTypeValue, | |
| 507 'mojom_type_identifier': GetMojomTypeIdentifier, | |
| 508 'is_imported_kind': IsImportedKind, | |
| 509 'is_array_kind': mojom.IsArrayKind, | |
| 410 'is_map_kind': mojom.IsMapKind, | 510 'is_map_kind': mojom.IsMapKind, |
| 411 'is_nullable_kind': mojom.IsNullableKind, | 511 'is_nullable_kind': mojom.IsNullableKind, |
| 412 'is_pointer_array_kind': IsPointerArrayKind, | 512 'is_pointer_array_kind': IsPointerArrayKind, |
| 413 'is_enum_array_kind': IsEnumArrayKind, | 513 'is_enum_array_kind': IsEnumArrayKind, |
| 414 'is_struct_kind': mojom.IsStructKind, | 514 'is_struct_kind': mojom.IsStructKind, |
| 415 'is_union_kind': mojom.IsUnionKind, | 515 'is_union_kind': mojom.IsUnionKind, |
| 416 'is_enum_kind': mojom.IsEnumKind, | 516 'is_enum_kind': mojom.IsEnumKind, |
| 517 'is_interface_kind': mojom.IsInterfaceKind, | |
| 518 'is_interface_request_kind': mojom.IsInterfaceRequestKind, | |
| 417 'dart_true_false': GetDartTrueFalse, | 519 'dart_true_false': GetDartTrueFalse, |
| 418 'dart_type': DartDeclType, | 520 'dart_type': DartDeclType, |
| 419 'name': GetNameForElement, | 521 'name': GetNameForElement, |
| 420 'tag_name': GetUnionFieldTagName, | 522 'tag_name': GetUnionFieldTagName, |
| 421 'interface_response_name': GetInterfaceResponseName, | 523 'interface_response_name': GetInterfaceResponseName, |
| 422 'dot_to_underscore': DotToUnderscore, | 524 'dot_to_underscore': DotToUnderscore, |
| 423 'is_cloneable_kind': mojom.IsCloneableKind, | 525 'is_cloneable_kind': mojom.IsCloneableKind, |
| 526 'upper_camel': UpperCamelCase, | |
| 424 } | 527 } |
| 425 | 528 |
| 529 # If set to True, then mojom type information will be generated. | |
| 530 should_gen_mojom_types = False | |
| 531 | |
| 426 def GetParameters(self, args): | 532 def GetParameters(self, args): |
| 427 return { | 533 package = GetPackageName(self.module) |
| 534 | |
| 535 parameters = { | |
| 428 "namespace": self.module.namespace, | 536 "namespace": self.module.namespace, |
| 429 "imports": self.GetImports(args), | 537 "imports": self.GetImports(args), |
| 430 "kinds": self.module.kinds, | 538 "kinds": self.module.kinds, |
| 431 "enums": self.module.enums, | 539 "enums": self.module.enums, |
| 432 "module": resolver.ResolveConstants(self.module, ExpressionToText), | 540 "module": resolver.ResolveConstants(self.module, ExpressionToText), |
| 433 "structs": self.GetStructs() + self.GetStructsFromMethods(), | 541 "structs": self.GetStructs() + self.GetStructsFromMethods(), |
| 434 "unions": self.GetUnions(), | 542 "unions": self.GetUnions(), |
| 435 "interfaces": self.GetInterfaces(), | 543 "interfaces": self.GetInterfaces(), |
| 436 "imported_interfaces": self.GetImportedInterfaces(), | 544 "imported_interfaces": self.GetImportedInterfaces(), |
| 437 "imported_from": self.ImportedFrom(), | 545 "imported_from": self.ImportedFrom(), |
| 546 "typepkg": '%s.' % _mojom_types_pkg_short, | |
| 547 "descpkg": '%s.' % _service_describer_pkg_short, | |
| 548 "mojom_types_import": 'import \'%s\' as %s;' % \ | |
| 549 (_mojom_types_pkg, _mojom_types_pkg_short), | |
| 550 "service_describer_import": 'import \'%s\' as %s;' % \ | |
| 551 (_service_describer_pkg, _service_describer_pkg_short), | |
| 552 } | |
| 553 | |
| 554 # If this is the mojom types package, clear the import-related params. | |
| 555 if package == _mojom_types_pkg_short: | |
| 556 parameters["typepkg"] = "" | |
| 557 parameters["mojom_types_import"] = "" | |
| 558 | |
| 559 # If this is the service describer package, clear the import-related params. | |
| 560 if package == _service_describer_pkg_short: | |
| 561 parameters["descpkg"] = "" | |
| 562 parameters["service_describer_import"] = "" | |
| 563 | |
| 564 # If no interfaces were defined, the service describer import isn't needed. | |
| 565 if len(self.module.interfaces) == 0: | |
| 566 parameters["service_describer_import"] = "" | |
| 567 | |
| 568 return parameters | |
| 569 | |
| 570 def GetGlobals(self): | |
| 571 return { | |
| 572 'should_gen_mojom_types': self.should_gen_mojom_types, | |
| 438 } | 573 } |
| 439 | 574 |
| 440 @UseJinja("dart_templates/module.lib.tmpl", filters=dart_filters) | 575 @UseJinja("dart_templates/module.lib.tmpl", filters=dart_filters) |
| 441 def GenerateLibModule(self, args): | 576 def GenerateLibModule(self, args): |
| 442 return self.GetParameters(args) | 577 return self.GetParameters(args) |
| 443 | 578 |
| 444 | 579 |
| 445 def GenerateFiles(self, args): | 580 def GenerateFiles(self, args): |
| 581 if "--dart_gen_types" in args: | |
| 582 self.should_gen_mojom_types = True | |
| 583 | |
| 446 elements = self.module.namespace.split('.') | 584 elements = self.module.namespace.split('.') |
| 447 elements.append("%s.dart" % self.module.name) | 585 elements.append("%s.dart" % self.module.name) |
| 448 | 586 |
| 449 lib_module = self.GenerateLibModule(args) | 587 lib_module = self.GenerateLibModule(args) |
| 450 | 588 |
| 451 # List of packages with checked in bindings. | 589 # List of packages with checked in bindings. |
| 452 # TODO(johnmccutchan): Stop generating bindings as part of build system | 590 # TODO(johnmccutchan): Stop generating bindings as part of build system |
| 453 # and then remove this. | 591 # and then remove this. |
| 454 packages_with_checked_in_bindings = [ | 592 packages_with_checked_in_bindings = [ |
| 455 '_mojo_for_test_only', | 593 '_mojo_for_test_only', |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 513 interface_to_import[name] = each_import["unique_name"] + "." + name | 651 interface_to_import[name] = each_import["unique_name"] + "." + name |
| 514 return interface_to_import | 652 return interface_to_import |
| 515 | 653 |
| 516 def ImportedFrom(self): | 654 def ImportedFrom(self): |
| 517 interface_to_import = {} | 655 interface_to_import = {} |
| 518 for each_import in self.module.imports: | 656 for each_import in self.module.imports: |
| 519 for each_interface in each_import["module"].interfaces: | 657 for each_interface in each_import["module"].interfaces: |
| 520 name = each_interface.name | 658 name = each_interface.name |
| 521 interface_to_import[name] = each_import["unique_name"] + "." | 659 interface_to_import[name] = each_import["unique_name"] + "." |
| 522 return interface_to_import | 660 return interface_to_import |
| OLD | NEW |