OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 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 |
| 4 # BSD-style license that can be found in the LICENSE file. |
| 5 |
| 6 """This module provides base functionality for systems to generate |
| 7 Dart APIs from the IDL database.""" |
| 8 |
| 9 import os |
| 10 import re |
| 11 |
| 12 # IDL->Dart primitive types conversion. |
| 13 _idl_to_dart_type_conversions = { |
| 14 'any': 'Object', |
| 15 'any[]': 'List', |
| 16 'custom': 'Dynamic', |
| 17 'boolean': 'bool', |
| 18 'DOMObject': 'Object', |
| 19 'DOMString': 'String', |
| 20 'DOMStringList': 'List<String>', |
| 21 'DOMTimeStamp': 'int', |
| 22 'Date': 'Date', |
| 23 # Map to num to enable callers to pass in Dart int, rational |
| 24 # types. Our implementations will need to convert these to |
| 25 # doubles or floats as needed. |
| 26 'double': 'num', |
| 27 'float': 'num', |
| 28 'int': 'int', |
| 29 # Map to extra precision - int is a bignum in Dart. |
| 30 'long': 'int', |
| 31 'long long': 'int', |
| 32 'object': 'Object', |
| 33 # Map to extra precision - int is a bignum in Dart. |
| 34 'short': 'int', |
| 35 'string': 'String', |
| 36 'void': 'void', |
| 37 'Array': 'List', |
| 38 'sequence': 'List', |
| 39 # TODO(sra): Come up with some meaningful name so that where this appears in |
| 40 # the documentation, the user is made aware that only a limited subset of |
| 41 # serializable types are actually permitted. |
| 42 'SerializedScriptValue': 'Dynamic', |
| 43 # TODO(vsm): Automatically recognize types defined in src. |
| 44 'TimeoutHandler': 'TimeoutHandler', |
| 45 'RequestAnimationFrameCallback': 'RequestAnimationFrameCallback', |
| 46 |
| 47 # TODO(sra): Flags is really a dictionary: {create:bool, exclusive:bool} |
| 48 # http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#the-flags-interfa
ce |
| 49 'WebKitFlags': 'Object', |
| 50 } |
| 51 |
| 52 _dart_to_idl_type_conversions = dict((v,k) for k, v in |
| 53 _idl_to_dart_type_conversions.iteritems()) |
| 54 |
| 55 # |
| 56 # Identifiers that are used in the IDL than need to be treated specially because |
| 57 # *some* JavaScript processors forbid them as properties. |
| 58 # |
| 59 _javascript_keywords = ['delete', 'continue'] |
| 60 |
| 61 # |
| 62 # Interface version of the DOM needs to delegate typed array constructors to a |
| 63 # factory provider. |
| 64 # |
| 65 interface_factories = { |
| 66 'Float32Array': '_TypedArrayFactoryProvider', |
| 67 'Float64Array': '_TypedArrayFactoryProvider', |
| 68 'Int8Array': '_TypedArrayFactoryProvider', |
| 69 'Int16Array': '_TypedArrayFactoryProvider', |
| 70 'Int32Array': '_TypedArrayFactoryProvider', |
| 71 'Uint8Array': '_TypedArrayFactoryProvider', |
| 72 'Uint16Array': '_TypedArrayFactoryProvider', |
| 73 'Uint32Array': '_TypedArrayFactoryProvider', |
| 74 'Uint8ClampedArray': '_TypedArrayFactoryProvider', |
| 75 } |
| 76 |
| 77 # |
| 78 # Custom methods that must be implemented by hand. |
| 79 # |
| 80 _custom_methods = set([ |
| 81 ('DOMWindow', 'setInterval'), |
| 82 ('DOMWindow', 'setTimeout'), |
| 83 ('WorkerContext', 'setInterval'), |
| 84 ('WorkerContext', 'setTimeout'), |
| 85 ('CanvasRenderingContext2D', 'setFillStyle'), |
| 86 ('CanvasRenderingContext2D', 'setStrokeStyle'), |
| 87 ('CanvasRenderingContext2D', 'setFillStyle'), |
| 88 ]) |
| 89 |
| 90 # |
| 91 # Custom getters that must be implemented by hand. |
| 92 # |
| 93 _custom_getters = set([ |
| 94 ('DOMWindow', 'localStorage'), |
| 95 ]) |
| 96 |
| 97 # |
| 98 # Custom native specs for the Frog dom. |
| 99 # |
| 100 _frog_dom_custom_native_specs = { |
| 101 # Decorate the singleton Console object, if present (workers do not have a |
| 102 # console). |
| 103 'Console': "=(typeof console == 'undefined' ? {} : console)", |
| 104 |
| 105 # DOMWindow aliased with global scope. |
| 106 'DOMWindow': '@*DOMWindow', |
| 107 } |
| 108 |
| 109 # |
| 110 # Simple method substitution when one method had different names on different |
| 111 # browsers, but are otherwise identical. The alternates are tried in order and |
| 112 # the first one defined is used. |
| 113 # |
| 114 # This can be probably be removed when Chrome renames initWebKitWheelEvent to |
| 115 # initWheelEvent. |
| 116 # |
| 117 _alternate_methods = { |
| 118 ('WheelEvent', 'initWheelEvent'): ['initWebKitWheelEvent', 'initWheelEvent'] |
| 119 } |
| 120 |
| 121 def ConvertPrimitiveType(type_name): |
| 122 if type_name.startswith('unsigned '): |
| 123 type_name = type_name[len('unsigned '):] |
| 124 |
| 125 if type_name in _idl_to_dart_type_conversions: |
| 126 # Primitive type conversion |
| 127 return _idl_to_dart_type_conversions[type_name] |
| 128 return None |
| 129 |
| 130 def IsPrimitiveType(type_name): |
| 131 return (ConvertPrimitiveType(type_name) is not None or |
| 132 type_name in _dart_to_idl_type_conversions) |
| 133 |
| 134 def MaybeListElementTypeName(type_name): |
| 135 """Returns the List element type T from string of form "List<T>", or None.""" |
| 136 match = re.match(r'List<(\w*)>$', type_name) |
| 137 if match: |
| 138 return match.group(1) |
| 139 return None |
| 140 |
| 141 def MaybeListElementType(interface): |
| 142 """Returns the List element type T, or None in interface does not implement |
| 143 List<T>. |
| 144 """ |
| 145 for parent in interface.parents: |
| 146 element_type = MaybeListElementTypeName(parent.type.id) |
| 147 if element_type: |
| 148 return element_type |
| 149 return None |
| 150 |
| 151 def MaybeTypedArrayElementType(interface): |
| 152 """Returns the typed array element type, or None in interface is not a |
| 153 TypedArray. |
| 154 """ |
| 155 # Typed arrays implement ArrayBufferView and List<T>. |
| 156 for parent in interface.parents: |
| 157 if parent.type.id == 'ArrayBufferView': |
| 158 return MaybeListElementType(interface) |
| 159 if parent.type.id == 'Uint8Array': |
| 160 return 'int' |
| 161 return None |
| 162 |
| 163 def MakeNativeSpec(javascript_binding_name): |
| 164 if javascript_binding_name in _frog_dom_custom_native_specs: |
| 165 return _frog_dom_custom_native_specs[javascript_binding_name] |
| 166 else: |
| 167 # Make the class 'hidden' so it is dynamically patched at runtime. This |
| 168 # is useful not only for browser compat, but to allow code that links |
| 169 # against dart:dom to load in a worker isolate. |
| 170 return '*' + javascript_binding_name |
| 171 |
| 172 |
| 173 def MatchSourceFilter(filter, thing): |
| 174 if not filter: |
| 175 return True |
| 176 else: |
| 177 return any(token in thing.annotations for token in filter) |
| 178 |
| 179 def AnalyzeOperation(interface, operations): |
| 180 """Makes operation calling convention decision for a set of overloads. |
| 181 |
| 182 Returns: An OperationInfo object. |
| 183 """ |
| 184 |
| 185 # Zip together arguments from each overload by position, then convert |
| 186 # to a dart argument. |
| 187 |
| 188 # Given a list of overloaded arguments, choose a suitable name. |
| 189 def OverloadedName(args): |
| 190 return '_OR_'.join(sorted(set(arg.id for arg in args))) |
| 191 |
| 192 # Given a list of overloaded arguments, choose a suitable type. |
| 193 def OverloadedType(args): |
| 194 typeIds = sorted(set(arg.type.id for arg in args)) |
| 195 if len(typeIds) == 1: |
| 196 return typeIds[0] |
| 197 else: |
| 198 return TypeName(typeIds, interface) |
| 199 |
| 200 # Given a list of overloaded arguments, render a dart argument. |
| 201 def DartArg(args): |
| 202 filtered = filter(None, args) |
| 203 optional = any(not arg or arg.is_optional for arg in args) |
| 204 type = OverloadedType(filtered) |
| 205 name = OverloadedName(filtered) |
| 206 if optional: |
| 207 return (name, type, 'null') |
| 208 else: |
| 209 return (name, type, None) |
| 210 |
| 211 args = map(lambda *args: DartArg(args), |
| 212 *(op.arguments for op in operations)) |
| 213 |
| 214 info = OperationInfo() |
| 215 info.overloads = operations |
| 216 info.declared_name = operations[0].id |
| 217 info.name = operations[0].ext_attrs.get('DartName', info.declared_name) |
| 218 info.js_name = info.declared_name |
| 219 info.type_name = operations[0].type.id # TODO: widen. |
| 220 info.arg_infos = args |
| 221 return info |
| 222 |
| 223 def RecognizeCallback(interface): |
| 224 """Returns the info for the callback method if the interface smells like a |
| 225 callback. |
| 226 """ |
| 227 if 'Callback' not in interface.ext_attrs: return None |
| 228 handlers = [op for op in interface.operations if op.id == 'handleEvent'] |
| 229 if not handlers: return None |
| 230 if not (handlers == interface.operations): return None |
| 231 return AnalyzeOperation(interface, handlers) |
| 232 |
| 233 def IsDartListType(type): |
| 234 return type == 'List' or type.startswith('List<') |
| 235 |
| 236 def IsDartCollectionType(type): |
| 237 return IsDartListType(type) |
| 238 |
| 239 def FindMatchingAttribute(interface, attr1): |
| 240 matches = [attr2 for attr2 in interface.attributes |
| 241 if attr1.id == attr2.id |
| 242 and attr1.is_fc_getter == attr2.is_fc_getter |
| 243 and attr1.is_fc_setter == attr2.is_fc_setter] |
| 244 if matches: |
| 245 assert len(matches) == 1 |
| 246 return matches[0] |
| 247 return None |
| 248 |
| 249 class OperationInfo(object): |
| 250 """Holder for various derived information from a set of overloaded operations. |
| 251 |
| 252 Attributes: |
| 253 overloads: A list of IDL operation overloads with the same name. |
| 254 name: A string, the simple name of the operation. |
| 255 type_name: A string, the name of the return type of the operation. |
| 256 arg_infos: A list of (name, type, default_value) tuples. |
| 257 default_value is None for mandatory arguments. |
| 258 """ |
| 259 |
| 260 def ParametersInterfaceDeclaration(self): |
| 261 """Returns a formatted string declaring the parameters for the interface.""" |
| 262 return self._FormatArgs(self.arg_infos, True) |
| 263 |
| 264 def ParametersImplementationDeclaration(self, rename_type=None): |
| 265 """Returns a formatted string declaring the parameters for the |
| 266 implementation. |
| 267 |
| 268 Args: |
| 269 rename_type: A function that allows the types to be renamed. |
| 270 """ |
| 271 args = self.arg_infos |
| 272 if rename_type: |
| 273 args = [(name, rename_type(type), default) |
| 274 for (name, type, default) in args] |
| 275 return self._FormatArgs(args, False) |
| 276 |
| 277 def ParametersAsArgumentList(self): |
| 278 """Returns a formatted string declaring the parameters names as an argument |
| 279 list. |
| 280 """ |
| 281 return ', '.join(map(lambda arg_info: arg_info[0], self.arg_infos)) |
| 282 |
| 283 def _FormatArgs(self, args, is_interface): |
| 284 def FormatArg(arg_info): |
| 285 """Returns an argument declaration fragment for an argument info tuple.""" |
| 286 (name, type, default) = arg_info |
| 287 if default: |
| 288 return '%s %s = %s' % (type, name, default) |
| 289 else: |
| 290 return '%s %s' % (type, name) |
| 291 |
| 292 required = [] |
| 293 optional = [] |
| 294 for (name, type, default) in args: |
| 295 if default: |
| 296 if is_interface: |
| 297 optional.append((name, type, None)) # Default values illegal. |
| 298 else: |
| 299 optional.append((name, type, default)) |
| 300 else: |
| 301 if optional: |
| 302 raise Exception('Optional arguments cannot precede required ones: ' |
| 303 + str(args)) |
| 304 required.append((name, type, None)) |
| 305 argtexts = map(FormatArg, required) |
| 306 if optional: |
| 307 argtexts.append('[' + ', '.join(map(FormatArg, optional)) + ']') |
| 308 return ', '.join(argtexts) |
| 309 |
| 310 |
| 311 def AttributeOutputOrder(a, b): |
| 312 """Canonical output ordering for attributes.""" |
| 313 # Getters before setters: |
| 314 if a.id < b.id: return -1 |
| 315 if a.id > b.id: return 1 |
| 316 if a.is_fc_setter < b.is_fc_setter: return -1 |
| 317 if a.is_fc_setter > b.is_fc_setter: return 1 |
| 318 return 0 |
| 319 |
| 320 def ConstantOutputOrder(a, b): |
| 321 """Canonical output ordering for constants.""" |
| 322 if a.id < b.id: return -1 |
| 323 if a.id > b.id: return 1 |
| 324 return 0 |
| 325 |
| 326 |
| 327 def _FormatNameList(names): |
| 328 """Returns JavaScript array literal expression with one name per line.""" |
| 329 #names = sorted(names) |
| 330 if len(names) <= 1: |
| 331 expression_string = str(names) # e.g. ['length'] |
| 332 else: |
| 333 expression_string = ',\n '.join(str(names).split(',')) |
| 334 expression_string = expression_string.replace('[', '[\n ') |
| 335 return expression_string |
| 336 |
| 337 |
| 338 def IndentText(text, indent): |
| 339 """Format lines of text with indent.""" |
| 340 def FormatLine(line): |
| 341 if line.strip(): |
| 342 return '%s%s\n' % (indent, line) |
| 343 else: |
| 344 return '\n' |
| 345 return ''.join(FormatLine(line) for line in text.split('\n')) |
| 346 |
| 347 class System(object): |
| 348 """Generates all the files for one implementation.""" |
| 349 |
| 350 def __init__(self, templates, database, emitters, output_dir): |
| 351 self._templates = templates |
| 352 self._database = database |
| 353 self._emitters = emitters |
| 354 self._output_dir = output_dir |
| 355 self._dart_callback_file_paths = [] |
| 356 |
| 357 def InterfaceGenerator(self, |
| 358 interface, |
| 359 common_prefix, |
| 360 super_interface_name, |
| 361 source_filter): |
| 362 """Returns an interface generator for |interface|.""" |
| 363 return None |
| 364 |
| 365 def ProcessCallback(self, interface, info): |
| 366 pass |
| 367 |
| 368 def GenerateLibraries(self, lib_dir): |
| 369 pass |
| 370 |
| 371 def Finish(self): |
| 372 pass |
| 373 |
| 374 |
| 375 def _ProcessCallback(self, interface, info, file_path): |
| 376 """Generates a typedef for the callback interface.""" |
| 377 self._dart_callback_file_paths.append(file_path) |
| 378 code = self._emitters.FileEmitter(file_path) |
| 379 |
| 380 code.Emit(self._templates.Load('callback.darttemplate')) |
| 381 code.Emit('typedef $TYPE $NAME($PARAMS);\n', |
| 382 NAME=interface.id, |
| 383 TYPE=info.type_name, |
| 384 PARAMS=info.ParametersImplementationDeclaration()) |
| 385 |
| 386 def _GenerateLibFile(self, lib_template, lib_file_path, file_paths, |
| 387 **template_args): |
| 388 """Generates a lib file from a template and a list of files. |
| 389 |
| 390 Additional keyword arguments are passed to the template. |
| 391 """ |
| 392 # Load template. |
| 393 template = self._templates.Load(lib_template) |
| 394 # Generate the .lib file. |
| 395 lib_file_contents = self._emitters.FileEmitter(lib_file_path) |
| 396 |
| 397 # Emit the list of #source directives. |
| 398 list_emitter = lib_file_contents.Emit(template, **template_args) |
| 399 lib_file_dir = os.path.dirname(lib_file_path) |
| 400 for path in sorted(file_paths): |
| 401 relpath = os.path.relpath(path, lib_file_dir) |
| 402 list_emitter.Emit("#source('$PATH');\n", PATH=relpath) |
| 403 |
| 404 |
| 405 def _BaseDefines(self, interface): |
| 406 """Returns a set of names (strings) for members defined in a base class. |
| 407 """ |
| 408 def WalkParentChain(interface): |
| 409 if interface.parents: |
| 410 # Only consider primary parent, secondary parents are not on the |
| 411 # implementation class inheritance chain. |
| 412 parent = interface.parents[0] |
| 413 if IsDartCollectionType(parent.type.id): |
| 414 return |
| 415 if self._database.HasInterface(parent.type.id): |
| 416 parent_interface = self._database.GetInterface(parent.type.id) |
| 417 for attr in parent_interface.attributes: |
| 418 result.add(attr.id) |
| 419 for op in parent_interface.operations: |
| 420 result.add(op.id) |
| 421 WalkParentChain(parent_interface) |
| 422 |
| 423 result = set() |
| 424 WalkParentChain(interface) |
| 425 return result; |
| 426 |
| 427 |
| 428 # ------------------------------------------------------------------------------ |
| 429 |
| 430 class InterfacesSystem(System): |
| 431 |
| 432 def __init__(self, templates, database, emitters, output_dir): |
| 433 super(InterfacesSystem, self).__init__( |
| 434 templates, database, emitters, output_dir) |
| 435 self._dart_interface_file_paths = [] |
| 436 |
| 437 |
| 438 def InterfaceGenerator(self, |
| 439 interface, |
| 440 common_prefix, |
| 441 super_interface_name, |
| 442 source_filter): |
| 443 """.""" |
| 444 interface_name = interface.id |
| 445 dart_interface_file_path = self._FilePathForDartInterface(interface_name) |
| 446 |
| 447 self._dart_interface_file_paths.append(dart_interface_file_path) |
| 448 |
| 449 dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path) |
| 450 |
| 451 template_file = 'interface_%s.darttemplate' % interface_name |
| 452 template = self._templates.TryLoad(template_file) |
| 453 if not template: |
| 454 template = self._templates.Load('interface.darttemplate') |
| 455 |
| 456 return DartInterfaceGenerator( |
| 457 interface, dart_interface_code, |
| 458 template, |
| 459 common_prefix, super_interface_name, |
| 460 source_filter) |
| 461 |
| 462 def ProcessCallback(self, interface, info): |
| 463 """Generates a typedef for the callback interface.""" |
| 464 interface_name = interface.id |
| 465 file_path = self._FilePathForDartInterface(interface_name) |
| 466 self._ProcessCallback(interface, info, file_path) |
| 467 |
| 468 def GenerateLibraries(self, lib_dir): |
| 469 pass |
| 470 |
| 471 |
| 472 def _FilePathForDartInterface(self, interface_name): |
| 473 """Returns the file path of the Dart interface definition.""" |
| 474 return os.path.join(self._output_dir, 'src', 'interface', |
| 475 '%s.dart' % interface_name) |
| 476 |
| 477 # ------------------------------------------------------------------------------ |
| 478 |
| 479 class DartInterfaceGenerator(object): |
| 480 """Generates Dart Interface definition for one DOM IDL interface.""" |
| 481 |
| 482 def __init__(self, interface, emitter, template, |
| 483 common_prefix, super_interface, source_filter): |
| 484 """Generates Dart code for the given interface. |
| 485 |
| 486 Args: |
| 487 interface -- an IDLInterface instance. It is assumed that all types have |
| 488 been converted to Dart types (e.g. int, String), unless they are in the |
| 489 same package as the interface. |
| 490 common_prefix -- the prefix for the common library, if any. |
| 491 super_interface -- the name of the common interface that this interface |
| 492 implements, if any. |
| 493 source_filter -- if specified, rewrites the names of any superinterfaces |
| 494 that are not from these sources to use the common prefix. |
| 495 """ |
| 496 self._interface = interface |
| 497 self._emitter = emitter |
| 498 self._template = template |
| 499 self._common_prefix = common_prefix |
| 500 self._super_interface = super_interface |
| 501 self._source_filter = source_filter |
| 502 |
| 503 |
| 504 def StartInterface(self): |
| 505 if self._super_interface: |
| 506 typename = self._super_interface |
| 507 else: |
| 508 typename = self._interface.id |
| 509 |
| 510 |
| 511 extends = [] |
| 512 suppressed_extends = [] |
| 513 |
| 514 for parent in self._interface.parents: |
| 515 # TODO(vsm): Remove source_filter. |
| 516 if MatchSourceFilter(self._source_filter, parent): |
| 517 # Parent is a DOM type. |
| 518 extends.append(parent.type.id) |
| 519 elif '<' in parent.type.id: |
| 520 # Parent is a Dart collection type. |
| 521 # TODO(vsm): Make this check more robust. |
| 522 extends.append(parent.type.id) |
| 523 else: |
| 524 suppressed_extends.append('%s.%s' % |
| 525 (self._common_prefix, parent.type.id)) |
| 526 |
| 527 comment = ' extends' |
| 528 extends_str = '' |
| 529 if extends: |
| 530 extends_str += ' extends ' + ', '.join(extends) |
| 531 comment = ',' |
| 532 if suppressed_extends: |
| 533 extends_str += ' /*%s %s */' % (comment, ', '.join(suppressed_extends)) |
| 534 |
| 535 if typename in interface_factories: |
| 536 extends_str += ' default ' + interface_factories[typename] |
| 537 |
| 538 # TODO(vsm): Add appropriate package / namespace syntax. |
| 539 (self._members_emitter, |
| 540 self._top_level_emitter) = self._emitter.Emit( |
| 541 self._template + '$!TOP_LEVEL', |
| 542 ID=typename, |
| 543 EXTENDS=extends_str) |
| 544 |
| 545 element_type = MaybeTypedArrayElementType(self._interface) |
| 546 if element_type: |
| 547 self._members_emitter.Emit( |
| 548 '\n' |
| 549 ' $CTOR(int length);\n' |
| 550 '\n' |
| 551 ' $CTOR.fromList(List<$TYPE> list);\n' |
| 552 '\n' |
| 553 ' $CTOR.fromBuffer(ArrayBuffer buffer);\n', |
| 554 CTOR=self._interface.id, |
| 555 TYPE=element_type) |
| 556 |
| 557 |
| 558 def FinishInterface(self): |
| 559 # TODO(vsm): Use typedef if / when that is supported in Dart. |
| 560 # Define variant as subtype. |
| 561 if (self._super_interface and |
| 562 self._interface.id is not self._super_interface): |
| 563 consts_emitter = self._top_level_emitter.Emit( |
| 564 '\n' |
| 565 'interface $NAME extends $BASE {\n' |
| 566 '$!CONSTS' |
| 567 '}\n', |
| 568 NAME=self._interface.id, |
| 569 BASE=self._super_interface) |
| 570 for const in sorted(self._interface.constants, ConstantOutputOrder): |
| 571 self._EmitConstant(consts_emitter, const) |
| 572 |
| 573 def AddConstant(self, constant): |
| 574 if (not self._super_interface or |
| 575 self._interface.id is self._super_interface): |
| 576 self._EmitConstant(self._members_emitter, constant) |
| 577 |
| 578 def _EmitConstant(self, emitter, constant): |
| 579 emitter.Emit('\n static final $TYPE $NAME = $VALUE;\n', |
| 580 NAME=constant.id, |
| 581 TYPE=constant.type.id, |
| 582 VALUE=constant.value) |
| 583 |
| 584 def AddAttribute(self, getter, setter): |
| 585 if getter and setter and getter.type.id == setter.type.id: |
| 586 self._members_emitter.Emit('\n $TYPE $NAME;\n', |
| 587 NAME=getter.id, TYPE=getter.type.id); |
| 588 return |
| 589 if getter and not setter: |
| 590 self._members_emitter.Emit('\n final $TYPE $NAME;\n', |
| 591 NAME=getter.id, TYPE=getter.type.id); |
| 592 return |
| 593 raise Exception('Unexpected getter/setter combination %s %s' % |
| 594 (getter, setter)) |
| 595 |
| 596 def AddIndexer(self, element_type): |
| 597 # Interface inherits all operations from List<element_type>. |
| 598 pass |
| 599 |
| 600 def AddOperation(self, info): |
| 601 """ |
| 602 Arguments: |
| 603 operations - contains the overloads, one or more operations with the same |
| 604 name. |
| 605 """ |
| 606 self._members_emitter.Emit('\n' |
| 607 ' $TYPE $NAME($PARAMS);\n', |
| 608 TYPE=info.type_name, |
| 609 NAME=info.name, |
| 610 PARAMS=info.ParametersInterfaceDeclaration()) |
| 611 |
| 612 # Interfaces get secondary members directly via the superinterfaces. |
| 613 def AddSecondaryAttribute(self, interface, getter, setter): |
| 614 pass |
| 615 |
| 616 def AddSecondaryOperation(self, interface, attr): |
| 617 pass |
| 618 |
| 619 def AddEventAttributes(self, event_attrs): |
| 620 pass |
| 621 |
| 622 # Given a sorted sequence of type identifiers, return an appropriate type |
| 623 # name |
| 624 def TypeName(typeIds, interface): |
| 625 # Dynamically type this field for now. |
| 626 return 'var' |
| 627 |
| 628 # ------------------------------------------------------------------------------ |
| 629 |
| 630 class DummyInterfaceGenerator(object): |
| 631 """Generates nothing.""" |
| 632 |
| 633 def __init__(self, system, interface): |
| 634 pass |
| 635 |
| 636 def StartInterface(self): |
| 637 pass |
| 638 |
| 639 def FinishInterface(self): |
| 640 pass |
| 641 |
| 642 def AddConstant(self, constant): |
| 643 pass |
| 644 |
| 645 def AddAttribute(self, getter, setter): |
| 646 pass |
| 647 |
| 648 def AddSecondaryAttribute(self, interface, getter, setter): |
| 649 pass |
| 650 |
| 651 def AddSecondaryOperation(self, interface, info): |
| 652 pass |
| 653 |
| 654 def AddIndexer(self, element_type): |
| 655 pass |
| 656 |
| 657 def AddTypedArrayConstructors(self, element_type): |
| 658 pass |
| 659 |
| 660 def AddOperation(self, info): |
| 661 pass |
| 662 |
| 663 def AddEventAttributes(self, event_attrs): |
| 664 pass |
| 665 |
OLD | NEW |