| Index: mojo/public/tools/bindings/generators/mojom_dart_generator.py
|
| diff --git a/mojo/public/tools/bindings/generators/mojom_dart_generator.py b/mojo/public/tools/bindings/generators/mojom_dart_generator.py
|
| index 90846056d0b6030361c745a04d592eee1e273f59..9fcdde8157586cdda646bb0dec4acacf2fa65ccb 100644
|
| --- a/mojo/public/tools/bindings/generators/mojom_dart_generator.py
|
| +++ b/mojo/public/tools/bindings/generators/mojom_dart_generator.py
|
| @@ -1,14 +1,20 @@
|
| -# Copyright 2013 The Chromium Authors. All rights reserved.
|
| +# Copyright 2014 The Chromium Authors. All rights reserved.
|
| # Use of this source code is governed by a BSD-style license that can be
|
| # found in the LICENSE file.
|
|
|
| -"""Generates Dart source files from a mojom.Module."""
|
| +"""Generates dart source files from a mojom.Module."""
|
| +
|
| +import re
|
|
|
| import mojom.generate.generator as generator
|
| import mojom.generate.module as mojom
|
| import mojom.generate.pack as pack
|
| from mojom.generate.template_expander import UseJinja
|
|
|
| +GENERATOR_PREFIX = 'dart'
|
| +
|
| +_HEADER_SIZE = 8
|
| +
|
| _kind_to_dart_default_value = {
|
| mojom.BOOL: "false",
|
| mojom.INT8: "0",
|
| @@ -35,7 +41,6 @@ _kind_to_dart_default_value = {
|
| mojom.NULLABLE_STRING: "null"
|
| }
|
|
|
| -
|
| _kind_to_dart_decl_type = {
|
| mojom.BOOL: "bool",
|
| mojom.INT8: "int",
|
| @@ -45,16 +50,16 @@ _kind_to_dart_decl_type = {
|
| mojom.INT32: "int",
|
| mojom.UINT32: "int",
|
| mojom.FLOAT: "double",
|
| - mojom.HANDLE: "core.RawMojoHandle",
|
| - mojom.DCPIPE: "core.RawMojoHandle",
|
| - mojom.DPPIPE: "core.RawMojoHandle",
|
| - mojom.MSGPIPE: "core.RawMojoHandle",
|
| - mojom.SHAREDBUFFER: "core.RawMojoHandle",
|
| - mojom.NULLABLE_HANDLE: "core.RawMojoHandle",
|
| - mojom.NULLABLE_DCPIPE: "core.RawMojoHandle",
|
| - mojom.NULLABLE_DPPIPE: "core.RawMojoHandle",
|
| - mojom.NULLABLE_MSGPIPE: "core.RawMojoHandle",
|
| - mojom.NULLABLE_SHAREDBUFFER: "core.RawMojoHandle",
|
| + mojom.HANDLE: "core.MojoHandle",
|
| + mojom.DCPIPE: "core.MojoHandle",
|
| + mojom.DPPIPE: "core.MojoHandle",
|
| + mojom.MSGPIPE: "core.MojoHandle",
|
| + mojom.SHAREDBUFFER: "core.MojoHandle",
|
| + mojom.NULLABLE_HANDLE: "core.MojoHandle",
|
| + mojom.NULLABLE_DCPIPE: "core.MojoHandle",
|
| + mojom.NULLABLE_DPPIPE: "core.MojoHandle",
|
| + mojom.NULLABLE_MSGPIPE: "core.MojoHandle",
|
| + mojom.NULLABLE_SHAREDBUFFER: "core.MojoHandle",
|
| mojom.INT64: "int",
|
| mojom.UINT64: "int",
|
| mojom.DOUBLE: "double",
|
| @@ -62,18 +67,68 @@ _kind_to_dart_decl_type = {
|
| mojom.NULLABLE_STRING: "String"
|
| }
|
|
|
| +_spec_to_decode_method = {
|
| + mojom.BOOL.spec: 'decodeBool',
|
| + mojom.DCPIPE.spec: 'decodeHandle',
|
| + mojom.DOUBLE.spec: 'decodeDouble',
|
| + mojom.DPPIPE.spec: 'decodeHandle',
|
| + mojom.FLOAT.spec: 'decodeFloat',
|
| + mojom.HANDLE.spec: 'decodeHandle',
|
| + mojom.INT16.spec: 'decodeInt16',
|
| + mojom.INT32.spec: 'decodeInt32',
|
| + mojom.INT64.spec: 'decodeInt64',
|
| + mojom.INT8.spec: 'decodeInt8',
|
| + mojom.MSGPIPE.spec: 'decodeHandle',
|
| + mojom.NULLABLE_DCPIPE.spec: 'decodeHandle',
|
| + mojom.NULLABLE_DPPIPE.spec: 'decodeHandle',
|
| + mojom.NULLABLE_HANDLE.spec: 'decodeHandle',
|
| + mojom.NULLABLE_MSGPIPE.spec: 'decodeHandle',
|
| + mojom.NULLABLE_SHAREDBUFFER.spec: 'decodeHandle',
|
| + mojom.NULLABLE_STRING.spec: 'decodeString',
|
| + mojom.SHAREDBUFFER.spec: 'decodeHandle',
|
| + mojom.STRING.spec: 'decodeString',
|
| + mojom.UINT16.spec: 'decodeUint16',
|
| + mojom.UINT32.spec: 'decodeUint32',
|
| + mojom.UINT64.spec: 'decodeUint64',
|
| + mojom.UINT8.spec: 'decodeUint8',
|
| +}
|
| +
|
| +_spec_to_encode_method = {
|
| + mojom.BOOL.spec: 'encodeBool',
|
| + mojom.DCPIPE.spec: 'encodeHandle',
|
| + mojom.DOUBLE.spec: 'encodeDouble',
|
| + mojom.DPPIPE.spec: 'encodeHandle',
|
| + mojom.FLOAT.spec: 'encodeFloat',
|
| + mojom.HANDLE.spec: 'encodeHandle',
|
| + mojom.INT16.spec: 'encodeInt16',
|
| + mojom.INT32.spec: 'encodeInt32',
|
| + mojom.INT64.spec: 'encodeInt64',
|
| + mojom.INT8.spec: 'encodeInt8',
|
| + mojom.MSGPIPE.spec: 'encodeHandle',
|
| + mojom.NULLABLE_DCPIPE.spec: 'encodeHandle',
|
| + mojom.NULLABLE_DPPIPE.spec: 'encodeHandle',
|
| + mojom.NULLABLE_HANDLE.spec: 'encodeHandle',
|
| + mojom.NULLABLE_MSGPIPE.spec: 'encodeHandle',
|
| + mojom.NULLABLE_SHAREDBUFFER.spec: 'encodeHandle',
|
| + mojom.NULLABLE_STRING.spec: 'encodeString',
|
| + mojom.SHAREDBUFFER.spec: 'encodeHandle',
|
| + mojom.STRING.spec: 'encodeString',
|
| + mojom.UINT16.spec: 'encodeUint16',
|
| + mojom.UINT32.spec: 'encodeUint32',
|
| + mojom.UINT64.spec: 'encodeUint64',
|
| + mojom.UINT8.spec: 'encodeUint8',
|
| +}
|
|
|
| -def DartType(kind):
|
| +def GetDartType(kind):
|
| if kind.imported_from:
|
| return kind.imported_from["unique_name"] + "." + kind.name
|
| return kind.name
|
|
|
| -
|
| def DartDefaultValue(field):
|
| if field.default:
|
| if mojom.IsStructKind(field.kind):
|
| assert field.default == "default"
|
| - return "new %s()" % DartType(field.kind)
|
| + return "new %s()" % GetDartType(field.kind)
|
| return ExpressionToText(field.default)
|
| if field.kind in mojom.PRIMITIVES:
|
| return _kind_to_dart_default_value[field.kind]
|
| @@ -89,12 +144,11 @@ def DartDefaultValue(field):
|
| if mojom.IsEnumKind(field.kind):
|
| return "0"
|
|
|
| -
|
| def DartDeclType(kind):
|
| if kind in mojom.PRIMITIVES:
|
| return _kind_to_dart_decl_type[kind]
|
| if mojom.IsStructKind(kind):
|
| - return DartType(kind)
|
| + return GetDartType(kind)
|
| if mojom.IsArrayKind(kind):
|
| array_type = DartDeclType(kind.kind)
|
| return "List<" + array_type + ">"
|
| @@ -108,104 +162,131 @@ def DartDeclType(kind):
|
| if mojom.IsEnumKind(kind):
|
| return "int"
|
|
|
| -def DartPayloadSize(packed):
|
| - packed_fields = packed.packed_fields
|
| - if not packed_fields:
|
| - return 0
|
| - last_field = packed_fields[-1]
|
| - offset = last_field.offset + last_field.size
|
| - pad = pack.GetPad(offset, 8)
|
| - return offset + pad
|
| -
|
| -
|
| -_kind_to_codec_type = {
|
| - mojom.BOOL: "bindings.Uint8",
|
| - mojom.INT8: "bindings.Int8",
|
| - mojom.UINT8: "bindings.Uint8",
|
| - mojom.INT16: "bindings.Int16",
|
| - mojom.UINT16: "bindings.Uint16",
|
| - mojom.INT32: "bindings.Int32",
|
| - mojom.UINT32: "bindings.Uint32",
|
| - mojom.FLOAT: "bindings.Float",
|
| - mojom.HANDLE: "bindings.Handle",
|
| - mojom.DCPIPE: "bindings.Handle",
|
| - mojom.DPPIPE: "bindings.Handle",
|
| - mojom.MSGPIPE: "bindings.Handle",
|
| - mojom.SHAREDBUFFER: "bindings.Handle",
|
| - mojom.NULLABLE_HANDLE: "bindings.NullableHandle",
|
| - mojom.NULLABLE_DCPIPE: "bindings.NullableHandle",
|
| - mojom.NULLABLE_DPPIPE: "bindings.NullableHandle",
|
| - mojom.NULLABLE_MSGPIPE: "bindings.NullableHandle",
|
| - mojom.NULLABLE_SHAREDBUFFER: "bindings.NullableHandle",
|
| - mojom.INT64: "bindings.Int64",
|
| - mojom.UINT64: "bindings.Uint64",
|
| - mojom.DOUBLE: "bindings.Double",
|
| - mojom.STRING: "bindings.MojoString",
|
| - mojom.NULLABLE_STRING: "bindings.NullableMojoString",
|
| -}
|
| -
|
| -
|
| -def CodecType(kind):
|
| - if kind in mojom.PRIMITIVES:
|
| - return _kind_to_codec_type[kind]
|
| - if mojom.IsStructKind(kind):
|
| - pointer_type = "NullablePointerTo" if mojom.IsNullableKind(kind) \
|
| - else "PointerTo"
|
| - return "new bindings.%s(%s)" % (pointer_type, DartType(kind))
|
| - if mojom.IsArrayKind(kind):
|
| - array_type = "NullableArrayOf" if mojom.IsNullableKind(kind) else "ArrayOf"
|
| - array_length = "" if kind.length is None else ", %d" % kind.length
|
| - element_type = ElementCodecType(kind.kind)
|
| - return "new bindings.%s(%s%s)" % (array_type, element_type, array_length)
|
| - if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
|
| - return CodecType(mojom.MSGPIPE)
|
| - if mojom.IsEnumKind(kind):
|
| - return _kind_to_codec_type[mojom.INT32]
|
| - if mojom.IsMapKind(kind):
|
| - map_type = "NullableMapOf" if mojom.IsNullableKind(kind) else "MapOf"
|
| - key_type = ElementCodecType(kind.key_kind)
|
| - value_type = ElementCodecType(kind.value_kind)
|
| - return "new bindings.%s(%s, %s)" % (map_type, key_type, value_type)
|
| - return kind
|
| -
|
| -def ElementCodecType(kind):
|
| - return "bindings.PackedBool" if mojom.IsBoolKind(kind) else CodecType(kind)
|
| -
|
| -def DartDecodeSnippet(kind):
|
| - if kind in mojom.PRIMITIVES:
|
| - return "decodeStruct(%s)" % CodecType(kind)
|
| - if mojom.IsStructKind(kind):
|
| - return "decodeStructPointer(%s)" % DartType(kind)
|
| - if mojom.IsMapKind(kind):
|
| - return "decodeMapPointer(%s, %s)" % \
|
| - (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind))
|
| - if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
|
| - return "decodeArrayPointer(bindings.PackedBool)"
|
| - if mojom.IsArrayKind(kind):
|
| - return "decodeArrayPointer(%s)" % CodecType(kind.kind)
|
| - if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
|
| - return DartDecodeSnippet(mojom.MSGPIPE)
|
| - if mojom.IsEnumKind(kind):
|
| - return DartDecodeSnippet(mojom.INT32)
|
| -
|
| -
|
| -def DartEncodeSnippet(kind):
|
| - if kind in mojom.PRIMITIVES:
|
| - return "encodeStruct(%s, " % CodecType(kind)
|
| - if mojom.IsStructKind(kind):
|
| - return "encodeStructPointer(%s, " % DartType(kind)
|
| - if mojom.IsMapKind(kind):
|
| - return "encodeMapPointer(%s, %s, " % \
|
| - (ElementCodecType(kind.key_kind), ElementCodecType(kind.value_kind))
|
| - if mojom.IsArrayKind(kind) and mojom.IsBoolKind(kind.kind):
|
| - return "encodeArrayPointer(bindings.PackedBool, ";
|
| +def NameToComponent(name):
|
| + # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar ->
|
| + # HTTP_Entry2_FooBar)
|
| + name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name)
|
| + # insert '_' between non upper and start of upper blocks (e.g.,
|
| + # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar)
|
| + name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name)
|
| + return [x.lower() for x in name.split('_')]
|
| +
|
| +def UpperCamelCase(name):
|
| + return ''.join([x.capitalize() for x in NameToComponent(name)])
|
| +
|
| +def CamelCase(name):
|
| + uccc = UpperCamelCase(name)
|
| + return uccc[0].lower() + uccc[1:]
|
| +
|
| +def ConstantStyle(name):
|
| + components = NameToComponent(name)
|
| + if components[0] == 'k' and len(components) > 1:
|
| + components = components[1:]
|
| + # variable cannot starts with a digit.
|
| + if components[0][0].isdigit():
|
| + components[0] = '_' + components[0]
|
| + return '_'.join([x.upper() for x in components])
|
| +
|
| +def GetNameForElement(element):
|
| + if (mojom.IsEnumKind(element) or mojom.IsInterfaceKind(element) or
|
| + mojom.IsStructKind(element)):
|
| + return UpperCamelCase(element.name)
|
| + if mojom.IsInterfaceRequestKind(element):
|
| + return GetNameForElement(element.kind)
|
| + if isinstance(element, (mojom.Method,
|
| + mojom.Parameter,
|
| + mojom.Field)):
|
| + return CamelCase(element.name)
|
| + if isinstance(element, mojom.EnumValue):
|
| + return (GetNameForElement(element.enum) + '.' +
|
| + ConstantStyle(element.name))
|
| + if isinstance(element, (mojom.NamedValue,
|
| + mojom.Constant,
|
| + mojom.EnumField)):
|
| + return ConstantStyle(element.name)
|
| + raise Exception('Unexpected element: %s' % element)
|
| +
|
| +def GetInterfaceResponseName(method):
|
| + return UpperCamelCase(method.name + 'Response')
|
| +
|
| +def GetResponseStructFromMethod(method):
|
| + return generator.GetDataHeader(
|
| + False, generator.GetResponseStructFromMethod(method))
|
| +
|
| +def GetStructFromMethod(method):
|
| + return generator.GetDataHeader(
|
| + False, generator.GetStructFromMethod(method))
|
| +
|
| +def GetDartTrueFalse(value):
|
| + return 'true' if value else 'false'
|
| +
|
| +def GetArrayNullabilityFlags(kind):
|
| + """Returns nullability flags for an array type, see codec.dart.
|
| +
|
| + As we have dedicated decoding functions for arrays, we have to pass
|
| + nullability information about both the array itself, as well as the array
|
| + element type there.
|
| + """
|
| + assert mojom.IsArrayKind(kind)
|
| + ARRAY_NULLABLE = 'bindings.kArrayNullable'
|
| + ELEMENT_NULLABLE = 'bindings.kElementNullable'
|
| + NOTHING_NULLABLE = 'bindings.kNothingNullable'
|
| +
|
| + flags_to_set = []
|
| + if mojom.IsNullableKind(kind):
|
| + flags_to_set.append(ARRAY_NULLABLE)
|
| + if mojom.IsNullableKind(kind.kind):
|
| + flags_to_set.append(ELEMENT_NULLABLE)
|
| +
|
| + if not flags_to_set:
|
| + flags_to_set = [NOTHING_NULLABLE]
|
| + return ' | '.join(flags_to_set)
|
| +
|
| +def AppendEncodeDecodeParams(initial_params, kind, bit):
|
| + """ Appends standard parameters shared between encode and decode calls. """
|
| + params = list(initial_params)
|
| + if (kind == mojom.BOOL):
|
| + params.append(str(bit))
|
| + if mojom.IsReferenceKind(kind):
|
| + if mojom.IsArrayKind(kind):
|
| + params.append(GetArrayNullabilityFlags(kind))
|
| + else:
|
| + params.append(GetDartTrueFalse(mojom.IsNullableKind(kind)))
|
| if mojom.IsArrayKind(kind):
|
| - return "encodeArrayPointer(%s, " % CodecType(kind.kind)
|
| - if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
|
| - return DartEncodeSnippet(mojom.MSGPIPE)
|
| - if mojom.IsEnumKind(kind):
|
| - return DartEncodeSnippet(mojom.INT32)
|
| -
|
| + params.append(GetArrayExpectedLength(kind))
|
| + return params
|
| +
|
| +def DecodeMethod(kind, offset, bit):
|
| + def _DecodeMethodName(kind):
|
| + if mojom.IsArrayKind(kind):
|
| + return _DecodeMethodName(kind.kind) + 'Array'
|
| + if mojom.IsEnumKind(kind):
|
| + return _DecodeMethodName(mojom.INT32)
|
| + if mojom.IsInterfaceRequestKind(kind):
|
| + return 'decodeHandle'
|
| + if mojom.IsInterfaceKind(kind):
|
| + return 'decodeHandle'
|
| + return _spec_to_decode_method[kind.spec]
|
| + methodName = _DecodeMethodName(kind)
|
| + params = AppendEncodeDecodeParams([ str(offset) ], kind, bit)
|
| + return '%s(%s)' % (methodName, ', '.join(params))
|
| +
|
| +def EncodeMethod(kind, variable, offset, bit):
|
| + def _EncodeMethodName(kind):
|
| + if mojom.IsStructKind(kind):
|
| + return 'encodeStruct'
|
| + if mojom.IsArrayKind(kind):
|
| + return _EncodeMethodName(kind.kind) + 'Array'
|
| + if mojom.IsEnumKind(kind):
|
| + return _EncodeMethodName(mojom.INT32)
|
| + if mojom.IsInterfaceRequestKind(kind):
|
| + return 'encodeHandle'
|
| + if mojom.IsInterfaceKind(kind):
|
| + return 'encodeHandle'
|
| + return _spec_to_encode_method[kind.spec]
|
| + methodName = _EncodeMethodName(kind)
|
| + params = AppendEncodeDecodeParams([ variable, str(offset) ], kind, bit)
|
| + return '%s(%s)' % (methodName, ', '.join(params))
|
|
|
| def TranslateConstants(token):
|
| if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
|
| @@ -235,21 +316,51 @@ def TranslateConstants(token):
|
|
|
| return token
|
|
|
| -
|
| def ExpressionToText(value):
|
| return TranslateConstants(value)
|
|
|
| +def GetArrayKind(kind, size = None):
|
| + if size is None:
|
| + return mojom.Array(kind)
|
| + else:
|
| + array = mojom.Array(kind, 0)
|
| + array.dart_map_size = size
|
| + return array
|
| +
|
| +def GetArrayExpectedLength(kind):
|
| + if mojom.IsArrayKind(kind) and kind.length is not None:
|
| + return getattr(kind, 'dart_map_size', str(kind.length))
|
| + else:
|
| + return 'bindings.kUnspecifiedArrayLength'
|
| +
|
| +def IsPointerArrayKind(kind):
|
| + if not mojom.IsArrayKind(kind):
|
| + return False
|
| + sub_kind = kind.kind
|
| + return mojom.IsObjectKind(sub_kind)
|
|
|
| class Generator(generator.Generator):
|
|
|
| dart_filters = {
|
| - "default_value": DartDefaultValue,
|
| - "payload_size": DartPayloadSize,
|
| - "decode_snippet": DartDecodeSnippet,
|
| - "encode_snippet": DartEncodeSnippet,
|
| - "expression_to_text": ExpressionToText,
|
| - "dart_decl_type": DartDeclType,
|
| - "stylize_method": generator.StudlyCapsToCamel,
|
| + 'array_expected_length': GetArrayExpectedLength,
|
| + 'array': GetArrayKind,
|
| + 'decode_method': DecodeMethod,
|
| + 'default_value': DartDefaultValue,
|
| + 'encode_method': EncodeMethod,
|
| + 'expression_to_text': ExpressionToText,
|
| + 'is_handle': mojom.IsNonInterfaceHandleKind,
|
| + 'is_map_kind': mojom.IsMapKind,
|
| + 'is_nullable_kind': mojom.IsNullableKind,
|
| + 'is_pointer_array_kind': IsPointerArrayKind,
|
| + 'is_struct_kind': mojom.IsStructKind,
|
| + 'dart_true_false': GetDartTrueFalse,
|
| + 'dart_type': DartDeclType,
|
| + 'name': GetNameForElement,
|
| + 'interface_response_name': GetInterfaceResponseName,
|
| + 'response_struct_from_method': GetResponseStructFromMethod,
|
| + 'struct_from_method': GetStructFromMethod,
|
| + 'upper_camel_case': UpperCamelCase,
|
| + 'struct_size': lambda ps: ps.GetTotalSize() + _HEADER_SIZE,
|
| }
|
|
|
| def GetParameters(self):
|
| @@ -278,8 +389,8 @@ class Generator(generator.Generator):
|
| for each_import in self.module.imports:
|
| simple_name = each_import["module_name"].split(".")[0]
|
|
|
| - # Since each import is assigned a variable in JS, they need to have unique
|
| - # names.
|
| + # Since each import is assigned a library in Dart, they need to have
|
| + # unique names.
|
| unique_name = simple_name
|
| counter = 0
|
| while unique_name in used_names:
|
|
|