def _CollectReferencedKinds(module, all_defined_kinds):
    """
  Takes a {mojom.Module} object and a list of all defined kinds within that
  module, and enumerates the complete dict of user-defined mojom types
  (as {mojom.Kind} objects) referenced by the module's own defined kinds (i.e.
  as types of struct or union or interface parameters. The returned dict is
  keyed by kind spec.
  """
    def extract_referenced_user_kinds(kind):
        if mojom.IsArrayKind(kind):
            return extract_referenced_user_kinds(kind.kind)
        if mojom.IsMapKind(kind):
            return (extract_referenced_user_kinds(kind.key_kind) +
                    extract_referenced_user_kinds(kind.value_kind))
        if mojom.IsInterfaceRequestKind(kind) or mojom.IsAssociatedKind(kind):
            return [kind.kind]
        if mojom.IsStructKind(kind):
            return [kind]
        if (mojom.IsInterfaceKind(kind) or mojom.IsEnumKind(kind)
                or mojom.IsUnionKind(kind)):
            return [kind]
        return []

    def sanitize_kind(kind):
        """Removes nullability from a kind"""
        if kind.spec.startswith('?'):
            return _Kind(module.kinds, kind.spec[1:],
                         (module.mojom_namespace, ''))
        return kind

    referenced_user_kinds = {}
    for defined_kind in all_defined_kinds:
        if mojom.IsStructKind(defined_kind) or mojom.IsUnionKind(defined_kind):
            for field in defined_kind.fields:
                for referenced_kind in extract_referenced_user_kinds(
                        field.kind):
                    sanitized_kind = sanitize_kind(referenced_kind)
                    referenced_user_kinds[sanitized_kind.spec] = sanitized_kind

    # Also scan for references in parameter lists
    for interface in module.interfaces:
        for method in interface.methods:
            for param in itertools.chain(method.parameters or [],
                                         method.response_parameters or []):
                if (mojom.IsStructKind(param.kind)
                        or mojom.IsUnionKind(param.kind)
                        or mojom.IsEnumKind(param.kind)
                        or mojom.IsAnyInterfaceKind(param.kind)):
                    for referenced_kind in extract_referenced_user_kinds(
                            param.kind):
                        sanitized_kind = sanitize_kind(referenced_kind)
                        referenced_user_kinds[
                            sanitized_kind.spec] = sanitized_kind

    return referenced_user_kinds
Exemple #2
0
  def test_user_defined_type_type(self):
    graph = mojom_files_mojom.MojomFileGraph()
    mojom_struct = mojom_types_mojom.MojomStruct(
        decl_data=mojom_types_mojom.DeclarationData(short_name='FirstStruct'))
    type_key = 'some opaque string'
    mojom_struct.fields = [
        # Make sure recursive structs are correctly handled.
        mojom_types_mojom.StructField(
          decl_data=mojom_types_mojom.DeclarationData(short_name='field00'),
          type=mojom_types_mojom.Type(
            type_reference=mojom_types_mojom.TypeReference(type_key=type_key)))
        ]
    add_version_info(mojom_struct, 1)
    graph.resolved_types = {
        type_key: mojom_types_mojom.UserDefinedType(struct_type=mojom_struct)}

    mojom_type = mojom_types_mojom.Type()
    mojom_type.type_reference = mojom_types_mojom.TypeReference(
        type_key=type_key)

    t = mojom_translator.FileTranslator(graph, None)
    result = t.KindFromMojom(mojom_type)
    self.assertTrue(module.IsStructKind(result))
    self.assertEquals(mojom_struct.decl_data.short_name, result.name)
    self.assertEquals(result, result.fields[0].kind)
    self.assertEquals(type_key, result.type_key)

    # Make sure we create only one module object per type.
    result2 = t.KindFromMojom(mojom_type)
    self.assertIs(result, result2)

    # Nullable type reference
    mojom_type.type_reference.nullable = True
    nullable_result = t.KindFromMojom(mojom_type)
    self.assertTrue(module.IsNullableKind(nullable_result))
 def extract_referenced_user_kinds(kind):
     if mojom.IsArrayKind(kind):
         return extract_referenced_user_kinds(kind.kind)
     if mojom.IsMapKind(kind):
         return (extract_referenced_user_kinds(kind.key_kind) +
                 extract_referenced_user_kinds(kind.value_kind))
     if mojom.IsInterfaceRequestKind(kind) or mojom.IsAssociatedKind(kind):
         return [kind.kind]
     if mojom.IsStructKind(kind):
         return [kind]
     if (mojom.IsInterfaceKind(kind) or mojom.IsEnumKind(kind)
             or mojom.IsUnionKind(kind)):
         return [kind]
     return []