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

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

Issue 2668423003: Fix for resynthesizing with multiply defined names. (Closed)
Patch Set: Created 3 years, 10 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 | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | 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 4
5 import 'package:analyzer/src/generated/utilities_dart.dart'; 5 import 'package:analyzer/src/generated/utilities_dart.dart';
6 import 'package:analyzer/src/summary/format.dart'; 6 import 'package:analyzer/src/summary/format.dart';
7 import 'package:analyzer/src/summary/idl.dart'; 7 import 'package:analyzer/src/summary/idl.dart';
8 import 'package:analyzer/src/summary/name_filter.dart'; 8 import 'package:analyzer/src/summary/name_filter.dart';
9 9
10 /** 10 /**
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 * prelinked. 46 * prelinked.
47 * 47 *
48 * If no file exists at the given uri, `null` should be returned. 48 * If no file exists at the given uri, `null` should be returned.
49 */ 49 */
50 typedef UnlinkedUnit GetPartCallback(String relativeUri); 50 typedef UnlinkedUnit GetPartCallback(String relativeUri);
51 51
52 /** 52 /**
53 * A [_Meaning] representing a class. 53 * A [_Meaning] representing a class.
54 */ 54 */
55 class _ClassMeaning extends _Meaning { 55 class _ClassMeaning extends _Meaning {
56 final Map<String, _Meaning> namespace; 56 final _Namespace namespace;
57 57
58 _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace) 58 _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace)
59 : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters); 59 : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters);
60 } 60 }
61 61
62 /** 62 /**
63 * A [_Meaning] stores all the information necessary to find the declaration 63 * A [_Meaning] stores all the information necessary to find the declaration
64 * referred to by a name in a namespace. 64 * referred to by a name in a namespace.
65 */ 65 */
66 class _Meaning { 66 class _Meaning {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 LinkedReferenceBuilder encodeReference() { 102 LinkedReferenceBuilder encodeReference() {
103 return new LinkedReferenceBuilder( 103 return new LinkedReferenceBuilder(
104 unit: unit, 104 unit: unit,
105 kind: kind, 105 kind: kind,
106 dependency: dependency, 106 dependency: dependency,
107 numTypeParameters: numTypeParameters); 107 numTypeParameters: numTypeParameters);
108 } 108 }
109 } 109 }
110 110
111 /** 111 /**
112 * Mapping from names to corresponding unique [_Meaning]s.
113 */
114 class _Namespace {
115 final Set<String> namesWithConflictingDefinitions = new Set<String>();
116 final Set<String> libraryNames = new Set<String>();
117 final Map<String, _Meaning> map = <String, _Meaning>{};
118
119 /**
120 * Return the [_Meaning] of the name, or `null` is not defined.
121 */
122 _Meaning operator [](String name) {
123 return map[name];
124 }
125
126 /**
127 * Define that the [name] has the given [value]. If the [name] already been
128 * defined with a different value, then it becomes undefined.
129 */
130 void add(String name, _Meaning value) {
131 // Already determined to be a conflict.
132 if (namesWithConflictingDefinitions.contains(name)) {
133 return;
134 }
135
136 _Meaning currentValue = map[name];
137 if (currentValue == null) {
138 map[name] = value;
139 } else if (currentValue == value) {
140 // The same value, ignore.
141 } else {
142 // A conflict, remember it, and un-define the name.
143 namesWithConflictingDefinitions.add(name);
144 map.remove(name);
145 }
146 }
147
148 /**
149 * Return `true` if the [name] was defined before [rememberLibraryNames]
150 * invocation.
151 */
152 bool definesLibraryName(String name) => libraryNames.contains(name);
153
154 /**
155 * Return `true` if the [name] is already defined.
156 */
157 bool definesName(String name) => map.containsKey(name);
158
159 /**
160 * Apply [f] to each name-meaning pair.
161 */
162 void forEach(void f(String key, _Meaning value)) {
163 map.forEach(f);
164 }
165
166 /**
167 * This method should be invoked after defining all names that are defined
168 * in a library, before defining imported names.
169 */
170 void rememberLibraryNames() {
171 libraryNames.addAll(map.keys);
172 }
173 }
174
175 /**
112 * A [_Meaning] representing a prefix introduced by an import directive. 176 * A [_Meaning] representing a prefix introduced by an import directive.
113 */ 177 */
114 class _PrefixMeaning extends _Meaning { 178 class _PrefixMeaning extends _Meaning {
115 final Map<String, _Meaning> namespace = <String, _Meaning>{}; 179 final _Namespace namespace = new _Namespace();
116 180
117 _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0); 181 _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0);
118 } 182 }
119 183
120 /** 184 /**
121 * Helper class containing temporary data structures needed to prelink a single 185 * Helper class containing temporary data structures needed to prelink a single
122 * library. 186 * library.
123 * 187 *
124 * Note: throughout this class, a `null` value for a relative URI represents 188 * Note: throughout this class, a `null` value for a relative URI represents
125 * the defining compilation unit of the library being prelinked. 189 * the defining compilation unit of the library being prelinked.
(...skipping 11 matching lines...) Expand all
137 <String, UnlinkedPublicNamespace>{}; 201 <String, UnlinkedPublicNamespace>{};
138 202
139 /** 203 /**
140 * Cache of values returned by [getPart]. 204 * Cache of values returned by [getPart].
141 */ 205 */
142 final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{}; 206 final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{};
143 207
144 /** 208 /**
145 * Names defined inside the library being prelinked. 209 * Names defined inside the library being prelinked.
146 */ 210 */
147 final Map<String, _Meaning> privateNamespace = <String, _Meaning>{ 211 final _Namespace privateNamespace = new _Namespace()
148 'dynamic': new _Meaning(0, ReferenceKind.classOrEnum, 0, 0), 212 ..add('dynamic', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0))
149 'void': new _Meaning(0, ReferenceKind.classOrEnum, 0, 0) 213 ..add('void', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0));
150 };
151 214
152 /** 215 /**
153 * List of dependencies of the library being prelinked. This will be output 216 * List of dependencies of the library being prelinked. This will be output
154 * to [LinkedLibrary.dependencies]. 217 * to [LinkedLibrary.dependencies].
155 */ 218 */
156 final List<LinkedDependencyBuilder> dependencies = <LinkedDependencyBuilder>[ 219 final List<LinkedDependencyBuilder> dependencies = <LinkedDependencyBuilder>[
157 new LinkedDependencyBuilder() 220 new LinkedDependencyBuilder()
158 ]; 221 ];
159 222
160 /** 223 /**
161 * Map from the relative URI of a dependent library to the index of the 224 * Map from the relative URI of a dependent library to the index of the
162 * corresponding entry in [dependencies]. 225 * corresponding entry in [dependencies].
163 */ 226 */
164 final Map<String, int> uriToDependency = <String, int>{null: 0}; 227 final Map<String, int> uriToDependency = <String, int>{null: 0};
165 228
166 /** 229 /**
167 * List of public namespaces corresponding to each entry in [dependencies]. 230 * List of public namespaces corresponding to each entry in [dependencies].
168 */ 231 */
169 final List<Map<String, _Meaning>> dependencyToPublicNamespace = 232 final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[null];
170 <Map<String, _Meaning>>[null];
171 233
172 _Prelinker(this.definingUnit, this.getPart, this.getImport, 234 _Prelinker(this.definingUnit, this.getPart, this.getImport,
173 this.getDeclaredVariable) { 235 this.getDeclaredVariable) {
174 partCache[null] = definingUnit; 236 partCache[null] = definingUnit;
175 importCache[null] = definingUnit.publicNamespace; 237 importCache[null] = definingUnit.publicNamespace;
176 } 238 }
177 239
178 /** 240 /**
179 * Compute the public namespace for the library whose URI is reachable from 241 * Compute the public namespace for the library whose URI is reachable from
180 * [definingUnit] via [relativeUri], by aggregating together public namespace 242 * [definingUnit] via [relativeUri], by aggregating together public namespace
181 * information from all of its parts. 243 * information from all of its parts.
182 */ 244 */
183 Map<String, _Meaning> aggregatePublicNamespace(String relativeUri) { 245 _Namespace aggregatePublicNamespace(String relativeUri) {
184 if (uriToDependency.containsKey(relativeUri)) { 246 if (uriToDependency.containsKey(relativeUri)) {
185 return dependencyToPublicNamespace[uriToDependency[relativeUri]]; 247 return dependencyToPublicNamespace[uriToDependency[relativeUri]];
186 } 248 }
187 assert(dependencies.length == dependencyToPublicNamespace.length); 249 assert(dependencies.length == dependencyToPublicNamespace.length);
188 int dependency = dependencies.length; 250 int dependency = dependencies.length;
189 uriToDependency[relativeUri] = dependency; 251 uriToDependency[relativeUri] = dependency;
190 List<String> unitUris = getUnitUris(relativeUri); 252 List<String> unitUris = getUnitUris(relativeUri);
191 LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder( 253 LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder(
192 uri: relativeUri, parts: unitUris.sublist(1)); 254 uri: relativeUri, parts: unitUris.sublist(1));
193 dependencies.add(linkedDependency); 255 dependencies.add(linkedDependency);
194 256
195 Map<String, _Meaning> aggregated = <String, _Meaning>{}; 257 _Namespace aggregated = new _Namespace();
196 258
197 for (int unitNum = 0; unitNum < unitUris.length; unitNum++) { 259 for (int unitNum = 0; unitNum < unitUris.length; unitNum++) {
198 String unitUri = unitUris[unitNum]; 260 String unitUri = unitUris[unitNum];
199 UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri); 261 UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri);
200 if (importedNamespace == null) { 262 if (importedNamespace == null) {
201 continue; 263 continue;
202 } 264 }
203 for (UnlinkedPublicName name in importedNamespace.names) { 265 for (UnlinkedPublicName name in importedNamespace.names) {
204 aggregated.putIfAbsent(name.name, () { 266 if (name.kind == ReferenceKind.classOrEnum) {
205 if (name.kind == ReferenceKind.classOrEnum) { 267 _Namespace namespace = new _Namespace();
206 Map<String, _Meaning> namespace = <String, _Meaning>{}; 268 name.members.forEach((executable) {
207 name.members.forEach((executable) { 269 namespace.add(
208 namespace[executable.name] = new _Meaning( 270 executable.name,
209 unitNum, executable.kind, 0, executable.numTypeParameters); 271 new _Meaning(
210 }); 272 unitNum, executable.kind, 0, executable.numTypeParameters));
211 return new _ClassMeaning( 273 });
212 unitNum, dependency, name.numTypeParameters, namespace); 274 aggregated.add(
213 } 275 name.name,
214 return new _Meaning( 276 new _ClassMeaning(
215 unitNum, name.kind, dependency, name.numTypeParameters); 277 unitNum, dependency, name.numTypeParameters, namespace));
216 }); 278 } else {
279 aggregated.add(
280 name.name,
281 new _Meaning(
282 unitNum, name.kind, dependency, name.numTypeParameters));
283 }
217 } 284 }
218 } 285 }
219 286
220 dependencyToPublicNamespace.add(aggregated); 287 dependencyToPublicNamespace.add(aggregated);
221 return aggregated; 288 return aggregated;
222 } 289 }
223 290
224 /** 291 /**
225 * Compute the export namespace for the library whose URI is reachable from 292 * Compute the export namespace for the library whose URI is reachable from
226 * [definingUnit] via [relativeUri], by aggregating together public namespace 293 * [definingUnit] via [relativeUri], by aggregating together public namespace
227 * information from the library and the transitive closure of its exports. 294 * information from the library and the transitive closure of its exports.
228 * 295 *
229 * If [relativeUri] is `null` (meaning the export namespace of [definingUnit] 296 * If [relativeUri] is `null` (meaning the export namespace of [definingUnit]
230 * should be computed), then names defined in [definingUnit] are ignored. 297 * should be computed), then names defined in [definingUnit] are ignored.
231 */ 298 */
232 Map<String, _Meaning> computeExportNamespace(String relativeUri) { 299 _Namespace computeExportNamespace(String relativeUri) {
233 Map<String, _Meaning> exportNamespace = relativeUri == null 300 _Namespace exportNamespace = relativeUri == null
234 ? <String, _Meaning>{} 301 ? new _Namespace()
235 : aggregatePublicNamespace(relativeUri); 302 : aggregatePublicNamespace(relativeUri);
236 void chaseExports( 303 void chaseExports(
237 NameFilter filter, String relativeUri, Set<String> seenUris) { 304 NameFilter filter, String relativeUri, Set<String> seenUris) {
238 if (seenUris.add(relativeUri)) { 305 if (seenUris.add(relativeUri)) {
239 UnlinkedPublicNamespace exportedNamespace = 306 UnlinkedPublicNamespace exportedNamespace =
240 getImportCached(relativeUri); 307 getImportCached(relativeUri);
241 if (exportedNamespace != null) { 308 if (exportedNamespace != null) {
242 for (UnlinkedExportPublic export in exportedNamespace.exports) { 309 for (UnlinkedExportPublic export in exportedNamespace.exports) {
243 String relativeExportUri = 310 String relativeExportUri =
244 _selectUri(export.uri, export.configurations); 311 _selectUri(export.uri, export.configurations);
245 String exportUri = resolveUri(relativeUri, relativeExportUri); 312 String exportUri = resolveUri(relativeUri, relativeExportUri);
246 NameFilter newFilter = filter.merge( 313 NameFilter newFilter = filter.merge(
247 new NameFilter.forUnlinkedCombinators(export.combinators)); 314 new NameFilter.forUnlinkedCombinators(export.combinators));
248 aggregatePublicNamespace(exportUri) 315 aggregatePublicNamespace(exportUri)
249 .forEach((String name, _Meaning meaning) { 316 .forEach((String name, _Meaning meaning) {
250 if (newFilter.accepts(name) && 317 if (newFilter.accepts(name)) {
251 !exportNamespace.containsKey(name)) { 318 exportNamespace.add(name, meaning);
252 exportNamespace[name] = meaning;
253 } 319 }
254 }); 320 });
255 chaseExports(newFilter, exportUri, seenUris); 321 chaseExports(newFilter, exportUri, seenUris);
256 } 322 }
257 } 323 }
258 seenUris.remove(relativeUri); 324 seenUris.remove(relativeUri);
259 } 325 }
260 } 326 }
261 327
262 chaseExports(NameFilter.identity, relativeUri, new Set<String>()); 328 chaseExports(NameFilter.identity, relativeUri, new Set<String>());
263 return exportNamespace; 329 return exportNamespace;
264 } 330 }
265 331
266 /** 332 /**
267 * Extract all the names defined in [unit] (which is the [unitNum]th unit in 333 * Extract all the names defined in [unit] (which is the [unitNum]th unit in
268 * the library being prelinked) and store them in [privateNamespace]. 334 * the library being prelinked) and store them in [privateNamespace].
269 * Excludes names introduced by `import` statements. 335 * Excludes names introduced by `import` statements.
270 */ 336 */
271 void extractPrivateNames(UnlinkedUnit unit, int unitNum) { 337 void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
272 for (UnlinkedClass cls in unit.classes) { 338 for (UnlinkedClass cls in unit.classes) {
273 privateNamespace.putIfAbsent(cls.name, () { 339 _Namespace namespace = new _Namespace();
274 Map<String, _Meaning> namespace = <String, _Meaning>{}; 340 cls.fields.forEach((field) {
275 cls.fields.forEach((field) { 341 if (field.isStatic && field.isConst) {
276 if (field.isStatic && field.isConst) { 342 namespace.add(field.name,
277 namespace[field.name] = 343 new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
278 new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0); 344 }
279 }
280 });
281 cls.executables.forEach((executable) {
282 ReferenceKind kind = null;
283 if (executable.kind == UnlinkedExecutableKind.constructor) {
284 kind = ReferenceKind.constructor;
285 } else if (executable.kind ==
286 UnlinkedExecutableKind.functionOrMethod &&
287 executable.isStatic) {
288 kind = ReferenceKind.method;
289 } else if (executable.kind == UnlinkedExecutableKind.getter &&
290 executable.isStatic) {
291 kind = ReferenceKind.propertyAccessor;
292 }
293 if (kind != null && executable.name.isNotEmpty) {
294 namespace[executable.name] = new _Meaning(
295 unitNum, kind, 0, executable.typeParameters.length);
296 }
297 });
298 return new _ClassMeaning(
299 unitNum, 0, cls.typeParameters.length, namespace);
300 }); 345 });
346 cls.executables.forEach((executable) {
347 ReferenceKind kind = null;
348 if (executable.kind == UnlinkedExecutableKind.constructor) {
349 kind = ReferenceKind.constructor;
350 } else if (executable.kind == UnlinkedExecutableKind.functionOrMethod &&
351 executable.isStatic) {
352 kind = ReferenceKind.method;
353 } else if (executable.kind == UnlinkedExecutableKind.getter &&
354 executable.isStatic) {
355 kind = ReferenceKind.propertyAccessor;
356 }
357 if (kind != null && executable.name.isNotEmpty) {
358 namespace.add(executable.name,
359 new _Meaning(unitNum, kind, 0, executable.typeParameters.length));
360 }
361 });
362 privateNamespace.add(cls.name,
363 new _ClassMeaning(unitNum, 0, cls.typeParameters.length, namespace));
301 } 364 }
302 for (UnlinkedEnum enm in unit.enums) { 365 for (UnlinkedEnum enm in unit.enums) {
303 privateNamespace.putIfAbsent(enm.name, () { 366 _Namespace namespace = new _Namespace();
304 Map<String, _Meaning> namespace = <String, _Meaning>{}; 367 enm.values.forEach((UnlinkedEnumValue value) {
305 enm.values.forEach((UnlinkedEnumValue value) { 368 namespace.add(value.name,
306 namespace[value.name] = 369 new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
307 new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0);
308 });
309 namespace['values'] =
310 new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0);
311 return new _ClassMeaning(unitNum, 0, 0, namespace);
312 }); 370 });
371 namespace.add('values',
372 new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
373 privateNamespace.add(
374 enm.name, new _ClassMeaning(unitNum, 0, 0, namespace));
313 } 375 }
314 for (UnlinkedExecutable executable in unit.executables) { 376 for (UnlinkedExecutable executable in unit.executables) {
315 privateNamespace.putIfAbsent( 377 privateNamespace.add(
316 executable.name, 378 executable.name,
317 () => new _Meaning( 379 new _Meaning(
318 unitNum, 380 unitNum,
319 executable.kind == UnlinkedExecutableKind.functionOrMethod 381 executable.kind == UnlinkedExecutableKind.functionOrMethod
320 ? ReferenceKind.topLevelFunction 382 ? ReferenceKind.topLevelFunction
321 : ReferenceKind.topLevelPropertyAccessor, 383 : ReferenceKind.topLevelPropertyAccessor,
322 0, 384 0,
323 executable.typeParameters.length)); 385 executable.typeParameters.length));
324 } 386 }
325 for (UnlinkedTypedef typedef in unit.typedefs) { 387 for (UnlinkedTypedef typedef in unit.typedefs) {
326 privateNamespace.putIfAbsent( 388 privateNamespace.add(
327 typedef.name, 389 typedef.name,
328 () => new _Meaning(unitNum, ReferenceKind.typedef, 0, 390 new _Meaning(unitNum, ReferenceKind.typedef, 0,
329 typedef.typeParameters.length)); 391 typedef.typeParameters.length));
330 } 392 }
331 for (UnlinkedVariable variable in unit.variables) { 393 for (UnlinkedVariable variable in unit.variables) {
332 privateNamespace.putIfAbsent( 394 privateNamespace.add(variable.name,
333 variable.name, 395 new _Meaning(unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
334 () => new _Meaning(
335 unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
336 if (!(variable.isConst || variable.isFinal)) { 396 if (!(variable.isConst || variable.isFinal)) {
337 privateNamespace.putIfAbsent( 397 privateNamespace.add(
338 variable.name + '=', 398 variable.name + '=',
339 () => new _Meaning( 399 new _Meaning(
340 unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0)); 400 unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
341 } 401 }
342 } 402 }
343 } 403 }
344 404
345 /** 405 /**
346 * Filter the export namespace for the library whose URI is reachable from 406 * Filter the export namespace for the library whose URI is reachable from
347 * [definingUnit] via [relativeUri], retaining only those names accepted by 407 * [definingUnit] via [relativeUri], retaining only those names accepted by
348 * [combinators], and store the resulting names in [result]. Names that 408 * [combinators], and store the resulting names in [result]. Names that
349 * already exist in [result] are not overwritten. 409 * already exist in [result] are not overwritten.
350 */ 410 */
351 void filterExportNamespace(String relativeUri, 411 void filterExportNamespace(String relativeUri,
352 List<UnlinkedCombinator> combinators, Map<String, _Meaning> result) { 412 List<UnlinkedCombinator> combinators, _Namespace result) {
353 Map<String, _Meaning> exportNamespace = computeExportNamespace(relativeUri); 413 _Namespace exportNamespace = computeExportNamespace(relativeUri);
354 if (result == null) { 414 if (result == null) {
355 // This can happen if the import prefix was shadowed by a local name, so 415 // This can happen if the import prefix was shadowed by a local name, so
356 // the imported symbols are inaccessible. 416 // the imported symbols are inaccessible.
357 return; 417 return;
358 } 418 }
359 NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators); 419 NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators);
360 exportNamespace.forEach((String name, _Meaning meaning) { 420 exportNamespace.forEach((String name, _Meaning meaning) {
361 if (filter.accepts(name) && !result.containsKey(name)) { 421 if (filter.accepts(name) && !result.definesLibraryName(name)) {
362 result[name] = meaning; 422 result.add(name, meaning);
363 } 423 }
364 }); 424 });
365 } 425 }
366 426
367 /** 427 /**
368 * Wrapper around [getImport] that caches the return value in [importCache]. 428 * Wrapper around [getImport] that caches the return value in [importCache].
369 */ 429 */
370 UnlinkedPublicNamespace getImportCached(String relativeUri) { 430 UnlinkedPublicNamespace getImportCached(String relativeUri) {
371 return importCache.putIfAbsent(relativeUri, () => getImport(relativeUri)); 431 return importCache.putIfAbsent(relativeUri, () => getImport(relativeUri));
372 } 432 }
(...skipping 25 matching lines...) Expand all
398 } 458 }
399 459
400 /** 460 /**
401 * Process a single `import` declaration in the library being prelinked. The 461 * Process a single `import` declaration in the library being prelinked. The
402 * return value is the index of the imported library in [dependencies]. 462 * return value is the index of the imported library in [dependencies].
403 */ 463 */
404 int handleImport(UnlinkedImport import) { 464 int handleImport(UnlinkedImport import) {
405 String uri = import.isImplicit 465 String uri = import.isImplicit
406 ? 'dart:core' 466 ? 'dart:core'
407 : _selectUri(import.uri, import.configurations); 467 : _selectUri(import.uri, import.configurations);
408 Map<String, _Meaning> targetNamespace = null; 468 _Namespace targetNamespace = null;
409 if (import.prefixReference != 0) { 469 if (import.prefixReference != 0) {
410 // The name introduced by an import declaration can't have a prefix of 470 // The name introduced by an import declaration can't have a prefix of
411 // its own. 471 // its own.
412 assert( 472 assert(
413 definingUnit.references[import.prefixReference].prefixReference == 0); 473 definingUnit.references[import.prefixReference].prefixReference == 0);
414 String prefix = definingUnit.references[import.prefixReference].name; 474 String prefix = definingUnit.references[import.prefixReference].name;
415 _Meaning prefixMeaning = privateNamespace[prefix]; 475 _Meaning prefixMeaning = privateNamespace[prefix];
416 if (prefixMeaning is _PrefixMeaning) { 476 if (prefixMeaning is _PrefixMeaning) {
417 targetNamespace = prefixMeaning.namespace; 477 targetNamespace = prefixMeaning.namespace;
418 } 478 }
419 } else { 479 } else {
420 targetNamespace = privateNamespace; 480 targetNamespace = privateNamespace;
421 } 481 }
422 filterExportNamespace(uri, import.combinators, targetNamespace); 482 filterExportNamespace(uri, import.combinators, targetNamespace);
423 return uriToDependency[uri]; 483 return uriToDependency[uri];
424 } 484 }
425 485
426 /** 486 /**
427 * Produce a [LinkedUnit] for the given [unit], by resolving every one of 487 * Produce a [LinkedUnit] for the given [unit], by resolving every one of
428 * its references. 488 * its references.
429 */ 489 */
430 LinkedUnitBuilder linkUnit(UnlinkedUnit unit) { 490 LinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
431 if (unit == null) { 491 if (unit == null) {
432 return new LinkedUnitBuilder(); 492 return new LinkedUnitBuilder();
433 } 493 }
434 Map<int, Map<String, _Meaning>> prefixNamespaces = 494 Map<int, _Namespace> prefixNamespaces = <int, _Namespace>{};
435 <int, Map<String, _Meaning>>{};
436 List<LinkedReferenceBuilder> references = <LinkedReferenceBuilder>[]; 495 List<LinkedReferenceBuilder> references = <LinkedReferenceBuilder>[];
437 for (int i = 0; i < unit.references.length; i++) { 496 for (int i = 0; i < unit.references.length; i++) {
438 UnlinkedReference reference = unit.references[i]; 497 UnlinkedReference reference = unit.references[i];
439 Map<String, _Meaning> namespace; 498 _Namespace namespace;
440 if (reference.prefixReference == 0) { 499 if (reference.prefixReference == 0) {
441 namespace = privateNamespace; 500 namespace = privateNamespace;
442 } else { 501 } else {
443 // Prefix references must always point backward. 502 // Prefix references must always point backward.
444 assert(reference.prefixReference < i); 503 assert(reference.prefixReference < i);
445 namespace = prefixNamespaces[reference.prefixReference]; 504 namespace = prefixNamespaces[reference.prefixReference];
446 // Expressions like 'a.b.c.d' cannot be prelinked. 505 // Expressions like 'a.b.c.d' cannot be prelinked.
447 namespace ??= const <String, _Meaning>{}; 506 namespace ??= new _Namespace();
448 } 507 }
449 _Meaning meaning = namespace[reference.name]; 508 _Meaning meaning = namespace[reference.name];
450 if (meaning != null) { 509 if (meaning != null) {
451 if (meaning is _PrefixMeaning) { 510 if (meaning is _PrefixMeaning) {
452 prefixNamespaces[i] = meaning.namespace; 511 prefixNamespaces[i] = meaning.namespace;
453 } else if (meaning is _ClassMeaning) { 512 } else if (meaning is _ClassMeaning) {
454 prefixNamespaces[i] = meaning.namespace; 513 prefixNamespaces[i] = meaning.namespace;
455 } 514 }
456 references.add(meaning.encodeReference()); 515 references.add(meaning.encodeReference());
457 } else { 516 } else {
(...skipping 20 matching lines...) Expand all
478 if (unit != null) { 537 if (unit != null) {
479 extractPrivateNames(unit, unitNum); 538 extractPrivateNames(unit, unitNum);
480 } 539 }
481 } 540 }
482 541
483 // Fill in exported names. This must be done before filling in prefixes 542 // Fill in exported names. This must be done before filling in prefixes
484 // defined in import declarations, because prefixes shouldn't shadow 543 // defined in import declarations, because prefixes shouldn't shadow
485 // exports. 544 // exports.
486 List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[]; 545 List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
487 computeExportNamespace(null).forEach((String name, _Meaning meaning) { 546 computeExportNamespace(null).forEach((String name, _Meaning meaning) {
488 if (!privateNamespace.containsKey(name)) { 547 if (!privateNamespace.definesName(name)) {
489 exportNames.add(meaning.encodeExportName(name)); 548 exportNames.add(meaning.encodeExportName(name));
490 } 549 }
491 }); 550 });
492 551
493 // Fill in prefixes defined in import declarations. 552 // Fill in prefixes defined in import declarations.
494 for (UnlinkedImport import in units[0].imports) { 553 for (UnlinkedImport import in units[0].imports) {
495 if (import.prefixReference != 0) { 554 if (import.prefixReference != 0) {
496 privateNamespace.putIfAbsent( 555 String name = units[0].references[import.prefixReference].name;
497 units[0].references[import.prefixReference].name, 556 if (!privateNamespace.definesName(name)) {
498 () => new _PrefixMeaning()); 557 privateNamespace.add(name, new _PrefixMeaning());
558 }
499 } 559 }
500 } 560 }
501 561
562 // All the names defined so far are library local, they take precedence
563 // over anything imported from other libraries.
564 privateNamespace.rememberLibraryNames();
565
502 // Fill in imported and exported names. 566 // Fill in imported and exported names.
503 List<int> importDependencies = 567 List<int> importDependencies =
504 definingUnit.imports.map(handleImport).toList(); 568 definingUnit.imports.map(handleImport).toList();
505 List<int> exportDependencies = 569 List<int> exportDependencies =
506 definingUnit.publicNamespace.exports.map((UnlinkedExportPublic exp) { 570 definingUnit.publicNamespace.exports.map((UnlinkedExportPublic exp) {
507 String uri = _selectUri(exp.uri, exp.configurations); 571 String uri = _selectUri(exp.uri, exp.configurations);
508 return uriToDependency[uri]; 572 return uriToDependency[uri];
509 }).toList(); 573 }).toList();
510 574
511 // Link each compilation unit. 575 // Link each compilation unit.
(...skipping 28 matching lines...) Expand all
540 String _selectUri( 604 String _selectUri(
541 String defaultUri, List<UnlinkedConfiguration> configurations) { 605 String defaultUri, List<UnlinkedConfiguration> configurations) {
542 for (UnlinkedConfiguration configuration in configurations) { 606 for (UnlinkedConfiguration configuration in configurations) {
543 if (getDeclaredVariable(configuration.name) == configuration.value) { 607 if (getDeclaredVariable(configuration.name) == configuration.value) {
544 return configuration.uri; 608 return configuration.uri;
545 } 609 }
546 } 610 }
547 return defaultUri; 611 return defaultUri;
548 } 612 }
549 } 613 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/driver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698