OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 2 # Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
3 # for details. All rights reserved. Use of this source code is governed by a | 3 # for details. All rights reserved. Use of this source code is governed by a |
4 # BSD-style license that can be found in the LICENSE file. | 4 # BSD-style license that can be found in the LICENSE file. |
5 | 5 |
6 """This module provides shared functionality for systems to generate | 6 """This module provides shared functionality for systems to generate |
7 Dart APIs from the IDL database.""" | 7 Dart APIs from the IDL database.""" |
8 | 8 |
9 import re | 9 import re |
10 | 10 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 # against dart:dom to load in a worker isolate. | 188 # against dart:dom to load in a worker isolate. |
189 return '*' + javascript_binding_name | 189 return '*' + javascript_binding_name |
190 | 190 |
191 | 191 |
192 def MatchSourceFilter(filter, thing): | 192 def MatchSourceFilter(filter, thing): |
193 if not filter: | 193 if not filter: |
194 return True | 194 return True |
195 else: | 195 else: |
196 return any(token in thing.annotations for token in filter) | 196 return any(token in thing.annotations for token in filter) |
197 | 197 |
198 def AnalyzeOperation(interface, operations): | |
199 """Makes operation calling convention decision for a set of overloads. | |
200 | 198 |
201 Returns: An OperationInfo object. | 199 # Given a list of overloaded arguments, render a dart argument. |
202 """ | 200 def _DartArg(args, interface): |
203 | |
204 # Zip together arguments from each overload by position, then convert | |
205 # to a dart argument. | |
206 | |
207 # Given a list of overloaded arguments, choose a suitable name. | 201 # Given a list of overloaded arguments, choose a suitable name. |
208 def OverloadedName(args): | 202 def OverloadedName(args): |
209 return '_OR_'.join(sorted(set(arg.id for arg in args))) | 203 return '_OR_'.join(sorted(set(arg.id for arg in args))) |
210 | 204 |
211 # Given a list of overloaded arguments, choose a suitable type. | 205 # Given a list of overloaded arguments, choose a suitable type. |
212 def OverloadedType(args): | 206 def OverloadedType(args): |
213 typeIds = sorted(set(arg.type.id for arg in args)) | 207 typeIds = sorted(set(arg.type.id for arg in args)) |
214 if len(typeIds) == 1: | 208 if len(typeIds) == 1: |
215 return typeIds[0] | 209 return typeIds[0] |
216 else: | 210 else: |
217 return TypeName(typeIds, interface) | 211 return TypeName(typeIds, interface) |
218 | 212 |
219 # Given a list of overloaded arguments, render a dart argument. | 213 filtered = filter(None, args) |
220 def DartArg(args): | 214 optional = any(not arg or arg.is_optional for arg in args) |
221 filtered = filter(None, args) | 215 type = OverloadedType(filtered) |
222 optional = any(not arg or arg.is_optional for arg in args) | 216 name = OverloadedName(filtered) |
223 type = OverloadedType(filtered) | 217 if optional: |
224 name = OverloadedName(filtered) | 218 return (name, type, 'null') |
225 if optional: | 219 else: |
226 return (name, type, 'null') | 220 return (name, type, None) |
227 else: | |
228 return (name, type, None) | |
229 | 221 |
230 args = map(lambda *args: DartArg(args), | 222 |
223 def AnalyzeOperation(interface, operations): | |
224 """Makes operation calling convention decision for a set of overloads. | |
225 | |
226 Returns: An OperationInfo object. | |
227 """ | |
228 | |
229 # Zip together arguments from each overload by position, then convert | |
230 # to a dart argument. | |
231 args = map(lambda *args: _DartArg(args, interface), | |
231 *(op.arguments for op in operations)) | 232 *(op.arguments for op in operations)) |
232 | 233 |
233 info = OperationInfo() | 234 info = OperationInfo() |
234 info.overloads = operations | 235 info.overloads = operations |
235 info.declared_name = operations[0].id | 236 info.declared_name = operations[0].id |
236 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) | 237 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) |
237 info.js_name = info.declared_name | 238 info.js_name = info.declared_name |
238 info.type_name = operations[0].type.id # TODO: widen. | 239 info.type_name = operations[0].type.id # TODO: widen. |
239 info.arg_infos = args | 240 info.arg_infos = args |
240 return info | 241 return info |
241 | 242 |
243 | |
244 def AnalyzeConstructor(interface): | |
245 """Returns an OperationInfo object for the constructor, or None if no COnstruc tor | |
vsm
2012/02/23 23:04:28
nit: line wrap, COnstructor -> Constructor
sra1
2012/02/24 00:35:05
Done.
| |
246 """ | |
247 def GetArgs(func_value): | |
248 return map(lambda arg: _DartArg([arg], interface), func_value.arguments) | |
249 | |
250 if 'Constructor' in interface.ext_attrs: | |
251 name = None | |
252 func_value = interface.ext_attrs.get('Constructor') | |
253 if func_value: | |
254 # [Constructor(param,...)] | |
255 args = GetArgs(func_value) # | |
vsm
2012/02/23 23:04:28
nit: extra # at eol
sra1
2012/02/24 00:35:05
Done.
| |
256 else: # [Constructor] | |
257 args = [] | |
258 else: | |
259 func_value = interface.ext_attrs.get('NamedConstructor') | |
260 if func_value: | |
261 name = func_value.id | |
262 args = GetArgs(func_value) | |
263 else: | |
264 return None | |
265 | |
266 info = OperationInfo() | |
267 info.overloads = None # [func_value] | |
268 info.declared_name = name | |
269 info.name = name | |
270 info.js_name = name | |
271 info.type_name = interface.id | |
272 info.arg_infos = args | |
273 return info | |
274 | |
275 | |
242 def RecognizeCallback(interface): | 276 def RecognizeCallback(interface): |
243 """Returns the info for the callback method if the interface smells like a | 277 """Returns the info for the callback method if the interface smells like a |
244 callback. | 278 callback. |
245 """ | 279 """ |
246 if 'Callback' not in interface.ext_attrs: return None | 280 if 'Callback' not in interface.ext_attrs: return None |
247 handlers = [op for op in interface.operations if op.id == 'handleEvent'] | 281 handlers = [op for op in interface.operations if op.id == 'handleEvent'] |
248 if not handlers: return None | 282 if not handlers: return None |
249 if not (handlers == interface.operations): return None | 283 if not (handlers == interface.operations): return None |
250 return AnalyzeOperation(interface, handlers) | 284 return AnalyzeOperation(interface, handlers) |
251 | 285 |
252 def IsDartListType(type): | 286 def IsDartListType(type): |
253 return type == 'List' or type.startswith('List<') | 287 return type == 'List' or type.startswith('List<') |
254 | 288 |
255 def IsDartCollectionType(type): | 289 def IsDartCollectionType(type): |
256 return IsDartListType(type) | 290 return IsDartListType(type) |
257 | 291 |
258 def FindMatchingAttribute(interface, attr1): | 292 def FindMatchingAttribute(interface, attr1): |
259 matches = [attr2 for attr2 in interface.attributes | 293 matches = [attr2 for attr2 in interface.attributes |
260 if attr1.id == attr2.id | 294 if attr1.id == attr2.id |
261 and attr1.is_fc_getter == attr2.is_fc_getter | 295 and attr1.is_fc_getter == attr2.is_fc_getter |
262 and attr1.is_fc_setter == attr2.is_fc_setter] | 296 and attr1.is_fc_setter == attr2.is_fc_setter] |
263 if matches: | 297 if matches: |
264 assert len(matches) == 1 | 298 assert len(matches) == 1 |
265 return matches[0] | 299 return matches[0] |
266 return None | 300 return None |
267 | 301 |
302 | |
268 class OperationInfo(object): | 303 class OperationInfo(object): |
269 """Holder for various derived information from a set of overloaded operations. | 304 """Holder for various derived information from a set of overloaded operations. |
270 | 305 |
271 Attributes: | 306 Attributes: |
272 overloads: A list of IDL operation overloads with the same name. | 307 overloads: A list of IDL operation overloads with the same name. |
273 name: A string, the simple name of the operation. | 308 name: A string, the simple name of the operation. |
274 type_name: A string, the name of the return type of the operation. | 309 type_name: A string, the name of the return type of the operation. |
275 arg_infos: A list of (name, type, default_value) tuples. | 310 arg_infos: A list of (name, type, default_value) tuples. |
276 default_value is None for mandatory arguments. | 311 default_value is None for mandatory arguments. |
277 """ | 312 """ |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
531 | 566 |
532 original_idl_types = { | 567 original_idl_types = { |
533 } | 568 } |
534 | 569 |
535 def GetIDLTypeInfo(idl_type): | 570 def GetIDLTypeInfo(idl_type): |
536 idl_type_name = original_idl_types.get(idl_type, idl_type.id) | 571 idl_type_name = original_idl_types.get(idl_type, idl_type.id) |
537 return GetIDLTypeInfoByName(idl_type_name) | 572 return GetIDLTypeInfoByName(idl_type_name) |
538 | 573 |
539 def GetIDLTypeInfoByName(idl_type_name): | 574 def GetIDLTypeInfoByName(idl_type_name): |
540 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) | 575 return _idl_type_registry.get(idl_type_name, IDLTypeInfo(idl_type_name)) |
OLD | NEW |