| Index: pkg/analysis_server/lib/src/index/store/codec.dart
|
| diff --git a/pkg/analysis_server/lib/src/index/store/codec.dart b/pkg/analysis_server/lib/src/index/store/codec.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..20a66fd560190c5588665a6f31363360e6278e78
|
| --- /dev/null
|
| +++ b/pkg/analysis_server/lib/src/index/store/codec.dart
|
| @@ -0,0 +1,216 @@
|
| +// Copyright (c) 2014, 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.
|
| +
|
| +library index.store.codec;
|
| +
|
| +import 'dart:collection';
|
| +
|
| +import 'package:analysis_server/src/index/store/collection.dart';
|
| +import 'package:analyzer/src/generated/element.dart';
|
| +import 'package:analyzer/src/generated/engine.dart';
|
| +import 'package:analyzer/src/generated/index.dart';
|
| +
|
| +
|
| +/**
|
| + * A helper that encodes/decodes [AnalysisContext]s from/to integers.
|
| + */
|
| +class ContextCodec {
|
| + /**
|
| + * A table mapping contexts to their unique indices.
|
| + */
|
| + Map<AnalysisContext, int> _contextToIndex = new HashMap<AnalysisContext, int>(
|
| + );
|
| +
|
| + /**
|
| + * A table mapping indices to the corresponding contexts.
|
| + */
|
| + Map<int, AnalysisContext> _indexToContext = new HashMap<int, AnalysisContext>(
|
| + );
|
| +
|
| + /**
|
| + * The next id to assign.
|
| + */
|
| + int _nextId = 0;
|
| +
|
| + /**
|
| + * Returns the [AnalysisContext] that corresponds to the given index.
|
| + */
|
| + AnalysisContext decode(int index) => _indexToContext[index];
|
| +
|
| + /**
|
| + * Returns an unique index for the given [AnalysisContext].
|
| + */
|
| + int encode(AnalysisContext context) {
|
| + int index = _contextToIndex[context];
|
| + if (index == null) {
|
| + index = _nextId++;
|
| + _contextToIndex[context] = index;
|
| + _indexToContext[index] = context;
|
| + }
|
| + return index;
|
| + }
|
| +
|
| + /**
|
| + * Removes the given [context].
|
| + */
|
| + void remove(AnalysisContext context) {
|
| + int id = _contextToIndex.remove(context);
|
| + if (id != null) {
|
| + _indexToContext.remove(id);
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +/**
|
| + * A helper that encodes/decodes [Element]s to/from integers.
|
| + */
|
| +class ElementCodec {
|
| + /**
|
| + * A list that works as a mapping of integers to element encodings (in form of integer arrays).
|
| + */
|
| + List<List<int>> _indexToPath = [];
|
| +
|
| + /**
|
| + * A table mapping element locations (in form of integer arrays) into a single integer.
|
| + */
|
| + IntArrayToIntMap _pathToIndex = new IntArrayToIntMap();
|
| +
|
| + final StringCodec _stringCodec;
|
| +
|
| + ElementCodec(this._stringCodec);
|
| +
|
| + /**
|
| + * Returns an [Element] that corresponds to the given location.
|
| + *
|
| + * @param context the [AnalysisContext] to find [Element] in
|
| + * @param index an integer corresponding to the [Element]
|
| + * @return the [Element] or `null`
|
| + */
|
| + Element decode(AnalysisContext context, int index) {
|
| + List<int> path = _indexToPath[index];
|
| + List<String> components = _getLocationComponents(path);
|
| + ElementLocation location = new ElementLocationImpl.con3(components);
|
| + return context.getElement(location);
|
| + }
|
| +
|
| + /**
|
| + * Returns a unique integer that corresponds to the given [Element].
|
| + */
|
| + int encode(Element element) {
|
| + List<int> path = _getLocationPath(element);
|
| + int index = _pathToIndex[path];
|
| + if (index == null) {
|
| + index = _indexToPath.length;
|
| + _pathToIndex[path] = index;
|
| + _indexToPath.add(path);
|
| + }
|
| + return index;
|
| + }
|
| +
|
| + List<String> _getLocationComponents(List<int> path) {
|
| + int length = path.length;
|
| + List<String> components = new List<String>();
|
| + for (int i = 0; i < length; i++) {
|
| + int componentId = path[i];
|
| + String component = _stringCodec.decode(componentId);
|
| + if (i < length - 1 && path[i + 1] < 0) {
|
| + component += '@${(-path[i + 1])}';
|
| + i++;
|
| + }
|
| + components.add(component);
|
| + }
|
| + return components;
|
| + }
|
| +
|
| + List<int> _getLocationPath(Element element) {
|
| + List<String> components = element.location.components;
|
| + int length = components.length;
|
| + if (_hasLocalOffset(components)) {
|
| + List<int> path = new List<int>();
|
| + for (String component in components) {
|
| + int atOffset = component.indexOf('@');
|
| + if (atOffset == -1) {
|
| + path.add(_stringCodec.encode(component));
|
| + } else {
|
| + String preAtString = component.substring(0, atOffset);
|
| + String atString = component.substring(atOffset + 1);
|
| + path.add(_stringCodec.encode(preAtString));
|
| + path.add(-1 * int.parse(atString));
|
| + }
|
| + }
|
| + return path;
|
| + } else {
|
| + List<int> path = new List<int>.filled(length, 0);
|
| + for (int i = 0; i < length; i++) {
|
| + String component = components[i];
|
| + path[i] = _stringCodec.encode(component);
|
| + }
|
| + return path;
|
| + }
|
| + }
|
| +
|
| + bool _hasLocalOffset(List<String> components) {
|
| + for (String component in components) {
|
| + if (component.indexOf('@') != -1) {
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +
|
| +/**
|
| + * A helper that encodes/decodes [Relationship]s to/from integers.
|
| + */
|
| +class RelationshipCodec {
|
| + final StringCodec _stringCodec;
|
| +
|
| + RelationshipCodec(this._stringCodec);
|
| +
|
| + Relationship decode(int idIndex) {
|
| + String id = _stringCodec.decode(idIndex);
|
| + return Relationship.getRelationship(id);
|
| + }
|
| +
|
| + int encode(Relationship relationship) {
|
| + String id = relationship.identifier;
|
| + return _stringCodec.encode(id);
|
| + }
|
| +}
|
| +
|
| +
|
| +/**
|
| + * A helper that encodes/decodes [String]s from/to integers.
|
| + */
|
| +class StringCodec {
|
| + /**
|
| + * A table mapping names to their unique indices.
|
| + */
|
| + final Map<String, int> nameToIndex = {};
|
| +
|
| + /**
|
| + * A table mapping indices to the corresponding strings.
|
| + */
|
| + List<String> _indexToName = [];
|
| +
|
| + /**
|
| + * Returns the [String] that corresponds to the given index.
|
| + */
|
| + String decode(int index) => _indexToName[index];
|
| +
|
| + /**
|
| + * Returns an unique index for the given [String].
|
| + */
|
| + int encode(String name) {
|
| + int index = nameToIndex[name];
|
| + if (index == null) {
|
| + index = _indexToName.length;
|
| + nameToIndex[name] = index;
|
| + _indexToName.add(name);
|
| + }
|
| + return index;
|
| + }
|
| +}
|
|
|