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
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 []