Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Side by Side Diff: pkg/analysis_server/lib/src/services/index/store/codec.dart

Issue 738673002: Use shorter DartElementLocation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 services.src.index.store.codec; 5 library services.src.index.store.codec;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analysis_server/src/services/index/index.dart'; 9 import 'package:analysis_server/src/services/index/index.dart';
10 import 'package:analysis_server/src/services/index/store/collection.dart'; 10 import 'package:analysis_server/src/services/index/store/collection.dart';
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 _indexToContext.remove(id); 61 _indexToContext.remove(id);
62 } 62 }
63 } 63 }
64 } 64 }
65 65
66 66
67 /** 67 /**
68 * A helper that encodes/decodes [Element]s to/from integers. 68 * A helper that encodes/decodes [Element]s to/from integers.
69 */ 69 */
70 class ElementCodec { 70 class ElementCodec {
71 static const KIND_DART = 0;
72 static const KIND_NAME = 1;
73 static const KIND_UNKNOWN = 2;
74
71 final StringCodec _stringCodec; 75 final StringCodec _stringCodec;
76 final ElementKindCodec _kindCodec = new ElementKindCodec();
72 77
73 /** 78 /**
74 * A table mapping element encodings to a single integer. 79 * A table mapping element encodings to a single integer.
75 */ 80 */
76 final IntArrayToIntMap _pathToIndex = new IntArrayToIntMap(); 81 final IntArrayToIntMap _pathToIndex = new IntArrayToIntMap();
77 82
78 /** 83 /**
79 * A list that works as a mapping of integers to element encodings. 84 * A list that works as a mapping of integers to element encodings.
80 */ 85 */
81 final List<List<int>> _indexToPath = <List<int>>[]; 86 final List<List<int>> _indexToPath = <List<int>>[];
82 87
83 ElementCodec(this._stringCodec); 88 ElementCodec(this._stringCodec);
84 89
85 /** 90 /**
86 * Returns an [Element] that corresponds to the given location. 91 * Returns an [Element] that corresponds to the given location.
87 * 92 *
88 * @param context the [AnalysisContext] to find [Element] in 93 * @param context the [AnalysisContext] to find [Element] in
89 * @param index an integer corresponding to the [Element] 94 * @param index an integer corresponding to the [Element]
90 * @return the [Element] or `null` 95 * @return the [Element] or `null`
91 */ 96 */
92 Element decode(AnalysisContext context, int index) { 97 Element decode(AnalysisContext context, int index) {
93 List<int> path = _indexToPath[index]; 98 List<int> path = _indexToPath[index];
94 List<String> components = _getLocationComponents(path); 99 if (path[0] == KIND_DART) {
95 ElementLocation location = new ElementLocationImpl.con3(components); 100 String librarySourceEncoding = _stringCodec.decode(path[1]);
96 Element element = context.getElement(location); 101 String unitSourceEncoding = _stringCodec.decode(path[2]);
97 return element; 102 int nameOffset = path[3];
103 ElementKind kind = _kindCodec.decode(path[4]);
104 ElementLocation location = new DartElementLocation(
105 librarySourceEncoding,
106 unitSourceEncoding,
107 nameOffset,
108 kind);
109 return context.getElement(location);
110 }
111 // TODO(scheglov) support for KIND_HTML ?
Brian Wilkerson 2014/11/18 15:11:22 And KIND_NAME.
112 return null;
98 } 113 }
99 114
100 /** 115 /**
101 * Returns a unique integer that corresponds to the given [Element]. 116 * Returns a unique integer that corresponds to the given [Element].
102 * 117 *
103 * If [forKey] is `true` then [element] is a part of a key, so it should use 118 * If [forKey] is `true` then [element] is a part of a key, so it should use
104 * file paths instead of [Element] location URIs. 119 * file paths instead of [Element] location URIs.
105 */ 120 */
106 int encode(Element element, bool forKey) { 121 int encode(Element element, bool forKey) {
107 List<int> path = _getLocationPath(element, forKey); 122 List<int> path = _getLocationPath(element, forKey);
(...skipping 13 matching lines...) Expand all
121 List<int> path = _getLocationPathLimited(element); 136 List<int> path = _getLocationPathLimited(element);
122 int index = _pathToIndex[path]; 137 int index = _pathToIndex[path];
123 if (index == null) { 138 if (index == null) {
124 index = _indexToPath.length; 139 index = _indexToPath.length;
125 _pathToIndex[path] = index; 140 _pathToIndex[path] = index;
126 _indexToPath.add(path); 141 _indexToPath.add(path);
127 } 142 }
128 return index; 143 return index;
129 } 144 }
130 145
131 List<String> _getLocationComponents(List<int> path) {
132 int length = path.length;
133 List<String> components = new List<String>();
134 for (int i = 0; i < length; i++) {
135 int componentId = path[i];
136 String component = _stringCodec.decode(componentId);
137 if (i < length - 1 && path[i + 1] < 0) {
138 component += '@${(-path[i + 1])}';
139 i++;
140 }
141 components.add(component);
142 }
143 return components;
144 }
145
146 /** 146 /**
147 * If [usePath] is `true` then [Source] path should be used instead of URI. 147 * If [usePath] is `true` then [Source] path should be used instead of URI.
148 */ 148 */
149 List<int> _getLocationPath(Element element, bool usePath) { 149 List<int> _getLocationPath(Element element, bool usePath) {
150 // prepare the location components 150 LibraryElement library = element.library;
151 List<String> components = element.location.components; 151 // DynamicElement, NameElement
152 if (usePath) { 152 if (library == null) {
153 LibraryElement library = element.library; 153 int nameId = _stringCodec.encode(element.name);
154 if (library != null) { 154 return <int>[KIND_NAME, nameId];
155 components[0] = library.source.fullName; 155 }
156 if (element.enclosingElement is CompilationUnitElement) { 156 // normal Element
157 components[1] = library.definingCompilationUnit.source.fullName; 157 ElementLocation location = element.location;
158 } 158 if (location is DartElementLocation) {
159 String librarySourceEncoding;
160 String unitSourceEncoding;
161 if (usePath) {
162 unitSourceEncoding = library.source.fullName;
163 unitSourceEncoding = element.source.fullName;
164 } else {
165 librarySourceEncoding = location.librarySourceEncoding;
166 unitSourceEncoding = location.unitSourceEncoding;
159 } 167 }
168 int libraryId = _stringCodec.encode(librarySourceEncoding);
169 int unitId = _stringCodec.encode(unitSourceEncoding);
170 // done
171 int nameOffset = location.nameOffset;
Brian Wilkerson 2014/11/18 15:11:22 Do we need to ensure that the name offset is non-n
172 int kindId = _kindCodec.encode(location.kind);
173 return <int>[KIND_DART, libraryId, unitId, nameOffset, kindId];
160 } 174 }
161 // encode the location 175 // unknown
162 int length = components.length; 176 return <int>[KIND_UNKNOWN];
163 if (_hasLocalOffset(components)) {
164 List<int> path = new List<int>();
165 for (String component in components) {
166 int atOffset = component.indexOf('@');
167 if (atOffset == -1) {
168 path.add(_stringCodec.encode(component));
169 } else {
170 String preAtString = component.substring(0, atOffset);
171 String atString = component.substring(atOffset + 1);
172 path.add(_stringCodec.encode(preAtString));
173 path.add(-1 * int.parse(atString));
174 }
175 }
176 return path;
177 } else {
178 List<int> path = new List<int>.filled(length, 0);
179 for (int i = 0; i < length; i++) {
180 String component = components[i];
181 path[i] = _stringCodec.encode(component);
182 }
183 return path;
184 }
185 } 177 }
186 178
187 /** 179 /**
188 * Returns an approximation of the [element]'s location. 180 * Returns an approximation of the [element]'s location.
189 */ 181 */
190 List<int> _getLocationPathLimited(Element element) { 182 List<int> _getLocationPathLimited(Element element) {
191 String firstComponent; 183 String firstComponent;
192 { 184 {
193 LibraryElement libraryElement = element.library; 185 LibraryElement libraryElement = element.library;
194 if (libraryElement != null) { 186 if (libraryElement != null) {
195 firstComponent = libraryElement.source.fullName; 187 firstComponent = libraryElement.source.fullName;
196 } else { 188 } else {
197 firstComponent = 'null'; 189 firstComponent = 'null';
198 } 190 }
199 } 191 }
200 String lastComponent = element.displayName; 192 String lastComponent = element.displayName;
201 int firstId = _stringCodec.encode(firstComponent); 193 int firstId = _stringCodec.encode(firstComponent);
202 int lastId = _stringCodec.encode(lastComponent); 194 int lastId = _stringCodec.encode(lastComponent);
203 return <int>[firstId, lastId]; 195 return <int>[firstId, lastId];
204 } 196 }
197 }
205 198
206 static bool _hasLocalOffset(List<String> components) { 199
207 for (String component in components) { 200 /**
208 if (component.indexOf('@') != -1) { 201 * A helper that encodes/decodes [ElementKind]s to/from integers.
209 return true; 202 */
203 class ElementKindCodec {
204 ElementKind decode(int id) {
205 for (ElementKind kind in ElementKind.values) {
206 if (kind.ordinal == id) {
207 return kind;
210 } 208 }
211 } 209 }
212 return false; 210 return null;
211 }
212
213 int encode(ElementKind kind) {
214 return kind.ordinal;
213 } 215 }
214 } 216 }
215 217
216 218
217 /** 219 /**
218 * A helper that encodes/decodes [Relationship]s to/from integers. 220 * A helper that encodes/decodes [Relationship]s to/from integers.
219 */ 221 */
220 class RelationshipCodec { 222 class RelationshipCodec {
221 final StringCodec _stringCodec; 223 final StringCodec _stringCodec;
222 224
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 int encode(String name) { 261 int encode(String name) {
260 int index = nameToIndex[name]; 262 int index = nameToIndex[name];
261 if (index == null) { 263 if (index == null) {
262 index = _indexToName.length; 264 index = _indexToName.length;
263 nameToIndex[name] = index; 265 nameToIndex[name] = index;
264 _indexToName.add(name); 266 _indexToName.add(name);
265 } 267 }
266 return index; 268 return index;
267 } 269 }
268 } 270 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698