| OLD | NEW |
| 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/dart/element/member.dart'; | 10 import 'package:analyzer/src/dart/element/member.dart'; |
| 11 import 'package:analyzer/src/generated/utilities_dart.dart'; | 11 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 12 import 'package:analyzer/src/summary/format.dart'; | 12 import 'package:analyzer/src/summary/format.dart'; |
| 13 import 'package:analyzer/src/summary/idl.dart'; | 13 import 'package:analyzer/src/summary/idl.dart'; |
| 14 | 14 |
| 15 /** | 15 /** |
| 16 * TODO(scheglov) add to the `meta` package. | |
| 17 */ | |
| 18 const visibleForTesting = const Object(); | |
| 19 | |
| 20 /** | |
| 21 * Information about an element referenced in index. | 16 * Information about an element referenced in index. |
| 22 */ | 17 */ |
| 23 class ElementInfo { | 18 class ElementInfo { |
| 24 /** | 19 /** |
| 25 * The identifier of the [CompilationUnitElement] containing this element. | 20 * The identifier of the [CompilationUnitElement] containing this element. |
| 26 */ | 21 */ |
| 27 final int unitId; | 22 final int unitId; |
| 28 | 23 |
| 29 /** | 24 /** |
| 30 * The name offset of the element. | 25 * The name offset of the element. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 */ | 78 */ |
| 84 final Map<String, _StringInfo> _stringMap = <String, _StringInfo>{}; | 79 final Map<String, _StringInfo> _stringMap = <String, _StringInfo>{}; |
| 85 | 80 |
| 86 /** | 81 /** |
| 87 * List of information about each unit indexed in this index. | 82 * List of information about each unit indexed in this index. |
| 88 */ | 83 */ |
| 89 final List<_UnitIndexAssembler> _units = <_UnitIndexAssembler>[]; | 84 final List<_UnitIndexAssembler> _units = <_UnitIndexAssembler>[]; |
| 90 | 85 |
| 91 /** | 86 /** |
| 92 * Assemble a new [PackageIndexBuilder] using the information gathered by | 87 * Assemble a new [PackageIndexBuilder] using the information gathered by |
| 93 * [index]. | 88 * [indexDeclarations] or [indexUnit]. |
| 94 */ | 89 */ |
| 95 PackageIndexBuilder assemble() { | 90 PackageIndexBuilder assemble() { |
| 96 // sort strings end set IDs | 91 // sort strings end set IDs |
| 97 List<_StringInfo> stringInfoList = _stringMap.values.toList(); | 92 List<_StringInfo> stringInfoList = _stringMap.values.toList(); |
| 98 stringInfoList.sort((a, b) { | 93 stringInfoList.sort((a, b) { |
| 99 return a.value.compareTo(b.value); | 94 return a.value.compareTo(b.value); |
| 100 }); | 95 }); |
| 101 for (int i = 0; i < stringInfoList.length; i++) { | 96 for (int i = 0; i < stringInfoList.length; i++) { |
| 102 stringInfoList[i].id = i; | 97 stringInfoList[i].id = i; |
| 103 } | 98 } |
| 104 // sort elements and set IDs | 99 // sort elements and set IDs |
| 105 List<ElementInfo> elementInfoList = _elementMap.values.toList(); | 100 List<ElementInfo> elementInfoList = _elementMap.values.toList(); |
| 106 elementInfoList.sort((a, b) { | 101 elementInfoList.sort((a, b) { |
| 107 return a.offset - b.offset; | 102 return a.offset - b.offset; |
| 108 }); | 103 }); |
| 109 for (int i = 0; i < elementInfoList.length; i++) { | 104 for (int i = 0; i < elementInfoList.length; i++) { |
| 110 elementInfoList[i].id = i; | 105 elementInfoList[i].id = i; |
| 111 } | 106 } |
| 112 return new PackageIndexBuilder( | 107 return new PackageIndexBuilder( |
| 113 unitLibraryUris: _unitLibraryUris.map((s) => s.id).toList(), | 108 unitLibraryUris: _unitLibraryUris.map((s) => s.id).toList(), |
| 114 unitUnitUris: _unitUnitUris.map((s) => s.id).toList(), | 109 unitUnitUris: _unitUnitUris.map((s) => s.id).toList(), |
| 115 elementUnits: elementInfoList.map((e) => e.unitId).toList(), | 110 elementUnits: elementInfoList.map((e) => e.unitId).toList(), |
| 116 elementOffsets: elementInfoList.map((e) => e.offset).toList(), | 111 elementOffsets: elementInfoList.map((e) => e.offset).toList(), |
| 117 elementKinds: elementInfoList.map((e) => e.kind).toList(), | 112 elementKinds: elementInfoList.map((e) => e.kind).toList(), |
| 118 strings: stringInfoList.map((s) => s.value).toList(), | 113 strings: stringInfoList.map((s) => s.value).toList(), |
| 119 units: _units.map((unit) => unit.assemble()).toList()); | 114 units: _units.map((unit) => unit.assemble()).toList()); |
| 120 } | 115 } |
| 121 | 116 |
| 122 /** | 117 /** |
| 118 * Index declarations in the given partially resolved [unit]. |
| 119 */ |
| 120 void indexDeclarations(CompilationUnit unit) { |
| 121 int unitId = _getUnitId(unit.element); |
| 122 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitId); |
| 123 _units.add(assembler); |
| 124 unit.accept(new _IndexDeclarationContributor(assembler)); |
| 125 } |
| 126 |
| 127 /** |
| 123 * Index the given fully resolved [unit]. | 128 * Index the given fully resolved [unit]. |
| 124 */ | 129 */ |
| 125 void index(CompilationUnit unit) { | 130 void indexUnit(CompilationUnit unit) { |
| 126 int unitId = _getUnitId(unit.element); | 131 int unitId = _getUnitId(unit.element); |
| 127 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitId); | 132 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitId); |
| 128 _units.add(assembler); | 133 _units.add(assembler); |
| 129 unit.accept(new _IndexContributor(assembler)); | 134 unit.accept(new _IndexContributor(assembler)); |
| 130 } | 135 } |
| 131 | 136 |
| 132 /** | 137 /** |
| 133 * Return the unique [ElementInfo] corresponding the [element]. The field | 138 * Return the unique [ElementInfo] corresponding the [element]. The field |
| 134 * [ElementInfo.id] is filled by [assemble] during final sorting. | 139 * [ElementInfo.id] is filled by [assemble] during final sorting. |
| 135 */ | 140 */ |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 final int length; | 289 final int length; |
| 285 final bool isQualified; | 290 final bool isQualified; |
| 286 | 291 |
| 287 _ElementRelationInfo( | 292 _ElementRelationInfo( |
| 288 this.elementInfo, this.kind, this.offset, this.length, this.isQualified); | 293 this.elementInfo, this.kind, this.offset, this.length, this.isQualified); |
| 289 } | 294 } |
| 290 | 295 |
| 291 /** | 296 /** |
| 292 * Visits a resolved AST and adds relationships into [_UnitIndexAssembler]. | 297 * Visits a resolved AST and adds relationships into [_UnitIndexAssembler]. |
| 293 */ | 298 */ |
| 294 class _IndexContributor extends GeneralizingAstVisitor { | 299 class _IndexContributor extends _IndexDeclarationContributor { |
| 295 final _UnitIndexAssembler assembler; | 300 _IndexContributor(_UnitIndexAssembler assembler) : super(assembler); |
| 296 | |
| 297 _IndexContributor(this.assembler); | |
| 298 | |
| 299 /** | |
| 300 * Record definition of the given [element]. | |
| 301 */ | |
| 302 void recordDefinedElement(Element element) { | |
| 303 if (element != null) { | |
| 304 String name = element.displayName; | |
| 305 int offset = element.nameOffset; | |
| 306 Element enclosing = element.enclosingElement; | |
| 307 if (enclosing is CompilationUnitElement) { | |
| 308 assembler.defineName(name, IndexNameKind.topLevel, offset); | |
| 309 } else if (enclosing is ClassElement) { | |
| 310 assembler.defineName(name, IndexNameKind.classMember, offset); | |
| 311 } | |
| 312 } | |
| 313 } | |
| 314 | 301 |
| 315 void recordIsAncestorOf(Element descendant) { | 302 void recordIsAncestorOf(Element descendant) { |
| 316 _recordIsAncestorOf(descendant, descendant, false, <ClassElement>[]); | 303 _recordIsAncestorOf(descendant, descendant, false, <ClassElement>[]); |
| 317 } | 304 } |
| 318 | 305 |
| 319 /** | 306 /** |
| 320 * Record that the name [node] has a relation of the given [kind]. | 307 * Record that the name [node] has a relation of the given [kind]. |
| 321 */ | 308 */ |
| 322 void recordNameRelation( | 309 void recordNameRelation( |
| 323 SimpleIdentifier node, IndexRelationKind kind, bool isQualified) { | 310 SimpleIdentifier node, IndexRelationKind kind, bool isQualified) { |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 } else { | 546 } else { |
| 560 int offset = node.thisKeyword.end; | 547 int offset = node.thisKeyword.end; |
| 561 recordRelationOffset( | 548 recordRelationOffset( |
| 562 element, IndexRelationKind.IS_REFERENCED_BY, offset, 0, true); | 549 element, IndexRelationKind.IS_REFERENCED_BY, offset, 0, true); |
| 563 } | 550 } |
| 564 super.visitRedirectingConstructorInvocation(node); | 551 super.visitRedirectingConstructorInvocation(node); |
| 565 } | 552 } |
| 566 | 553 |
| 567 @override | 554 @override |
| 568 visitSimpleIdentifier(SimpleIdentifier node) { | 555 visitSimpleIdentifier(SimpleIdentifier node) { |
| 569 Element element = node.bestElement; | |
| 570 // name in declaration | 556 // name in declaration |
| 571 if (node.inDeclarationContext()) { | 557 if (node.inDeclarationContext()) { |
| 558 Element element = node.staticElement; |
| 572 recordDefinedElement(element); | 559 recordDefinedElement(element); |
| 573 return; | 560 return; |
| 574 } | 561 } |
| 562 Element element = node.bestElement; |
| 575 // record unresolved name reference | 563 // record unresolved name reference |
| 576 bool isQualified = _isQualified(node); | 564 bool isQualified = _isQualified(node); |
| 577 if (element == null) { | 565 if (element == null) { |
| 578 bool inGetterContext = node.inGetterContext(); | 566 bool inGetterContext = node.inGetterContext(); |
| 579 bool inSetterContext = node.inSetterContext(); | 567 bool inSetterContext = node.inSetterContext(); |
| 580 IndexRelationKind kind; | 568 IndexRelationKind kind; |
| 581 if (inGetterContext && inSetterContext) { | 569 if (inGetterContext && inSetterContext) { |
| 582 kind = IndexRelationKind.IS_READ_WRITTEN_BY; | 570 kind = IndexRelationKind.IS_READ_WRITTEN_BY; |
| 583 } else if (inGetterContext) { | 571 } else if (inGetterContext) { |
| 584 kind = IndexRelationKind.IS_READ_BY; | 572 kind = IndexRelationKind.IS_READ_BY; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 _recordIsAncestorOf(descendant, mixinType.element, true, visitedElements); | 685 _recordIsAncestorOf(descendant, mixinType.element, true, visitedElements); |
| 698 } | 686 } |
| 699 for (InterfaceType implementedType in ancestor.interfaces) { | 687 for (InterfaceType implementedType in ancestor.interfaces) { |
| 700 _recordIsAncestorOf( | 688 _recordIsAncestorOf( |
| 701 descendant, implementedType.element, true, visitedElements); | 689 descendant, implementedType.element, true, visitedElements); |
| 702 } | 690 } |
| 703 } | 691 } |
| 704 } | 692 } |
| 705 | 693 |
| 706 /** | 694 /** |
| 695 * Visits a resolved AST and adds relationships into [_UnitIndexAssembler]. |
| 696 */ |
| 697 class _IndexDeclarationContributor extends GeneralizingAstVisitor { |
| 698 final _UnitIndexAssembler assembler; |
| 699 |
| 700 _IndexDeclarationContributor(this.assembler); |
| 701 |
| 702 /** |
| 703 * Record definition of the given [element]. |
| 704 */ |
| 705 void recordDefinedElement(Element element) { |
| 706 if (element != null) { |
| 707 String name = element.displayName; |
| 708 int offset = element.nameOffset; |
| 709 Element enclosing = element.enclosingElement; |
| 710 if (enclosing is CompilationUnitElement) { |
| 711 assembler.defineName(name, IndexNameKind.topLevel, offset); |
| 712 } else if (enclosing is ClassElement) { |
| 713 assembler.defineName(name, IndexNameKind.classMember, offset); |
| 714 } |
| 715 } |
| 716 } |
| 717 |
| 718 @override |
| 719 visitSimpleIdentifier(SimpleIdentifier node) { |
| 720 if (node.inDeclarationContext()) { |
| 721 Element element = node.staticElement; |
| 722 recordDefinedElement(element); |
| 723 return; |
| 724 } |
| 725 } |
| 726 } |
| 727 |
| 728 /** |
| 707 * Information about a single name relation. Any [_NameRelationInfo] is always | 729 * Information about a single name relation. Any [_NameRelationInfo] is always |
| 708 * part of a [_UnitIndexAssembler], so [offset] should be understood within the | 730 * part of a [_UnitIndexAssembler], so [offset] should be understood within the |
| 709 * context of the compilation unit pointed to by the [_UnitIndexAssembler]. | 731 * context of the compilation unit pointed to by the [_UnitIndexAssembler]. |
| 710 */ | 732 */ |
| 711 class _NameRelationInfo { | 733 class _NameRelationInfo { |
| 712 /** | 734 /** |
| 713 * The information about the name returned from | 735 * The information about the name returned from |
| 714 * [PackageIndexAssembler._getStringInfo]. | 736 * [PackageIndexAssembler._getStringInfo]. |
| 715 */ | 737 */ |
| 716 final _StringInfo nameInfo; | 738 final _StringInfo nameInfo; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 usedNameOffsets: nameRelations.map((r) => r.offset).toList(), | 827 usedNameOffsets: nameRelations.map((r) => r.offset).toList(), |
| 806 usedNameIsQualifiedFlags: | 828 usedNameIsQualifiedFlags: |
| 807 nameRelations.map((r) => r.isQualified).toList()); | 829 nameRelations.map((r) => r.isQualified).toList()); |
| 808 } | 830 } |
| 809 | 831 |
| 810 void defineName(String name, IndexNameKind kind, int offset) { | 832 void defineName(String name, IndexNameKind kind, int offset) { |
| 811 _StringInfo nameInfo = pkg._getStringInfo(name); | 833 _StringInfo nameInfo = pkg._getStringInfo(name); |
| 812 definedNames.add(new _DefinedNameInfo(nameInfo, kind, offset)); | 834 definedNames.add(new _DefinedNameInfo(nameInfo, kind, offset)); |
| 813 } | 835 } |
| 814 } | 836 } |
| OLD | NEW |