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

Side by Side Diff: pkg/analyzer/lib/src/summary/index_unit.dart

Issue 1733843007: Add tests for indexing. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 months 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 import 'package:analyzer/dart/ast/ast.dart'; 5 import 'package:analyzer/dart/ast/ast.dart';
6 import 'package:analyzer/dart/ast/token.dart'; 6 import 'package:analyzer/dart/ast/token.dart';
7 import 'package:analyzer/dart/ast/visitor.dart'; 7 import 'package:analyzer/dart/ast/visitor.dart';
8 import 'package:analyzer/dart/element/element.dart'; 8 import 'package:analyzer/dart/element/element.dart';
9 import 'package:analyzer/dart/element/type.dart'; 9 import 'package:analyzer/dart/element/type.dart';
10 import 'package:analyzer/src/generated/utilities_dart.dart'; 10 import 'package:analyzer/src/generated/utilities_dart.dart';
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 return a.offset - b.offset; 68 return a.offset - b.offset;
69 }); 69 });
70 for (int i = 0; i < elementInfoList.length; i++) { 70 for (int i = 0; i < elementInfoList.length; i++) {
71 elementInfoList[i].id = i; 71 elementInfoList[i].id = i;
72 } 72 }
73 return new PackageIndexBuilder( 73 return new PackageIndexBuilder(
74 elementLibraryUris: _elementLibraryUris, 74 elementLibraryUris: _elementLibraryUris,
75 elementUnitUris: _elementUnitUris, 75 elementUnitUris: _elementUnitUris,
76 elementUnits: elementInfoList.map((e) => e.unitId).toList(), 76 elementUnits: elementInfoList.map((e) => e.unitId).toList(),
77 elementOffsets: elementInfoList.map((e) => e.offset).toList(), 77 elementOffsets: elementInfoList.map((e) => e.offset).toList(),
78 elementKinds: elementInfoList.map((e) => e.kind).toList(),
78 uris: _uris, 79 uris: _uris,
79 units: _units.map((unit) => unit.assemble()).toList()); 80 units: _units.map((unit) => unit.assemble()).toList());
80 } 81 }
81 82
82 /** 83 /**
83 * Index the given fully resolved [unit]. 84 * Index the given fully resolved [unit].
84 */ 85 */
85 void index(CompilationUnit unit) { 86 void index(CompilationUnit unit) {
86 CompilationUnitElement unitElement = unit.element; 87 CompilationUnitElement unitElement = unit.element;
87 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitElement); 88 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitElement);
88 _units.add(assembler); 89 _units.add(assembler);
89 unit.accept(new _IndexContributor(assembler)); 90 unit.accept(new _IndexContributor(assembler));
90 } 91 }
91 92
92 /** 93 /**
93 * Return the unique [_ElementInfo] corresponding the [element]. The field 94 * Return the unique [_ElementInfo] corresponding the [element]. The field
94 * [_ElementInfo.id] is filled by [assemble] during final sorting. 95 * [_ElementInfo.id] is filled by [assemble] during final sorting.
95 */ 96 */
96 _ElementInfo _getElementInfo(Element element) { 97 _ElementInfo _getElementInfo(Element element) {
97 return _elementMap.putIfAbsent(element, () { 98 return _elementMap.putIfAbsent(element, () {
98 CompilationUnitElement unitElement = getUnitElement(element); 99 CompilationUnitElement unitElement = getUnitElement(element);
99 int unitId = _getUnitElementId(unitElement); 100 int unitId = _getUnitElementId(unitElement);
100 return new _ElementInfo(unitId, element.nameOffset); 101 int offset = element.nameOffset;
102 if (element is LibraryElement || element is CompilationUnitElement) {
103 offset = 0;
104 }
105 IndexElementKind kind = getIndexElementKind(element);
106 return new _ElementInfo(unitId, offset, kind);
101 }); 107 });
102 } 108 }
103 109
104 /** 110 /**
105 * Add information about [unitElement] to [_elementUnitUris] and 111 * Add information about [unitElement] to [_elementUnitUris] and
106 * [_elementLibraryUris] if necessary, and return the location in those 112 * [_elementLibraryUris] if necessary, and return the location in those
107 * arrays representing [unitElement]. 113 * arrays representing [unitElement].
108 */ 114 */
109 int _getUnitElementId(CompilationUnitElement unitElement) { 115 int _getUnitElementId(CompilationUnitElement unitElement) {
110 return _elementUnitMap.putIfAbsent(unitElement, () { 116 return _elementUnitMap.putIfAbsent(unitElement, () {
(...skipping 12 matching lines...) Expand all
123 int _getUriId(Uri uri) { 129 int _getUriId(Uri uri) {
124 String str = uri.toString(); 130 String str = uri.toString();
125 return _uriMap.putIfAbsent(str, () { 131 return _uriMap.putIfAbsent(str, () {
126 int id = _uris.length; 132 int id = _uris.length;
127 _uris.add(str); 133 _uris.add(str);
128 return id; 134 return id;
129 }); 135 });
130 } 136 }
131 137
132 /** 138 /**
139 * Return the kind of the given [element].
140 */
141 static IndexElementKind getIndexElementKind(Element element) {
142 if (element is ConstructorElement && element.isSynthetic) {
Paul Berry 2016/02/26 19:02:05 Why are only synthetic constructors classified as
143 return IndexElementKind.constructor;
144 } else if (element is PropertyAccessorElement) {
145 return element.isGetter
146 ? IndexElementKind.getter
147 : IndexElementKind.setter;
148 }
149 return IndexElementKind.element;
150 }
151
152 /**
133 * Return the [CompilationUnitElement] that should be used for [element]. 153 * Return the [CompilationUnitElement] that should be used for [element].
134 * Throw [StateError] if the [element] is not linked into a unit. 154 * Throw [StateError] if the [element] is not linked into a unit.
135 */ 155 */
136 static CompilationUnitElement getUnitElement(Element element) { 156 static CompilationUnitElement getUnitElement(Element element) {
137 for (Element e = element; e != null; e = e.enclosingElement) { 157 for (Element e = element; e != null; e = e.enclosingElement) {
138 if (e is CompilationUnitElement) { 158 if (e is CompilationUnitElement) {
139 return e; 159 return e;
140 } 160 }
141 if (e is LibraryElement) { 161 if (e is LibraryElement) {
142 return e.definingCompilationUnit; 162 return e.definingCompilationUnit;
143 } 163 }
144 } 164 }
145 throw new StateError(element.toString()); 165 throw new StateError(element.toString());
146 } 166 }
147 } 167 }
148 168
149 /** 169 /**
150 * Information about an element referenced in index. 170 * Information about an element referenced in index.
151 */ 171 */
152 class _ElementInfo { 172 class _ElementInfo {
173 static const int KIND_ELEMENT = 0;
Paul Berry 2016/02/26 19:02:05 I don't see where these are used, and I'm concerne
174 static const int KIND_GETTER = 1;
175 static const int KIND_SETTER = 2;
176 static const int KIND_CONSTRUCTOR = 3;
177
153 /** 178 /**
154 * The identifier of the [CompilationUnitElement] containing this element. 179 * The identifier of the [CompilationUnitElement] containing this element.
155 */ 180 */
156 final int unitId; 181 final int unitId;
157 182
158 /** 183 /**
159 * The name offset of the element. 184 * The name offset of the element.
160 */ 185 */
161 final int offset; 186 final int offset;
162 187
163 /** 188 /**
189 * The kind of the element.
190 */
191 final IndexElementKind kind;
192
193 /**
164 * The unique id of the element. It is set after indexing of the whole 194 * The unique id of the element. It is set after indexing of the whole
165 * package is done and we are assembling the full package index. 195 * package is done and we are assembling the full package index.
166 */ 196 */
167 int id; 197 int id;
168 198
169 _ElementInfo(this.unitId, this.offset); 199 _ElementInfo(this.unitId, this.offset, this.kind);
170 } 200 }
171 201
172 /** 202 /**
173 * Visits a resolved AST and adds relationships into [_UnitIndexAssembler]. 203 * Visits a resolved AST and adds relationships into [_UnitIndexAssembler].
174 */ 204 */
175 class _IndexContributor extends GeneralizingAstVisitor { 205 class _IndexContributor extends GeneralizingAstVisitor {
176 final _UnitIndexAssembler assembler; 206 final _UnitIndexAssembler assembler;
177 207
178 _IndexContributor(this.assembler); 208 _IndexContributor(this.assembler);
179 209
(...skipping 21 matching lines...) Expand all
201 } 231 }
202 } 232 }
203 if (implementsClause != null) { 233 if (implementsClause != null) {
204 for (TypeName interfaceNode in implementsClause.interfaces) { 234 for (TypeName interfaceNode in implementsClause.interfaces) {
205 recordSuperType(interfaceNode, IndexRelationKind.IS_IMPLEMENTED_BY); 235 recordSuperType(interfaceNode, IndexRelationKind.IS_IMPLEMENTED_BY);
206 } 236 }
207 } 237 }
208 } 238 }
209 239
210 /** 240 /**
211 * Records reference to defining [CompilationUnitElement] of the given
212 * [LibraryElement].
213 */
214 void recordLibraryReference(UriBasedDirective node, LibraryElement library) {
215 recordRelation(library, IndexRelationKind.IS_REFERENCED_BY, node?.uri);
216 }
217
218 /**
219 * Record reference to the given operator [Element] and name. 241 * Record reference to the given operator [Element] and name.
220 */ 242 */
221 void recordOperatorReference(Token operator, Element element) { 243 void recordOperatorReference(Token operator, Element element) {
222 recordRelationToken(element, IndexRelationKind.IS_INVOKED_BY, operator); 244 recordRelationToken(element, IndexRelationKind.IS_INVOKED_BY, operator);
223 // TODO(scheglov) do we need this? 245 // TODO(scheglov) do we need this?
224 // // prepare location 246 // // prepare location
225 // LocationImpl location = _createLocationForToken(operator, element != null) ; 247 // LocationImpl location = _createLocationForToken(operator, element != null) ;
226 // // record name reference 248 // // record name reference
227 // { 249 // {
228 // String name = operator.lexeme; 250 // String name = operator.lexeme;
(...skipping 28 matching lines...) Expand all
257 } 279 }
258 280
259 /** 281 /**
260 * Record that [element] has a relation of the given [kind] at the given 282 * Record that [element] has a relation of the given [kind] at the given
261 * [offset] and [length]. 283 * [offset] and [length].
262 */ 284 */
263 void recordRelationOffset( 285 void recordRelationOffset(
264 Element element, IndexRelationKind kind, int offset, int length) { 286 Element element, IndexRelationKind kind, int offset, int length) {
265 // Ignore elements that can't be referenced outside of the unit. 287 // Ignore elements that can't be referenced outside of the unit.
266 if (element == null || 288 if (element == null ||
289 element is FunctionElement &&
290 element.enclosingElement is ExecutableElement ||
291 element is LabelElement ||
267 element is LocalVariableElement || 292 element is LocalVariableElement ||
268 element is ParameterElement && 293 element is ParameterElement &&
269 element.parameterKind != ParameterKind.NAMED || 294 element.parameterKind != ParameterKind.NAMED ||
270 element is FunctionElement && 295 element is PrefixElement ||
271 element.enclosingElement is ExecutableElement) { 296 element is TypeParameterElement) {
272 return; 297 return;
273 } 298 }
274 // Add the relation. 299 // Add the relation.
275 assembler.addRelation(element, kind, offset, length); 300 assembler.addRelation(element, kind, offset, length);
276 } 301 }
277 302
278 /** 303 /**
279 * Record that [element] has a relation of the given [kind] at the location 304 * Record that [element] has a relation of the given [kind] at the location
280 * of the given [token]. 305 * of the given [token].
281 */ 306 */
(...skipping 26 matching lines...) Expand all
308 // IndexableElement indexable = new IndexableElement(element); 333 // IndexableElement indexable = new IndexableElement(element);
309 // int offset = element.nameOffset; 334 // int offset = element.nameOffset;
310 // int length = element.nameLength; 335 // int length = element.nameLength;
311 // LocationImpl location = new LocationImpl(indexable, offset, length); 336 // LocationImpl location = new LocationImpl(indexable, offset, length);
312 // recordRelationshipElement( 337 // recordRelationshipElement(
313 // _libraryElement, IndexConstants.DEFINES, location); 338 // _libraryElement, IndexConstants.DEFINES, location);
314 // _store.recordTopLevelDeclaration(element); 339 // _store.recordTopLevelDeclaration(element);
315 // } 340 // }
316 } 341 }
317 342
318 void recordUriFileReference(UriBasedDirective directive) { 343 void recordUriReference(Element element, UriBasedDirective directive) {
319 Element element = directive.element;
320 recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, directive.uri); 344 recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, directive.uri);
321 } 345 }
322 346
323 @override 347 @override
324 visitAssignmentExpression(AssignmentExpression node) { 348 visitAssignmentExpression(AssignmentExpression node) {
325 recordOperatorReference(node.operator, node.bestElement); 349 recordOperatorReference(node.operator, node.bestElement);
326 super.visitAssignmentExpression(node); 350 super.visitAssignmentExpression(node);
327 } 351 }
328 352
329 @override 353 @override
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 @override 412 @override
389 visitEnumDeclaration(EnumDeclaration node) { 413 visitEnumDeclaration(EnumDeclaration node) {
390 ClassElement element = node.element; 414 ClassElement element = node.element;
391 recordTopLevelElementDefinition(element); 415 recordTopLevelElementDefinition(element);
392 super.visitEnumDeclaration(node); 416 super.visitEnumDeclaration(node);
393 } 417 }
394 418
395 @override 419 @override
396 visitExportDirective(ExportDirective node) { 420 visitExportDirective(ExportDirective node) {
397 ExportElement element = node.element; 421 ExportElement element = node.element;
398 if (element != null) { 422 recordUriReference(element?.exportedLibrary, node);
399 LibraryElement expLibrary = element.exportedLibrary;
400 recordLibraryReference(node, expLibrary);
401 }
402 recordUriFileReference(node);
403 super.visitExportDirective(node); 423 super.visitExportDirective(node);
404 } 424 }
405 425
406 @override 426 @override
407 visitFunctionDeclaration(FunctionDeclaration node) { 427 visitFunctionDeclaration(FunctionDeclaration node) {
408 Element element = node.element; 428 Element element = node.element;
409 recordTopLevelElementDefinition(element); 429 recordTopLevelElementDefinition(element);
410 super.visitFunctionDeclaration(node); 430 super.visitFunctionDeclaration(node);
411 } 431 }
412 432
413 @override 433 @override
414 visitFunctionTypeAlias(FunctionTypeAlias node) { 434 visitFunctionTypeAlias(FunctionTypeAlias node) {
415 Element element = node.element; 435 Element element = node.element;
416 recordTopLevelElementDefinition(element); 436 recordTopLevelElementDefinition(element);
417 super.visitFunctionTypeAlias(node); 437 super.visitFunctionTypeAlias(node);
418 } 438 }
419 439
420 @override 440 @override
421 visitImportDirective(ImportDirective node) { 441 visitImportDirective(ImportDirective node) {
422 ImportElement element = node.element; 442 ImportElement element = node.element;
423 if (element != null) { 443 recordUriReference(element?.importedLibrary, node);
424 LibraryElement impLibrary = element.importedLibrary;
425 recordLibraryReference(node, impLibrary);
426 }
427 recordUriFileReference(node);
428 super.visitImportDirective(node); 444 super.visitImportDirective(node);
429 } 445 }
430 446
431 @override 447 @override
432 visitIndexExpression(IndexExpression node) { 448 visitIndexExpression(IndexExpression node) {
433 MethodElement element = node.bestElement; 449 MethodElement element = node.bestElement;
434 if (element is MethodElement) { 450 if (element is MethodElement) {
435 Token operator = node.leftBracket; 451 Token operator = node.leftBracket;
436 recordRelationToken(element, IndexRelationKind.IS_INVOKED_BY, operator); 452 recordRelationToken(element, IndexRelationKind.IS_INVOKED_BY, operator);
437 } 453 }
438 super.visitIndexExpression(node); 454 super.visitIndexExpression(node);
439 } 455 }
440 456
441 @override 457 @override
442 visitMethodInvocation(MethodInvocation node) { 458 visitMethodInvocation(MethodInvocation node) {
443 SimpleIdentifier name = node.methodName; 459 SimpleIdentifier name = node.methodName;
444 // TODO(scheglov) do we need this? 460 // TODO(scheglov) do we need this?
445 // LocationImpl location = _createLocationForNode(name); 461 // LocationImpl location = _createLocationForNode(name);
446 // // name invocation 462 // // name invocation
447 // recordRelationshipIndexable( 463 // recordRelationshipIndexable(
448 // new IndexableName(name.name), IndexConstants.IS_INVOKED_BY, location); 464 // new IndexableName(name.name), IndexConstants.IS_INVOKED_BY, location);
449 // element invocation 465 // element invocation
450 Element element = name.bestElement; 466 Element element = name.bestElement;
451 if (element is MethodElement || 467 if (element is MethodElement ||
452 element is PropertyAccessorElement || 468 element is PropertyAccessorElement ||
453 element is FunctionElement || 469 element is FunctionElement ||
454 element is VariableElement) { 470 element is VariableElement) {
455 recordRelation(element, IndexRelationKind.IS_INVOKED_BY, node); 471 recordRelation(element, IndexRelationKind.IS_INVOKED_BY, name);
456 } else if (element is ClassElement) { 472 } else if (element is ClassElement) {
457 recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, node); 473 recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, name);
458 } 474 }
459 node.target?.accept(this); 475 node.target?.accept(this);
460 node.argumentList?.accept(this); 476 node.argumentList?.accept(this);
461 } 477 }
462 478
463 @override 479 @override
464 visitPartDirective(PartDirective node) { 480 visitPartDirective(PartDirective node) {
465 recordRelation(node.element, IndexRelationKind.IS_REFERENCED_BY, node); 481 Element element = node.element;
466 recordUriFileReference(node); 482 recordUriReference(element, node);
467 super.visitPartDirective(node); 483 super.visitPartDirective(node);
468 } 484 }
469 485
470 @override 486 @override
471 visitPartOfDirective(PartOfDirective node) {
472 recordRelation(node.element, IndexRelationKind.IS_REFERENCED_BY, node);
473 }
474
475 @override
476 visitPostfixExpression(PostfixExpression node) { 487 visitPostfixExpression(PostfixExpression node) {
477 recordOperatorReference(node.operator, node.bestElement); 488 recordOperatorReference(node.operator, node.bestElement);
478 super.visitPostfixExpression(node); 489 super.visitPostfixExpression(node);
479 } 490 }
480 491
481 @override 492 @override
482 visitPrefixExpression(PrefixExpression node) { 493 visitPrefixExpression(PrefixExpression node) {
483 recordOperatorReference(node.operator, node.bestElement); 494 recordOperatorReference(node.operator, node.bestElement);
484 super.visitPrefixExpression(node); 495 super.visitPrefixExpression(node);
485 } 496 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 recordRelation(element.field, IndexRelationKind.IS_REFERENCED_BY, node); 536 recordRelation(element.field, IndexRelationKind.IS_REFERENCED_BY, node);
526 return; 537 return;
527 } 538 }
528 // record specific relations 539 // record specific relations
529 // TODO(scheglov) consider removing the conditions 540 // TODO(scheglov) consider removing the conditions
530 if (element is ClassElement || 541 if (element is ClassElement ||
531 element is FunctionElement || 542 element is FunctionElement ||
532 element is FunctionTypeAliasElement || 543 element is FunctionTypeAliasElement ||
533 element is LabelElement || 544 element is LabelElement ||
534 element is MethodElement || 545 element is MethodElement ||
546 element is ParameterElement ||
535 element is PrefixElement || 547 element is PrefixElement ||
536 element is PropertyAccessorElement || 548 element is PropertyAccessorElement ||
537 element is PropertyInducingElement || 549 element is PropertyInducingElement ||
538 element is TypeParameterElement) { 550 element is TypeParameterElement) {
539 recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, node); 551 recordRelation(element, IndexRelationKind.IS_REFERENCED_BY, node);
540 } 552 }
541 } 553 }
542 554
543 @override 555 @override
544 visitSuperConstructorInvocation(SuperConstructorInvocation node) { 556 visitSuperConstructorInvocation(SuperConstructorInvocation node) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 }); 652 });
641 return new UnitIndexBuilder( 653 return new UnitIndexBuilder(
642 elements: relations.map((r) => r.elementInfo.id).toList(), 654 elements: relations.map((r) => r.elementInfo.id).toList(),
643 kinds: relations.map((r) => r.kind).toList(), 655 kinds: relations.map((r) => r.kind).toList(),
644 locationOffsets: relations.map((r) => r.offset).toList(), 656 locationOffsets: relations.map((r) => r.offset).toList(),
645 locationLengths: relations.map((r) => r.length).toList(), 657 locationLengths: relations.map((r) => r.length).toList(),
646 libraryUri: pkg._getUriId(unitElement.library.source.uri), 658 libraryUri: pkg._getUriId(unitElement.library.source.uri),
647 unitUri: pkg._getUriId(unitElement.source.uri)); 659 unitUri: pkg._getUriId(unitElement.source.uri));
648 } 660 }
649 } 661 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698