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 // 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |