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 the system to generate | 6 """This module provides shared functionality for the system to generate |
7 Dart:html APIs from the IDL database.""" | 7 Dart:html APIs from the IDL database.""" |
8 | 8 |
9 import emitter | 9 import emitter |
10 import logging | 10 import logging |
(...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 | 551 |
552 secure_base_name = self._backend.SecureBaseName(interface_name) | 552 secure_base_name = self._backend.SecureBaseName(interface_name) |
553 if secure_base_name: | 553 if secure_base_name: |
554 implements.append(secure_base_name) | 554 implements.append(secure_base_name) |
555 | 555 |
556 implements_str = '' | 556 implements_str = '' |
557 if implements: | 557 if implements: |
558 implements_str = ' implements ' + ', '.join(set(implements)) | 558 implements_str = ' implements ' + ', '.join(set(implements)) |
559 | 559 |
560 mixins = self._backend.Mixins() | 560 mixins = self._backend.Mixins() |
| 561 |
| 562 # TODO(terry): Do we need a more generic solution other than handling NamedN
odeMap |
| 563 # we can't call super on a mixin interface - yet. |
| 564 if self._options.templates._conditions['DARTIUM'] and self._options.dart_js_
interop and self._interface.id == 'NamedNodeMap': |
| 565 mixins = None |
561 mixins_str = '' | 566 mixins_str = '' |
562 if mixins: | 567 if mixins: |
563 mixins_str = ' with ' + ', '.join(mixins) | 568 mixins_str = ' with ' + ', '.join(mixins) |
564 if not base_class: | 569 if not base_class: |
565 base_class = 'Interceptor' | 570 base_class = 'Interceptor' |
566 | 571 |
567 annotations = self._metadata.GetFormattedMetadata( | 572 annotations = self._metadata.GetFormattedMetadata( |
568 self._library_name, self._interface, None, '') | 573 self._library_name, self._interface, None, '') |
569 | 574 |
570 class_modifiers = '' | 575 class_modifiers = '' |
571 if (self._renamer.ShouldSuppressInterface(self._interface) or | 576 if (self._renamer.ShouldSuppressInterface(self._interface) or |
572 IsPureInterface(self._interface.id)): | 577 IsPureInterface(self._interface.id)): |
573 class_modifiers = 'abstract ' | 578 # XMLHttpRequestProgressEvent can't be abstract we need to instantiate |
| 579 # for JsInterop. |
| 580 if (not(isinstance(self._backend, Dart2JSBackend)) and |
| 581 self._interface.id == 'XMLHttpRequestProgressEvent'): |
| 582 # Only suppress abstract for XMLHttpRequestProgressEvent for Dartium. |
| 583 # Need to be able to instantiate the class; can't be abstract. |
| 584 class_modifiers = '' |
| 585 else: |
| 586 class_modifiers = 'abstract ' |
574 | 587 |
575 native_spec = '' | 588 native_spec = '' |
576 if not IsPureInterface(self._interface.id): | 589 if not IsPureInterface(self._interface.id): |
577 native_spec = self._backend.NativeSpec() | 590 native_spec = self._backend.NativeSpec() |
578 | 591 |
| 592 class_name = self._interface_type_info.implementation_name() |
| 593 |
| 594 js_interop_equivalence_op = \ |
| 595 ' bool operator ==(other) => unwrap_jso(other) == unwrap_jso(this) || ide
ntical(this, other);\n' |
| 596 # ClientRect overrides the equivalence operator. |
| 597 if interface_name == 'ClientRect' or interface_name == 'DomRectReadOnly': |
| 598 js_interop_equivalence_op = '' |
| 599 |
| 600 js_interop_wrapper = ''' |
| 601 |
| 602 static {0} internalCreate{0}() {{ |
| 603 return new {0}._internalWrap(); |
| 604 }} |
| 605 |
| 606 factory {0}._internalWrap() {{ |
| 607 return new {0}._internal(); |
| 608 }} |
| 609 |
| 610 {0}._internal() : super._internal(); |
| 611 |
| 612 '''.format(class_name) |
| 613 """ |
| 614 TODO(terry): Don't use Dart expando really don't need. |
| 615 final Object expandoJsObject = new Object(); |
| 616 final Expando<JsObject> dartium_expando = new Expando<JsObject>("Expando_j
sObject"); |
| 617 """ |
| 618 if base_class == 'NativeFieldWrapperClass2': |
| 619 js_interop_wrapper = ''' |
| 620 static {0} internalCreate{0}() {{ |
| 621 return new {0}._internalWrap(); |
| 622 }} |
| 623 |
| 624 JsObject blink_jsObject = null; |
| 625 |
| 626 factory {0}._internalWrap() {{ |
| 627 return new {0}._internal(); |
| 628 }} |
| 629 |
| 630 {0}._internal() {{ }} |
| 631 |
| 632 {1}'''.format(class_name, js_interop_equivalence_op) |
| 633 |
579 implementation_members_emitter = implementation_emitter.Emit( | 634 implementation_members_emitter = implementation_emitter.Emit( |
580 self._backend.ImplementationTemplate(), | 635 self._backend.ImplementationTemplate(), |
581 LIBRARYNAME='dart.dom.%s' % self._library_name, | 636 LIBRARYNAME='dart.dom.%s' % self._library_name, |
582 ANNOTATIONS=annotations, | 637 ANNOTATIONS=annotations, |
583 CLASS_MODIFIERS=class_modifiers, | 638 CLASS_MODIFIERS=class_modifiers, |
584 CLASSNAME=self._interface_type_info.implementation_name(), | 639 CLASSNAME=self._interface_type_info.implementation_name(), |
585 EXTENDS=' extends %s' % base_class if base_class else '', | 640 EXTENDS=' extends %s' % base_class if base_class else '', |
586 IMPLEMENTS=implements_str, | 641 IMPLEMENTS=implements_str, |
587 MIXINS=mixins_str, | 642 MIXINS=mixins_str, |
588 DOMNAME=self._interface.doc_js_name, | 643 DOMNAME=self._interface.doc_js_name, |
(...skipping 18 matching lines...) Expand all Loading... |
607 self._backend.CustomJSMembers(), | 662 self._backend.CustomJSMembers(), |
608 implementation_members_emitter, | 663 implementation_members_emitter, |
609 self._library_name) | 664 self._library_name) |
610 self._backend.AddConstructors( | 665 self._backend.AddConstructors( |
611 constructors, factory_provider, factory_constructor_name) | 666 constructors, factory_provider, factory_constructor_name) |
612 | 667 |
613 isElement = False | 668 isElement = False |
614 for parent in self._database.Hierarchy(self._interface): | 669 for parent in self._database.Hierarchy(self._interface): |
615 if parent.id == 'Element': | 670 if parent.id == 'Element': |
616 isElement = True | 671 isElement = True |
| 672 |
| 673 # Write out the JsInterop code. |
| 674 if implementation_members_emitter and self._options.templates._conditions['D
ARTIUM']: |
| 675 implementation_members_emitter.Emit(js_interop_wrapper) |
| 676 |
617 if isElement and self._interface.id != 'Element': | 677 if isElement and self._interface.id != 'Element': |
618 implementation_members_emitter.Emit( | 678 implementation_members_emitter.Emit( |
619 ' /**\n' | 679 ' /**\n' |
620 ' * Constructor instantiated by the DOM when a custom element has be
en created.\n' | 680 ' * Constructor instantiated by the DOM when a custom element has be
en created.\n' |
621 ' *\n' | 681 ' *\n' |
622 ' * This can only be called by subclasses from their created constru
ctor.\n' | 682 ' * This can only be called by subclasses from their created constru
ctor.\n' |
623 ' */\n' | 683 ' */\n' |
624 ' $CLASSNAME.created() : super.created();\n', | 684 ' $CLASSNAME.created() : super.created();\n', |
625 CLASSNAME=self._interface_type_info.implementation_name()) | 685 CLASSNAME=self._interface_type_info.implementation_name()) |
626 | 686 |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 if not template is None: | 1278 if not template is None: |
1219 emitter = emitter.Emit(template) | 1279 emitter = emitter.Emit(template) |
1220 self._path_to_emitter[path] = emitter | 1280 self._path_to_emitter[path] = emitter |
1221 | 1281 |
1222 self._dart_libraries.AddFile(basename, library_name, path) | 1282 self._dart_libraries.AddFile(basename, library_name, path) |
1223 return self._path_to_emitter[path] | 1283 return self._path_to_emitter[path] |
1224 | 1284 |
1225 def AddTypeEntry(self, basename, idl_name, dart_name): | 1285 def AddTypeEntry(self, basename, idl_name, dart_name): |
1226 self._dart_libraries.AddTypeEntry(basename, idl_name, dart_name) | 1286 self._dart_libraries.AddTypeEntry(basename, idl_name, dart_name) |
1227 | 1287 |
1228 def EmitLibraries(self, auxiliary_dir): | 1288 def EmitLibraries(self, auxiliary_dir, dart_js_interop): |
1229 self._dart_libraries.Emit(self._multiemitter, auxiliary_dir) | 1289 self._dart_libraries.Emit(self._multiemitter, auxiliary_dir) |
1230 | 1290 |
1231 # ------------------------------------------------------------------------------ | 1291 # ------------------------------------------------------------------------------ |
1232 class DartLibrary(): | 1292 class DartLibrary(): |
1233 def __init__(self, name, template_loader, library_type, output_dir): | 1293 def __init__(self, name, template_loader, library_type, output_dir, dart_js_in
terop): |
1234 self._template = template_loader.Load( | 1294 self._template = template_loader.Load( |
1235 '%s_%s.darttemplate' % (name, library_type)) | 1295 '%s_%s.darttemplate' % (name, library_type)) |
1236 self._dart_path = os.path.join( | 1296 self._dart_path = os.path.join( |
1237 output_dir, '%s_%s.dart' % (name, library_type)) | 1297 output_dir, '%s_%s.dart' % (name, library_type)) |
1238 self._paths = [] | 1298 self._paths = [] |
1239 self._typeMap = {} | 1299 self._typeMap = {} |
| 1300 self._dart_js_interop = dart_js_interop |
1240 | 1301 |
1241 def AddFile(self, path): | 1302 def AddFile(self, path): |
1242 self._paths.append(path) | 1303 self._paths.append(path) |
1243 | 1304 |
1244 def AddTypeEntry(self, idl_name, dart_name): | 1305 def AddTypeEntry(self, idl_name, dart_name): |
1245 self._typeMap[idl_name] = dart_name | 1306 self._typeMap[idl_name] = dart_name |
1246 | 1307 |
1247 def Emit(self, emitter, auxiliary_dir): | 1308 def Emit(self, emitter, auxiliary_dir): |
1248 def massage_path(path): | 1309 def massage_path(path): |
1249 # The most robust way to emit path separators is to use / always. | 1310 # The most robust way to emit path separators is to use / always. |
1250 return path.replace('\\', '/') | 1311 return path.replace('\\', '/') |
1251 | 1312 |
1252 library_emitter = emitter.FileEmitter(self._dart_path) | 1313 library_emitter = emitter.FileEmitter(self._dart_path) |
1253 library_file_dir = os.path.dirname(self._dart_path) | 1314 library_file_dir = os.path.dirname(self._dart_path) |
1254 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) | 1315 auxiliary_dir = os.path.relpath(auxiliary_dir, library_file_dir) |
1255 emitters = library_emitter.Emit( | 1316 emitters = library_emitter.Emit( |
1256 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) | 1317 self._template, AUXILIARY_DIR=massage_path(auxiliary_dir)) |
1257 if isinstance(emitters, tuple): | 1318 if isinstance(emitters, tuple): |
1258 imports_emitter, map_emitter = emitters | 1319 if self._dart_js_interop: |
| 1320 imports_emitter, map_emitter, function_emitter = emitters |
| 1321 else: |
| 1322 imports_emitter, map_emitter = emitters |
| 1323 function_emitter = None |
1259 else: | 1324 else: |
1260 imports_emitter, map_emitter = emitters, None | 1325 imports_emitter, map_emitter, function_emitter = emitters, None, None |
1261 | |
1262 | 1326 |
1263 for path in sorted(self._paths): | 1327 for path in sorted(self._paths): |
1264 relpath = os.path.relpath(path, library_file_dir) | 1328 relpath = os.path.relpath(path, library_file_dir) |
1265 imports_emitter.Emit( | 1329 imports_emitter.Emit( |
1266 "part '$PATH';\n", PATH=massage_path(relpath)) | 1330 "part '$PATH';\n", PATH=massage_path(relpath)) |
1267 | 1331 |
| 1332 # Emit the $!TYPE_MAP |
1268 if map_emitter: | 1333 if map_emitter: |
1269 items = self._typeMap.items() | 1334 items = self._typeMap.items() |
1270 items.sort() | 1335 items.sort() |
1271 for (idl_name, dart_name) in items: | 1336 for (idl_name, dart_name) in items: |
1272 map_emitter.Emit( | 1337 map_emitter.Emit( |
1273 " '$IDL_NAME': () => $DART_NAME,\n", | 1338 " '$IDL_NAME': () => $DART_NAME,\n", |
1274 IDL_NAME=idl_name, | 1339 IDL_NAME=idl_name, |
1275 DART_NAME=dart_name) | 1340 DART_NAME=dart_name) |
1276 | 1341 |
| 1342 # Emit the $!TYPE_FUNCTION_MAP |
| 1343 if function_emitter: |
| 1344 items = self._typeMap.items() |
| 1345 items.sort() |
| 1346 for (idl_name, dart_name) in items: |
| 1347 function_emitter.Emit( |
| 1348 " '$IDL_NAME': () => $DART_NAME.internalCreate$DART_NAME,\n", |
| 1349 IDL_NAME=idl_name, |
| 1350 DART_NAME=dart_name) |
| 1351 if self._dart_path.endswith('html_dartium.dart'): |
| 1352 function_emitter.Emit(" 'polymer-element': () => HtmlElement.internalCr
eateHtmlElement,\n") |
| 1353 |
1277 | 1354 |
1278 # ------------------------------------------------------------------------------ | 1355 # ------------------------------------------------------------------------------ |
1279 | 1356 |
1280 class DartLibraries(): | 1357 class DartLibraries(): |
1281 def __init__(self, libraries, template_loader, library_type, output_dir): | 1358 def __init__(self, libraries, template_loader, library_type, output_dir, dart_
js_interop): |
1282 self._libraries = {} | 1359 self._libraries = {} |
1283 for library_name in libraries: | 1360 for library_name in libraries: |
1284 self._libraries[library_name] = DartLibrary( | 1361 self._libraries[library_name] = DartLibrary( |
1285 library_name, template_loader, library_type, output_dir) | 1362 library_name, template_loader, library_type, output_dir, dart_js_inter
op) |
1286 | 1363 |
1287 def AddFile(self, basename, library_name, path): | 1364 def AddFile(self, basename, library_name, path): |
1288 self._libraries[library_name].AddFile(path) | 1365 self._libraries[library_name].AddFile(path) |
1289 | 1366 |
1290 def AddTypeEntry(self, library_name, idl_name, dart_name): | 1367 def AddTypeEntry(self, library_name, idl_name, dart_name): |
1291 self._libraries[library_name].AddTypeEntry(idl_name, dart_name) | 1368 self._libraries[library_name].AddTypeEntry(idl_name, dart_name) |
1292 | 1369 |
1293 def Emit(self, emitter, auxiliary_dir): | 1370 def Emit(self, emitter, auxiliary_dir): |
1294 for lib in self._libraries.values(): | 1371 for lib in self._libraries.values(): |
1295 lib.Emit(emitter, auxiliary_dir) | 1372 lib.Emit(emitter, auxiliary_dir) |
OLD | NEW |