From e1543ddc1e3cfeb3019cdda3357240727975d9d5 Mon Sep 17 00:00:00 2001 From: rockot <rockot@chromium.org> Date: Tue, 15 Dec 2015 21:36:09 -0800 Subject: [mojo] Add mojom parser support for native-only structs This allows struct declarations to be parsed in mojom with no struct body. Such structs are tagged as native-only and this information is propagated to different language generators. Part of a series of changes to support custom mojom serialization: 1. This CL 2. https://codereview.chromium.org/1517043004 3. https://codereview.chromium.org/1524693002 4. https://codereview.chromium.org/1520153002 5. https://codereview.chromium.org/1524613002 6. https://codereview.chromium.org/1526533002 7. https://codereview.chromium.org/1524703002 BUG=569669 Review URL: https://codereview.chromium.org/1515423002 Cr-Commit-Position: refs/heads/master@{#365467} --- mojo/public/interfaces/bindings/tests/BUILD.gn | 1 + .../bindings/tests/test_native_types.mojom | 11 +++++++++ .../tools/bindings/pylib/mojom/generate/data.py | 26 +++++++++++++++++----- .../tools/bindings/pylib/mojom/generate/module.py | 2 ++ .../public/tools/bindings/pylib/mojom/parse/ast.py | 2 +- .../tools/bindings/pylib/mojom/parse/parser.py | 6 ++++- .../tools/bindings/pylib/mojom/parse/translate.py | 15 ++++++++----- 7 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 mojo/public/interfaces/bindings/tests/test_native_types.mojom diff --git a/mojo/public/interfaces/bindings/tests/BUILD.gn b/mojo/public/interfaces/bindings/tests/BUILD.gn index d5baa9d..802bd58 100644 --- a/mojo/public/interfaces/bindings/tests/BUILD.gn +++ b/mojo/public/interfaces/bindings/tests/BUILD.gn @@ -20,6 +20,7 @@ mojom("test_interfaces") { "scoping.mojom", "serialization_test_structs.mojom", "test_constants.mojom", + "test_native_types.mojom", "test_structs.mojom", "validation_test_interfaces.mojom", ] diff --git a/mojo/public/interfaces/bindings/tests/test_native_types.mojom b/mojo/public/interfaces/bindings/tests/test_native_types.mojom new file mode 100644 index 0000000..3537703 --- /dev/null +++ b/mojo/public/interfaces/bindings/tests/test_native_types.mojom @@ -0,0 +1,11 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module mojo.test; + +// Used to verify that structs can be declared with no body in mojom. + +[native=True] +struct PickledStruct; + diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/data.py b/mojo/public/tools/bindings/pylib/mojom/generate/data.py index 1109a6a..60ae1e0 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/data.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/data.py @@ -209,15 +209,29 @@ def StructToData(struct): def StructFromData(module, data): struct = mojom.Struct(module=module) struct.name = data['name'] + struct.native_only = data['native_only'] struct.spec = 'x:' + module.namespace + '.' + struct.name module.kinds[struct.spec] = struct - struct.enums = map(lambda enum: - EnumFromData(module, enum, struct), data['enums']) - struct.constants = map(lambda constant: - ConstantFromData(module, constant, struct), data['constants']) - # Stash fields data here temporarily. - struct.fields_data = data['fields'] + if struct.native_only: + struct.enums = [] + struct.constants = [] + struct.fields_data = [] + else: + struct.enums = map(lambda enum: + EnumFromData(module, enum, struct), data['enums']) + struct.constants = map(lambda constant: + ConstantFromData(module, constant, struct), data['constants']) + # Stash fields data here temporarily. + struct.fields_data = data['fields'] struct.attributes = data.get('attributes') + + # Enforce that a [native=True] attribute is set to make native-only struct + # declarations more explicit. + if struct.native_only: + if not struct.attributes or not struct.attributes.get('native', False): + raise Exception("Native-only struct declarations must include a " + + "native=True attribute.") + return struct def UnionToData(union): diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/mojo/public/tools/bindings/pylib/mojom/generate/module.py index 8af874f..dfde609 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/module.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/module.py @@ -202,6 +202,7 @@ class UnionField(Field): pass class Struct(ReferenceKind): ReferenceKind.AddSharedProperty('name') + ReferenceKind.AddSharedProperty('native_only') ReferenceKind.AddSharedProperty('module') ReferenceKind.AddSharedProperty('imported_from') ReferenceKind.AddSharedProperty('fields') @@ -214,6 +215,7 @@ class Struct(ReferenceKind): spec = None ReferenceKind.__init__(self, spec) self.name = name + self.native_only = False self.module = module self.imported_from = None self.fields = [] diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/ast.py b/mojo/public/tools/bindings/pylib/mojom/parse/ast.py index ffb44e0..6473b02 100644 --- a/mojo/public/tools/bindings/pylib/mojom/parse/ast.py +++ b/mojo/public/tools/bindings/pylib/mojom/parse/ast.py @@ -326,7 +326,7 @@ class Struct(Definition): def __init__(self, name, attribute_list, body, **kwargs): assert attribute_list is None or isinstance(attribute_list, AttributeList) - assert isinstance(body, StructBody) + assert isinstance(body, StructBody) or body is None super(Struct, self).__init__(name, **kwargs) self.attribute_list = attribute_list self.body = body diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py index f52f91d..8d90cd5 100644 --- a/mojo/public/tools/bindings/pylib/mojom/parse/parser.py +++ b/mojo/public/tools/bindings/pylib/mojom/parse/parser.py @@ -155,10 +155,14 @@ class Parser(object): # 'eval' the literal to strip the quotes. p[0] = eval(p[1]) - def p_struct(self, p): + def p_struct_1(self, p): """struct : attribute_section STRUCT NAME LBRACE struct_body RBRACE SEMI""" p[0] = ast.Struct(p[3], p[1], p[5]) + def p_struct_2(self, p): + """struct : attribute_section STRUCT NAME SEMI""" + p[0] = ast.Struct(p[3], p[1], None) + def p_struct_body_1(self, p): """struct_body : """ p[0] = ast.StructBody() diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/translate.py b/mojo/public/tools/bindings/pylib/mojom/parse/translate.py index aad245f..e457f99 100644 --- a/mojo/public/tools/bindings/pylib/mojom/parse/translate.py +++ b/mojo/public/tools/bindings/pylib/mojom/parse/translate.py @@ -130,12 +130,15 @@ class _MojomBuilder(object): assert isinstance(struct, ast.Struct) data = {'name': struct.name, - 'fields': _MapTreeForType(StructFieldToDict, struct.body, - ast.StructField, struct.name), - 'enums': _MapTreeForType(_EnumToDict, struct.body, ast.Enum, - struct.name), - 'constants': _MapTreeForType(_ConstToDict, struct.body, - ast.Const, struct.name)} + 'native_only': struct.body is None} + if not data['native_only']: + data.update({ + 'fields': _MapTreeForType(StructFieldToDict, struct.body, + ast.StructField, struct.name), + 'enums': _MapTreeForType(_EnumToDict, struct.body, ast.Enum, + struct.name), + 'constants': _MapTreeForType(_ConstToDict, struct.body, + ast.Const, struct.name)}) _AddOptional(data, 'attributes', _AttributeListToDict(struct.attribute_list)) return data -- cgit v1.1