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

Side by Side Diff: pkg/kernel/lib/library_index.dart

Issue 2896423002: Make LibraryIndex lazy. (Closed)
Patch Set: Created 3 years, 6 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 library kernel.library_index; 4 library kernel.library_index;
5 5
6 import 'ast.dart'; 6 import 'ast.dart';
7 7
8 /// Provides name-based access to library, class, and member AST nodes. 8 /// Provides name-based access to library, class, and member AST nodes.
9 /// 9 ///
10 /// When constructed, a given set of libraries are indexed immediately, and 10 /// When constructed, a given set of libraries are indexed immediately, and
11 /// will not be up-to-date with changes made after it was created. 11 /// will not be up-to-date with changes made after it was created.
12 class LibraryIndex { 12 class LibraryIndex {
13 static const String getterPrefix = 'get:'; 13 static const String getterPrefix = 'get:';
14 static const String setterPrefix = 'set:'; 14 static const String setterPrefix = 'set:';
15 15
16 /// A special class name that can be used to access the top-level members 16 /// A special class name that can be used to access the top-level members
17 /// of a library. 17 /// of a library.
18 static const String topLevel = '::'; 18 static const String topLevel = '::';
19 19
20 final Map<String, _ClassTable> _libraries = <String, _ClassTable>{}; 20 final Map<String, _ClassTable> _libraries = <String, _ClassTable>{};
21 21
22 /// Indexes the libraries with the URIs given in [libraryUris]. 22 /// Indexes the libraries with the URIs given in [libraryUris].
23 LibraryIndex(Program program, Iterable<String> libraryUris) { 23 LibraryIndex(Program program, Iterable<String> libraryUris) {
24 for (var uri in libraryUris) { 24 var libraryUriSet = libraryUris.toSet();
25 _libraries[uri] = new _ClassTable();
26 }
27 for (var library in program.libraries) { 25 for (var library in program.libraries) {
28 var index = _libraries['${library.importUri}']; 26 var uri = '${library.importUri}';
29 if (index != null) { 27 if (libraryUriSet.contains(uri)) {
30 index.build(library); 28 _libraries[uri] = new _ClassTable(library);
31 } 29 }
32 } 30 }
33 } 31 }
34 32
35 /// Indexes the libraries with the URIs given in [libraryUris]. 33 /// Indexes the libraries with the URIs given in [libraryUris].
36 LibraryIndex.byUri(Program program, Iterable<Uri> libraryUris) 34 LibraryIndex.byUri(Program program, Iterable<Uri> libraryUris)
37 : this(program, libraryUris.map((uri) => '$uri')); 35 : this(program, libraryUris.map((uri) => '$uri'));
38 36
39 /// Indexes the libraries with the URIs given in [libraryUris]. 37 /// Indexes `dart:` libraries.
40 LibraryIndex.coreLibraries(Program program) { 38 LibraryIndex.coreLibraries(Program program) {
41 for (var library in program.libraries) { 39 for (var library in program.libraries) {
42 if (library.importUri.scheme == 'dart') { 40 if (library.importUri.scheme == 'dart') {
43 _libraries['${library.importUri}'] = new _ClassTable()..build(library); 41 _libraries['${library.importUri}'] = new _ClassTable(library);
44 } 42 }
45 } 43 }
46 } 44 }
47 45
48 /// Indexes the entire program. 46 /// Indexes the entire program.
49 /// 47 ///
50 /// Consider using another constructor to only index the libraries that 48 /// Consider using another constructor to only index the libraries that
51 /// are needed. 49 /// are needed.
52 LibraryIndex.all(Program program) { 50 LibraryIndex.all(Program program) {
53 for (var library in program.libraries) { 51 for (var library in program.libraries) {
54 _libraries['${library.importUri}'] = new _ClassTable()..build(library); 52 _libraries['${library.importUri}'] = new _ClassTable(library);
55 } 53 }
56 } 54 }
57 55
58 _ClassTable _getLibraryIndex(String uri) { 56 _ClassTable _getLibraryIndex(String uri) {
59 _ClassTable libraryIndex = _libraries[uri]; 57 _ClassTable libraryIndex = _libraries[uri];
60 if (libraryIndex == null) { 58 if (libraryIndex == null) {
61 throw "The library '$uri' has not been indexed"; 59 throw "The library '$uri' has not been indexed";
62 } 60 }
63 return libraryIndex; 61 return libraryIndex;
64 } 62 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 121 }
124 122
125 /// Like [getTopLevelMember] but returns `null` if not found. 123 /// Like [getTopLevelMember] but returns `null` if not found.
126 Member tryGetTopLevelMember( 124 Member tryGetTopLevelMember(
127 String library, String className, String memberName) { 125 String library, String className, String memberName) {
128 return tryGetMember(library, topLevel, memberName); 126 return tryGetMember(library, topLevel, memberName);
129 } 127 }
130 } 128 }
131 129
132 class _ClassTable { 130 class _ClassTable {
133 Library library; 131 final Library library;
134 final Map<String, _MemberTable> classes = <String, _MemberTable>{};
135 132
136 void build(Library library) { 133 Map<String, _MemberTable> _classes;
137 this.library = library; 134
138 classes[LibraryIndex.topLevel] = new _MemberTable.topLevel(this); 135 _ClassTable(this.library);
139 for (var class_ in library.classes) { 136
140 classes[class_.name] = new _MemberTable(this, class_); 137 Map<String, _MemberTable> get classes {
138 if (_classes == null) {
139 _classes = <String, _MemberTable>{};
140 _classes[LibraryIndex.topLevel] = new _MemberTable.topLevel(this);
141 for (var class_ in library.classes) {
142 _classes[class_.name] = new _MemberTable(this, class_);
143 }
141 } 144 }
145 return _classes;
142 } 146 }
143 147
144 String get containerName { 148 String get containerName {
145 // For useful error messages, it can be helpful to indicate if the library 149 // For useful error messages, it can be helpful to indicate if the library
146 // is external. If a class or member was not found in an external library, 150 // is external. If a class or member was not found in an external library,
147 // it might be that it exists in the actual library, but its interface was 151 // it might be that it exists in the actual library, but its interface was
148 // not included in this build unit. 152 // not included in this build unit.
149 return library.isExternal 153 return library.isExternal
150 ? "external library '${library.importUri}'" 154 ? "external library '${library.importUri}'"
151 : "library '${library.importUri}'"; 155 : "library '${library.importUri}'";
(...skipping 20 matching lines...) Expand all
172 } 176 }
173 177
174 Member tryGetMember(String className, String memberName) { 178 Member tryGetMember(String className, String memberName) {
175 return classes[className]?.tryGetMember(memberName); 179 return classes[className]?.tryGetMember(memberName);
176 } 180 }
177 } 181 }
178 182
179 class _MemberTable { 183 class _MemberTable {
180 final _ClassTable parent; 184 final _ClassTable parent;
181 final Class class_; // Null for top-level. 185 final Class class_; // Null for top-level.
182 final Map<String, Member> members = <String, Member>{}; 186 Map<String, Member> _members;
183 187
184 Library get library => parent.library; 188 Library get library => parent.library;
185 189
186 _MemberTable(this.parent, this.class_) { 190 _MemberTable(this.parent, this.class_);
187 class_.procedures.forEach(addMember);
188 class_.fields.forEach(addMember);
189 class_.constructors.forEach(addMember);
190 }
191 191
192 _MemberTable.topLevel(this.parent) : class_ = null { 192 _MemberTable.topLevel(this.parent) : class_ = null;
193 library.procedures.forEach(addMember); 193
194 library.fields.forEach(addMember); 194 Map<String, Member> get members {
195 if (_members == null) {
196 _members = <String, Member>{};
197 if (class_ != null) {
198 class_.procedures.forEach(addMember);
199 class_.fields.forEach(addMember);
200 class_.constructors.forEach(addMember);
201 } else {
202 library.procedures.forEach(addMember);
203 library.fields.forEach(addMember);
204 }
205 }
206 return _members;
195 } 207 }
196 208
197 String getDisambiguatedName(Member member) { 209 String getDisambiguatedName(Member member) {
198 if (member is Procedure) { 210 if (member is Procedure) {
199 if (member.isGetter) return LibraryIndex.getterPrefix + member.name.name; 211 if (member.isGetter) return LibraryIndex.getterPrefix + member.name.name;
200 if (member.isSetter) return LibraryIndex.setterPrefix + member.name.name; 212 if (member.isSetter) return LibraryIndex.setterPrefix + member.name.name;
201 } 213 }
202 return member.name.name; 214 return member.name.name;
203 } 215 }
204 216
205 void addMember(Member member) { 217 void addMember(Member member) {
206 if (member.name.isPrivate && member.name.library != library) { 218 if (member.name.isPrivate && member.name.library != library) {
207 // Members whose name is private to other libraries cannot currently 219 // Members whose name is private to other libraries cannot currently
208 // be found with the LibraryIndex class. 220 // be found with the LibraryIndex class.
209 return; 221 return;
210 } 222 }
211 members[getDisambiguatedName(member)] = member; 223 _members[getDisambiguatedName(member)] = member;
212 } 224 }
213 225
214 String get containerName { 226 String get containerName {
215 if (class_ == null) { 227 if (class_ == null) {
216 return "top-level of ${parent.containerName}"; 228 return "top-level of ${parent.containerName}";
217 } else { 229 } else {
218 return "class '${class_.name}' in ${parent.containerName}"; 230 return "class '${class_.name}' in ${parent.containerName}";
219 } 231 }
220 } 232 }
221 233
222 Member getMember(String name) { 234 Member getMember(String name) {
223 var member = members[name]; 235 var member = members[name];
224 if (member == null) { 236 if (member == null) {
225 String message = "A member with disambiguated name '$name' was not found " 237 String message = "A member with disambiguated name '$name' was not found "
226 "in $containerName"; 238 "in $containerName";
227 var getter = LibraryIndex.getterPrefix + name; 239 var getter = LibraryIndex.getterPrefix + name;
228 var setter = LibraryIndex.setterPrefix + name; 240 var setter = LibraryIndex.setterPrefix + name;
229 if (members[getter] != null || members[setter] != null) { 241 if (members[getter] != null || members[setter] != null) {
230 throw "$message. Did you mean '$getter' or '$setter'?"; 242 throw "$message. Did you mean '$getter' or '$setter'?";
231 } 243 }
232 throw message; 244 throw message;
233 } 245 }
234 return member; 246 return member;
235 } 247 }
236 248
237 Member tryGetMember(String name) => members[name]; 249 Member tryGetMember(String name) => members[name];
238 } 250 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698