| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library analyzer2dart.treeShaker; | 5 library analyzer2dart.treeShaker; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/analyzer.dart'; | 9 import 'package:analyzer/analyzer.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 fields); | 200 fields); |
| 201 methods.forEach(_addElement); | 201 methods.forEach(_addElement); |
| 202 accessors.forEach(_addElement); | 202 accessors.forEach(_addElement); |
| 203 fields.forEach(_addElement); | 203 fields.forEach(_addElement); |
| 204 } | 204 } |
| 205 | 205 |
| 206 ClosedWorld shake() { | 206 ClosedWorld shake() { |
| 207 _addElement(_world.mainFunction); | 207 _addElement(_world.mainFunction); |
| 208 while (_queue.isNotEmpty) { | 208 while (_queue.isNotEmpty) { |
| 209 Element element = _queue.removeLast(); | 209 Element element = _queue.removeLast(); |
| 210 print('Tree shaker handling $element'); | |
| 211 if (element is ExecutableElement) { | 210 if (element is ExecutableElement) { |
| 212 MethodAnalysis analysis = _localComputer.analyzeMethod(element); | 211 MethodAnalysis analysis = _localComputer.analyzeMethod(element); |
| 213 _world.executableElements[element] = analysis.declaration; | 212 _world.executableElements[element] = analysis.declaration; |
| 214 analysis.calls.forEach(_addElement); | 213 analysis.calls.forEach(_addElement); |
| 215 analysis.invokes.forEach(_addSelector); | 214 analysis.invokes.forEach(_addSelector); |
| 216 analysis.instantiates.forEach(_addElement); | 215 analysis.instantiates.forEach(_addElement); |
| 217 analysis.accesses.forEach(_addElement); | 216 analysis.accesses.forEach(_addElement); |
| 218 } else if (element is ClassElement) { | 217 } else if (element is ClassElement) { |
| 219 ClassAnalysis analysis = _localComputer.analyzeClass(element); | 218 ClassAnalysis analysis = _localComputer.analyzeClass(element); |
| 220 _world.instantiatedClasses[element] = analysis.declaration; | 219 _world.instantiatedClasses[element] = analysis.declaration; |
| 221 for (Selector selector in _selectors) { | 220 for (Selector selector in _selectors) { |
| 222 _matchClassToSelector(element, selector); | 221 _matchClassToSelector(element, selector); |
| 223 } | 222 } |
| 224 } else if (element is FieldElement) { | 223 } else if (element is FieldElement) { |
| 225 VariableDeclaration declaration = element.node; | 224 VariableDeclaration declaration = element.node; |
| 226 _world.fields[element] = declaration; | 225 _world.fields[element] = declaration; |
| 227 } else if (element is TopLevelVariableElement) { | 226 } else if (element is TopLevelVariableElement) { |
| 228 VariableDeclaration declaration = element.node; | 227 VariableDeclaration declaration = element.node; |
| 229 _world.variables[element] = declaration; | 228 _world.variables[element] = declaration; |
| 230 } else { | 229 } else { |
| 231 throw new Exception( | 230 throw new Exception( |
| 232 'Unexpected element type while tree shaking: ' | 231 'Unexpected element type while tree shaking: ' |
| 233 '$element (${element.runtimeType})'); | 232 '$element (${element.runtimeType})'); |
| 234 } | 233 } |
| 235 } | 234 } |
| 236 print('Tree shaking done'); | |
| 237 return _world; | 235 return _world; |
| 238 } | 236 } |
| 239 } | 237 } |
| 240 | 238 |
| 241 class TreeShakingVisitor extends SemanticVisitor { | 239 class TreeShakingVisitor extends SemanticVisitor { |
| 242 final MethodAnalysis analysis; | 240 final MethodAnalysis analysis; |
| 243 | 241 |
| 244 TreeShakingVisitor(this.analysis); | 242 TreeShakingVisitor(this.analysis); |
| 245 | 243 |
| 246 Source get currentSource => analysis.declaration.element.source; | 244 Source get currentSource => analysis.declaration.element.source; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 | 283 |
| 286 @override | 284 @override |
| 287 void visitStaticFieldInvocation(MethodInvocation node, | 285 void visitStaticFieldInvocation(MethodInvocation node, |
| 288 AccessSemantics semantics) { | 286 AccessSemantics semantics) { |
| 289 // Invocation of a static field. | 287 // Invocation of a static field. |
| 290 analysis.accesses.add(semantics.element); | 288 analysis.accesses.add(semantics.element); |
| 291 analysis.invokes.add(createSelectorFromMethodInvocation( | 289 analysis.invokes.add(createSelectorFromMethodInvocation( |
| 292 node.argumentList, 'call')); | 290 node.argumentList, 'call')); |
| 293 } | 291 } |
| 294 | 292 |
| 293 @override |
| 295 void visitStaticMethodInvocation(MethodInvocation node, | 294 void visitStaticMethodInvocation(MethodInvocation node, |
| 296 AccessSemantics semantics) { | 295 AccessSemantics semantics) { |
| 297 analysis.calls.add(semantics.element); | 296 analysis.calls.add(semantics.element); |
| 298 } | 297 } |
| 299 | 298 |
| 299 @override |
| 300 void visitStaticPropertyInvocation(MethodInvocation node, | 300 void visitStaticPropertyInvocation(MethodInvocation node, |
| 301 AccessSemantics semantics) { | 301 AccessSemantics semantics) { |
| 302 // Invocation of a property. TODO(paulberry): handle this. | 302 // Invocation of a property. TODO(paulberry): handle this. |
| 303 super.visitStaticPropertyInvocation(node, semantics); | 303 super.visitStaticPropertyInvocation(node, semantics); |
| 304 } | 304 } |
| 305 | 305 |
| 306 void visitDynamicAccess(AstNode node, AccessSemantics semantics) { | 306 void handleDynamicAccess(AccessSemantics semantics) { |
| 307 if (semantics.isRead) { | 307 if (semantics.isRead) { |
| 308 analysis.invokes.add( | 308 analysis.invokes.add( |
| 309 new Selector.getter(semantics.identifier.name, null)); | 309 new Selector.getter(semantics.identifier.name, null)); |
| 310 } | 310 } |
| 311 if (semantics.isWrite) { | 311 if (semantics.isWrite) { |
| 312 // Selector.setter constructor uses the convention that setter names | 312 // Selector.setter constructor uses the convention that setter names |
| 313 // don't end in '='. | 313 // don't end in '='. |
| 314 analysis.invokes.add( | 314 analysis.invokes.add( |
| 315 new Selector.setter(semantics.identifier.name, null)); | 315 new Selector.setter(semantics.identifier.name, null)); |
| 316 } | 316 } |
| 317 } | 317 } |
| 318 | 318 |
| 319 @override |
| 320 void visitDynamicAccess(AstNode node, AccessSemantics semantics) { |
| 321 handleDynamicAccess(semantics); |
| 322 } |
| 323 |
| 324 @override |
| 319 void visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) { | 325 void visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) { |
| 320 // Locals don't need to be tree shaken. | 326 // Locals don't need to be tree shaken. |
| 321 } | 327 } |
| 322 | 328 |
| 329 @override |
| 323 void visitLocalVariableAccess(AstNode node, AccessSemantics semantics) { | 330 void visitLocalVariableAccess(AstNode node, AccessSemantics semantics) { |
| 324 // Locals don't need to be tree shaken. | 331 // Locals don't need to be tree shaken. |
| 325 } | 332 } |
| 326 | 333 |
| 334 @override |
| 327 void visitParameterAccess(AstNode node, AccessSemantics semantics) { | 335 void visitParameterAccess(AstNode node, AccessSemantics semantics) { |
| 328 // Locals don't need to be tree shaken. | 336 // Locals don't need to be tree shaken. |
| 329 } | 337 } |
| 330 | 338 |
| 339 @override |
| 331 void visitStaticFieldAccess(AstNode node, AccessSemantics semantics) { | 340 void visitStaticFieldAccess(AstNode node, AccessSemantics semantics) { |
| 332 analysis.accesses.add(semantics.element); | 341 analysis.accesses.add(semantics.element); |
| 333 } | 342 } |
| 334 | 343 |
| 344 @override |
| 335 void visitStaticMethodAccess(AstNode node, AccessSemantics semantics) { | 345 void visitStaticMethodAccess(AstNode node, AccessSemantics semantics) { |
| 336 // Method tear-off. TODO(paulberry): implement. | 346 // Method tear-off. TODO(paulberry): implement. |
| 337 super.visitStaticMethodAccess(node, semantics); | 347 super.visitStaticMethodAccess(node, semantics); |
| 338 } | 348 } |
| 339 | 349 |
| 350 @override |
| 340 void visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) { | 351 void visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) { |
| 341 // TODO(paulberry): implement. | 352 // TODO(paulberry): implement. |
| 342 super.visitStaticPropertyAccess(node, semantics); | 353 super.visitStaticPropertyAccess(node, semantics); |
| 343 } | 354 } |
| 344 | 355 |
| 345 @override | 356 @override |
| 346 void visitConstructorDeclaration(ConstructorDeclaration node) { | 357 void visitConstructorDeclaration(ConstructorDeclaration node) { |
| 347 // TODO(paulberry): handle parameter list. | 358 // TODO(paulberry): handle parameter list. |
| 348 node.initializers.accept(this); | 359 node.initializers.accept(this); |
| 349 node.body.accept(this); | 360 node.body.accept(this); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 368 } | 379 } |
| 369 | 380 |
| 370 @override | 381 @override |
| 371 void | 382 void |
| 372 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { | 383 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { |
| 373 // Note: we don't have to worry about node.staticElement being | 384 // Note: we don't have to worry about node.staticElement being |
| 374 // null, because that would have been detected by the analyzer and | 385 // null, because that would have been detected by the analyzer and |
| 375 // reported as a compile time error. | 386 // reported as a compile time error. |
| 376 analysis.calls.add(node.staticElement); | 387 analysis.calls.add(node.staticElement); |
| 377 } | 388 } |
| 389 |
| 390 @override |
| 391 void handleAssignmentExpression(AssignmentExpression node) { |
| 392 // Don't special-case assignment expressions. |
| 393 } |
| 378 } | 394 } |
| OLD | NEW |