Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(777)

Side by Side Diff: mojo/public/tools/bindings/pylib/mojom/generate/data.py

Issue 268363003: Mojo: Add support for constants to the IDL compiler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: JS export constants Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 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 # TODO(vtl): "data" is a pretty vague name. Rename it? 5 # TODO(vtl): "data" is a pretty vague name. Rename it?
6 6
7 import copy 7 import copy
8 8
9 import module as mojom 9 import module as mojom
10 10
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 test_spec = 'x:' 58 test_spec = 'x:'
59 if i > 0: 59 if i > 0:
60 test_spec += '.'.join(scope[:i]) + '.' 60 test_spec += '.'.join(scope[:i]) + '.'
61 test_spec += name 61 test_spec += name
62 kind = kinds.get(test_spec) 62 kind = kinds.get(test_spec)
63 if kind: 63 if kind:
64 return kind 64 return kind
65 65
66 return kinds.get(spec) 66 return kinds.get(spec)
67 67
68 def LookupConstant(constants, name, scope): 68 def LookupValue(values, name, scope):
69 """Like LookupKind, but for constants.""" 69 """Like LookupKind, but for constant values."""
70 for i in xrange(len(scope), -1, -1): 70 for i in xrange(len(scope), -1, -1):
71 if i > 0: 71 if i > 0:
72 test_spec = '.'.join(scope[:i]) + '.' 72 test_spec = '.'.join(scope[:i]) + '.'
73 test_spec += name 73 test_spec += name
74 constant = constants.get(test_spec) 74 value = values.get(test_spec)
75 if constant: 75 if value:
76 return constant 76 return value
77 77
78 return constants.get(name) 78 return values.get(name)
79 79
80 def KindToData(kind): 80 def KindToData(kind):
81 return kind.spec 81 return kind.spec
82 82
83 def KindFromData(kinds, data, scope): 83 def KindFromData(kinds, data, scope):
84 kind = LookupKind(kinds, data, scope) 84 kind = LookupKind(kinds, data, scope)
85 if kind: 85 if kind:
86 return kind 86 return kind
87 if data.startswith('a:'): 87 if data.startswith('a:'):
88 kind = mojom.Array() 88 kind = mojom.Array()
(...skipping 18 matching lines...) Expand all
107 import_item['module_name'] = import_module.name 107 import_item['module_name'] = import_module.name
108 import_item['namespace'] = import_module.namespace 108 import_item['namespace'] = import_module.namespace
109 import_item['module'] = import_module 109 import_item['module'] = import_module
110 110
111 # Copy the struct kinds from our imports into the current module. 111 # Copy the struct kinds from our imports into the current module.
112 for kind in import_module.kinds.itervalues(): 112 for kind in import_module.kinds.itervalues():
113 if (isinstance(kind, (mojom.Struct, mojom.Enum)) and 113 if (isinstance(kind, (mojom.Struct, mojom.Enum)) and
114 kind.imported_from is None): 114 kind.imported_from is None):
115 kind = KindFromImport(kind, import_item) 115 kind = KindFromImport(kind, import_item)
116 module.kinds[kind.spec] = kind 116 module.kinds[kind.spec] = kind
117 # Ditto for constants. 117 # Ditto for values.
118 for constant in import_module.constants.itervalues(): 118 for value in import_module.values.itervalues():
119 if constant.imported_from is None: 119 if value.imported_from is None:
120 constant = copy.deepcopy(constant) 120 value = copy.deepcopy(value)
121 constant.imported_from = import_item 121 value.imported_from = import_item
122 module.constants[constant.GetSpec()] = constant 122 module.values[value.GetSpec()] = value
123 123
124 return import_item 124 return import_item
125 125
126 def StructToData(struct): 126 def StructToData(struct):
127 return { 127 return {
128 istr(0, 'name'): struct.name, 128 istr(0, 'name'): struct.name,
129 istr(1, 'fields'): map(FieldToData, struct.fields) 129 istr(1, 'fields'): map(FieldToData, struct.fields)
130 } 130 }
131 131
132 def StructFromData(module, data): 132 def StructFromData(module, data):
133 struct = mojom.Struct(module=module) 133 struct = mojom.Struct(module=module)
134 struct.name = data['name'] 134 struct.name = data['name']
135 struct.attributes = data['attributes'] 135 struct.attributes = data['attributes']
136 struct.spec = 'x:' + module.namespace + '.' + struct.name 136 struct.spec = 'x:' + module.namespace + '.' + struct.name
137 module.kinds[struct.spec] = struct 137 module.kinds[struct.spec] = struct
138 struct.enums = map(lambda enum: 138 struct.enums = map(lambda enum:
139 EnumFromData(module, enum, struct), data['enums']) 139 EnumFromData(module, enum, struct), data['enums'])
140 struct.constants = map(lambda constant:
141 ConstantFromData(module, constant, struct), data['constants'])
140 # Stash fields data here temporarily. 142 # Stash fields data here temporarily.
141 struct.fields_data = data['fields'] 143 struct.fields_data = data['fields']
142 return struct 144 return struct
143 145
144 def FieldToData(field): 146 def FieldToData(field):
145 data = { 147 data = {
146 istr(0, 'name'): field.name, 148 istr(0, 'name'): field.name,
147 istr(1, 'kind'): KindToData(field.kind) 149 istr(1, 'kind'): KindToData(field.kind)
148 } 150 }
149 if field.ordinal != None: 151 if field.ordinal != None:
150 data[istr(2, 'ordinal')] = field.ordinal 152 data[istr(2, 'ordinal')] = field.ordinal
151 if field.default != None: 153 if field.default != None:
152 data[istr(3, 'default')] = field.default 154 data[istr(3, 'default')] = field.default
153 return data 155 return data
154 156
155 def FixupExpression(module, value, scope): 157 def FixupExpression(module, value, scope):
156 if isinstance(value, (tuple, list)): 158 if isinstance(value, (tuple, list)):
157 for i in xrange(len(value)): 159 for i in xrange(len(value)):
158 if isinstance(value, tuple): 160 if isinstance(value, tuple):
159 FixupExpression(module, value[i], scope) 161 FixupExpression(module, value[i], scope)
160 else: 162 else:
161 value[i] = FixupExpression(module, value[i], scope) 163 value[i] = FixupExpression(module, value[i], scope)
162 elif value: 164 elif value:
163 constant = LookupConstant(module.constants, value, scope) 165 result = LookupValue(module.values, value, scope)
164 if constant: 166 if result:
165 return constant 167 return result
166 return value 168 return value
167 169
168 def FieldFromData(module, data, struct): 170 def FieldFromData(module, data, struct):
169 field = mojom.Field() 171 field = mojom.Field()
170 field.name = data['name'] 172 field.name = data['name']
171 field.kind = KindFromData( 173 field.kind = KindFromData(
172 module.kinds, data['kind'], (module.namespace, struct.name)) 174 module.kinds, data['kind'], (module.namespace, struct.name))
173 field.ordinal = data.get('ordinal') 175 field.ordinal = data.get('ordinal')
174 field.default = FixupExpression( 176 field.default = FixupExpression(
175 module, data.get('default'), (module.namespace, struct.name)) 177 module, data.get('default'), (module.namespace, struct.name))
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 } 230 }
229 231
230 def InterfaceFromData(module, data): 232 def InterfaceFromData(module, data):
231 interface = mojom.Interface(module=module) 233 interface = mojom.Interface(module=module)
232 interface.name = data['name'] 234 interface.name = data['name']
233 interface.spec = 'x:' + module.namespace + '.' + interface.name 235 interface.spec = 'x:' + module.namespace + '.' + interface.name
234 interface.peer = data['peer'] if data.has_key('peer') else None 236 interface.peer = data['peer'] if data.has_key('peer') else None
235 module.kinds[interface.spec] = interface 237 module.kinds[interface.spec] = interface
236 interface.enums = map(lambda enum: 238 interface.enums = map(lambda enum:
237 EnumFromData(module, enum, interface), data['enums']) 239 EnumFromData(module, enum, interface), data['enums'])
240 interface.constants = map(lambda constant:
241 ConstantFromData(module, constant, interface), data['constants'])
238 # Stash methods data here temporarily. 242 # Stash methods data here temporarily.
239 interface.methods_data = data['methods'] 243 interface.methods_data = data['methods']
240 return interface 244 return interface
241 245
242 def EnumFieldFromData(module, enum, data, parent_kind): 246 def EnumFieldFromData(module, enum, data, parent_kind):
243 field = mojom.EnumField() 247 field = mojom.EnumField()
244 field.name = data['name'] 248 field.name = data['name']
249 # TODO(mpcomplete): FixupExpression should be done in the second pass,
250 # so constants and enums can refer to each other.
251 # TODO(mpcomplete): But then, what if constants are initialized to an enum? Or
252 # vice versa?
245 if parent_kind: 253 if parent_kind:
246 field.value = FixupExpression( 254 field.value = FixupExpression(
247 module, data['value'], (module.namespace, parent_kind.name)) 255 module, data['value'], (module.namespace, parent_kind.name))
248 else: 256 else:
249 field.value = FixupExpression( 257 field.value = FixupExpression(
250 module, data['value'], (module.namespace, )) 258 module, data['value'], (module.namespace, ))
251 constant = mojom.Constant(module, enum, field) 259 value = mojom.EnumValue(module, enum, field)
252 module.constants[constant.GetSpec()] = constant 260 module.values[value.GetSpec()] = value
253 return field 261 return field
254 262
255 def EnumFromData(module, data, parent_kind): 263 def EnumFromData(module, data, parent_kind):
256 enum = mojom.Enum(module=module) 264 enum = mojom.Enum(module=module)
257 enum.name = data['name'] 265 enum.name = data['name']
258 name = enum.name 266 name = enum.name
259 if parent_kind: 267 if parent_kind:
260 name = parent_kind.name + '.' + name 268 name = parent_kind.name + '.' + name
261 enum.spec = 'x:%s.%s' % (module.namespace, name) 269 enum.spec = 'x:%s.%s' % (module.namespace, name)
262 enum.parent_kind = parent_kind 270 enum.parent_kind = parent_kind
263 271
264 enum.fields = map( 272 enum.fields = map(
265 lambda field: EnumFieldFromData(module, enum, field, parent_kind), 273 lambda field: EnumFieldFromData(module, enum, field, parent_kind),
266 data['fields']) 274 data['fields'])
267 module.kinds[enum.spec] = enum 275 module.kinds[enum.spec] = enum
268 return enum 276 return enum
269 277
278 def ConstantFromData(module, data, parent_kind):
279 constant = mojom.Constant()
280 constant.name = data['name']
281 if parent_kind:
282 scope = (module.namespace, parent_kind.name)
283 else:
284 scope = (module.namespace, )
285 # TODO(mpcomplete): maybe we should only support POD kinds.
286 constant.kind = KindFromData(module.kinds, data['kind'], scope)
287 constant.value = FixupExpression(module, data.get('value'), scope)
288
289 value = mojom.NamedValue(module, parent_kind, constant.name)
290 module.values[value.GetSpec()] = value
291 return constant
292
270 def ModuleToData(module): 293 def ModuleToData(module):
271 return { 294 return {
272 istr(0, 'name'): module.name, 295 istr(0, 'name'): module.name,
273 istr(1, 'namespace'): module.namespace, 296 istr(1, 'namespace'): module.namespace,
274 istr(2, 'structs'): map(StructToData, module.structs), 297 istr(2, 'structs'): map(StructToData, module.structs),
275 istr(3, 'interfaces'): map(InterfaceToData, module.interfaces) 298 istr(3, 'interfaces'): map(InterfaceToData, module.interfaces)
276 } 299 }
277 300
278 def ModuleFromData(data): 301 def ModuleFromData(data):
279 module = mojom.Module() 302 module = mojom.Module()
280 module.kinds = {} 303 module.kinds = {}
281 for kind in mojom.PRIMITIVES: 304 for kind in mojom.PRIMITIVES:
282 module.kinds[kind.spec] = kind 305 module.kinds[kind.spec] = kind
283 306
284 module.constants = {} 307 module.values = {}
285 308
286 module.name = data['name'] 309 module.name = data['name']
287 module.namespace = data['namespace'] 310 module.namespace = data['namespace']
288 module.attributes = data['attributes'] 311 module.attributes = data['attributes']
289 # Imports must come first, because they add to module.kinds which is used 312 # Imports must come first, because they add to module.kinds which is used
290 # by by the others. 313 # by by the others.
291 module.imports = map( 314 module.imports = map(
292 lambda import_data: ImportFromData(module, import_data), 315 lambda import_data: ImportFromData(module, import_data),
293 data['imports']) 316 data['imports'])
294 317
295 # First pass collects kinds. 318 # First pass collects kinds.
296 module.enums = map( 319 module.enums = map(
297 lambda enum: EnumFromData(module, enum, None), data['enums']) 320 lambda enum: EnumFromData(module, enum, None), data['enums'])
298 module.structs = map( 321 module.structs = map(
299 lambda struct: StructFromData(module, struct), data['structs']) 322 lambda struct: StructFromData(module, struct), data['structs'])
300 module.interfaces = map( 323 module.interfaces = map(
301 lambda interface: InterfaceFromData(module, interface), 324 lambda interface: InterfaceFromData(module, interface),
302 data['interfaces']) 325 data['interfaces'])
326 module.constants = map(
327 lambda constant: ConstantFromData(module, constant, None),
328 data['constants'])
303 329
304 # Second pass expands fields and methods. This allows fields and parameters 330 # Second pass expands fields and methods. This allows fields and parameters
305 # to refer to kinds defined anywhere in the mojom. 331 # to refer to kinds defined anywhere in the mojom.
306 for struct in module.structs: 332 for struct in module.structs:
307 struct.fields = map(lambda field: 333 struct.fields = map(lambda field:
308 FieldFromData(module, field, struct), struct.fields_data) 334 FieldFromData(module, field, struct), struct.fields_data)
309 del struct.fields_data 335 del struct.fields_data
310 for interface in module.interfaces: 336 for interface in module.interfaces:
311 interface.methods = map(lambda method: 337 interface.methods = map(lambda method:
312 MethodFromData(module, method, interface), interface.methods_data) 338 MethodFromData(module, method, interface), interface.methods_data)
313 del interface.methods_data 339 del interface.methods_data
314 340
315 return module 341 return module
316 342
317 def OrderedModuleFromData(data): 343 def OrderedModuleFromData(data):
318 module = ModuleFromData(data) 344 module = ModuleFromData(data)
319 next_interface_ordinal = 0 345 next_interface_ordinal = 0
320 for interface in module.interfaces: 346 for interface in module.interfaces:
321 next_ordinal = 0 347 next_ordinal = 0
322 for method in interface.methods: 348 for method in interface.methods:
323 if method.ordinal is None: 349 if method.ordinal is None:
324 method.ordinal = next_ordinal 350 method.ordinal = next_ordinal
325 next_ordinal = method.ordinal + 1 351 next_ordinal = method.ordinal + 1
326 return module 352 return module
OLDNEW
« no previous file with comments | « mojo/public/tools/bindings/generators/mojom_js_generator.py ('k') | mojo/public/tools/bindings/pylib/mojom/generate/module.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698