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