| 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 { |
| 11 final Node ast; | 11 final Node ast; |
| 12 final TreeElements treeElements; | 12 final TreeElements treeElements; |
| 13 | 13 |
| 14 ElementAst(AstElement element) | 14 ElementAst(AstElement element) |
| 15 : this.internal(element.resolvedAst.node, element.resolvedAst.elements); | 15 : this.internal(element.resolvedAst.node, element.resolvedAst.elements); |
| 16 | 16 |
| 17 ElementAst.internal(this.ast, this.treeElements); | 17 ElementAst.internal(this.ast, this.treeElements); |
| 18 } | 18 } |
| 19 | 19 |
| 20 class DartBackend extends Backend { | 20 class DartBackend extends Backend { |
| 21 final List<CompilerTask> tasks; | 21 final List<CompilerTask> tasks; |
| 22 final bool forceStripTypes; | 22 final bool forceStripTypes; |
| 23 final bool stripAsserts; | 23 final bool stripAsserts; |
| 24 // TODO(antonm): make available from command-line options. | 24 // TODO(antonm): make available from command-line options. |
| 25 final bool outputAst = false; | 25 final bool outputAst = false; |
| 26 final Map<Node, String> renames; | |
| 27 final Map<LibraryElement, String> imports; | |
| 28 final Map<ClassNode, List<Node>> memberNodes; | 26 final Map<ClassNode, List<Node>> memberNodes; |
| 29 Map<Element, LibraryElement> reexportingLibraries; | 27 Map<Element, LibraryElement> reexportingLibraries; |
| 30 | 28 |
| 29 PlaceholderRenamer placeholderRenamer; |
| 30 |
| 31 // TODO(zarah) Maybe change this to a command-line option. | 31 // TODO(zarah) Maybe change this to a command-line option. |
| 32 // Right now, it is set by the tests. | 32 // Right now, it is set by the tests. |
| 33 bool useMirrorHelperLibrary = false; | 33 bool useMirrorHelperLibrary = false; |
| 34 | 34 |
| 35 /// Initialized if the useMirrorHelperLibrary field is set. | 35 /// Initialized if the useMirrorHelperLibrary field is set. |
| 36 MirrorRenamer mirrorRenamer; | 36 MirrorRenamer mirrorRenamer; |
| 37 | 37 |
| 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 LibraryElement mirrorHelperLibrary; | 40 LibraryElement mirrorHelperLibrary; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 if (element.allSupertypes != null) { | 98 if (element.allSupertypes != null) { |
| 99 element.allSupertypes.forEach(workQueue.add); | 99 element.allSupertypes.forEach(workQueue.add); |
| 100 } | 100 } |
| 101 } | 101 } |
| 102 } | 102 } |
| 103 return true; | 103 return true; |
| 104 } | 104 } |
| 105 | 105 |
| 106 DartBackend(Compiler compiler, List<String> strips) | 106 DartBackend(Compiler compiler, List<String> strips) |
| 107 : tasks = <CompilerTask>[], | 107 : tasks = <CompilerTask>[], |
| 108 renames = new Map<Node, String>(), | |
| 109 imports = new Map<LibraryElement, String>(), | |
| 110 memberNodes = new Map<ClassNode, List<Node>>(), | 108 memberNodes = new Map<ClassNode, List<Node>>(), |
| 111 reexportingLibraries = <Element, LibraryElement>{}, | 109 reexportingLibraries = <Element, LibraryElement>{}, |
| 112 forceStripTypes = strips.indexOf('types') != -1, | 110 forceStripTypes = strips.indexOf('types') != -1, |
| 113 stripAsserts = strips.indexOf('asserts') != -1, | 111 stripAsserts = strips.indexOf('asserts') != -1, |
| 114 constantCompilerTask = new DartConstantTask(compiler), | 112 constantCompilerTask = new DartConstantTask(compiler), |
| 115 super(compiler) { | 113 super(compiler) { |
| 116 resolutionCallbacks = new DartResolutionCallbacks(this); | 114 resolutionCallbacks = new DartResolutionCallbacks(this); |
| 117 } | 115 } |
| 118 | 116 |
| 119 bool classNeedsRti(ClassElement cls) => false; | 117 bool classNeedsRti(ClassElement cls) => false; |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 | 387 |
| 390 if (element.isClass) { | 388 if (element.isClass) { |
| 391 classMembers[element].forEach(makePlaceholders); | 389 classMembers[element].forEach(makePlaceholders); |
| 392 } | 390 } |
| 393 } | 391 } |
| 394 topLevelElements.forEach(makePlaceholders); | 392 topLevelElements.forEach(makePlaceholders); |
| 395 // Create renames. | 393 // Create renames. |
| 396 bool shouldCutDeclarationTypes = forceStripTypes | 394 bool shouldCutDeclarationTypes = forceStripTypes |
| 397 || (compiler.enableMinification | 395 || (compiler.enableMinification |
| 398 && isSafeToRemoveTypeDeclarations(classMembers)); | 396 && isSafeToRemoveTypeDeclarations(classMembers)); |
| 399 renamePlaceholders( | 397 |
| 400 compiler, collector, renames, imports, | 398 placeholderRenamer = |
| 401 fixedMemberNames, reexportingLibraries, | 399 new PlaceholderRenamer(compiler, fixedMemberNames, reexportingLibraries, |
| 402 shouldCutDeclarationTypes, | 400 cutDeclarationTypes: shouldCutDeclarationTypes); |
| 403 uniqueGlobalNaming: useMirrorHelperLibrary); | 401 |
| 402 placeholderRenamer.computeRenamings(collector); |
| 404 | 403 |
| 405 // Sort elements. | 404 // Sort elements. |
| 406 final sortedTopLevels = sortElements(topLevelElements); | 405 final List<Element> sortedTopLevels = sortElements(topLevelElements); |
| 407 final sortedClassMembers = new Map<ClassElement, List<Element>>(); | 406 final sortedClassMembers = new Map<ClassElement, List<Element>>(); |
| 408 classMembers.forEach((classElement, members) { | 407 classMembers.forEach((classElement, members) { |
| 409 sortedClassMembers[classElement] = sortElements(members); | 408 sortedClassMembers[classElement] = sortElements(members); |
| 410 }); | 409 }); |
| 411 | 410 |
| 412 if (outputAst) { | 411 if (outputAst) { |
| 413 // TODO(antonm): Ideally XML should be a separate backend. | 412 // TODO(antonm): Ideally XML should be a separate backend. |
| 414 // TODO(antonm): obey renames and minification, at least as an option. | 413 // TODO(antonm): obey renames and minification, at least as an option. |
| 415 StringBuffer sb = new StringBuffer(); | 414 StringBuffer sb = new StringBuffer(); |
| 416 outputElement(element) { | 415 outputElement(element) { |
| 417 sb.write(element.parseNode(compiler).toDebugString()); | 416 sb.write(element.parseNode(compiler).toDebugString()); |
| 418 } | 417 } |
| 419 | 418 |
| 420 // Emit XML for AST instead of the program. | 419 // Emit XML for AST instead of the program. |
| 421 for (final topLevel in sortedTopLevels) { | 420 for (final topLevel in sortedTopLevels) { |
| 422 if (topLevel.isClass && !emitNoMembersFor.contains(topLevel)) { | 421 if (topLevel.isClass && !emitNoMembersFor.contains(topLevel)) { |
| 423 // TODO(antonm): add some class info. | 422 // TODO(antonm): add some class info. |
| 424 sortedClassMembers[topLevel].forEach(outputElement); | 423 sortedClassMembers[topLevel].forEach(outputElement); |
| 425 } else { | 424 } else { |
| 426 outputElement(topLevel); | 425 outputElement(topLevel); |
| 427 } | 426 } |
| 428 } | 427 } |
| 429 compiler.assembledCode = '<Program>\n$sb</Program>\n'; | 428 compiler.assembledCode = '<Program>\n$sb</Program>\n'; |
| 430 return; | 429 return; |
| 431 } | 430 } |
| 432 | 431 |
| 433 final topLevelNodes = <Node>[]; | 432 final List<Node> topLevelNodes = <Node>[]; |
| 434 for (final element in sortedTopLevels) { | 433 for (final element in sortedTopLevels) { |
| 435 topLevelNodes.add(elementAsts[element].ast); | 434 topLevelNodes.add(elementAsts[element].ast); |
| 436 if (element.isClass && !element.isMixinApplication) { | 435 if (element.isClass && !element.isMixinApplication) { |
| 437 final members = <Node>[]; | 436 final members = <Node>[]; |
| 438 for (final member in sortedClassMembers[element]) { | 437 for (final member in sortedClassMembers[element]) { |
| 439 members.add(elementAsts[member].ast); | 438 members.add(elementAsts[member].ast); |
| 440 } | 439 } |
| 441 memberNodes[elementAsts[element].ast] = members; | 440 memberNodes[elementAsts[element].ast] = members; |
| 442 } | 441 } |
| 443 } | 442 } |
| 444 | 443 |
| 445 if (useMirrorHelperLibrary) { | 444 if (useMirrorHelperLibrary) { |
| 446 mirrorRenamer.addRenames(renames, topLevelNodes, collector); | 445 mirrorRenamer.addRenames(placeholderRenamer.renames, |
| 446 topLevelNodes, collector); |
| 447 } | 447 } |
| 448 | 448 |
| 449 final unparser = new EmitterUnparser(renames, stripTypes: forceStripTypes, | 449 final unparser = new EmitterUnparser(placeholderRenamer.renames, |
| 450 minify: compiler.enableMinification); | 450 stripTypes: forceStripTypes, |
| 451 emitCode(unparser, imports, topLevelNodes, memberNodes); | 451 minify: compiler.enableMinification); |
| 452 String assembledCode = unparser.result; | 452 for(LibraryElement library in placeholderRenamer.platformImports) { |
| 453 compiler.outputProvider('', 'dart') | 453 if (library.isPlatformLibrary && !library.isInternalLibrary) { |
| 454 ..add(assembledCode) | 454 unparser.unparseImportTag(library.canonicalUri.toString()); |
| 455 ..close(); | 455 } |
| 456 compiler.assembledCode = assembledCode; | 456 } |
| 457 for (int i = 0; i < sortedTopLevels.length; i++) { |
| 458 Element element = sortedTopLevels[i]; |
| 459 Node node = topLevelNodes[i]; |
| 460 if (node is ClassNode) { |
| 461 // TODO(smok): Filter out default constructors here. |
| 462 unparser.unparseClassWithBody(node, memberNodes[node]); |
| 463 } else { |
| 464 unparser.unparse(node); |
| 465 } |
| 466 unparser.newline(); |
| 467 } |
| 457 | 468 |
| 469 compiler.assembledCode = unparser.result; |
| 470 compiler.outputProvider("", "dart") |
| 471 ..add(compiler.assembledCode) |
| 472 ..close(); |
| 458 // Output verbose info about size ratio of resulting bundle to all | 473 // Output verbose info about size ratio of resulting bundle to all |
| 459 // referenced non-platform sources. | 474 // referenced non-platform sources. |
| 460 logResultBundleSizeInfo(topLevelElements); | 475 logResultBundleSizeInfo(topLevelElements); |
| 461 } | 476 } |
| 462 | 477 |
| 463 void logResultBundleSizeInfo(Set<Element> topLevelElements) { | 478 void logResultBundleSizeInfo(Set<Element> topLevelElements) { |
| 464 Iterable<LibraryElement> referencedLibraries = | 479 Iterable<LibraryElement> referencedLibraries = |
| 465 compiler.libraryLoader.libraries.where(isUserLibrary); | 480 compiler.libraryLoader.libraries.where(isUserLibrary); |
| 466 // Sum total size of scripts in each referenced library. | 481 // Sum total size of scripts in each referenced library. |
| 467 int nonPlatformSize = 0; | 482 int nonPlatformSize = 0; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 } | 687 } |
| 673 | 688 |
| 674 Constant compileMetadata(MetadataAnnotation metadata, | 689 Constant compileMetadata(MetadataAnnotation metadata, |
| 675 Node node, | 690 Node node, |
| 676 TreeElements elements) { | 691 TreeElements elements) { |
| 677 return measure(() { | 692 return measure(() { |
| 678 return constantCompiler.compileMetadata(metadata, node, elements); | 693 return constantCompiler.compileMetadata(metadata, node, elements); |
| 679 }); | 694 }); |
| 680 } | 695 } |
| 681 } | 696 } |
| OLD | NEW |