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

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

Issue 1539673003: Generate Mojom Types in Dart (Take 2) (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: All Short Names use unsafe GetElementForName Created 4 years, 11 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
OLDNEW
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 import errno 7 import errno
8 import os 8 import os
9 import re 9 import re
10 import shutil 10 import shutil
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 mojom.NULLABLE_DPPIPE: "core.MojoDataPipeProducer", 116 mojom.NULLABLE_DPPIPE: "core.MojoDataPipeProducer",
117 mojom.NULLABLE_MSGPIPE: "core.MojoMessagePipeEndpoint", 117 mojom.NULLABLE_MSGPIPE: "core.MojoMessagePipeEndpoint",
118 mojom.NULLABLE_SHAREDBUFFER: "core.MojoSharedBuffer", 118 mojom.NULLABLE_SHAREDBUFFER: "core.MojoSharedBuffer",
119 mojom.INT64: "int", 119 mojom.INT64: "int",
120 mojom.UINT64: "int", 120 mojom.UINT64: "int",
121 mojom.DOUBLE: "double", 121 mojom.DOUBLE: "double",
122 mojom.STRING: "String", 122 mojom.STRING: "String",
123 mojom.NULLABLE_STRING: "String" 123 mojom.NULLABLE_STRING: "String"
124 } 124 }
125 125
126 _kind_to_mojom_type = {
127 mojom.BOOL: "bool",
128 mojom.INT8: "int8",
129 mojom.UINT8: "uint8",
130 mojom.INT16: "int16",
131 mojom.UINT16: "uint16",
132 mojom.INT32: "int32",
133 mojom.UINT32: "uint32",
134 mojom.FLOAT: "float",
135 mojom.HANDLE: "unspecified",
136 mojom.DCPIPE: "dataPipeConsumer",
137 mojom.DPPIPE: "dataPipeProducer",
138 mojom.MSGPIPE: "messagePipe",
139 mojom.SHAREDBUFFER: "sharedBuffer",
140 mojom.NULLABLE_HANDLE: "unspecified",
141 mojom.NULLABLE_DCPIPE: "dataPipeConsumer",
142 mojom.NULLABLE_DPPIPE: "dataPipeProducer",
143 mojom.NULLABLE_MSGPIPE: "messagePipe",
144 mojom.NULLABLE_SHAREDBUFFER: "sharedBuffer",
145 mojom.INT64: "int64",
146 mojom.UINT64: "uint64",
147 mojom.DOUBLE: "double"
148 }
149
126 _spec_to_decode_method = { 150 _spec_to_decode_method = {
127 mojom.BOOL.spec: 'decodeBool', 151 mojom.BOOL.spec: 'decodeBool',
128 mojom.DCPIPE.spec: 'decodeConsumerHandle', 152 mojom.DCPIPE.spec: 'decodeConsumerHandle',
129 mojom.DOUBLE.spec: 'decodeDouble', 153 mojom.DOUBLE.spec: 'decodeDouble',
130 mojom.DPPIPE.spec: 'decodeProducerHandle', 154 mojom.DPPIPE.spec: 'decodeProducerHandle',
131 mojom.FLOAT.spec: 'decodeFloat', 155 mojom.FLOAT.spec: 'decodeFloat',
132 mojom.HANDLE.spec: 'decodeHandle', 156 mojom.HANDLE.spec: 'decodeHandle',
133 mojom.INT16.spec: 'decodeInt16', 157 mojom.INT16.spec: 'decodeInt16',
134 mojom.INT32.spec: 'decodeInt32', 158 mojom.INT32.spec: 'decodeInt32',
135 mojom.INT64.spec: 'decodeInt64', 159 mojom.INT64.spec: 'decodeInt64',
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 mojom.NULLABLE_SHAREDBUFFER.spec: 'encodeSharedBufferHandle', 192 mojom.NULLABLE_SHAREDBUFFER.spec: 'encodeSharedBufferHandle',
169 mojom.NULLABLE_STRING.spec: 'encodeString', 193 mojom.NULLABLE_STRING.spec: 'encodeString',
170 mojom.SHAREDBUFFER.spec: 'encodeSharedBufferHandle', 194 mojom.SHAREDBUFFER.spec: 'encodeSharedBufferHandle',
171 mojom.STRING.spec: 'encodeString', 195 mojom.STRING.spec: 'encodeString',
172 mojom.UINT16.spec: 'encodeUint16', 196 mojom.UINT16.spec: 'encodeUint16',
173 mojom.UINT32.spec: 'encodeUint32', 197 mojom.UINT32.spec: 'encodeUint32',
174 mojom.UINT64.spec: 'encodeUint64', 198 mojom.UINT64.spec: 'encodeUint64',
175 mojom.UINT8.spec: 'encodeUint8', 199 mojom.UINT8.spec: 'encodeUint8',
176 } 200 }
177 201
202 # The mojom_types.mojom and service_describer.mojom files are special because
203 # they are used to generate mojom Type's and ServiceDescription implementations.
204 # They need to be imported, unless the file itself is being generated.
205 _service_describer_pkg_short = "service_describer"
206 _service_describer_pkg = "package:mojo/mojo/bindings/types/%s.mojom.dart" % \
207 _service_describer_pkg_short
208 _mojom_types_pkg_short = "mojom_types"
209 _mojom_types_pkg = "package:mojo/mojo/bindings/types/%s.mojom.dart" % \
210 _mojom_types_pkg_short
211
178 def GetDartType(kind): 212 def GetDartType(kind):
179 if kind.imported_from: 213 if kind.imported_from:
180 return kind.imported_from["unique_name"] + "." + GetNameForElement(kind) 214 return kind.imported_from["unique_name"] + "." + GetNameForElement(kind)
181 return GetNameForElement(kind) 215 return GetNameForElement(kind)
182 216
183 def DartDefaultValue(field): 217 def DartDefaultValue(field):
184 if field.default: 218 if field.default:
185 if mojom.IsStructKind(field.kind): 219 if mojom.IsStructKind(field.kind):
186 assert field.default == "default" 220 assert field.default == "default"
187 return "new %s()" % GetDartType(field.kind) 221 return "new %s()" % GetDartType(field.kind)
(...skipping 30 matching lines...) Expand all
218 if mojom.IsMapKind(kind): 252 if mojom.IsMapKind(kind):
219 key_type = DartDeclType(kind.key_kind) 253 key_type = DartDeclType(kind.key_kind)
220 value_type = DartDeclType(kind.value_kind) 254 value_type = DartDeclType(kind.value_kind)
221 return "Map<"+ key_type + ", " + value_type + ">" 255 return "Map<"+ key_type + ", " + value_type + ">"
222 if mojom.IsInterfaceKind(kind) or \ 256 if mojom.IsInterfaceKind(kind) or \
223 mojom.IsInterfaceRequestKind(kind): 257 mojom.IsInterfaceRequestKind(kind):
224 return "Object" 258 return "Object"
225 if mojom.IsEnumKind(kind): 259 if mojom.IsEnumKind(kind):
226 return GetDartType(kind) 260 return GetDartType(kind)
227 261
262 def GetSimpleMojomTypeName(kind):
263 if not kind in _kind_to_mojom_type:
264 raise Exception('Missing case for kind: %s' % kind)
265 return _kind_to_mojom_type[kind]
266
228 def NameToComponent(name): 267 def NameToComponent(name):
229 # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> 268 # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar ->
230 # HTTP_Entry2_FooBar). Numbers terminate a string of lower-case characters. 269 # HTTP_Entry2_FooBar). Numbers terminate a string of lower-case characters.
231 name = re.sub('([^_])([A-Z][^A-Z1-9_]+)', r'\1_\2', name) 270 name = re.sub('([^_])([A-Z][^A-Z1-9_]+)', r'\1_\2', name)
232 # insert '_' between non upper and start of upper blocks (e.g., 271 # insert '_' between non upper and start of upper blocks (e.g.,
233 # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar). 272 # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar).
234 name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name) 273 name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name)
235 return [x.lower() for x in name.split('_')] 274 return [x.lower() for x in name.split('_')]
236 275
237 def UpperCamelCase(name): 276 def UpperCamelCase(name):
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 458
420 def IsPointerArrayKind(kind): 459 def IsPointerArrayKind(kind):
421 if not mojom.IsArrayKind(kind): 460 if not mojom.IsArrayKind(kind):
422 return False 461 return False
423 sub_kind = kind.kind 462 sub_kind = kind.kind
424 return mojom.IsObjectKind(sub_kind) 463 return mojom.IsObjectKind(sub_kind)
425 464
426 def IsEnumArrayKind(kind): 465 def IsEnumArrayKind(kind):
427 return mojom.IsArrayKind(kind) and mojom.IsEnumKind(kind.kind) 466 return mojom.IsArrayKind(kind) and mojom.IsEnumKind(kind.kind)
428 467
468 def IsImportedKind(kind):
469 return hasattr(kind, 'imported_from') and kind.imported_from
470
429 def ParseStringAttribute(attribute): 471 def ParseStringAttribute(attribute):
430 assert isinstance(attribute, basestring) 472 assert isinstance(attribute, basestring)
431 return attribute 473 return attribute
432 474
433 def GetPackage(module): 475 def GetPackage(module):
434 if module.attributes and 'DartPackage' in module.attributes: 476 if module.attributes and 'DartPackage' in module.attributes:
435 return ParseStringAttribute(module.attributes['DartPackage']) 477 return ParseStringAttribute(module.attributes['DartPackage'])
436 # Default package. 478 # Default package.
437 return 'mojom' 479 return 'mojom'
438 480
481 def GetPackageName(module):
482 return module.name.split('.')[0]
483
439 def GetImportUri(module): 484 def GetImportUri(module):
440 package = GetPackage(module); 485 package = GetPackage(module);
441 elements = module.namespace.split('.') 486 elements = module.namespace.split('.')
442 elements.append("%s" % module.name) 487 elements.append("%s" % module.name)
443 return os.path.join(package, *elements) 488 return os.path.join(package, *elements)
444 489
490 # Returns a string of the form package.path.TypeName - the full identifier
azani 2016/01/26 00:29:23 Can you make that a docstring?
491 # for an element.
492 def GetFullIdentifier(element, exported=True):
493 return '%s.%s' % (element.module.namespace, GetNameForElementUnsafe(element))
494
495 def RaiseHelper(msg):
496 raise Exception(msg)
497
498 def GetMojomTypeIdentifier(kind):
499 """Get the mojom type's unique identifier from the kind's package and name."""
500 # Note: InterfaceRequest's should use the Interface inside them.
501 if hasattr(kind, 'module'):
502 package = GetPackageName(kind.module)
503 name = kind.name
504 elif mojom.IsInterfaceRequestKind(kind):
505 package = GetPackageName(kind.kind.module)
506 name = kind.kind.name
507 else:
508 # These kinds (e.g., simple kinds, maps, and arrays) lack identifiers.
509 raise Exception('Unexpected kind: %s' % kind)
510 return "%s_%s__" % (package, name)
511
445 class Generator(generator.Generator): 512 class Generator(generator.Generator):
446 513
447 dart_filters = { 514 dart_filters = {
448 'array_expected_length': GetArrayExpectedLength, 515 'array_expected_length': GetArrayExpectedLength,
449 'array': GetArrayKind, 516 'array': GetArrayKind,
450 'decode_method': DecodeMethod, 517 'decode_method': DecodeMethod,
451 'default_value': DartDefaultValue, 518 'default_value': DartDefaultValue,
452 'encode_method': EncodeMethod, 519 'encode_method': EncodeMethod,
520 'fullidentifier': GetFullIdentifier,
521 'simple_mojom_type_name': GetSimpleMojomTypeName,
522 'mojom_type_identifier': GetMojomTypeIdentifier,
523 'is_imported_kind': IsImportedKind,
524 'is_array_kind': mojom.IsArrayKind,
453 'is_map_kind': mojom.IsMapKind, 525 'is_map_kind': mojom.IsMapKind,
526 'is_numerical_kind': mojom.IsNumericalKind,
527 'is_any_handle_kind': mojom.IsAnyHandleKind,
528 'is_string_kind': mojom.IsStringKind,
454 'is_nullable_kind': mojom.IsNullableKind, 529 'is_nullable_kind': mojom.IsNullableKind,
455 'is_pointer_array_kind': IsPointerArrayKind, 530 'is_pointer_array_kind': IsPointerArrayKind,
456 'is_enum_array_kind': IsEnumArrayKind, 531 'is_enum_array_kind': IsEnumArrayKind,
457 'is_struct_kind': mojom.IsStructKind, 532 'is_struct_kind': mojom.IsStructKind,
458 'is_union_kind': mojom.IsUnionKind, 533 'is_union_kind': mojom.IsUnionKind,
459 'is_enum_kind': mojom.IsEnumKind, 534 'is_enum_kind': mojom.IsEnumKind,
535 'is_interface_kind': mojom.IsInterfaceKind,
536 'is_interface_request_kind': mojom.IsInterfaceRequestKind,
460 'dart_true_false': GetDartTrueFalse, 537 'dart_true_false': GetDartTrueFalse,
461 'dart_type': DartDeclType, 538 'dart_type': DartDeclType,
462 'name': GetNameForElement, 539 'name': GetNameForElement,
540 'name_unsafe': GetNameForElementUnsafe,
azani 2016/01/26 00:29:23 Could you name this something that expresses the f
463 'interface_response_name': GetInterfaceResponseName, 541 'interface_response_name': GetInterfaceResponseName,
464 'dot_to_underscore': DotToUnderscore, 542 'dot_to_underscore': DotToUnderscore,
465 'is_cloneable_kind': mojom.IsCloneableKind, 543 'is_cloneable_kind': mojom.IsCloneableKind,
544 'upper_camel': UpperCamelCase,
545 'lower_camel': CamelCase,
546 'raise': RaiseHelper,
466 } 547 }
467 548
549 # If set to True, then mojom type information will be generated.
550 should_gen_mojom_types = False
551
468 def GetParameters(self, args): 552 def GetParameters(self, args):
469 return { 553 package = GetPackageName(self.module)
554
555 parameters = {
470 "namespace": self.module.namespace, 556 "namespace": self.module.namespace,
471 "imports": self.GetImports(args), 557 "imports": self.GetImports(args),
472 "kinds": self.module.kinds, 558 "kinds": self.module.kinds,
473 "enums": self.module.enums, 559 "enums": self.module.enums,
474 "module": resolver.ResolveConstants(self.module, ExpressionToText), 560 "module": resolver.ResolveConstants(self.module, ExpressionToText),
475 "structs": self.GetStructs() + self.GetStructsFromMethods(), 561 "structs": self.GetStructs() + self.GetStructsFromMethods(),
476 "unions": self.GetUnions(), 562 "unions": self.GetUnions(),
477 "interfaces": self.GetInterfaces(), 563 "interfaces": self.GetInterfaces(),
478 "imported_interfaces": self.GetImportedInterfaces(), 564 "imported_interfaces": self.GetImportedInterfaces(),
479 "imported_from": self.ImportedFrom(), 565 "imported_from": self.ImportedFrom(),
566 "typepkg": '%s.' % _mojom_types_pkg_short,
567 "descpkg": '%s.' % _service_describer_pkg_short,
568 "mojom_types_import": 'import \'%s\' as %s;' % \
569 (_mojom_types_pkg, _mojom_types_pkg_short),
570 "service_describer_import": 'import \'%s\' as %s;' % \
571 (_service_describer_pkg, _service_describer_pkg_short),
572 }
573
574 # If this is the mojom types package, clear the import-related params.
575 if package == _mojom_types_pkg_short:
576 parameters["typepkg"] = ""
577 parameters["mojom_types_import"] = ""
578
579 # If this is the service describer package, clear the import-related params.
580 if package == _service_describer_pkg_short:
581 parameters["descpkg"] = ""
582 parameters["service_describer_import"] = ""
583
584 # If no interfaces were defined, the service describer import isn't needed.
585 if len(self.module.interfaces) == 0:
586 parameters["service_describer_import"] = ""
587
588 return parameters
589
590 def GetGlobals(self):
591 return {
592 'should_gen_mojom_types': self.should_gen_mojom_types,
480 } 593 }
481 594
482 @UseJinja("dart_templates/module.lib.tmpl", filters=dart_filters) 595 @UseJinja("dart_templates/module.lib.tmpl", filters=dart_filters)
483 def GenerateLibModule(self, args): 596 def GenerateLibModule(self, args):
484 return self.GetParameters(args) 597 return self.GetParameters(args)
485 598
486 599
487 def GenerateFiles(self, args): 600 def GenerateFiles(self, args):
601 self.should_gen_mojom_types = "--generate_type_info" in args
602
488 elements = self.module.namespace.split('.') 603 elements = self.module.namespace.split('.')
489 elements.append("%s.dart" % self.module.name) 604 elements.append("%s.dart" % self.module.name)
490 605
491 lib_module = self.GenerateLibModule(args) 606 lib_module = self.GenerateLibModule(args)
492 607
493 # List of packages with checked in bindings. 608 # List of packages with checked in bindings.
494 # TODO(johnmccutchan): Stop generating bindings as part of build system 609 # TODO(johnmccutchan): Stop generating bindings as part of build system
495 # and then remove this. 610 # and then remove this.
496 packages_with_checked_in_bindings = [ 611 packages_with_checked_in_bindings = [
497 '_mojo_for_test_only', 612 '_mojo_for_test_only',
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 interface_to_import[name] = each_import["unique_name"] + "." + name 676 interface_to_import[name] = each_import["unique_name"] + "." + name
562 return interface_to_import 677 return interface_to_import
563 678
564 def ImportedFrom(self): 679 def ImportedFrom(self):
565 interface_to_import = {} 680 interface_to_import = {}
566 for each_import in self.module.imports: 681 for each_import in self.module.imports:
567 for each_interface in each_import["module"].interfaces: 682 for each_interface in each_import["module"].interfaces:
568 name = each_interface.name 683 name = each_interface.name
569 interface_to_import[name] = each_import["unique_name"] + "." 684 interface_to_import[name] = each_import["unique_name"] + "."
570 return interface_to_import 685 return interface_to_import
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698