| 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 engine.element; | 5 library engine.element; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'dart:math' show min; |
| 8 | 9 |
| 9 import 'package:analyzer/src/generated/utilities_general.dart'; | 10 import 'package:analyzer/src/generated/utilities_general.dart'; |
| 10 import 'package:analyzer/src/task/dart.dart'; | 11 import 'package:analyzer/src/task/dart.dart'; |
| 11 import 'package:analyzer/task/model.dart' | 12 import 'package:analyzer/task/model.dart' |
| 12 show AnalysisTarget, ConstantEvaluationTarget; | 13 show AnalysisTarget, ConstantEvaluationTarget; |
| 13 | 14 |
| 14 import 'ast.dart'; | 15 import 'ast.dart'; |
| 15 import 'constant.dart' show EvaluationResultImpl; | 16 import 'constant.dart' show EvaluationResultImpl; |
| 16 import 'engine.dart' show AnalysisContext, AnalysisEngine, AnalysisException; | 17 import 'engine.dart' show AnalysisContext, AnalysisEngine, AnalysisException; |
| 17 import 'html.dart' show XmlAttributeNode, XmlTagNode; | 18 import 'html.dart' show XmlAttributeNode, XmlTagNode; |
| (...skipping 7315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7333 */ | 7334 */ |
| 7334 List<ImportElement> _imports = ImportElement.EMPTY_LIST; | 7335 List<ImportElement> _imports = ImportElement.EMPTY_LIST; |
| 7335 | 7336 |
| 7336 /** | 7337 /** |
| 7337 * A list containing specifications of all of the exports defined in this | 7338 * A list containing specifications of all of the exports defined in this |
| 7338 * library. | 7339 * library. |
| 7339 */ | 7340 */ |
| 7340 List<ExportElement> _exports = ExportElement.EMPTY_LIST; | 7341 List<ExportElement> _exports = ExportElement.EMPTY_LIST; |
| 7341 | 7342 |
| 7342 /** | 7343 /** |
| 7344 * A list containing the strongly connected component in the import/export |
| 7345 * graph in which the current library resides. Computed on demand, null |
| 7346 * if not present. If _libraryCycle is set, then the _libraryCycle field |
| 7347 * for all libraries reachable from this library in the import/export graph |
| 7348 * is also set. |
| 7349 */ |
| 7350 List<LibraryElement> _libraryCycle = null; |
| 7351 |
| 7352 /** |
| 7343 * A list containing all of the compilation units that are included in this | 7353 * A list containing all of the compilation units that are included in this |
| 7344 * library using a `part` directive. | 7354 * library using a `part` directive. |
| 7345 */ | 7355 */ |
| 7346 List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST; | 7356 List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST; |
| 7347 | 7357 |
| 7348 /** | 7358 /** |
| 7349 * The element representing the synthetic function `loadLibrary` that is | 7359 * The element representing the synthetic function `loadLibrary` that is |
| 7350 * defined for this library, or `null` if the element has not yet been created
. | 7360 * defined for this library, or `null` if the element has not yet been created
. |
| 7351 */ | 7361 */ |
| 7352 FunctionElement _loadLibraryFunction; | 7362 FunctionElement _loadLibraryFunction; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7520 } | 7530 } |
| 7521 return false; | 7531 return false; |
| 7522 } | 7532 } |
| 7523 | 7533 |
| 7524 @override | 7534 @override |
| 7525 ElementKind get kind => ElementKind.LIBRARY; | 7535 ElementKind get kind => ElementKind.LIBRARY; |
| 7526 | 7536 |
| 7527 @override | 7537 @override |
| 7528 LibraryElement get library => this; | 7538 LibraryElement get library => this; |
| 7529 | 7539 |
| 7540 List<LibraryElement> get libraryCycle { |
| 7541 if (_libraryCycle != null) { |
| 7542 return _libraryCycle; |
| 7543 } |
| 7544 |
| 7545 // Global counter for this run of the algorithm |
| 7546 int counter = 0; |
| 7547 // The discovery times of each library |
| 7548 Map<LibraryElementImpl, int> indices = {}; |
| 7549 // The set of scc candidates |
| 7550 Set<LibraryElementImpl> active = new Set(); |
| 7551 // The stack of discovered elements |
| 7552 List<LibraryElementImpl> stack = []; |
| 7553 // For a given library that has not yet been processed by this run of the |
| 7554 // algorithm, compute the strongly connected components. |
| 7555 int scc(LibraryElementImpl library) { |
| 7556 int index = counter++; |
| 7557 int root = index; |
| 7558 indices[library] = index; |
| 7559 active.add(library); |
| 7560 stack.add(library); |
| 7561 void recurse(LibraryElementImpl child) { |
| 7562 if (!indices.containsKey(child)) { |
| 7563 // We haven't visited this child yet, so recurse on the child, |
| 7564 // returning the lowest numbered node reachable from the child. If |
| 7565 // the child can reach a root which is lower numbered than anything |
| 7566 // we've reached so far, update the root. |
| 7567 root = min(root, scc(child)); |
| 7568 } else if (active.contains(child)) { |
| 7569 // The child has been visited, but has not yet been placed into a |
| 7570 // component. If the child is higher than anything we've seen so far |
| 7571 // update the root appropriately. |
| 7572 root = min(root, indices[child]); |
| 7573 } |
| 7574 } |
| 7575 // Recurse on all of the children in the import/export graph, filtering |
| 7576 // out those for which library cycles have already been computed. |
| 7577 library.exportedLibraries |
| 7578 .where((l) => l._libraryCycle == null) |
| 7579 .forEach(recurse); |
| 7580 library.importedLibraries |
| 7581 .where((l) => l._libraryCycle == null) |
| 7582 .forEach(recurse); |
| 7583 |
| 7584 if (root == index) { |
| 7585 // This is the root of a strongly connected component. |
| 7586 // Pop the elements, and share the component across all |
| 7587 // of the elements. |
| 7588 List<LibraryElement> component = <LibraryElement>[]; |
| 7589 LibraryElementImpl cur = null; |
| 7590 do { |
| 7591 cur = stack.removeLast(); |
| 7592 active.remove(cur); |
| 7593 component.add(cur); |
| 7594 cur._libraryCycle = component; |
| 7595 } while (cur != library); |
| 7596 } |
| 7597 return root; |
| 7598 } |
| 7599 scc(library); |
| 7600 return _libraryCycle; |
| 7601 } |
| 7602 |
| 7530 @override | 7603 @override |
| 7531 FunctionElement get loadLibraryFunction { | 7604 FunctionElement get loadLibraryFunction { |
| 7532 if (_loadLibraryFunction == null) { | 7605 if (_loadLibraryFunction == null) { |
| 7533 FunctionElementImpl function = | 7606 FunctionElementImpl function = |
| 7534 new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1); | 7607 new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1); |
| 7535 function.synthetic = true; | 7608 function.synthetic = true; |
| 7536 function.enclosingElement = this; | 7609 function.enclosingElement = this; |
| 7537 function.returnType = loadLibraryReturnType; | 7610 function.returnType = loadLibraryReturnType; |
| 7538 function.type = new FunctionTypeImpl(function); | 7611 function.type = new FunctionTypeImpl(function); |
| 7539 _loadLibraryFunction = function; | 7612 _loadLibraryFunction = function; |
| (...skipping 3304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10844 | 10917 |
| 10845 @override | 10918 @override |
| 10846 void visitElement(Element element) { | 10919 void visitElement(Element element) { |
| 10847 int offset = element.nameOffset; | 10920 int offset = element.nameOffset; |
| 10848 if (offset != -1) { | 10921 if (offset != -1) { |
| 10849 map[offset] = element; | 10922 map[offset] = element; |
| 10850 } | 10923 } |
| 10851 super.visitElement(element); | 10924 super.visitElement(element); |
| 10852 } | 10925 } |
| 10853 } | 10926 } |
| OLD | NEW |