Index: pkg/analyzer_plugin/lib/src/utilities/navigation.dart |
diff --git a/pkg/analyzer_plugin/lib/src/utilities/navigation.dart b/pkg/analyzer_plugin/lib/src/utilities/navigation.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..08560cba8995fee7b61604c801191387ec845e6b |
--- /dev/null |
+++ b/pkg/analyzer_plugin/lib/src/utilities/navigation.dart |
@@ -0,0 +1,83 @@ |
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+import 'package:analyzer/src/generated/source.dart' show SourceRange; |
+import 'package:analyzer_plugin/protocol/protocol_common.dart'; |
+import 'package:analyzer_plugin/utilities/navigation.dart'; |
+import 'package:analyzer_plugin/utilities/pair.dart'; |
+ |
+/** |
+ * A concrete implementation of [NavigationCollector]. |
+ */ |
+class NavigationCollectorImpl implements NavigationCollector { |
+ /** |
+ * A list of navigation regions. |
+ */ |
+ final List<NavigationRegion> regions = <NavigationRegion>[]; |
+ final Map<SourceRange, List<int>> regionMap = <SourceRange, List<int>>{}; |
+ |
+ /** |
+ * All the unique targets referenced by [regions]. |
+ */ |
+ final List<NavigationTarget> targets = <NavigationTarget>[]; |
+ final Map<Pair<ElementKind, Location>, int> targetMap = |
+ <Pair<ElementKind, Location>, int>{}; |
+ |
+ /** |
+ * All the unique files referenced by [targets]. |
+ */ |
+ final List<String> files = <String>[]; |
+ final Map<String, int> fileMap = <String, int>{}; |
+ |
+ @override |
+ void addRegion( |
+ int offset, int length, ElementKind targetKind, Location targetLocation) { |
+ SourceRange range = new SourceRange(offset, length); |
+ // add new target |
+ List<int> targets = regionMap.putIfAbsent(range, () => <int>[]); |
+ int targetIndex = _addTarget(targetKind, targetLocation); |
+ targets.add(targetIndex); |
+ } |
+ |
+ void createRegions() { |
+ regionMap.forEach((range, targets) { |
+ NavigationRegion region = |
+ new NavigationRegion(range.offset, range.length, targets); |
+ regions.add(region); |
+ }); |
+ regions.sort((NavigationRegion first, NavigationRegion second) { |
+ return first.offset - second.offset; |
+ }); |
+ } |
+ |
+ int _addFile(String file) { |
+ int index = fileMap[file]; |
+ if (index == null) { |
+ index = files.length; |
+ files.add(file); |
+ fileMap[file] = index; |
+ } |
+ return index; |
+ } |
+ |
+ int _addTarget(ElementKind kind, Location location) { |
+ var pair = new Pair<ElementKind, Location>(kind, location); |
+ int index = targetMap[pair]; |
+ if (index == null) { |
+ String file = location.file; |
+ int fileIndex = _addFile(file); |
+ index = targets.length; |
+ NavigationTarget target = new NavigationTarget( |
+ kind, |
+ fileIndex, |
+ location.offset, |
+ location.length, |
+ location.startLine, |
+ location.startColumn); |
+ targets.add(target); |
+ targetMap[pair] = index; |
+ } |
+ return index; |
+ } |
+} |