| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 MethodAnalysis analysis = new MethodAnalysis(declaration); | 83 MethodAnalysis analysis = new MethodAnalysis(declaration); |
| 84 if (declaration != null) { | 84 if (declaration != null) { |
| 85 declaration.accept(new TreeShakingVisitor(analysis)); | 85 declaration.accept(new TreeShakingVisitor(analysis)); |
| 86 } else if (method is ConstructorElement) { | 86 } else if (method is ConstructorElement) { |
| 87 // This constructor has no associated declaration in the AST. Either it | 87 // This constructor has no associated declaration in the AST. Either it |
| 88 // is a default constructor for an ordinary class, or it's a synthetic | 88 // is a default constructor for an ordinary class, or it's a synthetic |
| 89 // constructor associated with a mixin. For now we assume it's a default | 89 // constructor associated with a mixin. For now we assume it's a default |
| 90 // constructor, in which case all we need to do is record the class as | 90 // constructor, in which case all we need to do is record the class as |
| 91 // being instantiated by this method. TODO(paulberry): handle the | 91 // being instantiated by this method. TODO(paulberry): handle the |
| 92 // mixin case. | 92 // mixin case. |
| 93 analysis.instantiates.add(method.enclosingElement); | 93 ClassElement instantiatedClass = method.enclosingElement; |
| 94 analysis.instantiates.add(instantiatedClass); |
| 95 if (instantiatedClass.supertype != null) { |
| 96 ClassElement superClass = instantiatedClass.supertype.element; |
| 97 ConstructorElement superConstructor = superClass.unnamedConstructor; |
| 98 if (superConstructor != null) { |
| 99 // TODO(johnniwinther): Register instantiated type and selector. |
| 100 analysis.calls.add(superConstructor); |
| 101 } |
| 102 } |
| 94 } else { | 103 } else { |
| 95 // This is an executable element with no associated declaration in the | 104 // This is an executable element with no associated declaration in the |
| 96 // AST, and it's not a constructor. TODO(paulberry): can this ever | 105 // AST, and it's not a constructor. TODO(paulberry): can this ever |
| 97 // happen? | 106 // happen? |
| 98 throw new UnimplementedError(); | 107 throw new UnimplementedError(); |
| 99 } | 108 } |
| 100 return analysis; | 109 return analysis; |
| 101 } | 110 } |
| 102 | 111 |
| 103 /** | 112 /** |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 // TODO(paulberry): handle parameter list. | 371 // TODO(paulberry): handle parameter list. |
| 363 node.initializers.accept(this); | 372 node.initializers.accept(this); |
| 364 node.body.accept(this); | 373 node.body.accept(this); |
| 365 if (node.factoryKeyword == null) { | 374 if (node.factoryKeyword == null) { |
| 366 // This is a generative constructor. Figure out if it is redirecting. | 375 // This is a generative constructor. Figure out if it is redirecting. |
| 367 // If it isn't, then the constructor instantiates the class so we need to | 376 // If it isn't, then the constructor instantiates the class so we need to |
| 368 // add the class to analysis.instantiates. (If it is redirecting, then | 377 // add the class to analysis.instantiates. (If it is redirecting, then |
| 369 // we don't need to, because the redirected-to constructor will take care | 378 // we don't need to, because the redirected-to constructor will take care |
| 370 // of that). | 379 // of that). |
| 371 if (node.initializers.length != 1 || node.initializers[0] is! RedirectingC
onstructorInvocation) { | 380 if (node.initializers.length != 1 || node.initializers[0] is! RedirectingC
onstructorInvocation) { |
| 381 ClassElement classElement = node.element.enclosingElement; |
| 372 analysis.instantiates.add(node.element.enclosingElement); | 382 analysis.instantiates.add(node.element.enclosingElement); |
| 383 if (!node.initializers.any((i) => i is SuperConstructorInvocation)) { |
| 384 if (classElement.supertype != null) { |
| 385 ClassElement superClass = classElement.supertype.element; |
| 386 ConstructorElement superConstructor = superClass.unnamedConstructor; |
| 387 if (superConstructor != null) { |
| 388 // TODO(johnniwinther): Register instantiated type and selector. |
| 389 analysis.calls.add(superConstructor); |
| 390 } |
| 391 } |
| 392 } |
| 373 } | 393 } |
| 374 } else if (node.redirectedConstructor != null) { | 394 } else if (node.redirectedConstructor != null) { |
| 375 if (node.redirectedConstructor.staticElement == null) { | 395 if (node.redirectedConstructor.staticElement == null) { |
| 376 // Factory constructor redirects to a non-existent constructor. | 396 // Factory constructor redirects to a non-existent constructor. |
| 377 // TODO(paulberry): handle this. | 397 // TODO(paulberry): handle this. |
| 378 throw new UnimplementedError(); | 398 throw new UnimplementedError(); |
| 379 } else { | 399 } else { |
| 380 analysis.calls.add(node.redirectedConstructor.staticElement); | 400 analysis.calls.add(node.redirectedConstructor.staticElement); |
| 381 } | 401 } |
| 382 } | 402 } |
| 383 } | 403 } |
| 384 | 404 |
| 385 @override | 405 @override |
| 386 void | 406 void |
| 387 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { | 407 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { |
| 388 // Note: we don't have to worry about node.staticElement being | 408 // Note: we don't have to worry about node.staticElement being |
| 389 // null, because that would have been detected by the analyzer and | 409 // null, because that would have been detected by the analyzer and |
| 390 // reported as a compile time error. | 410 // reported as a compile time error. |
| 391 analysis.calls.add(node.staticElement); | 411 analysis.calls.add(node.staticElement); |
| 392 } | 412 } |
| 393 | 413 |
| 394 @override | 414 @override |
| 395 void handleAssignmentExpression(AssignmentExpression node) { | 415 void handleAssignmentExpression(AssignmentExpression node) { |
| 396 // Don't special-case assignment expressions. | 416 // Don't special-case assignment expressions. |
| 397 } | 417 } |
| 398 } | 418 } |
| OLD | NEW |