| 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 const bool REMOVE_ASSERTS = false; | |
| 6 | |
| 7 class ElementAst { | 5 class ElementAst { |
| 8 final Node ast; | 6 final Node ast; |
| 9 final TreeElements treeElements; | 7 final TreeElements treeElements; |
| 10 | 8 |
| 11 ElementAst(this.ast, this.treeElements); | 9 ElementAst(this.ast, this.treeElements); |
| 12 | 10 |
| 13 factory ElementAst.rewrite(compiler, ast, treeElements) { | 11 factory ElementAst.rewrite(compiler, ast, treeElements, stripAsserts) { |
| 14 final rewriter = new FunctionBodyRewriter(compiler, treeElements); | 12 final rewriter = |
| 13 new FunctionBodyRewriter(compiler, treeElements, stripAsserts); |
| 15 return new ElementAst(rewriter.visit(ast), rewriter.cloneTreeElements); | 14 return new ElementAst(rewriter.visit(ast), rewriter.cloneTreeElements); |
| 16 } | 15 } |
| 17 | 16 |
| 18 ElementAst.forClassLike(this.ast) | 17 ElementAst.forClassLike(this.ast) |
| 19 : this.treeElements = new TreeElementMapping(); | 18 : this.treeElements = new TreeElementMapping(); |
| 20 } | 19 } |
| 21 | 20 |
| 22 class AggregatedTreeElements extends TreeElementMapping { | 21 class AggregatedTreeElements extends TreeElementMapping { |
| 23 final List<TreeElements> treeElements; | 22 final List<TreeElements> treeElements; |
| 24 | 23 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 | 55 |
| 57 add(VariableElement element, TreeElements treeElements) { | 56 add(VariableElement element, TreeElements treeElements) { |
| 58 AggregatedTreeElements e = this.treeElements; | 57 AggregatedTreeElements e = this.treeElements; |
| 59 e[element.cachedNode] = element; | 58 e[element.cachedNode] = element; |
| 60 e.treeElements.add(treeElements); | 59 e.treeElements.add(treeElements); |
| 61 } | 60 } |
| 62 } | 61 } |
| 63 | 62 |
| 64 class FunctionBodyRewriter extends CloningVisitor { | 63 class FunctionBodyRewriter extends CloningVisitor { |
| 65 final Compiler compiler; | 64 final Compiler compiler; |
| 65 final bool stripAsserts; |
| 66 | 66 |
| 67 FunctionBodyRewriter(this.compiler, originalTreeElements) | 67 FunctionBodyRewriter(this.compiler, originalTreeElements, this.stripAsserts) |
| 68 : super(originalTreeElements); | 68 : super(originalTreeElements); |
| 69 | 69 |
| 70 visitBlock(Block block) { | 70 visitBlock(Block block) { |
| 71 shouldOmit(Statement statement) { | 71 shouldOmit(Statement statement) { |
| 72 if (statement is EmptyStatement) return true; | 72 if (statement is EmptyStatement) return true; |
| 73 if (statement is ExpressionStatement) { | 73 if (statement is ExpressionStatement) { |
| 74 Send send = statement.expression.asSend(); | 74 Send send = statement.expression.asSend(); |
| 75 if (send !== null) { | 75 if (send !== null) { |
| 76 Element element = originalTreeElements[send]; | 76 Element element = originalTreeElements[send]; |
| 77 if (REMOVE_ASSERTS && element === compiler.assertMethod) { | 77 if (stripAsserts && element === compiler.assertMethod) { |
| 78 return true; | 78 return true; |
| 79 } | 79 } |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 return false; | 82 return false; |
| 83 } | 83 } |
| 84 | 84 |
| 85 rewiteStatement(Statement statement) { | 85 rewiteStatement(Statement statement) { |
| 86 if (statement is Block) { | 86 if (statement is Block) { |
| 87 Link statements = statement.statements.nodes; | 87 Link statements = statement.statements.nodes; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 101 if (!shouldOmit(statement)) { | 101 if (!shouldOmit(statement)) { |
| 102 builder.addLast(visit(rewiteStatement(statement))); | 102 builder.addLast(visit(rewiteStatement(statement))); |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 return new Block(rewriteNodeList(statements, builder.toLink())); | 105 return new Block(rewriteNodeList(statements, builder.toLink())); |
| 106 } | 106 } |
| 107 } | 107 } |
| 108 | 108 |
| 109 class DartBackend extends Backend { | 109 class DartBackend extends Backend { |
| 110 final List<CompilerTask> tasks; | 110 final List<CompilerTask> tasks; |
| 111 final bool forceCutDeclarationTypes; | 111 final bool forceStripTypes; |
| 112 final bool stripAsserts; |
| 112 // TODO(antonm): make available from command-line options. | 113 // TODO(antonm): make available from command-line options. |
| 113 final bool outputAst = false; | 114 final bool outputAst = false; |
| 114 | 115 |
| 115 Map<Element, TreeElements> get resolvedElements => | 116 Map<Element, TreeElements> get resolvedElements => |
| 116 compiler.enqueuer.resolution.resolvedElements; | 117 compiler.enqueuer.resolution.resolvedElements; |
| 117 | 118 |
| 118 /** | 119 /** |
| 119 * Tells whether it is safe to remove type declarations from variables, | 120 * Tells whether it is safe to remove type declarations from variables, |
| 120 * functions parameters. It becomes not safe if: | 121 * functions parameters. It becomes not safe if: |
| 121 * 1) TypeError is used somewhere in the code, | 122 * 1) TypeError is used somewhere in the code, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 } | 175 } |
| 175 // Check all supertypes. | 176 // Check all supertypes. |
| 176 if (element.allSupertypes !== null) { | 177 if (element.allSupertypes !== null) { |
| 177 workQueue.addAll(element.allSupertypes.toList()); | 178 workQueue.addAll(element.allSupertypes.toList()); |
| 178 } | 179 } |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 return true; | 182 return true; |
| 182 } | 183 } |
| 183 | 184 |
| 184 DartBackend(Compiler compiler, this.forceCutDeclarationTypes) | 185 DartBackend(Compiler compiler, List<String> strips) |
| 185 : tasks = <CompilerTask>[], | 186 : tasks = <CompilerTask>[], |
| 187 forceStripTypes = strips.indexOf('types') != -1, |
| 188 stripAsserts = strips.indexOf('asserts') != -1, |
| 186 super(compiler); | 189 super(compiler); |
| 187 | 190 |
| 188 void enqueueHelpers(Enqueuer world) { | 191 void enqueueHelpers(Enqueuer world) { |
| 189 // Right now resolver doesn't always resolve interfaces needed | 192 // Right now resolver doesn't always resolve interfaces needed |
| 190 // for literals, so force them. TODO(antonm): fix in the resolver. | 193 // for literals, so force them. TODO(antonm): fix in the resolver. |
| 191 final LITERAL_TYPE_NAMES = const [ | 194 final LITERAL_TYPE_NAMES = const [ |
| 192 'Map', 'List', 'num', 'int', 'double', 'bool' | 195 'Map', 'List', 'num', 'int', 'double', 'bool' |
| 193 ]; | 196 ]; |
| 194 final coreLibrary = compiler.coreLibrary; | 197 final coreLibrary = compiler.coreLibrary; |
| 195 for (final name in LITERAL_TYPE_NAMES) { | 198 for (final name in LITERAL_TYPE_NAMES) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 new ElementAst.forClassLike(parse(element))); | 296 new ElementAst.forClassLike(parse(element))); |
| 294 }; | 297 }; |
| 295 newClassElementCallback = (ClassElement classElement) { | 298 newClassElementCallback = (ClassElement classElement) { |
| 296 if (!shouldOutput(classElement)) return; | 299 if (!shouldOutput(classElement)) return; |
| 297 addClass(classElement); | 300 addClass(classElement); |
| 298 }; | 301 }; |
| 299 | 302 |
| 300 resolvedElements.forEach((element, treeElements) { | 303 resolvedElements.forEach((element, treeElements) { |
| 301 if (!shouldOutput(element)) return; | 304 if (!shouldOutput(element)) return; |
| 302 | 305 |
| 303 var elementAst = | 306 var elementAst = new ElementAst.rewrite( |
| 304 new ElementAst.rewrite(compiler, parse(element), treeElements); | 307 compiler, parse(element), treeElements, stripAsserts); |
| 305 if (element.isField()) { | 308 if (element.isField()) { |
| 306 final list = (element as VariableElement).variables; | 309 final list = (element as VariableElement).variables; |
| 307 elementAst = elementAsts.putIfAbsent( | 310 elementAst = elementAsts.putIfAbsent( |
| 308 list, () => new VariableListAst(parse(list))); | 311 list, () => new VariableListAst(parse(list))); |
| 309 (elementAst as VariableListAst).add(element, treeElements); | 312 (elementAst as VariableListAst).add(element, treeElements); |
| 310 element = list; | 313 element = list; |
| 311 } | 314 } |
| 312 | 315 |
| 313 if (element.isMember()) { | 316 if (element.isMember()) { |
| 314 ClassElement enclosingClass = element.getEnclosingClass(); | 317 ClassElement enclosingClass = element.getEnclosingClass(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 makePlaceholders(element) { | 373 makePlaceholders(element) { |
| 371 collector.collect(element); | 374 collector.collect(element); |
| 372 if (element is ClassElement) { | 375 if (element is ClassElement) { |
| 373 classMembers[element].forEach(makePlaceholders); | 376 classMembers[element].forEach(makePlaceholders); |
| 374 } | 377 } |
| 375 } | 378 } |
| 376 topLevelElements.forEach(makePlaceholders); | 379 topLevelElements.forEach(makePlaceholders); |
| 377 // Create renames. | 380 // Create renames. |
| 378 Map<Node, String> renames = new Map<Node, String>(); | 381 Map<Node, String> renames = new Map<Node, String>(); |
| 379 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); | 382 Map<LibraryElement, String> imports = new Map<LibraryElement, String>(); |
| 380 bool shouldCutDeclarationTypes = forceCutDeclarationTypes | 383 bool shouldCutDeclarationTypes = forceStripTypes |
| 381 || (compiler.enableMinification | 384 || (compiler.enableMinification |
| 382 && isSafeToRemoveTypeDeclarations(classMembers)); | 385 && isSafeToRemoveTypeDeclarations(classMembers)); |
| 383 renamePlaceholders( | 386 renamePlaceholders( |
| 384 compiler, collector, renames, imports, | 387 compiler, collector, renames, imports, |
| 385 fixedMemberNames, shouldCutDeclarationTypes); | 388 fixedMemberNames, shouldCutDeclarationTypes); |
| 386 | 389 |
| 387 // Sort elements. | 390 // Sort elements. |
| 388 final sortedTopLevels = sortElements(topLevelElements); | 391 final sortedTopLevels = sortElements(topLevelElements); |
| 389 final sortedClassMembers = new Map<ClassElement, List<Element>>(); | 392 final sortedClassMembers = new Map<ClassElement, List<Element>>(); |
| 390 classMembers.forEach((classElement, members) { | 393 classMembers.forEach((classElement, members) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 } | 533 } |
| 531 | 534 |
| 532 compareElements(e0, e1) { | 535 compareElements(e0, e1) { |
| 533 int result = compareBy((e) => e.getLibrary().uri.toString())(e0, e1); | 536 int result = compareBy((e) => e.getLibrary().uri.toString())(e0, e1); |
| 534 if (result != 0) return result; | 537 if (result != 0) return result; |
| 535 return compareBy((e) => e.position().charOffset)(e0, e1); | 538 return compareBy((e) => e.position().charOffset)(e0, e1); |
| 536 } | 539 } |
| 537 | 540 |
| 538 List<Element> sortElements(Collection<Element> elements) => | 541 List<Element> sortElements(Collection<Element> elements) => |
| 539 sorted(elements, compareElements); | 542 sorted(elements, compareElements); |
| OLD | NEW |