Chromium Code Reviews| 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<ClassNode, List<Node>> memberNodes; | 26 final Map<ClassNode, List<Node>> memberNodes; |
| 27 | 27 |
| 28 /// If `true`, libraries are generated into separate files. | |
| 29 final bool multiFile; | |
| 30 | |
| 28 PlaceholderRenamer placeholderRenamer; | 31 PlaceholderRenamer placeholderRenamer; |
| 29 | 32 |
| 30 // TODO(zarah) Maybe change this to a command-line option. | 33 // TODO(zarah) Maybe change this to a command-line option. |
| 31 // Right now, it is set by the tests. | 34 // Right now, it is set by the tests. |
| 32 bool useMirrorHelperLibrary = false; | 35 bool useMirrorHelperLibrary = false; |
| 33 | 36 |
| 34 /// Initialized if the useMirrorHelperLibrary field is set. | 37 /// Initialized if the useMirrorHelperLibrary field is set. |
| 35 MirrorRenamer mirrorRenamer; | 38 MirrorRenamer mirrorRenamer; |
| 36 | 39 |
| 37 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary | 40 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 ClassElement element = type.element; | 98 ClassElement element = type.element; |
| 96 // Check all supertypes. | 99 // Check all supertypes. |
| 97 if (element.allSupertypes != null) { | 100 if (element.allSupertypes != null) { |
| 98 element.allSupertypes.forEach(workQueue.add); | 101 element.allSupertypes.forEach(workQueue.add); |
| 99 } | 102 } |
| 100 } | 103 } |
| 101 } | 104 } |
| 102 return true; | 105 return true; |
| 103 } | 106 } |
| 104 | 107 |
| 105 DartBackend(Compiler compiler, List<String> strips) | 108 DartBackend(Compiler compiler, List<String> strips, {this.multiFile}) |
| 106 : tasks = <CompilerTask>[], | 109 : tasks = <CompilerTask>[], |
| 107 memberNodes = new Map<ClassNode, List<Node>>(), | 110 memberNodes = new Map<ClassNode, List<Node>>(), |
| 108 forceStripTypes = strips.indexOf('types') != -1, | 111 forceStripTypes = strips.indexOf('types') != -1, |
| 109 stripAsserts = strips.indexOf('asserts') != -1, | 112 stripAsserts = strips.indexOf('asserts') != -1, |
| 110 constantCompilerTask = new DartConstantTask(compiler), | 113 constantCompilerTask = new DartConstantTask(compiler), |
| 111 super(compiler) { | 114 super(compiler) { |
| 112 resolutionCallbacks = new DartResolutionCallbacks(this); | 115 resolutionCallbacks = new DartResolutionCallbacks(this); |
| 113 } | 116 } |
| 114 | 117 |
| 115 bool classNeedsRti(ClassElement cls) => false; | 118 bool classNeedsRti(ClassElement cls) => false; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 compiler.tracer.traceGraph('Unshadow parameters', definition); | 260 compiler.tracer.traceGraph('Unshadow parameters', definition); |
| 258 | 261 |
| 259 TreeElementMapping treeElements = new TreeElementMapping(element); | 262 TreeElementMapping treeElements = new TreeElementMapping(element); |
| 260 backend_ast.Node backendAst = | 263 backend_ast.Node backendAst = |
| 261 backend_ast_emitter.emit(definition); | 264 backend_ast_emitter.emit(definition); |
| 262 Node frontend_ast = backend2frontend.emit(treeElements, backendAst); | 265 Node frontend_ast = backend2frontend.emit(treeElements, backendAst); |
| 263 return new ElementAst.internal(frontend_ast, treeElements); | 266 return new ElementAst.internal(frontend_ast, treeElements); |
| 264 } | 267 } |
| 265 } | 268 } |
| 266 | 269 |
| 270 List<LibraryElement> userLibraries = | |
| 271 compiler.libraryLoader.libraries.where(isUserLibrary).toList(); | |
| 272 | |
| 267 Set<Element> topLevelElements = new Set<Element>(); | 273 Set<Element> topLevelElements = new Set<Element>(); |
| 268 Map<ClassElement, Set<Element>> classMembers = | 274 Map<ClassElement, Set<Element>> classMembers = |
| 269 new Map<ClassElement, Set<Element>>(); | 275 new Map<ClassElement, Set<Element>>(); |
| 270 | 276 |
| 271 // Build all top level elements to emit and necessary class members. | 277 // Build all top level elements to emit and necessary class members. |
| 272 var newTypedefElementCallback, newClassElementCallback; | 278 var newTypedefElementCallback, newClassElementCallback; |
| 273 | 279 |
| 274 void processElement(Element element, ElementAst elementAst) { | 280 void processElement(Element element, ElementAst elementAst) { |
| 275 ReferencedElementCollector collector = | 281 ReferencedElementCollector collector = |
| 276 new ReferencedElementCollector(compiler, | 282 new ReferencedElementCollector(compiler, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 445 } | 451 } |
| 446 memberNodes[elementAsts[element].ast] = members; | 452 memberNodes[elementAsts[element].ast] = members; |
| 447 } | 453 } |
| 448 } | 454 } |
| 449 | 455 |
| 450 if (useMirrorHelperLibrary) { | 456 if (useMirrorHelperLibrary) { |
| 451 mirrorRenamer.addRenames(placeholderRenamer.renames, | 457 mirrorRenamer.addRenames(placeholderRenamer.renames, |
| 452 topLevelNodes, collector); | 458 topLevelNodes, collector); |
| 453 } | 459 } |
| 454 | 460 |
| 455 final EmitterUnparser unparser = | 461 Map<LibraryElement, String> outputPaths = new Map<LibraryElement, String>(); |
| 456 new EmitterUnparser(placeholderRenamer.renames, | 462 Map<LibraryElement, EmitterUnparser> unparsers = |
| 457 stripTypes: forceStripTypes, | 463 new Map<LibraryElement, EmitterUnparser>(); |
| 458 minify: compiler.enableMinification); | 464 |
| 459 for (LibraryElement library in placeholderRenamer.platformImports) { | 465 // The single unparser used if we collect all the output in one file |
| 460 if (library.isPlatformLibrary && !library.isInternalLibrary) { | 466 EmitterUnparser mainUnparser = multiFile |
| 461 unparser.unparseImportTag(library.canonicalUri.toString()); | 467 ? null |
| 468 : new EmitterUnparser(placeholderRenamer.renames, | |
| 469 stripTypes: forceStripTypes, | |
| 470 minify: compiler.enableMinification); | |
| 471 | |
| 472 if (multiFile) { | |
| 473 String mainName = compiler.outputUri.pathSegments.last; | |
| 474 String mainBaseName = mainName.endsWith(".dart") | |
| 475 ? mainName.substring(0, mainName.length - 5) | |
| 476 : mainName; | |
| 477 // Map each library to a path based on the uri of the original | |
| 478 // library and [compiler.outputUri]. | |
| 479 Set<String> usedLibraryPaths = new Set<String>(); | |
| 480 for (LibraryElement library in userLibraries) { | |
| 481 if (library == compiler.mainApp) { | |
| 482 outputPaths[library] = mainBaseName; | |
| 483 } else { | |
| 484 List<String> names = | |
| 485 library.canonicalUri.pathSegments.last.split("."); | |
| 486 if (names.last == "dart") { | |
| 487 names = names.sublist(0, names.length - 1); | |
| 488 } | |
| 489 outputPaths[library] = | |
| 490 "$mainBaseName.${makeUnique(names.join("."), usedLibraryPaths)}"; | |
| 491 } | |
| 492 } | |
| 493 | |
| 494 for(LibraryElement outputLibrary in userLibraries) { | |
|
floitsch
2014/08/28 20:10:07
Add comment explaining that you rewrite the import
sigurdm
2014/09/03 08:24:16
Done.
| |
| 495 EmitterUnparser unparser = new EmitterUnparser( | |
| 496 placeholderRenamer.renames, | |
| 497 stripTypes: forceStripTypes, | |
| 498 minify: compiler.enableMinification); | |
| 499 unparsers[outputLibrary] = unparser; | |
| 500 LibraryName libraryName = outputLibrary.libraryTag; | |
| 501 if (libraryName != null) { | |
| 502 unparser.visitLibraryName(libraryName); | |
| 503 } | |
| 504 for (LibraryTag tag in outputLibrary.tags) { | |
| 505 if (tag is! LibraryDependency) continue; | |
| 506 LibraryDependency dependency = tag; | |
| 507 LibraryElement libraryElement = | |
| 508 outputLibrary.getLibraryFromTag(dependency); | |
| 509 String uri = outputPaths.containsKey(libraryElement) | |
| 510 ? "${outputPaths[libraryElement]}.dart" | |
| 511 : libraryElement.canonicalUri.toString(); | |
| 512 if (dependency is Import) { | |
| 513 unparser.unparseImportTag(uri); | |
| 514 } else { | |
| 515 unparser.unparseExportTag(uri); | |
| 516 } | |
| 517 } | |
| 518 } | |
| 519 } else { | |
| 520 for(LibraryElement library in placeholderRenamer.platformImports) { | |
| 521 if (library.isPlatformLibrary && !library.isInternalLibrary) { | |
| 522 mainUnparser.unparseImportTag(library.canonicalUri.toString()); | |
| 523 } | |
| 462 } | 524 } |
| 463 } | 525 } |
| 526 | |
| 464 for (int i = 0; i < sortedTopLevels.length; i++) { | 527 for (int i = 0; i < sortedTopLevels.length; i++) { |
| 465 Element element = sortedTopLevels[i]; | 528 Element element = sortedTopLevels[i]; |
| 466 Node node = topLevelNodes[i]; | 529 Node node = topLevelNodes[i]; |
| 530 Unparser unparser = multiFile ? unparsers[element.library] : mainUnparser; | |
| 467 if (node is ClassNode) { | 531 if (node is ClassNode) { |
| 468 // TODO(smok): Filter out default constructors here. | 532 // TODO(smok): Filter out default constructors here. |
| 469 unparser.unparseClassWithBody(node, memberNodes[node]); | 533 unparser.unparseClassWithBody(node, memberNodes[node]); |
| 470 } else { | 534 } else { |
| 471 unparser.unparse(node); | 535 unparser.unparse(node); |
| 472 } | 536 } |
| 473 unparser.newline(); | 537 unparser.newline(); |
| 474 } | 538 } |
| 475 | 539 |
| 476 compiler.assembledCode = unparser.result; | 540 if (multiFile) { |
| 477 compiler.outputProvider("", "dart") | 541 for(LibraryElement outputLibrary in userLibraries) { |
| 478 ..add(compiler.assembledCode) | 542 compiler.outputProvider(outputPaths[outputLibrary], "dart") |
| 479 ..close(); | 543 // TODO(sigurdm): Make the unparser output directly into the buffer instead |
|
floitsch
2014/08/28 20:10:06
Write comment before statement.
sigurdm
2014/09/03 08:24:16
Done.
| |
| 480 // Output verbose info about size ratio of resulting bundle to all | 544 // of caching in `.result`. |
| 481 // referenced non-platform sources. | 545 ..add(unparsers[outputLibrary].result) |
| 482 logResultBundleSizeInfo(topLevelElements); | 546 ..close(); |
| 547 } | |
| 548 // TODO(sigurdm): What to do here? Probably we should get rid of | |
|
floitsch
2014/08/28 20:10:06
Agreed.
Until then we usually write the main unit
sigurdm
2014/09/03 08:24:16
Done.
| |
| 549 // compiler.assembledCode | |
| 550 compiler.assembledCode = ""; | |
| 551 } else { | |
| 552 compiler.assembledCode = mainUnparser.result; | |
| 553 compiler.outputProvider("", "dart") | |
| 554 ..add(compiler.assembledCode) | |
| 555 ..close(); | |
| 556 | |
| 557 // Output verbose info about size ratio of resulting bundle to all | |
| 558 // referenced non-platform sources. | |
| 559 logResultBundleSizeInfo(topLevelElements); | |
|
floitsch
2014/08/28 20:10:07
Can we do something similar?
sigurdm
2014/09/03 08:24:16
Done.
| |
| 560 } | |
| 483 } | 561 } |
| 484 | 562 |
| 485 void logResultBundleSizeInfo(Set<Element> topLevelElements) { | 563 void logResultBundleSizeInfo(Set<Element> topLevelElements) { |
| 486 Iterable<LibraryElement> referencedLibraries = | 564 Iterable<LibraryElement> referencedLibraries = |
| 487 compiler.libraryLoader.libraries.where(isUserLibrary); | 565 compiler.libraryLoader.libraries.where(isUserLibrary); |
| 488 // Sum total size of scripts in each referenced library. | 566 // Sum total size of scripts in each referenced library. |
| 489 int nonPlatformSize = 0; | 567 int nonPlatformSize = 0; |
| 490 for (LibraryElement lib in referencedLibraries) { | 568 for (LibraryElement lib in referencedLibraries) { |
| 491 for (CompilationUnitElement compilationUnit in lib.compilationUnits) { | 569 for (CompilationUnitElement compilationUnit in lib.compilationUnits) { |
| 492 nonPlatformSize += compilationUnit.script.file.length; | 570 nonPlatformSize += compilationUnit.script.file.length; |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 } | 772 } |
| 695 | 773 |
| 696 Constant compileMetadata(MetadataAnnotation metadata, | 774 Constant compileMetadata(MetadataAnnotation metadata, |
| 697 Node node, | 775 Node node, |
| 698 TreeElements elements) { | 776 TreeElements elements) { |
| 699 return measure(() { | 777 return measure(() { |
| 700 return constantCompiler.compileMetadata(metadata, node, elements); | 778 return constantCompiler.compileMetadata(metadata, node, elements); |
| 701 }); | 779 }); |
| 702 } | 780 } |
| 703 } | 781 } |
| OLD | NEW |