| Index: mojo/public/tools/bindings/generators/mojom_python_generator.py
|
| diff --git a/mojo/public/tools/bindings/generators/mojom_python_generator.py b/mojo/public/tools/bindings/generators/mojom_python_generator.py
|
| index ca9625ebc784a3c77d17c89028d31f1dde1fda82..88318b30589c3ef5ab768718391744a0edeca11c 100644
|
| --- a/mojo/public/tools/bindings/generators/mojom_python_generator.py
|
| +++ b/mojo/public/tools/bindings/generators/mojom_python_generator.py
|
| @@ -5,6 +5,7 @@
|
| """Generates Python source files from a mojom.Module."""
|
|
|
| import re
|
| +from itertools import ifilter
|
|
|
| import mojom.generate.generator as generator
|
| import mojom.generate.module as mojom
|
| @@ -34,24 +35,24 @@ def ConstantStyle(name):
|
| return '_'.join([x.upper() for x in components])
|
|
|
| def GetNameForElement(element):
|
| + if isinstance(element, mojom.EnumValue):
|
| + return (GetNameForElement(element.enum) + '.' +
|
| + ConstantStyle(element.name))
|
| if isinstance(element, (mojom.NamedValue,
|
| mojom.Constant)):
|
| return ConstantStyle(element.name)
|
| raise Exception('Unexpected element: ' % element)
|
|
|
| -def TranslateConstants(token):
|
| +def ExpressionToText(token):
|
| if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
|
| # Both variable and enum constants are constructed like:
|
| - # NamespaceUid.Struct[.Enum].CONSTANT_NAME
|
| + # PythonModule[.Struct][.Enum].CONSTANT_NAME
|
| name = []
|
| if token.imported_from:
|
| name.append(token.imported_from['python_module'])
|
| if token.parent_kind:
|
| name.append(GetNameForElement(token.parent_kind))
|
| - if isinstance(token, mojom.EnumValue):
|
| - name.append(GetNameForElement(token))
|
| - else:
|
| - name.append(token.name)
|
| + name.append(GetNameForElement(token))
|
| return '.'.join(name)
|
|
|
| if isinstance(token, mojom.BuiltinValue):
|
| @@ -66,9 +67,54 @@ def TranslateConstants(token):
|
| return token
|
|
|
|
|
| -def ExpressionToText(value):
|
| - return TranslateConstants(value)
|
| -
|
| +def ComputeConstantValues(module):
|
| + in_progress = set()
|
| + computed = set()
|
| +
|
| + def ResolveEnum(enum):
|
| + def GetComputedValue(enum_value):
|
| + field = next(ifilter(lambda field: field.name == enum_value.name,
|
| + enum_value.enum.fields), None)
|
| + if not field:
|
| + raise RuntimeError(
|
| + 'Unable to get computed value for field %s of enum %s' %
|
| + (enum_value.name, enum_value.enum.name))
|
| + if field not in computed:
|
| + ResolveEnum(enum_value.enum)
|
| + return field.computed_value
|
| +
|
| + def ResolveEnumField(enum, field, default_value):
|
| + if field in computed:
|
| + return
|
| + if field in in_progress:
|
| + raise RuntimeError('Circular dependency for enum: %s' % enum.name)
|
| + in_progress.add(field)
|
| + if field.value:
|
| + if isinstance(field.value, mojom.EnumValue):
|
| + computed_value = GetComputedValue(field.value)
|
| + elif isinstance(field.value, str):
|
| + computed_value = int(field.value, 0)
|
| + else:
|
| + raise RuntimeError('Unexpected value: %r' % field.value)
|
| + else:
|
| + computed_value = default_value
|
| + field.computed_value = computed_value
|
| + in_progress.remove(field)
|
| + computed.add(field)
|
| +
|
| + current_value = 0
|
| + for field in enum.fields:
|
| + ResolveEnumField(enum, field, current_value)
|
| + current_value = field.computed_value + 1
|
| +
|
| + for enum in module.enums:
|
| + ResolveEnum(enum)
|
| +
|
| + for struct in module.structs:
|
| + for enum in struct.enums:
|
| + ResolveEnum(enum)
|
| +
|
| + return module
|
|
|
| class Generator(generator.Generator):
|
|
|
| @@ -81,7 +127,8 @@ class Generator(generator.Generator):
|
| def GeneratePythonModule(self):
|
| return {
|
| 'imports': self.GetImports(),
|
| - 'module': self.module,
|
| + 'enums': self.module.enums,
|
| + 'module': ComputeConstantValues(self.module),
|
| }
|
|
|
| def GenerateFiles(self, args):
|
|
|