| Index: mojo/public/tools/bindings/pylib/mojom/generate/module.py
|
| diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
|
| index 2811e62858954c62832bd94803fc72bfaf6892d9..394dfac39005fd845965ef1cd52b0d2d40a81c15 100644
|
| --- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py
|
| +++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py
|
| @@ -294,6 +294,21 @@ class UnionField(Field): pass
|
|
|
|
|
| class Struct(ReferenceKind):
|
| + """A struct with typed fields.
|
| +
|
| + Attributes:
|
| + name: {str} The name of the struct type.
|
| + native_only: {bool} Does the struct have a body (i.e. any fields) or is it
|
| + purely a native struct that must be type-mapped.
|
| + module: {Module} The defining module.
|
| + imported_from: {dict} Information about where this union was
|
| + imported from.
|
| + fields: {List[StructField]} The members of the union.
|
| + attributes: {dict} Additional information about the struct, such as
|
| + which Java class name to use to represent it in the generated
|
| + bindings.
|
| + """
|
| +
|
| ReferenceKind.AddSharedProperty('name')
|
| ReferenceKind.AddSharedProperty('native_only')
|
| ReferenceKind.AddSharedProperty('module')
|
| @@ -425,11 +440,6 @@ class Map(ReferenceKind):
|
| ']')
|
| if IsNullableKind(key_kind):
|
| raise Exception("Nullable kinds cannot be keys in maps.")
|
| - if IsStructKind(key_kind):
|
| - # TODO(erg): It would sometimes be nice if we could key on struct
|
| - # values. However, what happens if the struct has a handle in it? Or
|
| - # non-copyable data like an array?
|
| - raise Exception("Structs cannot be keys in maps.")
|
| if IsAnyHandleKind(key_kind):
|
| raise Exception("Handles cannot be keys in maps.")
|
| if IsAnyInterfaceKind(key_kind):
|
| @@ -840,3 +850,40 @@ def HasSyncMethods(interface):
|
| if method.sync:
|
| return True
|
| return False
|
| +
|
| +
|
| +def ContainsHandles(kind):
|
| + """Check if the kind contains any handles.
|
| +
|
| + This check is recursive so it checks all struct fields, containers elements,
|
| + etc.
|
| +
|
| + Args:
|
| + struct: {Kind} The kind to check.
|
| +
|
| + Returns:
|
| + {bool}: True if the kind contains handles.
|
| + """
|
| + # We remember the types we already checked to avoid infinite recursion when
|
| + # checking recursive (or mutually recursive) types:
|
| + checked = set()
|
| + def Check(kind):
|
| + if kind.spec in checked:
|
| + return False
|
| + checked.add(kind.spec)
|
| + if IsStructKind(kind):
|
| + return any(Check(field.kind) for field in kind.fields)
|
| + elif IsUnionKind(kind):
|
| + return any(Check(field.kind) for field in kind.fields)
|
| + elif IsAnyHandleKind(kind):
|
| + return True
|
| + elif IsAnyInterfaceKind(kind):
|
| + # Interfaces are wrappers around handles.
|
| + return True
|
| + elif IsArrayKind(kind):
|
| + return Check(kind.kind)
|
| + elif IsMapKind(kind):
|
| + return Check(kind.key_kind) or Check(kind.value_kind)
|
| + else:
|
| + return False
|
| + return Check(kind)
|
|
|