| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of dart_backend; | 5 part of dart_backend; |
| 6 | 6 |
| 7 // TODO(ahe): This class is simply wrong. This backend should use | 7 // TODO(ahe): This class is simply wrong. This backend should use |
| 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, | 8 // elements when it can, not AST nodes. Perhaps a [Map<Element, |
| 9 // TreeElements>] is what is needed. | 9 // TreeElements>] is what is needed. |
| 10 class ElementAst { | 10 class ElementAst { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary | 38 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary |
| 39 /// field is set. | 39 /// field is set. |
| 40 FunctionElement mirrorHelperGetNameFunction; | 40 FunctionElement mirrorHelperGetNameFunction; |
| 41 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary | 41 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary |
| 42 /// field is set. | 42 /// field is set. |
| 43 Element mirrorHelperSymbolsMap; | 43 Element mirrorHelperSymbolsMap; |
| 44 | 44 |
| 45 Map<Element, TreeElements> get resolvedElements => | 45 Map<Element, TreeElements> get resolvedElements => |
| 46 compiler.enqueuer.resolution.resolvedElements; | 46 compiler.enqueuer.resolution.resolvedElements; |
| 47 | 47 |
| 48 final Set<ClassElement> usedTypeLiterals = new Set<ClassElement>(); |
| 49 |
| 48 /** | 50 /** |
| 49 * Tells whether it is safe to remove type declarations from variables, | 51 * Tells whether it is safe to remove type declarations from variables, |
| 50 * functions parameters. It becomes not safe if: | 52 * functions parameters. It becomes not safe if: |
| 51 * 1) TypeError is used somewhere in the code, | 53 * 1) TypeError is used somewhere in the code, |
| 52 * 2) The code has typedefs in right hand side of IS checks, | 54 * 2) The code has typedefs in right hand side of IS checks, |
| 53 * 3) The code has classes which extend typedefs, have type arguments typedefs | 55 * 3) The code has classes which extend typedefs, have type arguments typedefs |
| 54 * or type variable bounds typedefs. | 56 * or type variable bounds typedefs. |
| 55 * These restrictions can be less strict. | 57 * These restrictions can be less strict. |
| 56 */ | 58 */ |
| 57 bool isSafeToRemoveTypeDeclarations( | 59 bool isSafeToRemoveTypeDeclarations( |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 assert(shouldOutput(enclosingClass)); | 292 assert(shouldOutput(enclosingClass)); |
| 291 addClass(enclosingClass); | 293 addClass(enclosingClass); |
| 292 classMembers[enclosingClass].add(element); | 294 classMembers[enclosingClass].add(element); |
| 293 processElement(element, elementAst); | 295 processElement(element, elementAst); |
| 294 } else { | 296 } else { |
| 295 if (element.isTopLevel()) { | 297 if (element.isTopLevel()) { |
| 296 addTopLevel(element, elementAst); | 298 addTopLevel(element, elementAst); |
| 297 } | 299 } |
| 298 } | 300 } |
| 299 }); | 301 }); |
| 302 Set<ClassElement> emitNoMembersFor = new Set<ClassElement>(); |
| 303 usedTypeLiterals.forEach((ClassElement element) { |
| 304 if (shouldOutput(element)) { |
| 305 if (!topLevelElements.contains(element)) { |
| 306 // The class is only referenced by type literals. |
| 307 emitNoMembersFor.add(element); |
| 308 } |
| 309 addClass(element); |
| 310 } |
| 311 }); |
| 300 | 312 |
| 301 // Add synthesized constructors to classes with no resolved constructors, | 313 // Add synthesized constructors to classes with no resolved constructors, |
| 302 // but which originally had any constructor. That should prevent | 314 // but which originally had any constructor. That should prevent |
| 303 // those classes from being instantiable with default constructor. | 315 // those classes from being instantiable with default constructor. |
| 304 Identifier synthesizedIdentifier = new Identifier( | 316 Identifier synthesizedIdentifier = new Identifier( |
| 305 new StringToken.fromString(IDENTIFIER_INFO, '', -1)); | 317 new StringToken.fromString(IDENTIFIER_INFO, '', -1)); |
| 306 | 318 |
| 307 NextClassElement: | 319 NextClassElement: |
| 308 for (ClassElement classElement in classMembers.keys) { | 320 for (ClassElement classElement in classMembers.keys) { |
| 321 if (emitNoMembersFor.contains(classElement)) continue; |
| 309 for (Element member in classMembers[classElement]) { | 322 for (Element member in classMembers[classElement]) { |
| 310 if (member.isConstructor()) continue NextClassElement; | 323 if (member.isConstructor()) continue NextClassElement; |
| 311 } | 324 } |
| 312 if (classElement.constructors.isEmpty) continue NextClassElement; | 325 if (classElement.constructors.isEmpty) continue NextClassElement; |
| 313 | 326 |
| 314 // TODO(antonm): check with AAR team if there is better approach. | 327 // TODO(antonm): check with AAR team if there is better approach. |
| 315 // As an idea: provide template as a Dart code---class C { C.name(); }--- | 328 // As an idea: provide template as a Dart code---class C { C.name(); }--- |
| 316 // and then overwrite necessary parts. | 329 // and then overwrite necessary parts. |
| 317 var classNode = classElement.parseNode(compiler); | 330 var classNode = classElement.parseNode(compiler); |
| 318 SynthesizedConstructorElementX constructor = | 331 SynthesizedConstructorElementX constructor = |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 if (outputAst) { | 387 if (outputAst) { |
| 375 // TODO(antonm): Ideally XML should be a separate backend. | 388 // TODO(antonm): Ideally XML should be a separate backend. |
| 376 // TODO(antonm): obey renames and minification, at least as an option. | 389 // TODO(antonm): obey renames and minification, at least as an option. |
| 377 StringBuffer sb = new StringBuffer(); | 390 StringBuffer sb = new StringBuffer(); |
| 378 outputElement(element) { | 391 outputElement(element) { |
| 379 sb.write(element.parseNode(compiler).toDebugString()); | 392 sb.write(element.parseNode(compiler).toDebugString()); |
| 380 } | 393 } |
| 381 | 394 |
| 382 // Emit XML for AST instead of the program. | 395 // Emit XML for AST instead of the program. |
| 383 for (final topLevel in sortedTopLevels) { | 396 for (final topLevel in sortedTopLevels) { |
| 384 if (topLevel.isClass()) { | 397 if (topLevel.isClass() && !emitNoMembersFor.contains(topLevel)) { |
| 385 // TODO(antonm): add some class info. | 398 // TODO(antonm): add some class info. |
| 386 sortedClassMembers[topLevel].forEach(outputElement); | 399 sortedClassMembers[topLevel].forEach(outputElement); |
| 387 } else { | 400 } else { |
| 388 outputElement(topLevel); | 401 outputElement(topLevel); |
| 389 } | 402 } |
| 390 } | 403 } |
| 391 compiler.assembledCode = '<Program>\n$sb</Program>\n'; | 404 compiler.assembledCode = '<Program>\n$sb</Program>\n'; |
| 392 return; | 405 return; |
| 393 } | 406 } |
| 394 | 407 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 mirrorHelperLibrary = element; | 459 mirrorHelperLibrary = element; |
| 447 mirrorHelperGetNameFunction = mirrorHelperLibrary.find( | 460 mirrorHelperGetNameFunction = mirrorHelperLibrary.find( |
| 448 MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION); | 461 MirrorRenamer.MIRROR_HELPER_GET_NAME_FUNCTION); |
| 449 mirrorHelperSymbolsMap = mirrorHelperLibrary.find( | 462 mirrorHelperSymbolsMap = mirrorHelperLibrary.find( |
| 450 MirrorRenamer.MIRROR_HELPER_SYMBOLS_MAP_NAME); | 463 MirrorRenamer.MIRROR_HELPER_SYMBOLS_MAP_NAME); |
| 451 }); | 464 }); |
| 452 } | 465 } |
| 453 return new Future.value(); | 466 return new Future.value(); |
| 454 } | 467 } |
| 455 | 468 |
| 469 void registerTypeLiteral(Element element, |
| 470 Enqueuer enqueuer, |
| 471 TreeElements elements) { |
| 472 if (element.isClass()) { |
| 473 usedTypeLiterals.add(element); |
| 474 } |
| 475 } |
| 476 |
| 456 void registerStaticSend(Element element, Node node) { | 477 void registerStaticSend(Element element, Node node) { |
| 457 if (useMirrorHelperLibrary) { | 478 if (useMirrorHelperLibrary) { |
| 458 mirrorRenamer.registerStaticSend(element, node); | 479 mirrorRenamer.registerStaticSend(element, node); |
| 459 } | 480 } |
| 460 } | 481 } |
| 461 | 482 |
| 462 void registerMirrorHelperElement(Element element, Node node) { | 483 void registerMirrorHelperElement(Element element, Node node) { |
| 463 if (mirrorHelperLibrary != null | 484 if (mirrorHelperLibrary != null |
| 464 && element.getLibrary() == mirrorHelperLibrary) { | 485 && element.getLibrary() == mirrorHelperLibrary) { |
| 465 mirrorRenamer.registerHelperElement(element, node); | 486 mirrorRenamer.registerHelperElement(element, node); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 } | 574 } |
| 554 | 575 |
| 555 compareElements(e0, e1) { | 576 compareElements(e0, e1) { |
| 556 int result = compareBy((e) => e.getLibrary().canonicalUri.toString())(e0, e1); | 577 int result = compareBy((e) => e.getLibrary().canonicalUri.toString())(e0, e1); |
| 557 if (result != 0) return result; | 578 if (result != 0) return result; |
| 558 return compareBy((e) => e.position().charOffset)(e0, e1); | 579 return compareBy((e) => e.position().charOffset)(e0, e1); |
| 559 } | 580 } |
| 560 | 581 |
| 561 List<Element> sortElements(Iterable<Element> elements) => | 582 List<Element> sortElements(Iterable<Element> elements) => |
| 562 sorted(elements, compareElements); | 583 sorted(elements, compareElements); |
| OLD | NEW |