blob: 8459dff590f9d0c30a14e8c36b06dc4c9b719481 [file] [log] [blame]
// Copyright (c) 2015, 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 'dart:collection';
import 'package:analysis_server/plugin/analysis/navigation/navigation_core.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/protocol_server.dart' as protocol;
import 'package:analyzer/src/generated/source.dart' show SourceRange;
/**
* A concrete implementation of [NavigationCollector].
*/
class NavigationCollectorImpl implements NavigationCollector {
/**
* A list of navigation regions.
*/
final List<protocol.NavigationRegion> regions = <protocol.NavigationRegion>[];
final Map<SourceRange, List<int>> regionMap =
new HashMap<SourceRange, List<int>>();
/**
* All the unique targets referenced by [regions].
*/
final List<protocol.NavigationTarget> targets = <protocol.NavigationTarget>[];
final Map<Pair<protocol.ElementKind, protocol.Location>, int> targetMap =
new HashMap<Pair<protocol.ElementKind, protocol.Location>, int>();
/**
* All the unique files referenced by [targets].
*/
final List<String> files = <String>[];
final Map<String, int> fileMap = new HashMap<String, int>();
@override
void addRegion(int offset, int length, protocol.ElementKind targetKind,
protocol.Location targetLocation) {
SourceRange range = new SourceRange(offset, length);
// prepare targets
List<int> targets = regionMap[range];
if (targets == null) {
targets = <int>[];
regionMap[range] = targets;
}
// add new target
int targetIndex = _addTarget(targetKind, targetLocation);
targets.add(targetIndex);
}
void createRegions() {
regionMap.forEach((range, targets) {
protocol.NavigationRegion region =
new protocol.NavigationRegion(range.offset, range.length, targets);
regions.add(region);
});
regions.sort((a, b) {
return a.offset - b.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(protocol.ElementKind kind, protocol.Location location) {
var pair =
new Pair<protocol.ElementKind, protocol.Location>(kind, location);
int index = targetMap[pair];
if (index == null) {
String file = location.file;
int fileIndex = _addFile(file);
index = targets.length;
protocol.NavigationTarget target = new protocol.NavigationTarget(
kind,
fileIndex,
location.offset,
location.length,
location.startLine,
location.startColumn);
targets.add(target);
targetMap[pair] = index;
}
return index;
}
}