diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 23:34:31 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-28 23:34:31 +0000 |
commit | cf00319b3aa7905a5b22b3d3cb0baf6c28ad66c6 (patch) | |
tree | ea5d5bf7789e34a686e3525a73a4756164a9671b /mojo | |
parent | 03b1e3e69e1c6f09a9550e3b354e2e698ab35845 (diff) | |
download | chromium_src-cf00319b3aa7905a5b22b3d3cb0baf6c28ad66c6.zip chromium_src-cf00319b3aa7905a5b22b3d3cb0baf6c28ad66c6.tar.gz chromium_src-cf00319b3aa7905a5b22b3d3cb0baf6c28ad66c6.tar.bz2 |
Final touches on enums as mojom types.
1. Referencing enums from another struct now works.
2. Referencing enum constants now works in all cases.
BUG=320090
Review URL: https://codereview.chromium.org/180703003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@254270 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'mojo')
7 files changed, 105 insertions, 74 deletions
diff --git a/mojo/public/bindings/generators/js_templates/struct_definition.tmpl b/mojo/public/bindings/generators/js_templates/struct_definition.tmpl index a778b8b..1686820 100644 --- a/mojo/public/bindings/generators/js_templates/struct_definition.tmpl +++ b/mojo/public/bindings/generators/js_templates/struct_definition.tmpl @@ -39,8 +39,15 @@ tmp{{depth}}.{{subfield.name}} = {{result}}; {%- endif %} {%- endmacro %} - {#--- Begin #} +{#--- Enums. We must define these before the constructor because they + may be used there. Later, we alias these to be class static variables. #} +{%- from "enum_definition.tmpl" import enum_def %} +{% for enum in struct.enums %} + var {{enum_def("%s_%s"|format(struct.name, enum.name), enum, module)}} +{% endfor %} + +{#--- Constructor #} function {{struct.name}}() { {%- for packed_field in struct.packed.packed_fields %} {%- if packed_field.field.default %} @@ -55,13 +62,13 @@ this.{{packed_field.field.name}} = {{result}}; {%- endfor %} } -{#--- Enums #} -{%- from "enum_definition.tmpl" import enum_def %} +{#--- Alias any Struct_Enum enums to Struct.Enum #} {% for enum in struct.enums %} - {{enum_def("%s.%s"|format(struct.name, enum.name), enum, module)}} -{% endfor %} + {{struct.name}}.{{enum.name}} = {{struct.name}}_{{enum.name}}; +{%- endfor %} {#--- Encoding and decoding #} + {{struct.name}}.encodedSize = codec.kStructHeaderSize + {{struct.packed|payload_size}}; {{struct.name}}.decode = function(decoder) { diff --git a/mojo/public/bindings/generators/mojom_cpp_generator.py b/mojo/public/bindings/generators/mojom_cpp_generator.py index 1a0d8cc..754e42c 100644 --- a/mojo/public/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/bindings/generators/mojom_cpp_generator.py @@ -121,17 +121,24 @@ def IsStructWithHandles(struct): return True return False -def SubstituteNamespace(token, module): - for import_item in module.imports: - token = token.replace(import_item["namespace"] + ".", - import_item["namespace"] + "::") +def TranslateConstants(token, module): + if isinstance(token, mojom.Constant): + # Enum constants are constructed like: + # Namespace::Struct::FIELD_NAME + name = [] + if token.imported_from: + name.append(token.namespace) + if token.parent_kind: + name.append(token.parent_kind.name) + name.append(token.name[1]) + return "::".join(name) return token def ExpressionToText(value, module): if value[0] != "EXPRESSION": raise Exception("Expected EXPRESSION, got" + value) return "".join(mojom_generator.ExpressionMapper(value, - lambda token: SubstituteNamespace(token, module))) + lambda token: TranslateConstants(token, module))) _HEADER_SIZE = 8 diff --git a/mojo/public/bindings/generators/mojom_js_generator.py b/mojo/public/bindings/generators/mojom_js_generator.py index e52701f..03f7db8 100644 --- a/mojo/public/bindings/generators/mojom_js_generator.py +++ b/mojo/public/bindings/generators/mojom_js_generator.py @@ -154,56 +154,20 @@ def JavaScriptEncodeSnippet(kind): if isinstance(kind, mojom.Enum): return _kind_to_javascript_encode_snippet[mojom.INT32] -def GetConstants(module): - """Returns a generator that enumerates all constants that can be referenced - from this module.""" - class Constant: - def __init__(self, module, enum, field, imported_from): - self.namespace = \ - imported_from["namespace"] if imported_from else module.namespace - self.is_current_namespace = self.namespace == module.namespace - self.imported_from = imported_from - self.name = [] - if imported_from: - self.name.append(imported_from["unique_name"]) - if enum.parent_kind: - self.name.append(enum.parent_kind.name) - self.name.extend([enum.name, field.name]) - - for enum in module.enums: - for field in enum.fields: - yield Constant(module, enum, field, None) - - for struct in module.structs: - for enum in struct.enums: - for field in enum.fields: - yield Constant(module, enum, field, None) - - for interface in module.interfaces: - for enum in interface.enums: - for field in enum.fields: - yield Constant(module, enum, field, None) - - for each in module.imports: - for enum in each["module"].enums: - for field in enum.fields: - yield Constant(module, enum, field, each) - - -def TranslateConstants(value, module): - # We're assuming we're dealing with an identifier, but that may not be - # the case. If we're not, we just won't find any matches. - if value.find(".") != -1: - namespace, identifier = value.split(".") - else: - namespace, identifier = "", value - - for constant in GetConstants(module): - if namespace == constant.namespace or ( - namespace == "" and constant.is_current_namespace): - if constant.name[-1] == identifier: - return ".".join(constant.name) - return value +def TranslateConstants(token, module): + if isinstance(token, mojom.Constant): + # Enum constants are constructed like: + # NamespaceUid.Struct_Enum.FIELD_NAME + name = [] + if token.imported_from: + name.append(token.imported_from["unique_name"]) + if token.parent_kind: + name.append(token.parent_kind.name + "_" + token.name[0]) + else: + name.append(token.name[0]) + name.append(token.name[1]) + return ".".join(name) + return token def ExpressionToText(value, module): diff --git a/mojo/public/bindings/pylib/generate/mojom.py b/mojo/public/bindings/pylib/generate/mojom.py index 04d9dd1..5d3ee19 100644 --- a/mojo/public/bindings/pylib/generate/mojom.py +++ b/mojo/public/bindings/pylib/generate/mojom.py @@ -57,6 +57,19 @@ PRIMITIVES = ( ) +class Constant(object): + def __init__(self, module, enum, field): + self.namespace = module.namespace + self.parent_kind = enum.parent_kind + self.name = [enum.name, field.name] + self.imported_from = None + + def GetSpec(self): + return (self.namespace + '.' + + (self.parent_kind and (self.parent_kind.name + '.') or "") + \ + self.name[1]) + + class Field(object): def __init__(self, name = None, kind = None, ordinal = None, default = None): self.name = name diff --git a/mojo/public/bindings/pylib/generate/mojom_data.py b/mojo/public/bindings/pylib/generate/mojom_data.py index 9a580f8..b65808e 100644 --- a/mojo/public/bindings/pylib/generate/mojom_data.py +++ b/mojo/public/bindings/pylib/generate/mojom_data.py @@ -28,7 +28,6 @@ import copy # } # test_module = mojom_data.ModuleFromData(test_dict) - # Used to create a subclass of str that supports sorting by index, to make # pretty printing maintain the order. def istr(index, string): @@ -52,7 +51,7 @@ def LookupKind(kinds, spec, scope): to the location where the type is referenced.""" if spec.startswith('x:'): name = spec[2:] - for i in [2, 1, 0]: + for i in xrange(len(scope), -1, -1): test_spec = 'x:' if i > 0: test_spec += '.'.join(scope[:i]) + '.' @@ -63,6 +62,18 @@ def LookupKind(kinds, spec, scope): return kinds.get(spec) +def LookupConstant(constants, name, scope): + """Like LookupKind, but for constants.""" + for i in xrange(len(scope), -1, -1): + if i > 0: + test_spec = '.'.join(scope[:i]) + '.' + test_spec += name + constant = constants.get(test_spec) + if constant: + return constant + + return constants.get(name) + def KindToData(kind): return kind.spec @@ -100,6 +111,13 @@ def ImportFromData(module, data): kind.imported_from is None): kind = KindFromImport(kind, import_item) module.kinds[kind.spec] = kind + # Ditto for constants. + for constant in import_module.constants.itervalues(): + if constant.imported_from is None: + constant = copy.deepcopy(constant) + constant.imported_from = import_item + module.constants[constant.GetSpec()] = constant + return import_item def StructToData(struct): @@ -130,13 +148,27 @@ def FieldToData(field): data[istr(3, 'default')] = field.default return data +def FixupExpression(module, value, scope): + if isinstance(value, (tuple, list)): + for i in xrange(len(value)): + if isinstance(value, tuple): + FixupExpression(module, value[i], scope) + else: + value[i] = FixupExpression(module, value[i], scope) + elif value: + constant = LookupConstant(module.constants, value, scope) + if constant: + return constant + return value + def FieldFromData(module, data, struct): field = mojom.Field() field.name = data['name'] field.kind = KindFromData( module.kinds, data['kind'], (module.namespace, struct.name)) field.ordinal = data.get('ordinal') - field.default = data.get('default') + field.default = FixupExpression( + module, data.get('default'), (module.namespace, struct.name)) return field def ParameterToData(parameter): @@ -196,10 +228,17 @@ def InterfaceFromData(module, data): MethodFromData(module, method, interface), data['methods']) return interface -def EnumFieldFromData(module, data): +def EnumFieldFromData(module, enum, data, parent_kind): field = mojom.EnumField() field.name = data['name'] - field.value = data['value'] + if parent_kind: + field.value = FixupExpression( + module, data['value'], (module.namespace, parent_kind.name)) + else: + field.value = FixupExpression( + module, data['value'], (module.namespace, )) + constant = mojom.Constant(module, enum, field) + module.constants[constant.GetSpec()] = constant return field def EnumFromData(module, data, parent_kind): @@ -212,7 +251,8 @@ def EnumFromData(module, data, parent_kind): enum.parent_kind = parent_kind enum.fields = map( - lambda field: EnumFieldFromData(module, field), data['fields']) + lambda field: EnumFieldFromData(module, enum, field, parent_kind), + data['fields']) module.kinds[enum.spec] = enum return enum @@ -230,6 +270,8 @@ def ModuleFromData(data): for kind in mojom.PRIMITIVES: module.kinds[kind.spec] = kind + module.constants = {} + module.name = data['name'] module.namespace = data['namespace'] # Imports must come first, because they add to module.kinds which is used @@ -244,6 +286,7 @@ def ModuleFromData(data): module.interfaces = map( lambda interface: InterfaceFromData(module, interface), data['interfaces']) + return module def OrderedModuleFromData(data): diff --git a/mojo/public/bindings/pylib/parse/mojo_parser.py b/mojo/public/bindings/pylib/parse/mojo_parser.py index 7c6fcfb..8af77cb 100755 --- a/mojo/public/bindings/pylib/parse/mojo_parser.py +++ b/mojo/public/bindings/pylib/parse/mojo_parser.py @@ -155,14 +155,10 @@ class Parser(object): p[0] = p[1] def p_basictypename(self, p): - """basictypename : NAME + """basictypename : identifier | HANDLE - | NAME DOT NAME | specializedhandle""" - if len(p) == 2: - p[0] = p[1] - else: - p[0] = p[1] + '.' + p[3] + p[0] = p[1] def p_specializedhandle(self, p): """specializedhandle : HANDLE LT specializedhandlename GT""" @@ -302,7 +298,7 @@ class Parser(object): def p_identifier(self, p): """identifier : NAME - | NAME DOT NAME""" + | NAME DOT identifier""" p[0] = ''.join(p[1:]) def p_constant(self, p): diff --git a/mojo/public/bindings/tests/sample_service.mojom b/mojo/public/bindings/tests/sample_service.mojom index 045c696..2a89e18 100644 --- a/mojo/public/bindings/tests/sample_service.mojom +++ b/mojo/public/bindings/tests/sample_service.mojom @@ -17,7 +17,7 @@ struct Bar { uint8 alpha = (0x100 - 1) @0; uint8 beta @1; uint8 gamma @2; - Type type @3; + Type type = sample.Bar.TYPE_VERTICAL @3; }; [RequiredFields=7] @@ -48,6 +48,7 @@ struct DefaultsTest { imported.Point point = {7, 15} @3; int32[] shape_masks = [1 << imported.SHAPE_RECTANGLE] @4; imported.Thing thing = {imported.SHAPE_CIRCLE, imported.COLOR_BLACK}; + Bar.Type bar_type = Bar.TYPE_BOTH; }; interface Port { |