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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart

Issue 476583003: Allow dart2dart to output one file per library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Insert library-names in generateds libraries. Fix bug of previous upload Created 6 years, 4 months 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
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698