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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |