| OLD | NEW | 
|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be | 
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. | 
| 4 | 4 | 
| 5 """Generates Python source files from a mojom.Module.""" | 5 """Generates Python source files from a mojom.Module.""" | 
| 6 | 6 | 
| 7 import re | 7 import re | 
| 8 from itertools import ifilter | 8 from itertools import ifilter | 
| 9 | 9 | 
| 10 import mojom.generate.generator as generator | 10 import mojom.generate.generator as generator | 
| 11 import mojom.generate.module as mojom | 11 import mojom.generate.module as mojom | 
| 12 from mojom.generate.template_expander import UseJinja | 12 from mojom.generate.template_expander import UseJinja | 
| 13 | 13 | 
| 14 _kind_to_type = { | 14 _kind_to_type = { | 
| 15   mojom.BOOL:                  '_descriptor.TYPE_BOOL', | 15   mojom.BOOL:                  "_descriptor.TYPE_BOOL", | 
| 16   mojom.INT8:                  '_descriptor.TYPE_INT8', | 16   mojom.INT8:                  "_descriptor.TYPE_INT8", | 
| 17   mojom.UINT8:                 '_descriptor.TYPE_UINT8', | 17   mojom.UINT8:                 "_descriptor.TYPE_UINT8", | 
| 18   mojom.INT16:                 '_descriptor.TYPE_INT16', | 18   mojom.INT16:                 "_descriptor.TYPE_INT16", | 
| 19   mojom.UINT16:                '_descriptor.TYPE_UINT16', | 19   mojom.UINT16:                "_descriptor.TYPE_UINT16", | 
| 20   mojom.INT32:                 '_descriptor.TYPE_INT32', | 20   mojom.INT32:                 "_descriptor.TYPE_INT32", | 
| 21   mojom.UINT32:                '_descriptor.TYPE_UINT32', | 21   mojom.UINT32:                "_descriptor.TYPE_UINT32", | 
| 22   mojom.INT64:                 '_descriptor.TYPE_INT64', | 22   mojom.INT64:                 "_descriptor.TYPE_INT64", | 
| 23   mojom.UINT64:                '_descriptor.TYPE_UINT64', | 23   mojom.UINT64:                "_descriptor.TYPE_UINT64", | 
| 24   mojom.FLOAT:                 '_descriptor.TYPE_FLOAT', | 24   mojom.FLOAT:                 "_descriptor.TYPE_FLOAT", | 
| 25   mojom.DOUBLE:                '_descriptor.TYPE_DOUBLE', | 25   mojom.DOUBLE:                "_descriptor.TYPE_DOUBLE", | 
| 26   mojom.STRING:                '_descriptor.TYPE_STRING', | 26   mojom.STRING:                "_descriptor.TYPE_STRING", | 
| 27   mojom.NULLABLE_STRING:       '_descriptor.TYPE_NULLABLE_STRING', | 27   mojom.NULLABLE_STRING:       "_descriptor.TYPE_NULLABLE_STRING", | 
| 28   mojom.HANDLE:                '_descriptor.TYPE_HANDLE', | 28   mojom.HANDLE:                "_descriptor.TYPE_HANDLE", | 
| 29   mojom.DCPIPE:                '_descriptor.TYPE_HANDLE', | 29   mojom.DCPIPE:                "_descriptor.TYPE_HANDLE", | 
| 30   mojom.DPPIPE:                '_descriptor.TYPE_HANDLE', | 30   mojom.DPPIPE:                "_descriptor.TYPE_HANDLE", | 
| 31   mojom.MSGPIPE:               '_descriptor.TYPE_HANDLE', | 31   mojom.MSGPIPE:               "_descriptor.TYPE_HANDLE", | 
| 32   mojom.SHAREDBUFFER:          '_descriptor.TYPE_HANDLE', | 32   mojom.SHAREDBUFFER:          "_descriptor.TYPE_HANDLE", | 
| 33   mojom.NULLABLE_HANDLE:       '_descriptor.TYPE_NULLABLE_HANDLE', | 33   mojom.NULLABLE_HANDLE:       "_descriptor.TYPE_NULLABLE_HANDLE", | 
| 34   mojom.NULLABLE_DCPIPE:       '_descriptor.TYPE_NULLABLE_HANDLE', | 34   mojom.NULLABLE_DCPIPE:       "_descriptor.TYPE_NULLABLE_HANDLE", | 
| 35   mojom.NULLABLE_DPPIPE:       '_descriptor.TYPE_NULLABLE_HANDLE', | 35   mojom.NULLABLE_DPPIPE:       "_descriptor.TYPE_NULLABLE_HANDLE", | 
| 36   mojom.NULLABLE_MSGPIPE:      '_descriptor.TYPE_NULLABLE_HANDLE', | 36   mojom.NULLABLE_MSGPIPE:      "_descriptor.TYPE_NULLABLE_HANDLE", | 
| 37   mojom.NULLABLE_SHAREDBUFFER: '_descriptor.TYPE_NULLABLE_HANDLE', | 37   mojom.NULLABLE_SHAREDBUFFER: "_descriptor.TYPE_NULLABLE_HANDLE", | 
| 38 } | 38 } | 
| 39 | 39 | 
| 40 # int64 integers are not handled by array.array. int64/uint64 array are | 40 # int64 integers are not handled by array.array. int64/uint64 array are | 
| 41 # supported but storage is not optimized (ie. they are plain python list, not | 41 # supported but storage is not optimized (ie. they are plain python list, not | 
| 42 # array.array) | 42 # array.array) | 
| 43 _kind_to_typecode_for_native_array = { | 43 _kind_to_typecode = { | 
| 44   mojom.INT8:   'b', | 44   mojom.INT8:   "'b'", | 
| 45   mojom.UINT8:  'B', | 45   mojom.UINT8:  "'B'", | 
| 46   mojom.INT16:  'h', | 46   mojom.INT16:  "'h'", | 
| 47   mojom.UINT16: 'H', | 47   mojom.UINT16: "'H'", | 
| 48   mojom.INT32:  'i', | 48   mojom.INT32:  "'i'", | 
| 49   mojom.UINT32: 'I', | 49   mojom.UINT32: "'I'", | 
| 50   mojom.FLOAT:  'f', | 50   mojom.FLOAT:  "'f'", | 
| 51   mojom.DOUBLE: 'd', | 51   mojom.DOUBLE: "'d'", | 
| 52 } | 52 } | 
| 53 | 53 | 
| 54 _kind_to_typecode = dict(_kind_to_typecode_for_native_array) |  | 
| 55 _kind_to_typecode.update({ |  | 
| 56   mojom.INT64:                 'q', |  | 
| 57   mojom.UINT64:                'Q', |  | 
| 58   mojom.HANDLE:                'i', |  | 
| 59   mojom.DCPIPE:                'i', |  | 
| 60   mojom.DPPIPE:                'i', |  | 
| 61   mojom.MSGPIPE:               'i', |  | 
| 62   mojom.SHAREDBUFFER:          'i', |  | 
| 63   mojom.NULLABLE_HANDLE:       'i', |  | 
| 64   mojom.NULLABLE_DCPIPE:       'i', |  | 
| 65   mojom.NULLABLE_DPPIPE:       'i', |  | 
| 66   mojom.NULLABLE_MSGPIPE:      'i', |  | 
| 67   mojom.NULLABLE_SHAREDBUFFER: 'i', |  | 
| 68 }) |  | 
| 69 |  | 
| 70 | 54 | 
| 71 def NameToComponent(name): | 55 def NameToComponent(name): | 
| 72   # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> | 56   # insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar -> | 
| 73   # HTTP_Entry2_FooBar) | 57   # HTTP_Entry2_FooBar) | 
| 74   name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name) | 58   name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name) | 
| 75   # insert '_' between non upper and start of upper blocks (e.g., | 59   # insert '_' between non upper and start of upper blocks (e.g., | 
| 76   # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar) | 60   # HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar) | 
| 77   name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name) | 61   name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name) | 
| 78   return [x.lower() for x in name.split('_')] | 62   return [x.lower() for x in name.split('_')] | 
| 79 | 63 | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 108 | 92 | 
| 109   if isinstance(token, mojom.BuiltinValue): | 93   if isinstance(token, mojom.BuiltinValue): | 
| 110     if token.value == 'double.INFINITY' or token.value == 'float.INFINITY': | 94     if token.value == 'double.INFINITY' or token.value == 'float.INFINITY': | 
| 111       return 'float(\'inf\')'; | 95       return 'float(\'inf\')'; | 
| 112     if (token.value == 'double.NEGATIVE_INFINITY' or | 96     if (token.value == 'double.NEGATIVE_INFINITY' or | 
| 113         token.value == 'float.NEGATIVE_INFINITY'): | 97         token.value == 'float.NEGATIVE_INFINITY'): | 
| 114       return 'float(\'-inf\')' | 98       return 'float(\'-inf\')' | 
| 115     if token.value == 'double.NAN' or token.value == 'float.NAN': | 99     if token.value == 'double.NAN' or token.value == 'float.NAN': | 
| 116       return 'float(\'nan\')'; | 100       return 'float(\'nan\')'; | 
| 117 | 101 | 
| 118   if token in ['true', 'false']: | 102   if token in ["true", "false"]: | 
| 119     return str(token == 'true') | 103     return str(token == "true") | 
| 120 | 104 | 
| 121   return token | 105   return token | 
| 122 | 106 | 
| 123 def GetStructClass(kind): | 107 def GetStructClass(kind): | 
| 124   name = [] | 108   name = [] | 
| 125   if kind.imported_from: | 109   if kind.imported_from: | 
| 126     name.append(kind.imported_from['python_module']) | 110     name.append(kind.imported_from['python_module']) | 
| 127   name.append(GetNameForElement(kind)) | 111   name.append(GetNameForElement(kind)) | 
| 128   return '.'.join(name) | 112   return '.'.join(name) | 
| 129 | 113 | 
| 130 def GetFieldType(kind, field=None): | 114 def GetFieldType(kind, field=None): | 
| 131   if mojom.IsAnyArrayKind(kind): | 115   if mojom.IsAnyArrayKind(kind): | 
| 132     arguments = [] | 116     if kind.kind in _kind_to_typecode: | 
| 133     if kind.kind in _kind_to_typecode_for_native_array: | 117       arguments = [ _kind_to_typecode[kind.kind] ] | 
| 134       arguments.append('%r' %_kind_to_typecode_for_native_array[kind.kind]) | 118     else: | 
| 135     elif kind.kind != mojom.BOOL: | 119       arguments = [ GetFieldType(kind.kind) ] | 
| 136       arguments.append(GetFieldType(kind.kind)) |  | 
| 137     if mojom.IsNullableKind(kind): | 120     if mojom.IsNullableKind(kind): | 
| 138       arguments.append('nullable=True') | 121       arguments.append("nullable=True") | 
| 139     if mojom.IsFixedArrayKind(kind): | 122     if mojom.IsFixedArrayKind(kind): | 
| 140       arguments.append('length=%d' % kind.length) | 123       arguments.append("length=%d" % kind.length) | 
| 141     array_type = 'GenericArrayType' | 124     if kind.kind in _kind_to_typecode: | 
| 142     if kind.kind == mojom.BOOL: | 125       return "_descriptor.NativeArrayType(%s)" % ", ".join(arguments) | 
| 143       array_type = 'BooleanArrayType' | 126     else: | 
| 144     elif kind.kind in _kind_to_typecode_for_native_array: | 127       return "_descriptor.PointerArrayType(%s)" % ", ".join(arguments) | 
| 145       array_type = 'NativeArrayType' |  | 
| 146     return '_descriptor.%s(%s)' % (array_type, ', '.join(arguments)) |  | 
| 147 | 128 | 
| 148   if mojom.IsStructKind(kind): | 129   if mojom.IsStructKind(kind): | 
| 149     arguments = [ GetStructClass(kind) ] | 130     arguments = [ GetStructClass(kind) ] | 
| 150     if mojom.IsNullableKind(kind): | 131     if mojom.IsNullableKind(kind): | 
| 151       arguments.append('nullable=True') | 132       arguments.append("nullable=True") | 
| 152     return '_descriptor.StructType(%s)' % ', '.join(arguments) | 133     return "_descriptor.StructType(%s)" % ", ".join(arguments) | 
| 153 | 134 | 
| 154   if mojom.IsEnumKind(kind): | 135   if mojom.IsEnumKind(kind): | 
| 155     return GetFieldType(mojom.INT32) | 136     return GetFieldType(mojom.INT32) | 
| 156 | 137 | 
| 157   return _kind_to_type.get(kind, '_descriptor.TYPE_NONE') | 138   return _kind_to_type.get(kind, "_descriptor.TYPE_NONE") | 
| 158 | 139 | 
| 159 def GetFieldDescriptor(packed_field): | 140 def GetFieldDescriptor(packed_field): | 
| 160   field = packed_field.field | 141   field = packed_field.field | 
| 161   class_name = 'SingleFieldGroup' | 142   arguments = [ '\'%s\'' % field.name ] | 
|  | 143   arguments.append(GetFieldType(field.kind, field)) | 
|  | 144   arguments.append(str(packed_field.offset)) | 
| 162   if field.kind == mojom.BOOL: | 145   if field.kind == mojom.BOOL: | 
| 163     class_name = 'FieldDescriptor' | 146     arguments.append('bit_offset=%d' % packed_field.bit) | 
| 164   arguments = [ '%r' % field.name ] |  | 
| 165   arguments.append(GetFieldType(field.kind, field)) |  | 
| 166   arguments.append(str(packed_field.field.ordinal)) |  | 
| 167   if field.default: | 147   if field.default: | 
| 168     if mojom.IsStructKind(field.kind): | 148     if mojom.IsStructKind(field.kind): | 
| 169       arguments.append('default_value=True') | 149       arguments.append('default_value=True') | 
| 170     else: | 150     else: | 
| 171       arguments.append('default_value=%s' % ExpressionToText(field.default)) | 151       arguments.append('default_value=%s' % ExpressionToText(field.default)) | 
| 172   return '_descriptor.%s(%s)' % (class_name, ', '.join(arguments)) | 152   return '_descriptor.FieldDescriptor(%s)' % ', '.join(arguments) | 
| 173 |  | 
| 174 def GetFieldGroup(byte): |  | 
| 175   if len(byte.packed_fields) > 1: |  | 
| 176     descriptors = map(GetFieldDescriptor, byte.packed_fields) |  | 
| 177     return '_descriptor.BooleanGroup([%s])' % ', '.join(descriptors) |  | 
| 178   assert len(byte.packed_fields) == 1 |  | 
| 179   return GetFieldDescriptor(byte.packed_fields[0]) |  | 
| 180 | 153 | 
| 181 def ComputeStaticValues(module): | 154 def ComputeStaticValues(module): | 
| 182   in_progress = set() | 155   in_progress = set() | 
| 183   computed = set() | 156   computed = set() | 
| 184 | 157 | 
| 185   def GetComputedValue(named_value): | 158   def GetComputedValue(named_value): | 
| 186     if isinstance(named_value, mojom.EnumValue): | 159     if isinstance(named_value, mojom.EnumValue): | 
| 187       field = next(ifilter(lambda field: field.name == named_value.name, | 160       field = next(ifilter(lambda field: field.name == named_value.name, | 
| 188                            named_value.enum.fields), None) | 161                            named_value.enum.fields), None) | 
| 189       if not field: | 162       if not field: | 
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 249     for constant in struct.constants: | 222     for constant in struct.constants: | 
| 250       ResolveConstant(constant) | 223       ResolveConstant(constant) | 
| 251     for enum in struct.enums: | 224     for enum in struct.enums: | 
| 252       ResolveEnum(enum) | 225       ResolveEnum(enum) | 
| 253     for field in struct.fields: | 226     for field in struct.fields: | 
| 254       if isinstance(field.default, (mojom.ConstantValue, mojom.EnumValue)): | 227       if isinstance(field.default, (mojom.ConstantValue, mojom.EnumValue)): | 
| 255         field.default.computed_value = GetComputedValue(field.default) | 228         field.default.computed_value = GetComputedValue(field.default) | 
| 256 | 229 | 
| 257   return module | 230   return module | 
| 258 | 231 | 
| 259 |  | 
| 260 class Generator(generator.Generator): | 232 class Generator(generator.Generator): | 
| 261 | 233 | 
| 262   python_filters = { | 234   python_filters = { | 
| 263     'expression_to_text': ExpressionToText, | 235     'expression_to_text': ExpressionToText, | 
| 264     'field_group': GetFieldGroup, | 236     'field_descriptor': GetFieldDescriptor, | 
| 265     'name': GetNameForElement, | 237     'name': GetNameForElement, | 
| 266   } | 238   } | 
| 267 | 239 | 
| 268   @UseJinja('python_templates/module.py.tmpl', filters=python_filters) | 240   @UseJinja('python_templates/module.py.tmpl', filters=python_filters) | 
| 269   def GeneratePythonModule(self): | 241   def GeneratePythonModule(self): | 
| 270     return { | 242     return { | 
| 271       'imports': self.GetImports(), | 243       'imports': self.GetImports(), | 
| 272       'enums': self.module.enums, | 244       'enums': self.module.enums, | 
| 273       'module': ComputeStaticValues(self.module), | 245       'module': ComputeStaticValues(self.module), | 
| 274       'structs': self.GetStructs(), | 246       'structs': self.GetStructs(), | 
| 275     } | 247     } | 
| 276 | 248 | 
| 277   def GenerateFiles(self, args): | 249   def GenerateFiles(self, args): | 
| 278     self.Write(self.GeneratePythonModule(), | 250     self.Write(self.GeneratePythonModule(), | 
| 279                '%s.py' % self.module.name.replace('.mojom', '_mojom')) | 251                '%s.py' % self.module.name.replace('.mojom', '_mojom')) | 
| 280 | 252 | 
| 281   def GetImports(self): | 253   def GetImports(self): | 
| 282     for each in self.module.imports: | 254     for each in self.module.imports: | 
| 283       each['python_module'] = each['module_name'].replace('.mojom', '_mojom') | 255       each['python_module'] = each['module_name'].replace('.mojom', '_mojom') | 
| 284     return self.module.imports | 256     return self.module.imports | 
| 285 | 257 | 
| 286   def GetJinjaParameters(self): | 258   def GetJinjaParameters(self): | 
| 287     return { | 259     return { | 
| 288       'lstrip_blocks': True, | 260       'lstrip_blocks': True, | 
| 289       'trim_blocks': True, | 261       'trim_blocks': True, | 
| 290     } | 262     } | 
| OLD | NEW | 
|---|