Beispiel #1
0
    def _GetCppWrapperType(self, kind, add_same_module_namespaces=False):
        def _AddOptional(type_name):
            return "base::Optional<%s>" % type_name

        if self._IsTypemappedKind(kind):
            type_name = self._GetNativeTypeName(kind)
            if (mojom.IsNullableKind(kind)
                    and not self.typemap[self._GetFullMojomNameForKind(
                        kind)]["nullable_is_same_type"]):
                type_name = _AddOptional(type_name)
            return type_name
        if mojom.IsEnumKind(kind):
            return self._GetNameForKind(
                kind, add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
            return "%sPtr" % self._GetNameForKind(
                kind, add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsArrayKind(kind):
            pattern = "WTF::Vector<%s>" if self.for_blink else "std::vector<%s>"
            if mojom.IsNullableKind(kind):
                pattern = _AddOptional(pattern)
            return pattern % self._GetCppWrapperType(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsMapKind(kind):
            pattern = ("WTF::HashMap<%s, %s>"
                       if self.for_blink else "base::flat_map<%s, %s>")
            if mojom.IsNullableKind(kind):
                pattern = _AddOptional(pattern)
            return pattern % (
                self._GetCppWrapperType(
                    kind.key_kind,
                    add_same_module_namespaces=add_same_module_namespaces),
                self._GetCppWrapperType(
                    kind.value_kind,
                    add_same_module_namespaces=add_same_module_namespaces))
        if mojom.IsInterfaceKind(kind):
            return "%sPtrInfo" % self._GetNameForKind(
                kind, add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsInterfaceRequestKind(kind):
            return "%sRequest" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsPendingRemoteKind(kind):
            return "mojo::PendingRemote<%s>" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsPendingReceiverKind(kind):
            return "mojo::PendingReceiver<%s>" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsPendingAssociatedRemoteKind(kind):
            return "mojo::PendingAssociatedRemote<%s>" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsPendingAssociatedReceiverKind(kind):
            return "mojo::PendingAssociatedReceiver<%s>" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsAssociatedInterfaceKind(kind):
            return "%sAssociatedPtrInfo" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsAssociatedInterfaceRequestKind(kind):
            return "%sAssociatedRequest" % self._GetNameForKind(
                kind.kind,
                add_same_module_namespaces=add_same_module_namespaces)
        if mojom.IsStringKind(kind):
            if self.for_blink:
                return "WTF::String"
            type_name = "std::string"
            return (_AddOptional(type_name)
                    if mojom.IsNullableKind(kind) else type_name)
        if mojom.IsGenericHandleKind(kind):
            return "mojo::ScopedHandle"
        if mojom.IsDataPipeConsumerKind(kind):
            return "mojo::ScopedDataPipeConsumerHandle"
        if mojom.IsDataPipeProducerKind(kind):
            return "mojo::ScopedDataPipeProducerHandle"
        if mojom.IsMessagePipeKind(kind):
            return "mojo::ScopedMessagePipeHandle"
        if mojom.IsSharedBufferKind(kind):
            return "mojo::ScopedSharedBufferHandle"
        if mojom.IsPlatformHandleKind(kind):
            return "mojo::PlatformHandle"
        if not kind in _kind_to_cpp_type:
            raise Exception("Unrecognized kind %s" % kind.spec)
        return _kind_to_cpp_type[kind]
Beispiel #2
0
def IsEnumField(field):
  return mojom.IsEnumKind(field.kind)
Beispiel #3
0
def ShouldPassParamByValue(kind):
    if IsTypemappedKind(kind):
        if mojom.IsEnumKind(kind):
            return True
        return _current_typemap[GetFullMojomNameForKind(kind)]["pass_by_value"]
    return not mojom.IsStringKind(kind)
Beispiel #4
0
def IsNativeOnlyKind(kind):
    return (mojom.IsStructKind(kind) or mojom.IsEnumKind(kind)) and \
        kind.native_only
Beispiel #5
0
def IsEnumArrayKind(kind):
  return mojom.IsArrayKind(kind) and mojom.IsEnumKind(kind.kind)
Beispiel #6
0
def TranslateConstants(token, kind):
    if isinstance(token, mojom.NamedValue):
        # Both variable and enum constants are constructed like:
        # Namespace::Struct::CONSTANT_NAME
        # For enums, CONSTANT_NAME is ENUM_NAME_ENUM_VALUE.
        name = []
        if token.imported_from:
            name.extend(NamespaceToArray(token.namespace))
        if token.parent_kind:
            name.append(token.parent_kind.name)
        if IsEnumToken(token):
            name.extend([token.enum.name, token.name])
        else:
            name.append(token.name)

        ret = "::".join(name)

        # Explicitly disallow cases where we are translating an enum token for a
        # non-enum (but defined) kind.
        if IsEnumToken(
                token) and kind is not None and not mojom.IsEnumKind(kind):
            raise Exception(
                "Assignment of enum value '%s' to type %s is disallowed" %
                (ret, _kind_to_cpp_type.get(kind, "<unknown>")))

        # Explicitly disallow a non-enum token for an enum kind, we need an explicit
        # cast.
        if not IsEnumToken(token) and mojom.IsEnumKind(kind):
            raise Exception(
                "Assignment of non-enum value '%s' to enum-type %s is disallowed"
                % (ret, GetNameForKind(kind)))

        return ret

    if isinstance(token, mojom.BuiltinValue):
        if token.value == "double.INFINITY" or token.value == "float.INFINITY":
            return "INFINITY"
        if token.value == "double.NEGATIVE_INFINITY" or \
           token.value == "float.NEGATIVE_INFINITY":
            return "-INFINITY"
        if token.value == "double.NAN" or token.value == "float.NAN":
            return "NAN"

    if (kind is not None and mojom.IsFloatKind(kind)):
        return token if token.isdigit() else token + "f"

    # Per C++11, 2.14.2, the type of an integer literal is the first of the
    # corresponding list in Table 6 in which its value can be represented. In this
    # case, the list for decimal constants with no suffix is:
    #   int, long int, long long int
    # The standard considers a program ill-formed if it contains an integer
    # literal that cannot be represented by any of the allowed types.
    #
    # As it turns out, MSVC doesn't bother trying to fall back to long long int,
    # so the integral constant -2147483648 causes it grief: it decides to
    # represent 2147483648 as an unsigned integer, and then warns that the unary
    # minus operator doesn't make sense on unsigned types. Doh!
    if kind == mojom.INT32 and token == "-2147483648":
        return "(-%d - 1) /* %s */" % (
            2**31 - 1, "Workaround for MSVC bug; see https://crbug.com/445618")

    ret = "%s%s" % (token, _kind_to_cpp_literal_suffix.get(kind, ""))

    # Literal tokens may not be assigned to enum variable.  By definition, the
    # only valid tokens for the RHS of an assignment to an enum named values
    # (specifically, members of the enumeration).
    if mojom.IsEnumKind(kind):
        raise Exception(
            "Assignment of literal '%s' to enum-type %s is disallowed" %
            (ret, GetNameForKind(kind)))

    return ret
Beispiel #7
0
 def IsMojoType(kind):
     return mojom.IsEnumKind(kind)
Beispiel #8
0
def GetCppWrapperType(kind, add_same_module_namespaces=False):
  def _AddOptional(type_name):
    pattern = "WTF::Optional<%s>" if _for_blink else "base::Optional<%s>"
    return pattern % type_name

  if IsTypemappedKind(kind):
    type_name = GetNativeTypeName(kind)
    if (mojom.IsNullableKind(kind) and
        not _current_typemap[GetFullMojomNameForKind(kind)][
           "nullable_is_same_type"]):
      type_name = _AddOptional(type_name)
    return type_name
  if mojom.IsEnumKind(kind):
    return GetNameForKind(
        kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsStructKind(kind) or mojom.IsUnionKind(kind):
    return "%sPtr" % GetNameForKind(
        kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsArrayKind(kind):
    pattern = None
    if _use_new_wrapper_types:
      pattern = "WTF::Vector<%s>" if _for_blink else "std::vector<%s>"
      if mojom.IsNullableKind(kind):
        pattern = _AddOptional(pattern)
    else:
      pattern = "mojo::WTFArray<%s>" if _for_blink else "mojo::Array<%s>"
    return pattern % GetCppWrapperType(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsMapKind(kind):
    pattern = None
    if _use_new_wrapper_types:
      pattern = ("WTF::HashMap<%s, %s>" if _for_blink else
                 "std::unordered_map<%s, %s>")
      if mojom.IsNullableKind(kind):
        pattern = _AddOptional(pattern)
    else:
      pattern = "mojo::WTFMap<%s, %s>" if _for_blink else "mojo::Map<%s, %s>"
    return pattern % (
        GetCppWrapperType(
            kind.key_kind,
            add_same_module_namespaces=add_same_module_namespaces),
        GetCppWrapperType(
            kind.value_kind,
            add_same_module_namespaces=add_same_module_namespaces))
  if mojom.IsInterfaceKind(kind):
    return "%sPtr" % GetNameForKind(
        kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsInterfaceRequestKind(kind):
    return "%sRequest" % GetNameForKind(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsAssociatedInterfaceKind(kind):
    return "%sAssociatedPtrInfo" % GetNameForKind(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsAssociatedInterfaceRequestKind(kind):
    return "%sAssociatedRequest" % GetNameForKind(
        kind.kind, add_same_module_namespaces=add_same_module_namespaces)
  if mojom.IsStringKind(kind):
    if _for_blink:
      return "WTF::String"
    if not _use_new_wrapper_types:
      return "mojo::String"
    type_name = "std::string"
    return _AddOptional(type_name) if mojom.IsNullableKind(kind) else type_name
  if mojom.IsGenericHandleKind(kind):
    return "mojo::ScopedHandle"
  if mojom.IsDataPipeConsumerKind(kind):
    return "mojo::ScopedDataPipeConsumerHandle"
  if mojom.IsDataPipeProducerKind(kind):
    return "mojo::ScopedDataPipeProducerHandle"
  if mojom.IsMessagePipeKind(kind):
    return "mojo::ScopedMessagePipeHandle"
  if mojom.IsSharedBufferKind(kind):
    return "mojo::ScopedSharedBufferHandle"
  if not kind in _kind_to_cpp_type:
    raise Exception("Unrecognized kind %s" % kind.spec)
  return _kind_to_cpp_type[kind]
    def _CppToObjCAssign(self, field, obj):
        kind = field.kind
        accessor = "%s.%s" % (obj, field.name)
        if self._IsObjCNumberKind(kind):
            return accessor
        if self._IsMojomStruct(kind):
            args = (self.class_prefix, kind.name, kind.name, accessor)
            base = "[[%s%s alloc] initWith%s:*%s]" % args
            if mojom.IsNullableKind(kind):
                return """^%s%s *{
          if (%s.get() != nullptr) {
            return %s;
          }
          return nil;
        }()""" % (self.class_prefix, kind.name, accessor, base)
            else:
                return base
        if mojom.IsEnumKind(kind):
            return "static_cast<%s%s>(%s)" % (self.class_prefix, kind.name,
                                              accessor)
        if mojom.IsStringKind(kind):
            return "[NSString stringWithUTF8String:%s.c_str()]" % accessor
        if mojom.IsArrayKind(kind):
            # Only currently supporting: `[string]`, `[number]`, and `[struct]`
            array_kind = kind.kind
            if mojom.IsStringKind(array_kind) or self._IsObjCNumberKind(
                    array_kind):
                return "NSArrayFromVector(%s)" % accessor
            elif self._IsMojomStruct(array_kind):
                # Mojo IDL array<struct> actually creates a
                # `std::vector<mojom::StructPtr<struct>>``, instead of just a plain
                # vector of `struct`, which needs to be handled appropriately as
                # `StructPtr` does not allow copy and assign, and acts like a unique_ptr
                return """^{
          const auto a = [NSMutableArray new];
          for (const auto& o : %s) {
            [a addObject:%s];
          }
          return a;
        }()""" % (accessor, self._CppPtrToObjCTransform(array_kind, 'o'))
            else:
                raise Exception("Unsupported array kind %s" % array_kind.spec)
        if mojom.IsMapKind(kind):
            # Only currently supporting: `{string: string}`, `{string: number}`, and
            # `{string: struct}`
            key_kind = kind.key_kind
            val_kind = kind.value_kind
            if mojom.IsStringKind(key_kind):
                if mojom.IsStringKind(val_kind) or self._IsObjCNumberKind(
                        val_kind):
                    return "NSDictionaryFromMap(%s)" % accessor
                elif self._IsMojomStruct(val_kind):
                    # Mojo IDL map<*, struct> actually creates a
                    # `base::flat_map<*, mojom::StructPtr<struct>>``, instead of just a
                    # plain std::map of `struct`, which needs to be handled appropriately
                    # as `StructPtr` does not allow copy and assign, and acts like a
                    # unique_ptr
                    return """^{
            const auto d = [NSMutableDictionary new];
            for (const auto& item : %s) {
              d[[NSString stringWithUTF8String:item.first.c_str()]] = %s;
            }
            return d;
          }()""" % (accessor,
                    self._CppPtrToObjCTransform(val_kind, 'item.second'))
                else:
                    raise Exception("Unsupported dictionary value kind %s" %
                                    val_kind.spec)
            else:
                raise Exception("Unsupported dictionary key kind %s" %
                                key_kind.spec)

        return "%s" % accessor
def _WriteInputParamForTracingImpl(generator, kind, cpp_parameter_name,
                                   output_context):
  """Generates lines of C++ to log a parameter into TracedValue
  |output_context.value|. Use |output_context.name| if |output_context| is of
  inhereted type from _OutputContext.

  Args:
    kind: {Kind} The kind of the parameter (corresponds to its C++ type).
    cpp_parameter_name: {string} The actual C++ variable name corresponding to
      the mojom parameter |parameter_name|. Can be a valid C++ expression
      (e.g., dereferenced variable |"(*var)"|).
    output_context: {_OutputContext} Represents the TracedValue* variable to be
      written into. Possibly also holds the mojo parameter name corresponding to
      |cpp_parameter_name|.

  Yields:
    {string} C++ lines of code that trace a |cpp_parameter_name| into
      |output_context.value|.
  """

  def _WrapIfNullable(inner_lines):
    """Check if kind is nullable if so yield code to check whether it has
    value.

    Args:
      inner_lines: {function} Function taking single argument and returning
        iterable. If kind is nullable, yield from this method with
        |cpp_parameter_name+'.value()'| otherwise yield with the parameter
        |cpp_parameter_name|.

    Args from the surrounding method:
      kind
      cpp_parameter_name
      output_context.AddSingleValue
    """
    if mojom.IsNullableKind(kind):
      yield 'if (%s.has_value()) {' % cpp_parameter_name
      for line in inner_lines(cpp_parameter_name + '.value()'):
        yield '  ' + line
      yield '} else {'
      yield '  ' + output_context.AddSingleValue('String', '"base::nullopt"')
      yield '}'
    else:
      # |yield from| is introduced in Python3.3.
      for line in inner_lines(cpp_parameter_name):
        yield line

  # TODO(crbug.com/1103623): Support more involved types.
  if mojom.IsEnumKind(kind):
    if generator._IsTypemappedKind(kind) or IsNativeOnlyKind(kind):
      yield output_context.AddSingleValue(
          'Integer', 'static_cast<int>(%s)' % cpp_parameter_name)
    else:
      yield output_context.AddSingleValue(
          'String', 'base::trace_event::ValueToString(%s)' % cpp_parameter_name)
    return
  if mojom.IsStringKind(kind):
    if generator.for_blink:
      # WTF::String is nullable on its own.
      yield output_context.AddSingleValue('String',
                                          '%s.Utf8()' % cpp_parameter_name)
      return
    # The type might be base::Optional<std::string> or std::string.
    for line in _WrapIfNullable(lambda cpp_parameter_name: [
        output_context.AddSingleValue('String', cpp_parameter_name)
    ]):
      yield line
    return
  if kind == mojom.BOOL:
    yield output_context.AddSingleValue('Boolean', cpp_parameter_name)
    return
  # TODO(crbug.com/1103623): Make TracedValue support int64_t, then move to
  # mojom.IsIntegralKind.
  if kind in [mojom.INT8, mojom.UINT8, mojom.INT16, mojom.UINT16, mojom.INT32]:
    # Parameter is representable as 32bit int.
    yield output_context.AddSingleValue('Integer', cpp_parameter_name)
    return
  if kind in [mojom.UINT32, mojom.INT64, mojom.UINT64]:
    yield output_context.AddSingleValue(
        'String', 'base::NumberToString(%s)' % cpp_parameter_name)
    return
  if mojom.IsFloatKind(kind) or mojom.IsDoubleKind(kind):
    yield output_context.AddSingleValue('Double', cpp_parameter_name)
    return
  if (mojom.IsStructKind(kind) and not generator._IsTypemappedKind(kind)
      and not IsNativeOnlyKind(kind)):
    yield 'if (%s.is_null()) {' % cpp_parameter_name
    yield '  ' + output_context.AddSingleValue('String', '"nullptr"')
    yield '} else {'
    yield '  ' + output_context.BeginContainer('Dictionary')
    yield '  ' + output_context.AsValueInto(cpp_parameter_name)
    yield '  ' + output_context.EndContainer('Dictionary')
    yield '}'
    return

  if mojom.IsArrayKind(kind):
    iterator_name = 'item'
    loop_body = _WriteInputParamForTracingImpl(generator=generator,
                                               kind=kind.kind,
                                               cpp_parameter_name=iterator_name,
                                               output_context=_ArrayItem(
                                                   output_context.value))
    loop_generator = lambda cpp_parameter_name: output_context.TraceContainer(
        container_type='Array',
        iterator_name=iterator_name,
        container_name=cpp_parameter_name,
        loop_body=loop_body)
    # Array might be a nullable kind.
    for line in _WrapIfNullable(loop_generator):
      yield line
    return

  def _TraceEventToString(cpp_parameter_name=cpp_parameter_name, kind=kind):
    return 'base::trace_event::ValueToString(%s, "<value of type %s>")' % (
        cpp_parameter_name, generator._GetCppWrapperParamType(kind))

  if mojom.IsMapKind(kind):
    iterator_name = 'item'
    if generator.for_blink:
      # WTF::HashMap<,>
      key_access = '.key'
      value_access = '.value'
    else:
      # base::flat_map<,>
      key_access = '.first'
      value_access = '.second'
    loop_body = _WriteInputParamForTracingImpl(
        generator=generator,
        kind=kind.value_kind,
        cpp_parameter_name=iterator_name + value_access,
        output_context=_DictionaryItemWithCopiedKey(
            value=output_context.value,
            name=_TraceEventToString(cpp_parameter_name=iterator_name +
                                     key_access,
                                     kind=kind.key_kind)))
    loop_generator = lambda cpp_parameter_name: output_context.TraceContainer(
        container_type="Dictionary",
        iterator_name=iterator_name,
        container_name=cpp_parameter_name,
        loop_body=loop_body)
    # Dictionary might be a nullable kind.
    for line in _WrapIfNullable(loop_generator):
      yield line
    return
  yield output_context.AddSingleValue('String', _TraceEventToString())
    def _ObjCToCppAssign(self, field, obj):
        kind = field.kind
        accessor = "%s.%s" % (obj, self._ObjCPropertyFormatter(field.name))

        if self._IsObjCNumberKind(kind):
            return accessor
        if self._IsMojomStruct(kind):
            if mojom.IsNullableKind(kind):
                return "%s != nil ? %s.cppObjPtr : nullptr" % (accessor,
                                                               accessor)
            else:
                return "%s.cppObjPtr" % accessor
        if mojom.IsEnumKind(kind):
            return "static_cast<%s::%s>(%s)" % (self._CppNamespace(),
                                                kind.name, accessor)
        if mojom.IsStringKind(kind):
            return "%s.UTF8String" % accessor
        if mojom.IsArrayKind(kind):
            # Only currently supporting: `[string]`, `[number]`, and `[struct]`
            array_kind = kind.kind
            if mojom.IsStringKind(array_kind):
                return "VectorFromNSArray(%s)" % accessor
            if self._IsObjCNumberKind(array_kind):
                return """^{
          std::vector<%s> array;
          for (NSNumber *number in %s) {
            array.push_back(number.%s);
          }
          return array;
        }()""" % (_kind_to_objc_type[array_kind], accessor,
                  _kind_to_nsnumber_getter[array_kind])
            elif mojom.IsStringKind(array_kind):
                return """^{
          std::vector<std::string> array;
          for (NSString *string in %s) {
            array.push_back(string.UTF8String);
          }
          return array;
        }()""" % accessor
            elif self._IsMojomStruct(array_kind):
                return """^{
            std::vector<%s::%sPtr> array;
            for (%s%s *obj in %s) {
              array.push_back(obj.cppObjPtr);
            }
            return array;
          }()""" % (self._CppNamespace(), array_kind.name, self.class_prefix,
                    array_kind.name, accessor)
            else:
                raise Exception("Unsupported array kind %s" % array_kind.spec)
        if mojom.IsMapKind(kind):
            # Only currently supporting: `{string: string}`, `{string: number}`, and
            # `{string: struct}`
            key_kind = kind.key_kind
            val_kind = kind.value_kind
            if mojom.IsStringKind(key_kind):
                if self._IsObjCNumberKind(val_kind):
                    return """^{
            base::flat_map<std::string, %s> map;
            for (NSString *key in %s) {
              map[key.UTF8String] = %s[key].%s;
            }
            return map;
          }()""" % (_kind_to_objc_type[val_kind], accessor, accessor,
                    _kind_to_nsnumber_getter[val_kind])
                elif mojom.IsStringKind(val_kind):
                    return """^{
            base::flat_map<std::string, std::string> map;
            for (NSString *key in %s) {
              map[key.UTF8String] = %s[key].UTF8String;
            }
            return map;
          }()""" % (accessor, accessor)
                elif self._IsMojomStruct(val_kind):
                    return """^{
            base::flat_map<std::string, %s::%sPtr> map;
            for (NSString *key in %s) {
              map[key.UTF8String] = %s[key].cppObjPtr;
            }
            return map;
          }()""" % (self._CppNamespace(), val_kind.name, accessor, accessor)
                else:
                    raise Exception("Unsupported dictionary value kind %s" %
                                    val_kind.spec)
            else:
                raise Exception("Unsupported dictionary key kind %s" %
                                key_kind.spec)
        return "%s" % accessor
Beispiel #12
0
def EncodeSuffix(kind):
  if mojom.IsEnumKind(kind):
    return EncodeSuffix(mojom.INT32)
  if mojom.IsInterfaceKind(kind) or mojom.IsInterfaceRequestKind(kind):
    return EncodeSuffix(mojom.MSGPIPE)
  return _kind_infos[kind].encode_suffix
def BitWidth(element):
    if element.kind in _bit_widths:
        return _bit_widths[element.kind]
    if mojom.IsEnumKind(element.kind):
        return '32'
    return ''
def IsEnum(element):
    return mojom.IsEnumKind(element.kind)
Beispiel #15
0
 def _FormatEnumConstantDeclaration(self, constant):
     if mojom.IsEnumKind(constant.kind):
         return "constexpr %s %s = %s" % (self._GetNameForKind(
             constant.kind), constant.name, self._ConstantValue(constant))