| 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 copy | 9 import copy |
| 10 import re | 10 import re |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 | 170 |
| 171 def Copy(self): | 171 def Copy(self): |
| 172 return ParamInfo(self.name, self.type_id, self.dart_type, self.is_optional) | 172 return ParamInfo(self.name, self.type_id, self.dart_type, self.is_optional) |
| 173 | 173 |
| 174 def __repr__(self): | 174 def __repr__(self): |
| 175 content = 'name = %s, type_id = %s, dart_type = %s, is_optional = %s' % ( | 175 content = 'name = %s, type_id = %s, dart_type = %s, is_optional = %s' % ( |
| 176 self.name, self.type_id, self.dart_type, self.is_optional) | 176 self.name, self.type_id, self.dart_type, self.is_optional) |
| 177 return '<ParamInfo(%s)>' % content | 177 return '<ParamInfo(%s)>' % content |
| 178 | 178 |
| 179 | 179 |
| 180 # Given a list of overloaded arguments, render a dart argument. | 180 # Given a list of overloaded arguments, render dart arguments. |
| 181 def _DartArg(args, interface, constructor=False): | 181 def _BuildArguments(args, interface, constructor=False): |
| 182 def IsOptional(argument): |
| 183 if 'Callback' in argument.ext_attrs: |
| 184 # Callbacks with 'Optional=XXX' are treated as optional arguments. |
| 185 return 'Optional' in argument.ext_attrs |
| 186 if constructor: |
| 187 # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as |
| 188 # optional arguments. |
| 189 return 'Optional' in argument.ext_attrs |
| 190 return False |
| 191 |
| 182 # Given a list of overloaded arguments, choose a suitable name. | 192 # Given a list of overloaded arguments, choose a suitable name. |
| 183 def OverloadedName(args): | 193 def OverloadedName(args): |
| 184 return '_OR_'.join(sorted(set(arg.id for arg in args))) | 194 return '_OR_'.join(sorted(set(arg.id for arg in args))) |
| 185 | 195 |
| 186 # Given a list of overloaded arguments, choose a suitable type. | 196 # Given a list of overloaded arguments, choose a suitable type. |
| 187 def OverloadedType(args): | 197 def OverloadedType(args): |
| 188 type_ids = sorted(set(arg.type.id for arg in args)) | 198 type_ids = sorted(set(arg.type.id for arg in args)) |
| 189 dart_types = sorted(set(DartType(arg.type.id) for arg in args)) | 199 dart_types = sorted(set(DartType(arg.type.id) for arg in args)) |
| 190 if len(dart_types) == 1: | 200 if len(dart_types) == 1: |
| 191 if len(type_ids) == 1: | 201 if len(type_ids) == 1: |
| 192 return (type_ids[0], type_ids[0]) | 202 return (type_ids[0], type_ids[0]) |
| 193 else: | 203 else: |
| 194 return (None, type_ids[0]) | 204 return (None, type_ids[0]) |
| 195 else: | 205 else: |
| 196 return (None, TypeName(type_ids, interface)) | 206 return (None, TypeName(type_ids, interface)) |
| 197 | 207 |
| 198 def IsOptional(argument): | 208 result = [] |
| 199 if not argument: | |
| 200 return True | |
| 201 if 'Callback' in argument.ext_attrs: | |
| 202 # Callbacks with 'Optional=XXX' are treated as optional arguments. | |
| 203 return 'Optional' in argument.ext_attrs | |
| 204 if constructor: | |
| 205 # FIXME: Constructors with 'Optional=XXX' shouldn't be treated as | |
| 206 # optional arguments. | |
| 207 return 'Optional' in argument.ext_attrs | |
| 208 return False | |
| 209 | 209 |
| 210 filtered = filter(None, args) | 210 is_optional = False |
| 211 is_optional = any(IsOptional(arg) for arg in args) | 211 for arg_tuple in map(lambda *x: x, *args): |
| 212 (type_id, dart_type) = OverloadedType(filtered) | 212 is_optional = is_optional or any(arg is None or IsOptional(arg) for arg in a
rg_tuple) |
| 213 name = OverloadedName(filtered) | 213 |
| 214 return ParamInfo(name, type_id, dart_type, is_optional) | 214 filtered = filter(None, arg_tuple) |
| 215 (type_id, dart_type) = OverloadedType(filtered) |
| 216 name = OverloadedName(filtered) |
| 217 result.append(ParamInfo(name, type_id, dart_type, is_optional)) |
| 218 |
| 219 return result |
| 215 | 220 |
| 216 def IsOptional(argument): | 221 def IsOptional(argument): |
| 217 return ('Optional' in argument.ext_attrs and | 222 return ('Optional' in argument.ext_attrs and |
| 218 argument.ext_attrs['Optional'] == None) | 223 argument.ext_attrs['Optional'] == None) |
| 219 | 224 |
| 220 def AnalyzeOperation(interface, operations): | 225 def AnalyzeOperation(interface, operations): |
| 221 """Makes operation calling convention decision for a set of overloads. | 226 """Makes operation calling convention decision for a set of overloads. |
| 222 | 227 |
| 223 Returns: An OperationInfo object. | 228 Returns: An OperationInfo object. |
| 224 """ | 229 """ |
| 225 | 230 |
| 226 # split operations with optional args into multiple operations | 231 # split operations with optional args into multiple operations |
| 227 split_operations = [] | 232 split_operations = [] |
| 228 for operation in operations: | 233 for operation in operations: |
| 229 for i in range(0, len(operation.arguments)): | 234 for i in range(0, len(operation.arguments)): |
| 230 if IsOptional(operation.arguments[i]): | 235 if IsOptional(operation.arguments[i]): |
| 231 new_operation = copy.deepcopy(operation) | 236 new_operation = copy.deepcopy(operation) |
| 232 new_operation.arguments = new_operation.arguments[:i] | 237 new_operation.arguments = new_operation.arguments[:i] |
| 233 split_operations.append(new_operation) | 238 split_operations.append(new_operation) |
| 234 split_operations.append(operation) | 239 split_operations.append(operation) |
| 235 | 240 |
| 236 # Zip together arguments from each overload by position, then convert | 241 # Zip together arguments from each overload by position, then convert |
| 237 # to a dart argument. | 242 # to a dart argument. |
| 238 args = map(lambda *args: _DartArg(args, interface), | |
| 239 *(op.arguments for op in split_operations)) | |
| 240 | |
| 241 info = OperationInfo() | 243 info = OperationInfo() |
| 242 info.operations = operations | 244 info.operations = operations |
| 243 info.overloads = split_operations | 245 info.overloads = split_operations |
| 244 info.declared_name = operations[0].id | 246 info.declared_name = operations[0].id |
| 245 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) | 247 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) |
| 246 info.constructor_name = None | 248 info.constructor_name = None |
| 247 info.js_name = info.declared_name | 249 info.js_name = info.declared_name |
| 248 info.type_name = operations[0].type.id # TODO: widen. | 250 info.type_name = operations[0].type.id # TODO: widen. |
| 249 info.param_infos = args | 251 info.param_infos = _BuildArguments([op.arguments for op in split_operations],
interface) |
| 250 return info | 252 return info |
| 251 | 253 |
| 252 | 254 |
| 253 def AnalyzeConstructor(interface): | 255 def AnalyzeConstructor(interface): |
| 254 """Returns an OperationInfo object for the constructor. | 256 """Returns an OperationInfo object for the constructor. |
| 255 | 257 |
| 256 Returns None if the interface has no Constructor. | 258 Returns None if the interface has no Constructor. |
| 257 """ | 259 """ |
| 258 def GetArgs(func_value): | |
| 259 return map(lambda arg: _DartArg([arg], interface, True), | |
| 260 func_value.arguments) | |
| 261 | |
| 262 if 'Constructor' in interface.ext_attrs: | 260 if 'Constructor' in interface.ext_attrs: |
| 263 name = None | 261 name = None |
| 264 func_value = interface.ext_attrs.get('Constructor') | 262 func_value = interface.ext_attrs.get('Constructor') |
| 265 if func_value: | 263 if not func_value: |
| 266 # [Constructor(param,...)] | |
| 267 args = GetArgs(func_value) | |
| 268 idl_args = func_value.arguments | |
| 269 else: # [Constructor] | |
| 270 args = [] | 264 args = [] |
| 271 idl_args = [] | 265 idl_args = [] |
| 266 elif 'NamedConstructor' in interface.ext_attrs: |
| 267 func_value = interface.ext_attrs.get('NamedConstructor') |
| 268 name = func_value.id |
| 272 else: | 269 else: |
| 273 func_value = interface.ext_attrs.get('NamedConstructor') | 270 return None |
| 274 if func_value: | 271 |
| 275 name = func_value.id | 272 if func_value: |
| 276 args = GetArgs(func_value) | 273 idl_args = func_value.arguments |
| 277 idl_args = func_value.arguments | 274 args =_BuildArguments([idl_args], interface, True) |
| 278 else: | |
| 279 return None | |
| 280 | 275 |
| 281 info = OperationInfo() | 276 info = OperationInfo() |
| 282 info.overloads = None | 277 info.overloads = None |
| 283 info.idl_args = idl_args | 278 info.idl_args = idl_args |
| 284 info.declared_name = name | 279 info.declared_name = name |
| 285 info.name = name | 280 info.name = name |
| 286 info.constructor_name = None | 281 info.constructor_name = None |
| 287 info.js_name = name | 282 info.js_name = name |
| 288 info.type_name = interface.id | 283 info.type_name = interface.id |
| 289 info.param_infos = args | 284 info.param_infos = args |
| (...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 874 if match: | 869 if match: |
| 875 if type_name == 'DOMString[]': | 870 if type_name == 'DOMString[]': |
| 876 return DOMStringArrayTypeInfo(TypeData('Sequence'), self.TypeInfo('DOMSt
ring')) | 871 return DOMStringArrayTypeInfo(TypeData('Sequence'), self.TypeInfo('DOMSt
ring')) |
| 877 item_info = self.TypeInfo(match.group(1) or match.group(2)) | 872 item_info = self.TypeInfo(match.group(1) or match.group(2)) |
| 878 return SequenceIDLTypeInfo(type_name, TypeData('Sequence'), item_info) | 873 return SequenceIDLTypeInfo(type_name, TypeData('Sequence'), item_info) |
| 879 if not type_name in _idl_type_registry: | 874 if not type_name in _idl_type_registry: |
| 880 return InterfaceIDLTypeInfo(type_name, TypeData('Interface')) | 875 return InterfaceIDLTypeInfo(type_name, TypeData('Interface')) |
| 881 type_data = _idl_type_registry.get(type_name) | 876 type_data = _idl_type_registry.get(type_name) |
| 882 class_name = '%sIDLTypeInfo' % type_data.clazz | 877 class_name = '%sIDLTypeInfo' % type_data.clazz |
| 883 return globals()[class_name](type_name, type_data) | 878 return globals()[class_name](type_name, type_data) |
| OLD | NEW |