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

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: 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 // Should the output go to one file per input library, or everything in one
29 // file.
Johnni Winther 2014/08/15 08:07:31 Paraphrase to something like "If `true`, libraries
sigurdm 2014/08/15 13:31:42 Done.
30 final bool multiFile;
31
28 PlaceholderRenamer placeholderRenamer; 32 PlaceholderRenamer placeholderRenamer;
29 33
30 // TODO(zarah) Maybe change this to a command-line option. 34 // TODO(zarah) Maybe change this to a command-line option.
31 // Right now, it is set by the tests. 35 // Right now, it is set by the tests.
32 bool useMirrorHelperLibrary = false; 36 bool useMirrorHelperLibrary = false;
33 37
34 /// Initialized if the useMirrorHelperLibrary field is set. 38 /// Initialized if the useMirrorHelperLibrary field is set.
35 MirrorRenamer mirrorRenamer; 39 MirrorRenamer mirrorRenamer;
36 40
37 /// Initialized when dart:mirrors is loaded if the useMirrorHelperLibrary 41 /// 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; 99 ClassElement element = type.element;
96 // Check all supertypes. 100 // Check all supertypes.
97 if (element.allSupertypes != null) { 101 if (element.allSupertypes != null) {
98 element.allSupertypes.forEach(workQueue.add); 102 element.allSupertypes.forEach(workQueue.add);
99 } 103 }
100 } 104 }
101 } 105 }
102 return true; 106 return true;
103 } 107 }
104 108
105 DartBackend(Compiler compiler, List<String> strips) 109 DartBackend(Compiler compiler, List<String> strips, {this.multiFile})
106 : tasks = <CompilerTask>[], 110 : tasks = <CompilerTask>[],
107 memberNodes = new Map<ClassNode, List<Node>>(), 111 memberNodes = new Map<ClassNode, List<Node>>(),
108 forceStripTypes = strips.indexOf('types') != -1, 112 forceStripTypes = strips.indexOf('types') != -1,
109 stripAsserts = strips.indexOf('asserts') != -1, 113 stripAsserts = strips.indexOf('asserts') != -1,
110 constantCompilerTask = new DartConstantTask(compiler), 114 constantCompilerTask = new DartConstantTask(compiler),
111 super(compiler) { 115 super(compiler) {
112 resolutionCallbacks = new DartResolutionCallbacks(this); 116 resolutionCallbacks = new DartResolutionCallbacks(this);
113 } 117 }
114 118
115 bool classNeedsRti(ClassElement cls) => false; 119 bool classNeedsRti(ClassElement cls) => false;
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 compiler.tracer.traceGraph('Unshadow parameters', definition); 261 compiler.tracer.traceGraph('Unshadow parameters', definition);
258 262
259 TreeElementMapping treeElements = new TreeElementMapping(element); 263 TreeElementMapping treeElements = new TreeElementMapping(element);
260 backend_ast.Node backendAst = 264 backend_ast.Node backendAst =
261 backend_ast_emitter.emit(definition); 265 backend_ast_emitter.emit(definition);
262 Node frontend_ast = backend2frontend.emit(treeElements, backendAst); 266 Node frontend_ast = backend2frontend.emit(treeElements, backendAst);
263 return new ElementAst.internal(frontend_ast, treeElements); 267 return new ElementAst.internal(frontend_ast, treeElements);
264 } 268 }
265 } 269 }
266 270
271 List<LibraryElement> userLibraries =
272 compiler.libraryLoader.libraries.where(isUserLibrary).toList();
273
267 Set<Element> topLevelElements = new Set<Element>(); 274 Set<Element> topLevelElements = new Set<Element>();
268 Map<ClassElement, Set<Element>> classMembers = 275 Map<ClassElement, Set<Element>> classMembers =
269 new Map<ClassElement, Set<Element>>(); 276 new Map<ClassElement, Set<Element>>();
270 277
271 // Build all top level elements to emit and necessary class members. 278 // Build all top level elements to emit and necessary class members.
272 var newTypedefElementCallback, newClassElementCallback; 279 var newTypedefElementCallback, newClassElementCallback;
273 280
274 void processElement(Element element, ElementAst elementAst) { 281 void processElement(Element element, ElementAst elementAst) {
275 ReferencedElementCollector collector = 282 ReferencedElementCollector collector =
276 new ReferencedElementCollector(compiler, 283 new ReferencedElementCollector(compiler,
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 } 451 }
445 memberNodes[elementAsts[element].ast] = members; 452 memberNodes[elementAsts[element].ast] = members;
446 } 453 }
447 } 454 }
448 455
449 if (useMirrorHelperLibrary) { 456 if (useMirrorHelperLibrary) {
450 mirrorRenamer.addRenames(placeholderRenamer.renames, 457 mirrorRenamer.addRenames(placeholderRenamer.renames,
451 topLevelNodes, collector); 458 topLevelNodes, collector);
452 } 459 }
453 460
454 final unparser = new EmitterUnparser(placeholderRenamer.renames, 461 Map<LibraryElement, String> outputUris = new Map<LibraryElement, String>();
455 stripTypes: forceStripTypes, 462 Map<LibraryElement, EmitterUnparser> unparsers =
456 minify: compiler.enableMinification); 463 new Map<LibraryElement, EmitterUnparser>();
457 for(LibraryElement library in placeholderRenamer.platformImports) { 464
458 if (library.isPlatformLibrary && !library.isInternalLibrary) { 465 // The single unparser used if we collect all the output in one file
459 unparser.unparseImportTag(library.canonicalUri.toString()); 466 EmitterUnparser mainUnparser = multiFile
467 ? null
468 : new EmitterUnparser(placeholderRenamer.renames,
469 stripTypes: forceStripTypes,
470 minify: compiler.enableMinification);
471
472 if (multiFile) {
473 Set<String> usedLibraryNames = new Set<String>();
474 for (LibraryElement library in userLibraries) {
475 List<String> names = library.canonicalUri.pathSegments.last.split(".");
476 if (names.last == "dart") {
477 names = names.sublist(0, names.length - 1);
floitsch 2014/08/15 11:59:36 names is only used when the library is not the mai
sigurdm 2014/08/15 13:31:42 Done.
478 }
479 String mainName = compiler.outputUri.path.split('/').last;
jgruber1 2014/08/15 06:20:53 Does this work on windows?
Johnni Winther 2014/08/15 08:07:31 Use [Uri.pathSegments] instead of `path.split('/')
floitsch 2014/08/15 11:59:36 You should be able to compute the mainName/mmainBa
sigurdm 2014/08/15 13:31:42 I think so - Uri's should normalize path segment s
sigurdm 2014/08/15 13:31:42 Thanks
sigurdm 2014/08/15 13:31:42 Done.
480 String mainBaseName = mainName.endsWith(".dart")
481 ? mainName.substring(0, mainName.length - 5)
482 : mainName;
483 String uri = library == compiler.mainApp
484 ? mainBaseName
485 : "$mainBaseName.${makeUnique(names.join("."), usedLibraryNames)}";
floitsch 2014/08/15 11:59:36 usedLibraryNames does not contain the "mainBaseNam
sigurdm 2014/08/15 13:31:42 But this is only a suffix. So we generate mainBase
486 outputUris[library] = uri;
487 unparsers[library] = new EmitterUnparser(placeholderRenamer.renames,
488 stripTypes: forceStripTypes, minify: compiler.enableMinification);
489 }
490
491 for(LibraryElement outputLibrary in userLibraries) {
jgruber1 2014/08/15 06:20:53 Can we merge this into the previous for loop?
Johnni Winther 2014/08/15 08:07:31 No. This loop requires [outputUris] to be fully co
sigurdm 2014/08/15 13:31:42 Acknowledged.
sigurdm 2014/08/15 13:31:42 We want to set up all the ouputUris before using t
492 EmitterUnparser unparser = unparsers[outputLibrary];
493 for (LibraryTag tag in outputLibrary.tags) {
494 if (tag is! LibraryDependency) continue;
495 LibraryDependency dependency = tag;
496 LibraryElement libraryElement =
497 outputLibrary.getLibraryFromTag(dependency);
498 String uri = outputUris.containsKey(libraryElement)
499 ? outputUris[libraryElement] + ".dart"
Johnni Winther 2014/08/15 08:07:31 Use '${outputUri[LibraryElement]}.dart' instead of
sigurdm 2014/08/15 13:31:42 Done.
500 : libraryElement.canonicalUri.toString();
501 if (dependency is Import) {
502 unparser.unparseImportTag('$uri');
jgruber1 2014/08/15 06:20:53 unparseImportTag(uri)?
sigurdm 2014/08/15 13:31:42 Done.
503 } else {
504 unparser.unparseExportTag('$uri');
505 }
506 }
507 }
508 } else {
509 for(LibraryElement library in placeholderRenamer.platformImports) {
510 if (library.isPlatformLibrary && !library.isInternalLibrary) {
511 mainUnparser.unparseImportTag(library.canonicalUri.toString());
512 }
460 } 513 }
461 } 514 }
515
462 for (int i = 0; i < sortedTopLevels.length; i++) { 516 for (int i = 0; i < sortedTopLevels.length; i++) {
463 Element element = sortedTopLevels[i]; 517 Element element = sortedTopLevels[i];
464 Node node = topLevelNodes[i]; 518 Node node = topLevelNodes[i];
519 Unparser unparser = multiFile ? unparsers[element.library] : mainUnparser;
465 if (node is ClassNode) { 520 if (node is ClassNode) {
466 // TODO(smok): Filter out default constructors here. 521 // TODO(smok): Filter out default constructors here.
467 unparser.unparseClassWithBody(node, memberNodes[node]); 522 unparser.unparseClassWithBody(node, memberNodes[node]);
468 } else { 523 } else {
469 unparser.unparse(node); 524 unparser.unparse(node);
470 } 525 }
471 unparser.newline(); 526 unparser.newline();
472 } 527 }
473 528
474 compiler.assembledCode = unparser.result; 529 if (multiFile) {
475 compiler.outputProvider("", "dart") 530 for(LibraryElement outputLibrary in userLibraries) {
476 ..add(compiler.assembledCode) 531 compiler.outputProvider(outputUris[outputLibrary], "dart")
477 ..close(); 532 ..add(unparsers[outputLibrary].result)
Johnni Winther 2014/08/15 08:07:31 Add a TODO to enable direct output, i.e. avoid cac
sigurdm 2014/08/15 13:31:42 Done.
478 // Output verbose info about size ratio of resulting bundle to all 533 ..close();
479 // referenced non-platform sources. 534 }
480 logResultBundleSizeInfo(topLevelElements); 535 // TODO(sigurdm): What to do here? Probably we should get rid of
536 // compiler.assembledCode
537 compiler.assembledCode = "";
538 } else {
539 compiler.assembledCode = mainUnparser.result;
540 compiler.outputProvider("", "dart")
541 ..add(compiler.assembledCode)
542 ..close();
543
544 // Output verbose info about size ratio of resulting bundle to all
545 // referenced non-platform sources.
546 logResultBundleSizeInfo(topLevelElements);
547 }
481 } 548 }
482 549
483 void logResultBundleSizeInfo(Set<Element> topLevelElements) { 550 void logResultBundleSizeInfo(Set<Element> topLevelElements) {
484 Iterable<LibraryElement> referencedLibraries = 551 Iterable<LibraryElement> referencedLibraries =
485 compiler.libraryLoader.libraries.where(isUserLibrary); 552 compiler.libraryLoader.libraries.where(isUserLibrary);
486 // Sum total size of scripts in each referenced library. 553 // Sum total size of scripts in each referenced library.
487 int nonPlatformSize = 0; 554 int nonPlatformSize = 0;
488 for (LibraryElement lib in referencedLibraries) { 555 for (LibraryElement lib in referencedLibraries) {
489 for (CompilationUnitElement compilationUnit in lib.compilationUnits) { 556 for (CompilationUnitElement compilationUnit in lib.compilationUnits) {
490 nonPlatformSize += compilationUnit.script.file.length; 557 nonPlatformSize += compilationUnit.script.file.length;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
692 } 759 }
693 760
694 Constant compileMetadata(MetadataAnnotation metadata, 761 Constant compileMetadata(MetadataAnnotation metadata,
695 Node node, 762 Node node,
696 TreeElements elements) { 763 TreeElements elements) {
697 return measure(() { 764 return measure(() {
698 return constantCompiler.compileMetadata(metadata, node, elements); 765 return constantCompiler.compileMetadata(metadata, node, elements);
699 }); 766 });
700 } 767 }
701 } 768 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698