Chromium Code Reviews| 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 c55b85e2e3313667dfaafb2bde993cbc12570ea2..74a459d32034491b7d41ede3d5fba38e678a67db 100644 |
| --- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py |
| +++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py |
| @@ -11,31 +11,95 @@ |
| # interface = module.AddInterface('Bar') |
| # method = interface.AddMethod('Tat', 0) |
| # method.AddParameter('baz', 0, mojom.INT32) |
| -# |
| + |
| class Kind(object): |
| def __init__(self, spec=None): |
| self.spec = spec |
| self.parent_kind = None |
| + |
| +class ReferenceKind(Kind): |
| + """ReferenceKind represents pointer types and handle types. |
| + A type is nullable means that NULL (for pointer types) or invalid handle |
| + (for handle types) is a legal value for the type. |
| + """ |
| + |
| + def __init__(self, spec=None, is_nullable=False): |
| + assert spec is None or is_nullable == spec.startswith('?') |
| + Kind.__init__(self, spec) |
| + self.is_nullable = is_nullable |
| + self.shared_definition = {} |
| + |
| + def MakeNullableKind(self): |
| + assert not self.is_nullable |
| + |
| + if self == STRING: |
| + return NLBL_STRING |
| + if self == HANDLE: |
| + return NLBL_HANDLE |
| + if self == DCPIPE: |
| + return NLBL_DCPIPE |
| + if self == DPPIPE: |
| + return NLBL_DPPIPE |
| + if self == MSGPIPE: |
| + return NLBL_MSGPIPE |
| + if self == SHAREDBUFFER: |
| + return NLBL_SHAREDBUFFER |
| + |
| + nullable_kind = type(self)() |
| + nullable_kind.shared_definition = self.shared_definition |
| + if self.spec is not None: |
| + nullable_kind.spec = '?' + self.spec |
| + nullable_kind.is_nullable = True |
| + |
| + return nullable_kind |
| + |
| + @classmethod |
| + def AddProperty(cls, name): |
| + """Adds a property |name| to |cls|, which accesses the corresponding item in |
| + |shared_definition|. |
| + |
| + The reason of adding such indirection is to enable sharing definition |
| + between a reference kind and its nullable variation. For example: |
| + a = Struct('test_struct_1') |
| + b = a.MakeNullableKind() |
| + a.name = 'test_struct_2' |
| + print b.name # Outputs 'test_struct_2'. |
| + """ |
| + def Get(self): |
| + return self.shared_definition[name] |
| + |
| + def Set(self, value): |
| + self.shared_definition[name] = value |
| + |
| + setattr(cls, name, property(Get, Set)) |
| + |
| + |
| # Initialize the set of primitive types. These can be accessed by clients. |
| -BOOL = Kind('b') |
| -INT8 = Kind('i8') |
| -INT16 = Kind('i16') |
| -INT32 = Kind('i32') |
| -INT64 = Kind('i64') |
| -UINT8 = Kind('u8') |
| -UINT16 = Kind('u16') |
| -UINT32 = Kind('u32') |
| -UINT64 = Kind('u64') |
| -FLOAT = Kind('f') |
| -DOUBLE = Kind('d') |
| -STRING = Kind('s') |
| -HANDLE = Kind('h') |
| -DCPIPE = Kind('h:d:c') |
| -DPPIPE = Kind('h:d:p') |
| -MSGPIPE = Kind('h:m') |
| -SHAREDBUFFER = Kind('h:s') |
| +BOOL = Kind('b') |
| +INT8 = Kind('i8') |
| +INT16 = Kind('i16') |
| +INT32 = Kind('i32') |
| +INT64 = Kind('i64') |
| +UINT8 = Kind('u8') |
| +UINT16 = Kind('u16') |
| +UINT32 = Kind('u32') |
| +UINT64 = Kind('u64') |
| +FLOAT = Kind('f') |
| +DOUBLE = Kind('d') |
| +STRING = ReferenceKind('s') |
| +HANDLE = ReferenceKind('h') |
| +DCPIPE = ReferenceKind('h:d:c') |
| +DPPIPE = ReferenceKind('h:d:p') |
| +MSGPIPE = ReferenceKind('h:m') |
| +SHAREDBUFFER = ReferenceKind('h:s') |
| +NLBL_STRING = ReferenceKind('?s', True) |
|
darin (slow to review)
2014/08/06 22:48:26
I know we have been abbreviating labels here, but
yzshen1
2014/08/06 22:55:42
Done. Thanks!
|
| +NLBL_HANDLE = ReferenceKind('?h', True) |
| +NLBL_DCPIPE = ReferenceKind('?h:d:c', True) |
| +NLBL_DPPIPE = ReferenceKind('?h:d:p', True) |
| +NLBL_MSGPIPE = ReferenceKind('?h:m', True) |
| +NLBL_SHAREDBUFFER = ReferenceKind('?h:s', True) |
| # Collection of all Primitive types |
| @@ -56,7 +120,13 @@ PRIMITIVES = ( |
| DCPIPE, |
| DPPIPE, |
| MSGPIPE, |
| - SHAREDBUFFER |
| + SHAREDBUFFER, |
| + NLBL_STRING, |
| + NLBL_HANDLE, |
| + NLBL_DCPIPE, |
| + NLBL_DPPIPE, |
| + NLBL_MSGPIPE, |
| + NLBL_SHAREDBUFFER |
| ) |
| @@ -100,16 +170,21 @@ class Field(object): |
| self.default = default |
| -class Struct(Kind): |
| +class Struct(ReferenceKind): |
| + ReferenceKind.AddProperty('name') |
| + ReferenceKind.AddProperty('module') |
| + ReferenceKind.AddProperty('imported_from') |
| + ReferenceKind.AddProperty('fields') |
| + |
| def __init__(self, name=None, module=None): |
| - self.name = name |
| - self.module = module |
| - self.imported_from = None |
| if name is not None: |
| spec = 'x:' + name |
| else: |
| spec = None |
| - Kind.__init__(self, spec) |
| + ReferenceKind.__init__(self, spec) |
| + self.name = name |
| + self.module = module |
| + self.imported_from = None |
| self.fields = [] |
| def AddField(self, name, kind, ordinal=None, default=None): |
| @@ -118,30 +193,39 @@ class Struct(Kind): |
| return field |
| -class Array(Kind): |
| +class Array(ReferenceKind): |
| + ReferenceKind.AddProperty('kind') |
| + |
| def __init__(self, kind=None): |
| - self.kind = kind |
| if kind is not None: |
| - Kind.__init__(self, 'a:' + kind.spec) |
| + ReferenceKind.__init__(self, 'a:' + kind.spec) |
| else: |
| - Kind.__init__(self) |
| - |
| -class FixedArray(Kind): |
| - def __init__(self, length, kind=None): |
| + ReferenceKind.__init__(self) |
| self.kind = kind |
| - self.length = length |
| + |
| + |
| +class FixedArray(ReferenceKind): |
| + ReferenceKind.AddProperty('kind') |
| + ReferenceKind.AddProperty('length') |
| + |
| + def __init__(self, length=-1, kind=None): |
| if kind is not None: |
| - Kind.__init__(self, 'a' + length + ':' + kind.spec) |
| + ReferenceKind.__init__(self, 'a%d:%s' % (length, kind.spec)) |
| else: |
| - Kind.__init__(self) |
| + ReferenceKind.__init__(self) |
| + self.kind = kind |
| + self.length = length |
| + |
| + |
| +class InterfaceRequest(ReferenceKind): |
| + ReferenceKind.AddProperty('kind') |
| -class InterfaceRequest(Kind): |
| def __init__(self, kind=None): |
| - self.kind = kind |
| if kind is not None: |
| - Kind.__init__(self, 'r:' + kind.spec) |
| + ReferenceKind.__init__(self, 'r:' + kind.spec) |
| else: |
| - Kind.__init__(self) |
| + ReferenceKind.__init__(self) |
| + self.kind = kind |
| class Parameter(object): |
| @@ -173,16 +257,22 @@ class Method(object): |
| return parameter |
| -class Interface(Kind): |
| +class Interface(ReferenceKind): |
| + ReferenceKind.AddProperty('module') |
| + ReferenceKind.AddProperty('name') |
| + ReferenceKind.AddProperty('imported_from') |
| + ReferenceKind.AddProperty('client') |
| + ReferenceKind.AddProperty('methods') |
| + |
| def __init__(self, name=None, client=None, module=None): |
| - self.module = module |
| - self.name = name |
| - self.imported_from = None |
| if name is not None: |
| spec = 'x:' + name |
| else: |
| spec = None |
| - Kind.__init__(self, spec) |
| + ReferenceKind.__init__(self, spec) |
| + self.module = module |
| + self.name = name |
| + self.imported_from = None |
| self.client = client |
| self.methods = [] |