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

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

Issue 1779233002: Fix for indexing synthetic elements. (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/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.
22 */
23 class ElementInfo {
24 /**
25 * The identifier of the [CompilationUnitElement] containing this element.
26 */
27 final int unitId;
28
29 /**
30 * The name offset of the element.
31 */
32 final int offset;
33
34 /**
35 * The kind of the element.
36 */
37 final IndexSyntheticElementKind kind;
38
39 /**
40 * The unique id of the element. It is set after indexing of the whole
41 * package is done and we are assembling the full package index.
42 */
43 int id;
44
45 ElementInfo(this.unitId, this.offset, this.kind) {
46 assert(offset >= 0);
47 }
48 }
49
50 /**
16 * Object that gathers information about the whole package index and then uses 51 * Object that gathers information about the whole package index and then uses
17 * it to assemble a new [PackageIndexBuilder]. Call [index] on each compilation 52 * it to assemble a new [PackageIndexBuilder]. Call [index] on each compilation
18 * unit to be indexed, then call [assemble] to retrieve the complete index for 53 * unit to be indexed, then call [assemble] to retrieve the complete index for
19 * the package. 54 * the package.
20 */ 55 */
21 class PackageIndexAssembler { 56 class PackageIndexAssembler {
22 /** 57 /**
23 * Map associating referenced elements with their [_ElementInfo]s. 58 * Map associating referenced elements with their [ElementInfo]s.
24 */ 59 */
25 final Map<Element, _ElementInfo> _elementMap = <Element, _ElementInfo>{}; 60 final Map<Element, ElementInfo> _elementMap = <Element, ElementInfo>{};
26 61
27 /** 62 /**
28 * Map associating [CompilationUnitElement]s with their identifiers, which 63 * Map associating [CompilationUnitElement]s with their identifiers, which
29 * are indices into [_unitLibraryUris] and [_unitUnitUris]. 64 * are indices into [_unitLibraryUris] and [_unitUnitUris].
30 */ 65 */
31 final Map<CompilationUnitElement, int> _unitMap = 66 final Map<CompilationUnitElement, int> _unitMap =
32 <CompilationUnitElement, int>{}; 67 <CompilationUnitElement, int>{};
33 68
34 /** 69 /**
35 * Each item of this list corresponds to the library URI of a unique 70 * Each item of this list corresponds to the library URI of a unique
(...skipping 24 matching lines...) Expand all
60 PackageIndexBuilder assemble() { 95 PackageIndexBuilder assemble() {
61 // sort strings end set IDs 96 // sort strings end set IDs
62 List<_StringInfo> stringInfoList = _stringMap.values.toList(); 97 List<_StringInfo> stringInfoList = _stringMap.values.toList();
63 stringInfoList.sort((a, b) { 98 stringInfoList.sort((a, b) {
64 return a.value.compareTo(b.value); 99 return a.value.compareTo(b.value);
65 }); 100 });
66 for (int i = 0; i < stringInfoList.length; i++) { 101 for (int i = 0; i < stringInfoList.length; i++) {
67 stringInfoList[i].id = i; 102 stringInfoList[i].id = i;
68 } 103 }
69 // sort elements and set IDs 104 // sort elements and set IDs
70 List<_ElementInfo> elementInfoList = _elementMap.values.toList(); 105 List<ElementInfo> elementInfoList = _elementMap.values.toList();
71 elementInfoList.sort((a, b) { 106 elementInfoList.sort((a, b) {
72 return a.offset - b.offset; 107 return a.offset - b.offset;
73 }); 108 });
74 for (int i = 0; i < elementInfoList.length; i++) { 109 for (int i = 0; i < elementInfoList.length; i++) {
75 elementInfoList[i].id = i; 110 elementInfoList[i].id = i;
76 } 111 }
77 return new PackageIndexBuilder( 112 return new PackageIndexBuilder(
78 unitLibraryUris: _unitLibraryUris.map((s) => s.id).toList(), 113 unitLibraryUris: _unitLibraryUris.map((s) => s.id).toList(),
79 unitUnitUris: _unitUnitUris.map((s) => s.id).toList(), 114 unitUnitUris: _unitUnitUris.map((s) => s.id).toList(),
80 elementUnits: elementInfoList.map((e) => e.unitId).toList(), 115 elementUnits: elementInfoList.map((e) => e.unitId).toList(),
81 elementOffsets: elementInfoList.map((e) => e.offset).toList(), 116 elementOffsets: elementInfoList.map((e) => e.offset).toList(),
82 elementKinds: elementInfoList.map((e) => e.kind).toList(), 117 elementKinds: elementInfoList.map((e) => e.kind).toList(),
83 strings: stringInfoList.map((s) => s.value).toList(), 118 strings: stringInfoList.map((s) => s.value).toList(),
84 units: _units.map((unit) => unit.assemble()).toList()); 119 units: _units.map((unit) => unit.assemble()).toList());
85 } 120 }
86 121
87 /** 122 /**
88 * Index the given fully resolved [unit]. 123 * Index the given fully resolved [unit].
89 */ 124 */
90 void index(CompilationUnit unit) { 125 void index(CompilationUnit unit) {
91 int unitId = _getUnitId(unit.element); 126 int unitId = _getUnitId(unit.element);
92 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitId); 127 _UnitIndexAssembler assembler = new _UnitIndexAssembler(this, unitId);
93 _units.add(assembler); 128 _units.add(assembler);
94 unit.accept(new _IndexContributor(assembler)); 129 unit.accept(new _IndexContributor(assembler));
95 } 130 }
96 131
97 /** 132 /**
98 * Return the unique [_ElementInfo] corresponding the [element]. The field 133 * Return the unique [ElementInfo] corresponding the [element]. The field
99 * [_ElementInfo.id] is filled by [assemble] during final sorting. 134 * [ElementInfo.id] is filled by [assemble] during final sorting.
100 */ 135 */
101 _ElementInfo _getElementInfo(Element element) { 136 ElementInfo _getElementInfo(Element element) {
102 if (element is Member) { 137 if (element is Member) {
103 element = (element as Member).baseElement; 138 element = (element as Member).baseElement;
104 } 139 }
105 return _elementMap.putIfAbsent(element, () { 140 return _elementMap.putIfAbsent(element, () {
106 CompilationUnitElement unitElement = getUnitElement(element); 141 CompilationUnitElement unitElement = getUnitElement(element);
107 int unitId = _getUnitId(unitElement); 142 int unitId = _getUnitId(unitElement);
108 int offset = element.nameOffset; 143 return newElementInfo(unitId, element);
109 if (element is LibraryElement || element is CompilationUnitElement) {
110 offset = 0;
111 }
112 IndexSyntheticElementKind kind = getIndexElementKind(element);
113 return new _ElementInfo(unitId, offset, kind);
114 }); 144 });
115 } 145 }
116 146
117 /** 147 /**
118 * Return the unique [_StringInfo] corresponding the [str]. The field 148 * Return the unique [_StringInfo] corresponding the [str]. The field
119 * [_StringInfo.id] is filled by [assemble] during final sorting. 149 * [_StringInfo.id] is filled by [assemble] during final sorting.
120 */ 150 */
121 _StringInfo _getStringInfo(String str) { 151 _StringInfo _getStringInfo(String str) {
122 return _stringMap.putIfAbsent(str, () { 152 return _stringMap.putIfAbsent(str, () {
123 return new _StringInfo(str); 153 return new _StringInfo(str);
(...skipping 18 matching lines...) Expand all
142 /** 172 /**
143 * Return the unique [_StringInfo] corresponding [uri]. The field 173 * Return the unique [_StringInfo] corresponding [uri]. The field
144 * [_StringInfo.id] is filled by [assemble] during final sorting. 174 * [_StringInfo.id] is filled by [assemble] during final sorting.
145 */ 175 */
146 _StringInfo _getUriInfo(Uri uri) { 176 _StringInfo _getUriInfo(Uri uri) {
147 String str = uri.toString(); 177 String str = uri.toString();
148 return _getStringInfo(str); 178 return _getStringInfo(str);
149 } 179 }
150 180
151 /** 181 /**
152 * Return the kind of the given [element].
153 */
154 static IndexSyntheticElementKind getIndexElementKind(Element element) {
155 if (element.isSynthetic) {
156 if (element is ConstructorElement) {
157 return IndexSyntheticElementKind.constructor;
158 }
159 if (element is PropertyAccessorElement) {
160 return element.isGetter
161 ? IndexSyntheticElementKind.getter
162 : IndexSyntheticElementKind.setter;
163 }
164 }
165 return IndexSyntheticElementKind.notSynthetic;
166 }
167
168 /**
169 * Return the [CompilationUnitElement] that should be used for [element]. 182 * Return the [CompilationUnitElement] that should be used for [element].
170 * Throw [StateError] if the [element] is not linked into a unit. 183 * Throw [StateError] if the [element] is not linked into a unit.
171 */ 184 */
172 static CompilationUnitElement getUnitElement(Element element) { 185 static CompilationUnitElement getUnitElement(Element element) {
173 for (Element e = element; e != null; e = e.enclosingElement) { 186 for (Element e = element; e != null; e = e.enclosingElement) {
174 if (e is CompilationUnitElement) { 187 if (e is CompilationUnitElement) {
175 return e; 188 return e;
176 } 189 }
177 if (e is LibraryElement) { 190 if (e is LibraryElement) {
178 return e.definingCompilationUnit; 191 return e.definingCompilationUnit;
179 } 192 }
180 } 193 }
181 throw new StateError(element.toString()); 194 throw new StateError(element.toString());
182 } 195 }
196
197 /**
198 * Return a new [ElementInfo] for the given [element] in the given [unitId].
199 * This method is static, so it cannot add any information to the index.
200 */
201 static ElementInfo newElementInfo(int unitId, Element element) {
202 IndexSyntheticElementKind kind = IndexSyntheticElementKind.notSynthetic;
203 if (element.isSynthetic) {
204 if (element is ConstructorElement) {
205 kind = IndexSyntheticElementKind.constructor;
206 element = element.enclosingElement;
207 } else if (element is PropertyAccessorElement) {
208 PropertyAccessorElement property = element;
209 kind = property.isGetter
210 ? IndexSyntheticElementKind.getter
211 : IndexSyntheticElementKind.setter;
212 element = element.enclosingElement;
213 } else {
214 throw new ArgumentError(
215 'Unsupported synthetic element ${element.runtimeType}');
216 }
217 }
218 int offset = element.nameOffset;
219 if (element is LibraryElement || element is CompilationUnitElement) {
220 offset = 0;
221 }
222 return new ElementInfo(unitId, offset, kind);
223 }
183 } 224 }
184 225
185 /** 226 /**
186 * Information about a single defined name. Any [_DefinedNameInfo] is always 227 * Information about a single defined name. Any [_DefinedNameInfo] is always
187 * part of a [_UnitIndexAssembler], so [offset] should be understood within the 228 * part of a [_UnitIndexAssembler], so [offset] should be understood within the
188 * context of the compilation unit pointed to by the [_UnitIndexAssembler]. 229 * context of the compilation unit pointed to by the [_UnitIndexAssembler].
189 */ 230 */
190 class _DefinedNameInfo { 231 class _DefinedNameInfo {
191 /** 232 /**
192 * The information about the name returned from 233 * The information about the name returned from
193 * [PackageIndexAssembler._getStringInfo]. 234 * [PackageIndexAssembler._getStringInfo].
194 */ 235 */
195 final _StringInfo nameInfo; 236 final _StringInfo nameInfo;
196 237
197 /** 238 /**
198 * The coarse-grained kind of the defined name. 239 * The coarse-grained kind of the defined name.
199 */ 240 */
200 final IndexNameKind kind; 241 final IndexNameKind kind;
201 242
202 /** 243 /**
203 * The name offset of the defined element. 244 * The name offset of the defined element.
204 */ 245 */
205 final int offset; 246 final int offset;
206 247
207 _DefinedNameInfo(this.nameInfo, this.kind, this.offset); 248 _DefinedNameInfo(this.nameInfo, this.kind, this.offset);
208 } 249 }
209 250
210 /** 251 /**
211 * Information about an element referenced in index.
212 */
213 class _ElementInfo {
214 /**
215 * The identifier of the [CompilationUnitElement] containing this element.
216 */
217 final int unitId;
218
219 /**
220 * The name offset of the element.
221 */
222 final int offset;
223
224 /**
225 * The kind of the element.
226 */
227 final IndexSyntheticElementKind kind;
228
229 /**
230 * The unique id of the element. It is set after indexing of the whole
231 * package is done and we are assembling the full package index.
232 */
233 int id;
234
235 _ElementInfo(this.unitId, this.offset, this.kind);
236 }
237
238 /**
239 * Information about a string referenced in the index.
240 */
241 class _StringInfo {
242 /**
243 * The value of the string.
244 */
245 final String value;
246
247 /**
248 * The unique id of the string. It is set after indexing of the whole
249 * package is done and we are assembling the full package index.
250 */
251 int id;
252
253 _StringInfo(this.value);
254 }
255
256 /**
257 * Information about a single relation. Any [_ElementRelationInfo] is always 252 * Information about a single relation. Any [_ElementRelationInfo] is always
258 * part of a [_UnitIndexAssembler], so [offset] and [length] should be 253 * part of a [_UnitIndexAssembler], so [offset] and [length] should be
259 * understood within the context of the compilation unit pointed to by the 254 * understood within the context of the compilation unit pointed to by the
260 * [_UnitIndexAssembler]. 255 * [_UnitIndexAssembler].
261 */ 256 */
262 class _ElementRelationInfo { 257 class _ElementRelationInfo {
263 final _ElementInfo elementInfo; 258 final ElementInfo elementInfo;
264 final IndexRelationKind kind; 259 final IndexRelationKind kind;
265 final int offset; 260 final int offset;
266 final int length; 261 final int length;
267 final bool isQualified; 262 final bool isQualified;
268 263
269 _ElementRelationInfo( 264 _ElementRelationInfo(
270 this.elementInfo, this.kind, this.offset, this.length, this.isQualified); 265 this.elementInfo, this.kind, this.offset, this.length, this.isQualified);
271 } 266 }
272 267
273 /** 268 /**
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 * [PackageIndexAssembler._getStringInfo]. 669 * [PackageIndexAssembler._getStringInfo].
675 */ 670 */
676 final _StringInfo nameInfo; 671 final _StringInfo nameInfo;
677 final IndexRelationKind kind; 672 final IndexRelationKind kind;
678 final int offset; 673 final int offset;
679 674
680 _NameRelationInfo(this.nameInfo, this.kind, this.offset); 675 _NameRelationInfo(this.nameInfo, this.kind, this.offset);
681 } 676 }
682 677
683 /** 678 /**
679 * Information about a string referenced in the index.
680 */
681 class _StringInfo {
682 /**
683 * The value of the string.
684 */
685 final String value;
686
687 /**
688 * The unique id of the string. It is set after indexing of the whole
689 * package is done and we are assembling the full package index.
690 */
691 int id;
692
693 _StringInfo(this.value);
694 }
695
696 /**
684 * Assembler of a single [CompilationUnit] index. The intended usage sequence: 697 * Assembler of a single [CompilationUnit] index. The intended usage sequence:
685 * 698 *
686 * - Call [defineName] for each name defined in the compilation unit. 699 * - Call [defineName] for each name defined in the compilation unit.
687 * - Call [addElementRelation] for each element relation found in the 700 * - Call [addElementRelation] for each element relation found in the
688 * compilation unit. 701 * compilation unit.
689 * - Call [addNameRelation] for each name relation found in the 702 * - Call [addNameRelation] for each name relation found in the
690 * compilation unit. 703 * compilation unit.
691 * - Assign ids to all the [_ElementInfo] objects reachable from 704 * - Assign ids to all the [ElementInfo] objects reachable from
692 * [elementRelations]. 705 * [elementRelations].
693 * - Call [assemble] to produce the final unit index. 706 * - Call [assemble] to produce the final unit index.
694 */ 707 */
695 class _UnitIndexAssembler { 708 class _UnitIndexAssembler {
696 final PackageIndexAssembler pkg; 709 final PackageIndexAssembler pkg;
697 final int unitId; 710 final int unitId;
698 final List<_DefinedNameInfo> definedNames = <_DefinedNameInfo>[]; 711 final List<_DefinedNameInfo> definedNames = <_DefinedNameInfo>[];
699 final List<_ElementRelationInfo> elementRelations = <_ElementRelationInfo>[]; 712 final List<_ElementRelationInfo> elementRelations = <_ElementRelationInfo>[];
700 final List<_NameRelationInfo> nameRelations = <_NameRelationInfo>[]; 713 final List<_NameRelationInfo> nameRelations = <_NameRelationInfo>[];
701 714
702 _UnitIndexAssembler(this.pkg, this.unitId); 715 _UnitIndexAssembler(this.pkg, this.unitId);
703 716
704 void addElementRelation(Element element, IndexRelationKind kind, int offset, 717 void addElementRelation(Element element, IndexRelationKind kind, int offset,
705 int length, bool isQualified) { 718 int length, bool isQualified) {
706 try { 719 try {
707 _ElementInfo elementInfo = pkg._getElementInfo(element); 720 ElementInfo elementInfo = pkg._getElementInfo(element);
708 elementRelations.add(new _ElementRelationInfo( 721 elementRelations.add(new _ElementRelationInfo(
709 elementInfo, kind, offset, length, isQualified)); 722 elementInfo, kind, offset, length, isQualified));
710 } on StateError {} 723 } on StateError {}
711 } 724 }
712 725
713 void addNameRelation(String name, IndexRelationKind kind, int offset) { 726 void addNameRelation(String name, IndexRelationKind kind, int offset) {
714 _StringInfo nameId = pkg._getStringInfo(name); 727 _StringInfo nameId = pkg._getStringInfo(name);
715 nameRelations.add(new _NameRelationInfo(nameId, kind, offset)); 728 nameRelations.add(new _NameRelationInfo(nameId, kind, offset));
716 } 729 }
717 730
(...skipping 25 matching lines...) Expand all
743 usedNames: nameRelations.map((r) => r.nameInfo.id).toList(), 756 usedNames: nameRelations.map((r) => r.nameInfo.id).toList(),
744 usedNameKinds: nameRelations.map((r) => r.kind).toList(), 757 usedNameKinds: nameRelations.map((r) => r.kind).toList(),
745 usedNameOffsets: nameRelations.map((r) => r.offset).toList()); 758 usedNameOffsets: nameRelations.map((r) => r.offset).toList());
746 } 759 }
747 760
748 void defineName(String name, IndexNameKind kind, int offset) { 761 void defineName(String name, IndexNameKind kind, int offset) {
749 _StringInfo nameInfo = pkg._getStringInfo(name); 762 _StringInfo nameInfo = pkg._getStringInfo(name);
750 definedNames.add(new _DefinedNameInfo(nameInfo, kind, offset)); 763 definedNames.add(new _DefinedNameInfo(nameInfo, kind, offset));
751 } 764 }
752 } 765 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/test/services/search/search_engine2_test.dart ('k') | pkg/analyzer/test/src/summary/index_unit_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698