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 9756576c16238ddfde9d729b9333a2a16c4ba8a4..9417298d4b3cf5d01f8b098658b4379ebe3090de 100644 |
--- a/mojo/public/tools/bindings/generators/mojom_python_generator.py |
+++ b/mojo/public/tools/bindings/generators/mojom_python_generator.py |
@@ -11,6 +11,32 @@ import mojom.generate.generator as generator |
import mojom.generate.module as mojom |
from mojom.generate.template_expander import UseJinja |
+_kind_to_type = { |
+ mojom.BOOL: "_descriptor.TYPE_BOOL", |
+ mojom.INT8: "_descriptor.TYPE_INT8", |
+ mojom.UINT8: "_descriptor.TYPE_UINT8", |
+ mojom.INT16: "_descriptor.TYPE_INT16", |
+ mojom.UINT16: "_descriptor.TYPE_UINT16", |
+ mojom.INT32: "_descriptor.TYPE_INT32", |
+ mojom.UINT32: "_descriptor.TYPE_UINT32", |
+ mojom.INT64: "_descriptor.TYPE_INT64", |
+ mojom.UINT64: "_descriptor.TYPE_UINT64", |
+ mojom.FLOAT: "_descriptor.TYPE_FLOAT", |
+ mojom.DOUBLE: "_descriptor.TYPE_DOUBLE", |
+ mojom.STRING: "_descriptor.TYPE_STRING", |
+ mojom.NULLABLE_STRING: "_descriptor.TYPE_NULLABLE_STRING", |
+ mojom.HANDLE: "_descriptor.TYPE_HANDLE", |
+ mojom.DCPIPE: "_descriptor.TYPE_HANDLE", |
+ mojom.DPPIPE: "_descriptor.TYPE_HANDLE", |
+ mojom.MSGPIPE: "_descriptor.TYPE_HANDLE", |
+ mojom.SHAREDBUFFER: "_descriptor.TYPE_HANDLE", |
+ mojom.NULLABLE_HANDLE: "_descriptor.TYPE_NULLABLE_HANDLE", |
+ mojom.NULLABLE_DCPIPE: "_descriptor.TYPE_NULLABLE_HANDLE", |
+ mojom.NULLABLE_DPPIPE: "_descriptor.TYPE_NULLABLE_HANDLE", |
+ mojom.NULLABLE_MSGPIPE: "_descriptor.TYPE_NULLABLE_HANDLE", |
+ mojom.NULLABLE_SHAREDBUFFER: "_descriptor.TYPE_NULLABLE_HANDLE", |
+} |
+ |
def NameToComponent(name): |
# insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> |
@@ -48,15 +74,7 @@ def GetNameForElement(element): |
def ExpressionToText(token): |
if isinstance(token, (mojom.EnumValue, mojom.NamedValue)): |
- # Both variable and enum constants are constructed like: |
- # 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)) |
- name.append(GetNameForElement(token)) |
- return '.'.join(name) |
+ return str(token.computed_value) |
if isinstance(token, mojom.BuiltinValue): |
if token.value == 'double.INFINITY' or token.value == 'float.INFINITY': |
@@ -67,25 +85,89 @@ def ExpressionToText(token): |
if token.value == 'double.NAN' or token.value == 'float.NAN': |
return 'float(\'nan\')'; |
- return token |
+ if token in ["true", "false"]: |
+ return str(token == "true") |
+ return token |
-def ComputeConstantValues(module): |
+def GetStructClass(kind): |
+ name = [] |
+ if kind.imported_from: |
+ name.append(kind.imported_from['python_module']) |
+ name.append(GetNameForElement(kind)) |
+ return '.'.join(name) |
+ |
+def GetFieldType(kind, field=None): |
+ if mojom.IsAnyArrayKind(kind): |
+ arguments = [ GetFieldType(kind.kind) ] |
+ if mojom.IsNullableKind(kind): |
+ arguments.append("nullable=True") |
+ if mojom.IsFixedArrayKind(kind): |
+ arguments.append("length=%d" % kind.length) |
+ return "_descriptor.ArrayType(%s)" % ", ".join(arguments) |
+ |
+ if mojom.IsStructKind(kind): |
+ arguments = [ GetStructClass(kind) ] |
+ if mojom.IsNullableKind(kind): |
+ arguments.append("nullable=True") |
+ return "_descriptor.StructType(%s)" % ", ".join(arguments) |
+ |
+ if mojom.IsEnumKind(kind): |
+ return GetFieldType(mojom.INT32) |
+ |
+ return _kind_to_type.get(kind, "_descriptor.TYPE_NONE") |
+ |
+def GetFieldDescriptor(packed_field): |
+ field = packed_field.field |
+ arguments = [ '\'%s\'' % field.name ] |
+ arguments.append(GetFieldType(field.kind, field)) |
+ arguments.append(str(packed_field.offset)) |
+ if field.kind == mojom.BOOL: |
+ arguments.append('bit_offset=%d' % packed_field.bit) |
+ if field.default: |
+ if mojom.IsStructKind(field.kind): |
+ arguments.append('default_value=True') |
+ else: |
+ arguments.append('default_value=%s' % ExpressionToText(field.default)) |
+ return '_descriptor.FieldDescriptor(%s)' % ', '.join(arguments) |
+ |
+def ComputeStaticValues(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) |
+ def GetComputedValue(named_value): |
+ if isinstance(named_value, mojom.EnumValue): |
+ field = next(ifilter(lambda field: field.name == named_value.name, |
+ named_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)) |
+ (named_value.name, named_value.enum.name)) |
if field not in computed: |
- ResolveEnum(enum_value.enum) |
+ ResolveEnum(named_value.enum) |
return field.computed_value |
+ elif isinstance(named_value, mojom.ConstantValue): |
+ ResolveConstant(named_value.constant) |
+ named_value.computed_value = named_value.constant.computed_value |
+ return named_value.computed_value |
+ else: |
+ print named_value |
+ |
+ def ResolveConstant(constant): |
+ if constant in computed: |
+ return |
+ if constant in in_progress: |
+ raise RuntimeError('Circular dependency for constant: %s' % constant.name) |
+ in_progress.add(constant) |
+ if isinstance(constant.value, (mojom.EnumValue, mojom.ConstantValue)): |
+ computed_value = GetComputedValue(constant.value) |
+ else: |
+ computed_value = ExpressionToText(constant.value) |
+ constant.computed_value = computed_value |
+ in_progress.remove(constant) |
+ computed.add(constant) |
+ def ResolveEnum(enum): |
def ResolveEnumField(enum, field, default_value): |
if field in computed: |
return |
@@ -98,7 +180,7 @@ def ComputeConstantValues(module): |
elif isinstance(field.value, str): |
computed_value = int(field.value, 0) |
else: |
- raise RuntimeError('Unexpected value: %r' % field.value) |
+ raise RuntimeError('Unexpected value: %s' % field.value) |
else: |
computed_value = default_value |
field.computed_value = computed_value |
@@ -110,12 +192,20 @@ def ComputeConstantValues(module): |
ResolveEnumField(enum, field, current_value) |
current_value = field.computed_value + 1 |
+ for constant in module.constants: |
+ ResolveConstant(constant) |
+ |
for enum in module.enums: |
ResolveEnum(enum) |
for struct in module.structs: |
+ for constant in struct.constants: |
+ ResolveConstant(constant) |
for enum in struct.enums: |
ResolveEnum(enum) |
+ for field in struct.fields: |
+ if isinstance(field.default, (mojom.ConstantValue, mojom.EnumValue)): |
+ field.default.computed_value = GetComputedValue(field.default) |
return module |
@@ -123,6 +213,7 @@ class Generator(generator.Generator): |
python_filters = { |
'expression_to_text': ExpressionToText, |
+ 'field_descriptor': GetFieldDescriptor, |
'name': GetNameForElement, |
} |
@@ -131,7 +222,7 @@ class Generator(generator.Generator): |
return { |
'imports': self.GetImports(), |
'enums': self.module.enums, |
- 'module': ComputeConstantValues(self.module), |
+ 'module': ComputeStaticValues(self.module), |
'structs': self.GetStructs(), |
} |