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

Side by Side Diff: client/dom/scripts/dartgenerator.py

Issue 8889001: Implement typed array constructors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: comment Created 9 years 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
« no previous file with comments | « client/dom/idl/dart/dart.idl ('k') | client/dom/scripts/template_frog_dom.darttemplate » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2011, 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 generates Dart APIs from the IDL database.""" 6 """This module generates Dart APIs from the IDL database."""
7 7
8 import emitter 8 import emitter
9 import idlnode 9 import idlnode
10 import logging 10 import logging
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 'FileReader': '', 74 'FileReader': '',
75 'XMLHttpRequest': '', 75 'XMLHttpRequest': '',
76 'WebKitCSSMatrix': '[String spec]', 76 'WebKitCSSMatrix': '[String spec]',
77 'WebKitPoint': 'num x, num y', 77 'WebKitPoint': 'num x, num y',
78 # dart:html types 78 # dart:html types
79 'CSSMatrix': '[String spec]', 79 'CSSMatrix': '[String spec]',
80 'Point': 'num x, num y', 80 'Point': 'num x, num y',
81 } 81 }
82 82
83 # 83 #
84 # Interface version of the DOM needs to delegate typed array constructors to a
85 # factory provider.
86 #
87 _interface_factories = {
88 'Float32Array': '_TypedArrayFactoryProvider',
89 'Float64Array': '_TypedArrayFactoryProvider',
90 'Int8Array': '_TypedArrayFactoryProvider',
91 'Int16Array': '_TypedArrayFactoryProvider',
92 'Int32Array': '_TypedArrayFactoryProvider',
93 'Uint8Array': '_TypedArrayFactoryProvider',
94 'Uint16Array': '_TypedArrayFactoryProvider',
95 'Uint32Array': '_TypedArrayFactoryProvider',
96 }
97
98 #
84 # Custom methods that must be implemented by hand. 99 # Custom methods that must be implemented by hand.
85 # 100 #
86 _custom_methods = set([ 101 _custom_methods = set([
87 ('DOMWindow', 'setInterval'), 102 ('DOMWindow', 'setInterval'),
88 ('DOMWindow', 'setTimeout'), 103 ('DOMWindow', 'setTimeout'),
89 ('WorkerContext', 'setInterval'), 104 ('WorkerContext', 'setInterval'),
90 ('WorkerContext', 'setTimeout'), 105 ('WorkerContext', 'setTimeout'),
91 ('CanvasRenderingContext2D', 'setFillStyle'), 106 ('CanvasRenderingContext2D', 'setFillStyle'),
92 ('CanvasRenderingContext2D', 'setStrokeStyle'), 107 ('CanvasRenderingContext2D', 'setStrokeStyle'),
93 ('CanvasRenderingContext2D', 'setFillStyle'), 108 ('CanvasRenderingContext2D', 'setFillStyle'),
94 ]) 109 ])
95 110
96 # 111 #
97 # Custom getters that must be implemented by hand. 112 # Custom getters that must be implemented by hand.
98 # 113 #
99 _custom_getters = set([ 114 _custom_getters = set([
100 ('DOMWindow', 'localStorage'), 115 ('DOMWindow', 'localStorage'),
101 ]) 116 ])
102 117
103 # 118 #
104 # Custom native specs for the Frog dom. 119 # Custom native specs for the Frog dom.
105 # 120 #
106 _frog_dom_custom_native_specs = { 121 _frog_dom_custom_native_specs = {
107 'Console': '=console', # Decorate the singleton Console object. 122 'Console': '=console', # Decorate the singleton Console object.
108 'DOMWindow': '@*DOMWindow', # DOMWindow aliased with global scope. 123 'DOMWindow': '@*DOMWindow', # DOMWindow aliased with global scope.
124
125 # Temporary hack: make these not be 'hidden'. Will not work on IE9.
126 'Float32Array': 'Float32Array',
127 'Float64Array': 'Float64Array',
128 'Int8Array': 'Int8Array',
129 'Int16Array': 'Int16Array',
130 'Int32Array': 'Int32Array',
131 'Uint8Array': 'Uint8Array',
132 'Uint16Array': 'Uint16Array',
133 'Uint32Array': 'Uint32Array',
109 } 134 }
110 135
111 # 136 #
112 # Publically visible types common across all supported browsers. 137 # Publically visible types common across all supported browsers.
113 # 138 #
114 _BROWSER_SHARED_TYPES = [ 139 _BROWSER_SHARED_TYPES = [
115 'Attr', 140 'Attr',
116 'CDATASection', 141 'CDATASection',
117 'CSSFontFaceRule', 142 'CSSFontFaceRule',
118 'CSSImportRule', 143 'CSSImportRule',
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 if attr.type.id == 'EventListener': continue 728 if attr.type.id == 'EventListener': continue
704 if attr.is_fc_getter: 729 if attr.is_fc_getter:
705 for generator in generators: 730 for generator in generators:
706 generator.AddGetter(attr) 731 generator.AddGetter(attr)
707 elif attr.is_fc_setter: 732 elif attr.is_fc_setter:
708 for generator in generators: 733 for generator in generators:
709 generator.AddSetter(attr) 734 generator.AddSetter(attr)
710 735
711 # The implementation should define an indexer if the interface directly 736 # The implementation should define an indexer if the interface directly
712 # extends List. 737 # extends List.
713 for parent in interface.parents: 738 element_type = MaybeListElementType(interface)
714 match = re.match(r'List<(\w*)>$', parent.type.id) 739 if element_type:
715 if match: 740 for generator in generators:
716 element_type = match.group(1) 741 generator.AddIndexer(element_type)
717 for generator in generators:
718 generator.AddIndexer(element_type)
719 break
720 742
721 # Group overloaded operations by id 743 # Group overloaded operations by id
722 operationsById = {} 744 operationsById = {}
723 for operation in interface.operations: 745 for operation in interface.operations:
724 if operation.id not in operationsById: 746 if operation.id not in operationsById:
725 operationsById[operation.id] = [] 747 operationsById[operation.id] = []
726 operationsById[operation.id].append(operation) 748 operationsById[operation.id].append(operation)
727 749
728 # Generate operations 750 # Generate operations
729 for id in sorted(operationsById.keys()): 751 for id in sorted(operationsById.keys()):
730 operations = operationsById[id] 752 operations = operationsById[id]
731 info = self._AnalyzeOperation(interface, operations) 753 info = self._AnalyzeOperation(interface, operations)
732 for generator in generators: 754 for generator in generators:
733 generator.AddOperation(info) 755 generator.AddOperation(info)
734 756
735 # With multiple inheritance, attributes and operations of non-first 757 # With multiple inheritance, attributes and operations of non-first
736 # interfaces need to be added. Sometimes the attribute or operation is 758 # interfaces need to be added. Sometimes the attribute or operation is
737 # defined in the current interface as well as a parent. In that case we 759 # defined in the current interface as well as a parent. In that case we
738 # avoid making a duplicate definition and pray that the signatures match. 760 # avoid making a duplicate definition and pray that the signatures match.
739 761
740 for parent_interface in self._TransitiveSecondaryParents(interface): 762 for parent_interface in self._TransitiveSecondaryParents(interface):
741 if isinstance(interface, str): # _IsDartCollectionType(parent_interface) 763 if isinstance(parent_interface, str): # _IsDartCollectionType(parent_inte rface)
742 continue 764 continue
743 attributes = sorted(parent_interface.attributes, 765 attributes = sorted(parent_interface.attributes,
744 AttributeOutputOrder) 766 AttributeOutputOrder)
745 for attr in attributes: 767 for attr in attributes:
746 if not self._DefinesSameAttribute(interface, attr): 768 if not self._DefinesSameAttribute(interface, attr):
747 if attr.is_fc_getter: 769 if attr.is_fc_getter:
748 for generator in generators: 770 for generator in generators:
749 generator.AddSecondaryGetter(parent_interface, attr) 771 generator.AddSecondaryGetter(parent_interface, attr)
750 elif attr.is_fc_setter: 772 elif attr.is_fc_setter:
751 for generator in generators: 773 for generator in generators:
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 type_name: A string, the name of the return type of the operation. 1314 type_name: A string, the name of the return type of the operation.
1293 arg_declarations: A list of strings, Dart argument declarations for the 1315 arg_declarations: A list of strings, Dart argument declarations for the
1294 member that implements the set of overloads. Each string is of the form 1316 member that implements the set of overloads. Each string is of the form
1295 "T arg" or "T arg = null". 1317 "T arg" or "T arg = null".
1296 arg_infos: A list of (name, type, default_value) tuples. 1318 arg_infos: A list of (name, type, default_value) tuples.
1297 default_value is None for mandatory arguments. 1319 default_value is None for mandatory arguments.
1298 """ 1320 """
1299 pass 1321 pass
1300 1322
1301 1323
1324 def MaybeListElementType(interface):
1325 """Returns the List element type T, or None in interface does not implement
1326 List<T>.
1327 """
1328 for parent in interface.parents:
1329 match = re.match(r'List<(\w*)>$', parent.type.id)
1330 if match:
1331 return match.group(1)
1332 return None
1333
1334 def MaybeTypedArrayElementType(interface):
1335 """Returns the typed array element type, or None in interface is not a
1336 TypedArray.
1337 """
1338 # Typed arrays implement ArrayBufferView and List<T>.
1339 for parent in interface.parents:
1340 if parent.type.id == 'ArrayBufferView':
1341 return MaybeListElementType(interface)
1342 return None
1343
1344
1302 def AttributeOutputOrder(a, b): 1345 def AttributeOutputOrder(a, b):
1303 """Canonical output ordering for attributes.""" 1346 """Canonical output ordering for attributes."""
1304 # Getters before setters: 1347 # Getters before setters:
1305 if a.id < b.id: return -1 1348 if a.id < b.id: return -1
1306 if a.id > b.id: return 1 1349 if a.id > b.id: return 1
1307 if a.is_fc_setter < b.is_fc_setter: return -1 1350 if a.is_fc_setter < b.is_fc_setter: return -1
1308 if a.is_fc_setter > b.is_fc_setter: return 1 1351 if a.is_fc_setter > b.is_fc_setter: return 1
1309 return 0 1352 return 0
1310 1353
1311 def ConstantOutputOrder(a, b): 1354 def ConstantOutputOrder(a, b):
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 1439
1397 comment = ' extends' 1440 comment = ' extends'
1398 if extends: 1441 if extends:
1399 extends_emitter.Emit(' extends $SUPERS', SUPERS=', '.join(extends)) 1442 extends_emitter.Emit(' extends $SUPERS', SUPERS=', '.join(extends))
1400 comment = ',' 1443 comment = ','
1401 if suppressed_extends: 1444 if suppressed_extends:
1402 extends_emitter.Emit(' /*$COMMENT $SUPERS */', 1445 extends_emitter.Emit(' /*$COMMENT $SUPERS */',
1403 COMMENT=comment, 1446 COMMENT=comment,
1404 SUPERS=', '.join(suppressed_extends)) 1447 SUPERS=', '.join(suppressed_extends))
1405 1448
1449 if typename in _interface_factories:
1450 extends_emitter.Emit(' factory $F', F=_interface_factories[typename])
1451
1452 element_type = MaybeTypedArrayElementType(self._interface)
1453 if element_type:
1454 self._members_emitter.Emit(
1455 '\n'
1456 ' $CTOR(int length);\n'
1457 '\n'
1458 ' $CTOR.fromList(List<$TYPE> list);\n'
1459 '\n'
1460 ' $CTOR.fromBuffer(ArrayBuffer buffer);\n',
1461 CTOR=self._interface.id,
1462 TYPE=element_type)
1463
1464
1406 def FinishInterface(self): 1465 def FinishInterface(self):
1407 # Write snippet text that was inlined in the IDL. 1466 # Write snippet text that was inlined in the IDL.
1408 for snippet in self._interface.snippets: 1467 for snippet in self._interface.snippets:
1409 self._members_emitter.Emit('\n$LINES', 1468 self._members_emitter.Emit('\n$LINES',
1410 LINES=IndentText(snippets.text, ' ')) 1469 LINES=IndentText(snippets.text, ' '))
1411 1470
1412 # TODO(vsm): Test if snippets are extra methods or extra types. 1471 # TODO(vsm): Test if snippets are extra methods or extra types.
1413 # Since Dart doesn't permit inner types, append after the interface. 1472 # Since Dart doesn't permit inner types, append after the interface.
1414 # Consider moving these types to auxilary classes instead. 1473 # Consider moving these types to auxilary classes instead.
1415 if self._extra_snippets is not None: 1474 if self._extra_snippets is not None:
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 if not [op for op in interface.operations if op.id == 'addEventListener' ]: 2324 if not [op for op in interface.operations if op.id == 'addEventListener' ]:
2266 base = self._ImplClassName(supertype) 2325 base = self._ImplClassName(supertype)
2267 else: 2326 else:
2268 base = self._ImplClassName(supertype) 2327 base = self._ImplClassName(supertype)
2269 2328
2270 if base: 2329 if base:
2271 extends = " extends " + base 2330 extends = " extends " + base
2272 else: 2331 else:
2273 extends = "" 2332 extends = ""
2274 2333
2275 if interface_name in _constructable_types.keys():
2276 parameters = _constructable_types[interface_name]
2277 constructor = ' %s(%s) native;\n\n' % (interface_name, parameters)
2278 else:
2279 constructor = ''
2280
2281 if interface_name in _frog_dom_custom_native_specs: 2334 if interface_name in _frog_dom_custom_native_specs:
2282 native_spec = _frog_dom_custom_native_specs[interface_name] 2335 native_spec = _frog_dom_custom_native_specs[interface_name]
2283 else: 2336 else:
2284 # Is the type's constructor accessible from the global scope? If so, we 2337 # Is the type's JavaScript constructor accessible from the global scope?
2285 # can directly patch the prototype. We don't really want to do this yet 2338 # If so, we can directly patch the prototype. We don't really want to do
2286 # because the dynamic patching mechanism is tricky and we want to test it 2339 # this yet because the dynamic patching mechanism is tricky and we want to
2287 # a lot. But patching is currently broken on FireFox for non-leaf types, 2340 # test it a lot. But patching is currently broken on FireFox for non-leaf
2288 # so 'hide' only the leaf types. 2341 # types, so 'hide' only the leaf types.
2289 is_hidden = interface_name not in _BROWSER_SHARED_TYPES 2342 is_hidden = interface_name not in _BROWSER_SHARED_TYPES
2290 if interface_name not in self._interfaces_with_subtypes: 2343 if interface_name not in self._interfaces_with_subtypes:
2291 is_hidden = True 2344 is_hidden = True
2292 2345
2293 native_spec = '*' if is_hidden else '' 2346 native_spec = '*' if is_hidden else ''
2294 native_spec += interface_name 2347 native_spec += interface_name
2295 2348
2349 # TODO: Include all implemented interfaces, including other Lists.
2350 implements = ''
2351 element_type = MaybeTypedArrayElementType(self._interface)
2352 if element_type:
2353 implements = ' implements List<' + element_type + '>'
2354
2296 (self._members_emitter, self._base_emitter) = self._dart_code.Emit( 2355 (self._members_emitter, self._base_emitter) = self._dart_code.Emit(
2297 '\n' 2356 '\n'
2298 'class $CLASS$BASE native "$NATIVE" {\n' 2357 'class $CLASS$BASE$IMPLEMENTS native "$NATIVE" {\n'
2299 '$CONSTRUCTOR$!MEMBERS' 2358 '$!MEMBERS'
2300 '$!ADDITIONS' 2359 '$!ADDITIONS'
2301 '}\n', 2360 '}\n',
2302 CLASS=self._class_name, BASE=extends, 2361 CLASS=self._class_name, BASE=extends,
2303 INTERFACE=interface_name, CONSTRUCTOR=constructor, 2362 INTERFACE=interface_name,
2363 IMPLEMENTS=implements,
2304 NATIVE=native_spec) 2364 NATIVE=native_spec)
2305 2365
2366 if interface_name in _constructable_types.keys():
2367 self._members_emitter.Emit(
2368 ' $NAME($PARAMS) native;\n\n',
2369 NAME=interface_name,
2370 PARAMS=_constructable_types[interface_name])
2371
2372 element_type = MaybeTypedArrayElementType(interface)
2373 if element_type:
2374 self.AddTypedArrayConstructors(element_type)
2375
2306 if not base: 2376 if not base:
2307 # Emit shared base functionality here as we have no common base type. 2377 # Emit shared base functionality here as we have no common base type.
2308 self._base_emitter.Emit( 2378 self._base_emitter.Emit(
2309 '\n' 2379 '\n'
2310 ' var dartObjectLocalStorage;\n' 2380 ' var dartObjectLocalStorage;\n'
2311 '\n' 2381 '\n'
2312 ' String get typeName() native;\n') 2382 ' String get typeName() native;\n')
2313 2383
2314 def _ImplClassName(self, type_name): 2384 def _ImplClassName(self, type_name):
2315 return type_name 2385 return type_name
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2375 # 2445 #
2376 # and 2446 # and
2377 # 2447 #
2378 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; } 2448 # class YImpl extends ListBase<T> { copies of transitive XImpl methods; }
2379 # 2449 #
2380 self._members_emitter.Emit( 2450 self._members_emitter.Emit(
2381 '\n' 2451 '\n'
2382 ' $TYPE operator[](int index) native;\n', 2452 ' $TYPE operator[](int index) native;\n',
2383 TYPE=element_type) 2453 TYPE=element_type)
2384 2454
2455 if 'HasCustomIndexSetter' in self._interface.ext_attrs:
2456 self._members_emitter.Emit(
2457 '\n'
2458 ' void operator[]=(int index, $TYPE value) native;\n',
2459 TYPE=element_type)
2460 else:
2461 self._members_emitter.Emit(
2462 '\n'
2463 ' void operator[]=(int index, $TYPE value) {\n'
2464 ' throw new UnsupportedOperationException("Cannot assign element of immutable List.");\n'
2465 ' }\n',
2466 TYPE=element_type)
2467
2468
2469 def AddTypedArrayConstructors(self, element_type):
2470 self._members_emitter.Emit(
2471 '\n'
2472 ' factory $CTOR(int length) => _construct(length);\n'
2473 '\n'
2474 ' factory $CTOR.fromList(List<$TYPE> list) => _construct(list);\n'
2475 '\n'
2476 ' factory $CTOR.fromBuffer(ArrayBuffer buffer) => _construct(buffer);\n '
2477 '\n'
2478 ' static _construct(arg) native \'return new $CTOR(arg);\';\n',
2479 CTOR=self._interface.id,
2480 TYPE=element_type)
2481
2482
2385 def AddOperation(self, info): 2483 def AddOperation(self, info):
2386 """ 2484 """
2387 Arguments: 2485 Arguments:
2388 info: An OperationInfo object. 2486 info: An OperationInfo object.
2389 """ 2487 """
2390 # TODO(vsm): Handle overloads. 2488 # TODO(vsm): Handle overloads.
2391 self._members_emitter.Emit( 2489 self._members_emitter.Emit(
2392 '\n' 2490 '\n'
2393 ' $TYPE $NAME($ARGS) native;\n', 2491 ' $TYPE $NAME($ARGS) native;\n',
2394 TYPE=info.type_name, 2492 TYPE=info.type_name,
2395 NAME=info.name, 2493 NAME=info.name,
2396 ARGS=info.arg_implementation_declaration) 2494 ARGS=info.arg_implementation_declaration)
OLDNEW
« no previous file with comments | « client/dom/idl/dart/dart.idl ('k') | client/dom/scripts/template_frog_dom.darttemplate » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698