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 { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 return new Block(rewriteNodeList(statements, builder.toLink())); | 115 return new Block(rewriteNodeList(statements, builder.toLink())); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 class DartBackend extends Backend { | 119 class DartBackend extends Backend { |
| 120 final List<CompilerTask> tasks; | 120 final List<CompilerTask> tasks; |
| 121 final bool forceStripTypes; | 121 final bool forceStripTypes; |
| 122 final bool stripAsserts; | 122 final bool stripAsserts; |
| 123 // TODO(antonm): make available from command-line options. | 123 // TODO(antonm): make available from command-line options. |
| 124 final bool outputAst = false; | 124 final bool outputAst = false; |
| 125 final Map<Node, String> renames; | |
| 126 final Map<LibraryElement, String> imports; | |
| 127 final Map<ClassNode, List<Node>> memberNodes; | |
| 128 // TODO(zarah) Maybe change this to a command-line option; | |
| 129 bool mirrorHelping = false; | |
|
ahe
2013/08/06 15:53:36
Could you make the name a little more descriptive?
zarah
2013/08/08 12:17:10
Done.
| |
| 125 | 130 |
| 126 Map<Element, TreeElements> get resolvedElements => | 131 Map<Element, TreeElements> get resolvedElements => |
| 127 compiler.enqueuer.resolution.resolvedElements; | 132 compiler.enqueuer.resolution.resolvedElements; |
| 128 | 133 |
| 129 /** | 134 /** |
| 130 * Tells whether it is safe to remove type declarations from variables, | 135 * Tells whether it is safe to remove type declarations from variables, |
| 131 * functions parameters. It becomes not safe if: | 136 * functions parameters. It becomes not safe if: |
| 132 * 1) TypeError is used somewhere in the code, | 137 * 1) TypeError is used somewhere in the code, |
| 133 * 2) The code has typedefs in right hand side of IS checks, | 138 * 2) The code has typedefs in right hand side of IS checks, |
| 134 * 3) The code has classes which extend typedefs, have type arguments typedefs | 139 * 3) The code has classes which extend typedefs, have type arguments typedefs |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 164 if (element.allSupertypes != null) { | 169 if (element.allSupertypes != null) { |
| 165 workQueue.addAll(element.allSupertypes.toList()); | 170 workQueue.addAll(element.allSupertypes.toList()); |
| 166 } | 171 } |
| 167 } | 172 } |
| 168 } | 173 } |
| 169 return true; | 174 return true; |
| 170 } | 175 } |
| 171 | 176 |
| 172 DartBackend(Compiler compiler, List<String> strips) | 177 DartBackend(Compiler compiler, List<String> strips) |
| 173 : tasks = <CompilerTask>[], | 178 : tasks = <CompilerTask>[], |
| 179 renames = new Map<Node, String>(), | |
| 180 imports = new Map<LibraryElement, String>(), | |
| 181 memberNodes = new Map<ClassNode, List<Node>>(), | |
| 174 forceStripTypes = strips.indexOf('types') != -1, | 182 forceStripTypes = strips.indexOf('types') != -1, |
| 175 stripAsserts = strips.indexOf('asserts') != -1, | 183 stripAsserts = strips.indexOf('asserts') != -1, |
| 176 super(compiler); | 184 super(compiler); |
| 177 | 185 |
| 178 bool classNeedsRti(ClassElement cls) => false; | 186 bool classNeedsRti(ClassElement cls) => false; |
| 179 bool methodNeedsRti(FunctionElement function) => false; | 187 bool methodNeedsRti(FunctionElement function) => false; |
| 180 | 188 |
| 181 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements) { | 189 void enqueueHelpers(ResolutionEnqueuer world, TreeElements elements) { |
| 182 // Right now resolver doesn't always resolve interfaces needed | 190 // Right now resolver doesn't always resolve interfaces needed |
| 183 // for literals, so force them. TODO(antonm): fix in the resolver. | 191 // for literals, so force them. TODO(antonm): fix in the resolver. |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 // some unused identifier. | 396 // some unused identifier. |
| 389 collector.unresolvedNodes.add(synthesizedIdentifier); | 397 collector.unresolvedNodes.add(synthesizedIdentifier); |
| 390 makePlaceholders(element) { | 398 makePlaceholders(element) { |
| 391 collector.collect(element); | 399 collector.collect(element); |
| 392 if (element.isClass()) { | 400 if (element.isClass()) { |
| 393 classMembers[element].forEach(makePlaceholders); | 401 classMembers[element].forEach(makePlaceholders); |
| 394 } | 402 } |
| 395 } | 403 } |
| 396 topLevelElements.forEach(makePlaceholders); | 404 topLevelElements.forEach(makePlaceholders); |
| 397 // Create renames. | 405 // Create renames. |
| 398 Map<Node, String> renames = new Map<Node, String>(); | |
| 399 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); | |
| 400 bool shouldCutDeclarationTypes = forceStripTypes | 406 bool shouldCutDeclarationTypes = forceStripTypes |
| 401 || (compiler.enableMinification | 407 || (compiler.enableMinification |
| 402 && isSafeToRemoveTypeDeclarations(classMembers)); | 408 && isSafeToRemoveTypeDeclarations(classMembers)); |
| 403 renamePlaceholders( | 409 renamePlaceholders( |
| 404 compiler, collector, renames, imports, | 410 compiler, collector, renames, imports, |
| 405 fixedMemberNames, shouldCutDeclarationTypes); | 411 fixedMemberNames, shouldCutDeclarationTypes); |
| 406 | 412 |
| 407 // Sort elements. | 413 // Sort elements. |
| 408 final sortedTopLevels = sortElements(topLevelElements); | 414 final sortedTopLevels = sortElements(topLevelElements); |
| 409 final sortedClassMembers = new Map<ClassElement, List<Element>>(); | 415 final sortedClassMembers = new Map<ClassElement, List<Element>>(); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 424 sortedClassMembers[topLevel].forEach(outputElement); | 430 sortedClassMembers[topLevel].forEach(outputElement); |
| 425 } else { | 431 } else { |
| 426 outputElement(topLevel); | 432 outputElement(topLevel); |
| 427 } | 433 } |
| 428 } | 434 } |
| 429 compiler.assembledCode = '<Program>\n$sb</Program>\n'; | 435 compiler.assembledCode = '<Program>\n$sb</Program>\n'; |
| 430 return; | 436 return; |
| 431 } | 437 } |
| 432 | 438 |
| 433 final topLevelNodes = <Node>[]; | 439 final topLevelNodes = <Node>[]; |
| 434 final memberNodes = new Map<ClassNode, List<Node>>(); | |
| 435 for (final element in sortedTopLevels) { | 440 for (final element in sortedTopLevels) { |
| 436 topLevelNodes.add(elementAsts[element].ast); | 441 topLevelNodes.add(elementAsts[element].ast); |
| 437 if (element.isClass() && !element.isMixinApplication) { | 442 if (element.isClass() && !element.isMixinApplication) { |
| 438 final members = <Node>[]; | 443 final members = <Node>[]; |
| 439 for (final member in sortedClassMembers[element]) { | 444 for (final member in sortedClassMembers[element]) { |
| 440 members.add(elementAsts[member].ast); | 445 members.add(elementAsts[member].ast); |
| 441 } | 446 } |
| 442 memberNodes[elementAsts[element].ast] = members; | 447 memberNodes[elementAsts[element].ast] = members; |
| 443 } | 448 } |
| 444 } | 449 } |
| 445 | 450 |
| 451 if (mirrorHelping && compiler.mirrorsLibrary != null) { | |
| 452 MirrorRenamer.addMirrorHelperImport(imports); | |
| 453 } | |
| 454 | |
| 446 final unparser = new EmitterUnparser(renames); | 455 final unparser = new EmitterUnparser(renames); |
| 447 emitCode(unparser, imports, topLevelNodes, memberNodes); | 456 emitCode(unparser, imports, topLevelNodes, memberNodes); |
| 448 compiler.assembledCode = unparser.result; | 457 compiler.assembledCode = unparser.result; |
| 449 | 458 |
| 450 // Output verbose info about size ratio of resulting bundle to all | 459 // Output verbose info about size ratio of resulting bundle to all |
| 451 // referenced non-platform sources. | 460 // referenced non-platform sources. |
| 452 logResultBundleSizeInfo(topLevelElements); | 461 logResultBundleSizeInfo(topLevelElements); |
| 453 } | 462 } |
| 454 | 463 |
| 455 void logResultBundleSizeInfo(Set<Element> topLevelElements) { | 464 void logResultBundleSizeInfo(Set<Element> topLevelElements) { |
| 456 Iterable<LibraryElement> referencedLibraries = | 465 Iterable<LibraryElement> referencedLibraries = |
| 457 compiler.libraries.values.where(isUserLibrary); | 466 compiler.libraries.values.where(isUserLibrary); |
| 458 // Sum total size of scripts in each referenced library. | 467 // Sum total size of scripts in each referenced library. |
| 459 int nonPlatformSize = 0; | 468 int nonPlatformSize = 0; |
| 460 for (LibraryElement lib in referencedLibraries) { | 469 for (LibraryElement lib in referencedLibraries) { |
| 461 for (CompilationUnitElement compilationUnit in lib.compilationUnits) { | 470 for (CompilationUnitElement compilationUnit in lib.compilationUnits) { |
| 462 nonPlatformSize += compilationUnit.script.text.length; | 471 nonPlatformSize += compilationUnit.script.text.length; |
| 463 } | 472 } |
| 464 } | 473 } |
| 465 int percentage = compiler.assembledCode.length * 100 ~/ nonPlatformSize; | 474 int percentage = compiler.assembledCode.length * 100 ~/ nonPlatformSize; |
| 466 log('Total used non-platform files size: ${nonPlatformSize} bytes, ' | 475 log('Total used non-platform files size: ${nonPlatformSize} bytes, ' |
| 467 'bundle size: ${compiler.assembledCode.length} bytes (${percentage}%)'); | 476 'bundle size: ${compiler.assembledCode.length} bytes (${percentage}%)'); |
| 468 } | 477 } |
| 469 | 478 |
| 470 log(String message) => compiler.log('[DartBackend] $message'); | 479 log(String message) => compiler.log('[DartBackend] $message'); |
| 480 | |
| 481 void registerStaticSend(Element element, Node node) { | |
| 482 if (mirrorHelping && compiler.mirrorsLibrary != null) { | |
| 483 MirrorRenamer.handleStaticSend(renames, element, node, compiler); | |
| 484 } | |
| 485 } | |
| 486 | |
|
ahe
2013/08/06 15:53:36
Extra line.
zarah
2013/08/08 12:17:10
Done.
| |
| 471 } | 487 } |
| 472 | 488 |
| 473 class EmitterUnparser extends Unparser { | 489 class EmitterUnparser extends Unparser { |
| 474 final Map<Node, String> renames; | 490 final Map<Node, String> renames; |
| 475 | 491 |
| 476 EmitterUnparser(this.renames); | 492 EmitterUnparser(this.renames); |
| 477 | 493 |
| 478 visit(Node node) { | 494 visit(Node node) { |
| 479 if (node != null && renames.containsKey(node)) { | 495 if (node != null && renames.containsKey(node)) { |
| 480 sb.write(renames[node]); | 496 sb.write(renames[node]); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 546 } | 562 } |
| 547 | 563 |
| 548 compareElements(e0, e1) { | 564 compareElements(e0, e1) { |
| 549 int result = compareBy((e) => e.getLibrary().canonicalUri.toString())(e0, e1); | 565 int result = compareBy((e) => e.getLibrary().canonicalUri.toString())(e0, e1); |
| 550 if (result != 0) return result; | 566 if (result != 0) return result; |
| 551 return compareBy((e) => e.position().charOffset)(e0, e1); | 567 return compareBy((e) => e.position().charOffset)(e0, e1); |
| 552 } | 568 } |
| 553 | 569 |
| 554 List<Element> sortElements(Iterable<Element> elements) => | 570 List<Element> sortElements(Iterable<Element> elements) => |
| 555 sorted(elements, compareElements); | 571 sorted(elements, compareElements); |
| OLD | NEW |