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

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

Issue 2700843002: Use absolute URIs for LinkedDependency.uri/parts. (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
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 /**
11 * Create a [LinkedLibraryBuilder] corresponding to the given 11 * Create a [LinkedLibraryBuilder] corresponding to the given [definingUnitUri]
12 * [definingUnit], which should be the defining compilation unit for a library. 12 * and [definingUnit], which should be the defining compilation unit for a
13 * Compilation units referenced by the defining compilation unit via `part` 13 * library. Compilation units referenced by the defining compilation unit via
14 * declarations will be retrieved using [getPart]. Public namespaces for 14 * `part` declarations will be retrieved using [getPart]. Public namespaces
15 * libraries referenced by the defining compilation unit via `import` 15 * for libraries referenced by the defining compilation unit via `import`
16 * declarations (and files reachable from them via `part` and `export` 16 * declarations (and files reachable from them via `part` and `export`
17 * declarations) will be retrieved using [getImport]. 17 * declarations) will be retrieved using [getImport].
18 */ 18 */
19 LinkedLibraryBuilder prelink(UnlinkedUnit definingUnit, GetPartCallback getPart, 19 LinkedLibraryBuilder prelink(
20 GetImportCallback getImport, GetDeclaredVariable getDeclaredVariable) { 20 String definingUnitUri,
21 return new _Prelinker(definingUnit, getPart, getImport, getDeclaredVariable) 21 UnlinkedUnit definingUnit,
22 GetPartCallback getPart,
23 GetImportCallback getImport,
24 GetDeclaredVariable getDeclaredVariable) {
25 return new _Prelinker(definingUnitUri, definingUnit, getPart, getImport,
26 getDeclaredVariable)
22 .prelink(); 27 .prelink();
23 } 28 }
24 29
25 /** 30 /**
26 * Return the raw string value of the variable with the given [name], 31 * Return the raw string value of the variable with the given [name],
27 * or `null` of the variable is not defined. 32 * or `null` of the variable is not defined.
28 */ 33 */
29 typedef String GetDeclaredVariable(String name); 34 typedef String GetDeclaredVariable(String name);
30 35
31 /** 36 /**
32 * Type of the callback used by the prelinker to obtain public namespace 37 * Type of the callback used by the prelinker to obtain public namespace
33 * information about libraries imported by the library to be prelinked (and 38 * information about libraries with the given [absoluteUri] imported by the
34 * the transitive closure of parts and exports reachable from those libraries). 39 * library to be prelinked (and the transitive closure of parts and exports
35 * [relativeUri] should be interpreted relative to the defining compilation 40 * reachable from those libraries).
36 * unit of the library being prelinked.
37 * 41 *
38 * If no file exists at the given uri, `null` should be returned. 42 * If no file exists at the given uri, `null` should be returned.
39 */ 43 */
40 typedef UnlinkedPublicNamespace GetImportCallback(String relativeUri); 44 typedef UnlinkedPublicNamespace GetImportCallback(String absoluteUri);
41 45
42 /** 46 /**
43 * Type of the callback used by the prelinker to obtain unlinked summaries of 47 * Type of the callback used by the prelinker to obtain unlinked summaries of
44 * part files of the library to be prelinked. [relativeUri] should be 48 * part files of the library to be prelinked.
45 * interpreted relative to the defining compilation unit of the library being
46 * prelinked.
47 * 49 *
48 * If no file exists at the given uri, `null` should be returned. 50 * If no file exists at the given uri, `null` should be returned.
49 */ 51 */
50 typedef UnlinkedUnit GetPartCallback(String relativeUri); 52 typedef UnlinkedUnit GetPartCallback(String absoluteUri);
51 53
52 /** 54 /**
53 * A [_Meaning] representing a class. 55 * A [_Meaning] representing a class.
54 */ 56 */
55 class _ClassMeaning extends _Meaning { 57 class _ClassMeaning extends _Meaning {
56 final _Namespace namespace; 58 final _Namespace namespace;
57 59
58 _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace) 60 _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace)
59 : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters); 61 : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters);
60 } 62 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 */ 179 */
178 class _PrefixMeaning extends _Meaning { 180 class _PrefixMeaning extends _Meaning {
179 final _Namespace namespace = new _Namespace(); 181 final _Namespace namespace = new _Namespace();
180 182
181 _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0); 183 _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0);
182 } 184 }
183 185
184 /** 186 /**
185 * Helper class containing temporary data structures needed to prelink a single 187 * Helper class containing temporary data structures needed to prelink a single
186 * library. 188 * library.
187 *
188 * Note: throughout this class, a `null` value for a relative URI represents
189 * the defining compilation unit of the library being prelinked.
190 */ 189 */
191 class _Prelinker { 190 class _Prelinker {
191 final String definingUnitUri;
192 final UnlinkedUnit definingUnit; 192 final UnlinkedUnit definingUnit;
193 final GetPartCallback getPart; 193 final GetPartCallback getPart;
194 final GetImportCallback getImport; 194 final GetImportCallback getImport;
195 final GetDeclaredVariable getDeclaredVariable; 195 final GetDeclaredVariable getDeclaredVariable;
196 196
197 /** 197 /**
198 * Cache of values returned by [getImport]. 198 * Cache of values returned by [getImport].
199 */ 199 */
200 final Map<String, UnlinkedPublicNamespace> importCache = 200 final Map<String, UnlinkedPublicNamespace> importCache =
201 <String, UnlinkedPublicNamespace>{}; 201 <String, UnlinkedPublicNamespace>{};
202 202
203 /** 203 /**
204 * Cache of values returned by [getPart]. 204 * Cache of values returned by [getPart].
205 */ 205 */
206 final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{}; 206 final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{};
207 207
208 /** 208 /**
209 * Names defined inside the library being prelinked. 209 * Names defined inside the library being prelinked.
210 */ 210 */
211 final _Namespace privateNamespace = new _Namespace() 211 final _Namespace privateNamespace = new _Namespace()
212 ..add('dynamic', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0)) 212 ..add('dynamic', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0))
213 ..add('void', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0)); 213 ..add('void', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0));
214 214
215 /** 215 /**
216 * 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
217 * to [LinkedLibrary.dependencies]. 217 * to [LinkedLibrary.dependencies].
218 */ 218 */
219 final List<LinkedDependencyBuilder> dependencies = <LinkedDependencyBuilder>[ 219 final List<LinkedDependencyBuilder> dependencies =
220 new LinkedDependencyBuilder() 220 <LinkedDependencyBuilder>[];
221 ];
222 221
223 /** 222 /**
224 * Map from the relative URI of a dependent library to the index of the 223 * Map from the absolute URI of a dependent library to the index of the
225 * corresponding entry in [dependencies]. 224 * corresponding entry in [dependencies].
226 */ 225 */
227 final Map<String, int> uriToDependency = <String, int>{null: 0}; 226 final Map<String, int> uriToDependency = <String, int>{};
Paul Berry 2017/02/16 22:17:50 I don't understand this change. Why don't we need
scheglov 2017/02/16 22:32:36 computeExportNamespace() needs to use absolute URI
Paul Berry 2017/02/16 22:55:26 Ok, thanks.
228 227
229 /** 228 /**
230 * List of public namespaces corresponding to each entry in [dependencies]. 229 * List of public namespaces corresponding to each entry in [dependencies].
231 */ 230 */
232 final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[null]; 231 final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[];
233 232
234 _Prelinker(this.definingUnit, this.getPart, this.getImport, 233 _Prelinker(this.definingUnitUri, this.definingUnit, this.getPart,
235 this.getDeclaredVariable) { 234 this.getImport, this.getDeclaredVariable) {
236 partCache[null] = definingUnit; 235 partCache[definingUnitUri] = definingUnit;
237 importCache[null] = definingUnit.publicNamespace; 236 importCache[definingUnitUri] = definingUnit.publicNamespace;
238 } 237 }
239 238
240 /** 239 /**
241 * Compute the public namespace for the library whose URI is reachable from 240 * Compute the public namespace for the library whose URI is reachable from
242 * [definingUnit] via [relativeUri], by aggregating together public namespace 241 * [definingUnit] via [absoluteUri], by aggregating together public namespace
243 * information from all of its parts. 242 * information from all of its parts.
244 */ 243 */
245 _Namespace aggregatePublicNamespace(String relativeUri) { 244 _Namespace aggregatePublicNamespace(String absoluteUri) {
246 if (uriToDependency.containsKey(relativeUri)) { 245 if (uriToDependency.containsKey(absoluteUri)) {
247 return dependencyToPublicNamespace[uriToDependency[relativeUri]]; 246 return dependencyToPublicNamespace[uriToDependency[absoluteUri]];
248 } 247 }
249 assert(dependencies.length == dependencyToPublicNamespace.length); 248 assert(dependencies.length == dependencyToPublicNamespace.length);
250 int dependency = dependencies.length; 249 int dependency = dependencies.length;
251 uriToDependency[relativeUri] = dependency; 250 uriToDependency[absoluteUri] = dependency;
252 List<String> unitUris = getUnitUris(relativeUri); 251 List<String> unitUris = getUnitUris(absoluteUri);
253 LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder( 252 LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder(
254 uri: relativeUri, parts: unitUris.sublist(1)); 253 uri: absoluteUri,
254 parts: unitUris.skip(1).map((uri) => uri ?? '').toList());
255 dependencies.add(linkedDependency); 255 dependencies.add(linkedDependency);
256 256
257 _Namespace aggregated = new _Namespace(); 257 _Namespace aggregated = new _Namespace();
258 258
259 for (int unitNum = 0; unitNum < unitUris.length; unitNum++) { 259 for (int unitNum = 0; unitNum < unitUris.length; unitNum++) {
260 String unitUri = unitUris[unitNum]; 260 String unitUri = unitUris[unitNum];
261 UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri); 261 UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri);
262 if (importedNamespace == null) { 262 if (importedNamespace == null) {
263 continue; 263 continue;
264 } 264 }
(...skipping 20 matching lines...) Expand all
285 } 285 }
286 286
287 aggregated.rememberLibraryNames(); 287 aggregated.rememberLibraryNames();
288 288
289 dependencyToPublicNamespace.add(aggregated); 289 dependencyToPublicNamespace.add(aggregated);
290 return aggregated; 290 return aggregated;
291 } 291 }
292 292
293 /** 293 /**
294 * Compute the export namespace for the library whose URI is reachable from 294 * Compute the export namespace for the library whose URI is reachable from
295 * [definingUnit] via [relativeUri], by aggregating together public namespace 295 * [definingUnit] via [absoluteUri], by aggregating together public namespace
296 * information from the library and the transitive closure of its exports. 296 * information from the library and the transitive closure of its exports.
297 *
298 * If [relativeUri] is `null` (meaning the export namespace of [definingUnit]
299 * should be computed), then names defined in [definingUnit] are ignored.
300 */ 297 */
301 _Namespace computeExportNamespace(String relativeUri) { 298 _Namespace computeExportNamespace(String absoluteUri) {
302 Set<String> seenUris = new Set<String>(); 299 Set<String> seenUris = new Set<String>();
303 _Namespace chaseExports(String relativeUri, NameFilter filter) { 300 _Namespace chaseExports(String absoluteUri, NameFilter filter) {
304 _Namespace exportedNamespace = relativeUri == null 301 _Namespace exportedNamespace = aggregatePublicNamespace(absoluteUri);
305 ? new _Namespace() 302 if (seenUris.add(absoluteUri)) {
306 : aggregatePublicNamespace(relativeUri); 303 UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
307 if (seenUris.add(relativeUri)) {
308 UnlinkedPublicNamespace publicNamespace = getImportCached(relativeUri);
309 if (publicNamespace != null) { 304 if (publicNamespace != null) {
310 for (UnlinkedExportPublic export in publicNamespace.exports) { 305 for (UnlinkedExportPublic export in publicNamespace.exports) {
311 String relativeExportUri = 306 String unlinkedExportUri =
312 _selectUri(export.uri, export.configurations); 307 _selectUri(export.uri, export.configurations);
313 String exportUri = resolveUri(relativeUri, relativeExportUri); 308 String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
314 NameFilter newFilter = filter.merge( 309 if (exportUri != null) {
315 new NameFilter.forUnlinkedCombinators(export.combinators)); 310 NameFilter newFilter = filter.merge(
316 _Namespace exportNamespace = chaseExports(exportUri, newFilter); 311 new NameFilter.forUnlinkedCombinators(export.combinators));
317 exportNamespace.forEach((String name, _Meaning meaning) { 312 _Namespace exportNamespace = chaseExports(exportUri, newFilter);
318 if (newFilter.accepts(name) && 313 exportNamespace.forEach((String name, _Meaning meaning) {
319 !exportedNamespace.definesLibraryName(name)) { 314 if (newFilter.accepts(name) &&
320 exportedNamespace.add(name, meaning); 315 !exportedNamespace.definesLibraryName(name)) {
321 } 316 exportedNamespace.add(name, meaning);
322 }); 317 }
318 });
319 }
323 } 320 }
324 } 321 }
325 seenUris.remove(relativeUri); 322 seenUris.remove(absoluteUri);
326 } 323 }
327 return exportedNamespace; 324 return exportedNamespace;
328 } 325 }
329 326
330 return chaseExports(relativeUri, NameFilter.identity); 327 return chaseExports(absoluteUri, NameFilter.identity);
331 } 328 }
332 329
333 /** 330 /**
334 * Extract all the names defined in [unit] (which is the [unitNum]th unit in 331 * Extract all the names defined in [unit] (which is the [unitNum]th unit in
335 * the library being prelinked) and store them in [privateNamespace]. 332 * the library being prelinked) and store them in [privateNamespace].
336 * Excludes names introduced by `import` statements. 333 * Excludes names introduced by `import` statements.
337 */ 334 */
338 void extractPrivateNames(UnlinkedUnit unit, int unitNum) { 335 void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
339 for (UnlinkedClass cls in unit.classes) { 336 for (UnlinkedClass cls in unit.classes) {
340 _Namespace namespace = new _Namespace(); 337 _Namespace namespace = new _Namespace();
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 if (!(variable.isConst || variable.isFinal)) { 394 if (!(variable.isConst || variable.isFinal)) {
398 privateNamespace.add( 395 privateNamespace.add(
399 variable.name + '=', 396 variable.name + '=',
400 new _Meaning( 397 new _Meaning(
401 unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0)); 398 unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
402 } 399 }
403 } 400 }
404 } 401 }
405 402
406 /** 403 /**
407 * Filter the export namespace for the library whose URI is reachable from 404 * Filter the export namespace for the library whose URI is reachable the
408 * [definingUnit] via [relativeUri], retaining only those names accepted by 405 * given [absoluteUri], retaining only those names accepted by
409 * [combinators], and store the resulting names in [result]. Names that 406 * [combinators], and store the resulting names in [result]. Names that
410 * already exist in [result] are not overwritten. 407 * already exist in [result] are not overwritten.
411 */ 408 */
412 void filterExportNamespace(String relativeUri, 409 void filterExportNamespace(String absoluteUri,
413 List<UnlinkedCombinator> combinators, _Namespace result) { 410 List<UnlinkedCombinator> combinators, _Namespace result) {
414 _Namespace exportNamespace = computeExportNamespace(relativeUri); 411 _Namespace exportNamespace = computeExportNamespace(absoluteUri);
415 if (result == null) { 412 if (result == null) {
416 // This can happen if the import prefix was shadowed by a local name, so 413 // This can happen if the import prefix was shadowed by a local name, so
417 // the imported symbols are inaccessible. 414 // the imported symbols are inaccessible.
418 return; 415 return;
419 } 416 }
420 NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators); 417 NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators);
421 exportNamespace.forEach((String name, _Meaning meaning) { 418 exportNamespace.forEach((String name, _Meaning meaning) {
422 if (filter.accepts(name) && !result.definesLibraryName(name)) { 419 if (filter.accepts(name) && !result.definesLibraryName(name)) {
423 result.add(name, meaning); 420 result.add(name, meaning);
424 } 421 }
425 }); 422 });
426 } 423 }
427 424
428 /** 425 /**
429 * Wrapper around [getImport] that caches the return value in [importCache]. 426 * Wrapper around [getImport] that caches the return value in [importCache].
430 */ 427 */
431 UnlinkedPublicNamespace getImportCached(String relativeUri) { 428 UnlinkedPublicNamespace getImportCached(String absoluteUri) {
432 return importCache.putIfAbsent(relativeUri, () => getImport(relativeUri)); 429 return importCache.putIfAbsent(absoluteUri, () => getImport(absoluteUri));
433 } 430 }
434 431
435 /** 432 /**
436 * Wrapper around [getPart] that caches the return value in [partCache] and 433 * Wrapper around [getPart] that caches the return value in [partCache] and
437 * updates [importCache] appropriately. 434 * updates [importCache] appropriately.
438 */ 435 */
439 UnlinkedUnit getPartCached(String relativeUri) { 436 UnlinkedUnit getPartCached(String absoluteUri) {
440 return partCache.putIfAbsent(relativeUri, () { 437 return partCache.putIfAbsent(absoluteUri, () {
441 UnlinkedUnit unit = getPart(relativeUri); 438 UnlinkedUnit unit = getPart(absoluteUri);
442 importCache[relativeUri] = unit?.publicNamespace; 439 importCache[absoluteUri] = unit?.publicNamespace;
443 return unit; 440 return unit;
444 }); 441 });
445 } 442 }
446 443
447 /** 444 /**
448 * Compute the set of relative URIs of all the compilation units in the 445 * Compute the set of absolute URIs of all the compilation units in the
449 * library whose URI is reachable from [definingUnit] via [relativeUri]. 446 * library whose URI is reachable from [definingUnit] via [absoluteUri].
450 */ 447 */
451 List<String> getUnitUris(String relativeUri) { 448 List<String> getUnitUris(String absoluteUri) {
452 List<String> result = <String>[relativeUri]; 449 List<String> result = <String>[absoluteUri];
453 UnlinkedPublicNamespace publicNamespace = getImportCached(relativeUri); 450 UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
454 if (publicNamespace != null) { 451 if (publicNamespace != null) {
455 result.addAll(publicNamespace.parts 452 result.addAll(publicNamespace.parts.map((String uri) {
456 .map((String uri) => resolveUri(relativeUri, uri))); 453 return resolveUri(absoluteUri, uri);
454 }));
457 } 455 }
458 return result; 456 return result;
459 } 457 }
460 458
461 /** 459 /**
462 * Process a single `import` declaration in the library being prelinked. The 460 * Process a single `import` declaration in the library being prelinked. The
463 * return value is the index of the imported library in [dependencies]. 461 * return value is the index of the imported library in [dependencies].
464 */ 462 */
465 int handleImport(UnlinkedImport import) { 463 int handleImport(UnlinkedImport import) {
466 String uri = import.isImplicit 464 String unlinkedUri = import.isImplicit
467 ? 'dart:core' 465 ? 'dart:core'
468 : _selectUri(import.uri, import.configurations); 466 : _selectUri(import.uri, import.configurations);
467 String absoluteUri = resolveUri(definingUnitUri, unlinkedUri);
468
469 _Namespace targetNamespace = null; 469 _Namespace targetNamespace = null;
470 if (import.prefixReference != 0) { 470 if (import.prefixReference != 0) {
471 // The name introduced by an import declaration can't have a prefix of 471 // The name introduced by an import declaration can't have a prefix of
472 // its own. 472 // its own.
473 assert( 473 assert(
474 definingUnit.references[import.prefixReference].prefixReference == 0); 474 definingUnit.references[import.prefixReference].prefixReference == 0);
475 String prefix = definingUnit.references[import.prefixReference].name; 475 String prefix = definingUnit.references[import.prefixReference].name;
476 _Meaning prefixMeaning = privateNamespace[prefix]; 476 _Meaning prefixMeaning = privateNamespace[prefix];
477 if (prefixMeaning is _PrefixMeaning) { 477 if (prefixMeaning is _PrefixMeaning) {
478 targetNamespace = prefixMeaning.namespace; 478 targetNamespace = prefixMeaning.namespace;
479 } 479 }
480 } else { 480 } else {
481 targetNamespace = privateNamespace; 481 targetNamespace = privateNamespace;
482 } 482 }
483 filterExportNamespace(uri, import.combinators, targetNamespace); 483 filterExportNamespace(absoluteUri, import.combinators, targetNamespace);
484 return uriToDependency[uri]; 484 return uriToDependency[absoluteUri];
485 } 485 }
486 486
487 /** 487 /**
488 * Produce a [LinkedUnit] for the given [unit], by resolving every one of 488 * Produce a [LinkedUnit] for the given [unit], by resolving every one of
489 * its references. 489 * its references.
490 */ 490 */
491 LinkedUnitBuilder linkUnit(UnlinkedUnit unit) { 491 LinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
492 if (unit == null) { 492 if (unit == null) {
493 return new LinkedUnitBuilder(); 493 return new LinkedUnitBuilder();
494 } 494 }
(...skipping 25 matching lines...) Expand all
520 } 520 }
521 } 521 }
522 return new LinkedUnitBuilder(references: references); 522 return new LinkedUnitBuilder(references: references);
523 } 523 }
524 524
525 /** 525 /**
526 * Form the [LinkedLibrary] for the [definingUnit] that was passed to the 526 * Form the [LinkedLibrary] for the [definingUnit] that was passed to the
527 * constructor. 527 * constructor.
528 */ 528 */
529 LinkedLibraryBuilder prelink() { 529 LinkedLibraryBuilder prelink() {
530 aggregatePublicNamespace(definingUnitUri);
531
530 // Gather up the unlinked summaries for all the compilation units in the 532 // Gather up the unlinked summaries for all the compilation units in the
531 // library. 533 // library.
532 List<UnlinkedUnit> units = getUnitUris(null).map(getPartCached).toList(); 534 List<String> unitUris = getUnitUris(definingUnitUri);
535 List<UnlinkedUnit> units = unitUris.map(getPartCached).toList();
533 536
534 // Create the private namespace for the library by gathering all the names 537 // Create the private namespace for the library by gathering all the names
535 // defined in its compilation units. 538 // defined in its compilation units.
536 for (int unitNum = 0; unitNum < units.length; unitNum++) { 539 for (int unitNum = 0; unitNum < units.length; unitNum++) {
537 UnlinkedUnit unit = units[unitNum]; 540 UnlinkedUnit unit = units[unitNum];
538 if (unit != null) { 541 if (unit != null) {
539 extractPrivateNames(unit, unitNum); 542 extractPrivateNames(unit, unitNum);
540 } 543 }
541 } 544 }
542 545
543 // Fill in exported names. This must be done before filling in prefixes 546 // Fill in exported names. This must be done before filling in prefixes
544 // defined in import declarations, because prefixes shouldn't shadow 547 // defined in import declarations, because prefixes shouldn't shadow
545 // exports. 548 // exports.
546 List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[]; 549 List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
547 computeExportNamespace(null).forEach((String name, _Meaning meaning) { 550 computeExportNamespace(definingUnitUri)
551 .forEach((String name, _Meaning meaning) {
548 if (!privateNamespace.definesName(name)) { 552 if (!privateNamespace.definesName(name)) {
549 exportNames.add(meaning.encodeExportName(name)); 553 exportNames.add(meaning.encodeExportName(name));
550 } 554 }
551 }); 555 });
552 556
553 // Fill in prefixes defined in import declarations. 557 // Fill in prefixes defined in import declarations.
554 for (UnlinkedImport import in units[0].imports) { 558 for (UnlinkedImport import in units[0].imports) {
555 if (import.prefixReference != 0) { 559 if (import.prefixReference != 0) {
556 String name = units[0].references[import.prefixReference].name; 560 String name = units[0].references[import.prefixReference].name;
557 if (!privateNamespace.definesName(name)) { 561 if (!privateNamespace.definesName(name)) {
558 privateNamespace.add(name, new _PrefixMeaning()); 562 privateNamespace.add(name, new _PrefixMeaning());
559 } 563 }
560 } 564 }
561 } 565 }
562 566
563 // All the names defined so far are library local, they take precedence 567 // All the names defined so far are library local, they take precedence
564 // over anything imported from other libraries. 568 // over anything imported from other libraries.
565 privateNamespace.rememberLibraryNames(); 569 privateNamespace.rememberLibraryNames();
566 570
567 // Fill in imported and exported names. 571 // Fill in imported and exported names.
568 List<int> importDependencies = 572 List<int> importDependencies =
569 definingUnit.imports.map(handleImport).toList(); 573 definingUnit.imports.map(handleImport).toList();
570 List<int> exportDependencies = 574 List<int> exportDependencies = definingUnit.publicNamespace.exports
571 definingUnit.publicNamespace.exports.map((UnlinkedExportPublic exp) { 575 .map((UnlinkedExportPublic exp) {
572 String uri = _selectUri(exp.uri, exp.configurations); 576 String unlinkedUri = _selectUri(exp.uri, exp.configurations);
573 return uriToDependency[uri]; 577 String absoluteUri = resolveUri(definingUnitUri, unlinkedUri);
574 }).toList(); 578 return uriToDependency[absoluteUri];
579 })
580 .where((dependency) => dependency != null)
581 .toList();
575 582
576 // Link each compilation unit. 583 // Link each compilation unit.
577 List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList(); 584 List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
578 585
579 return new LinkedLibraryBuilder( 586 return new LinkedLibraryBuilder(
580 units: linkedUnits, 587 units: linkedUnits,
581 dependencies: dependencies, 588 dependencies: dependencies,
582 importDependencies: importDependencies, 589 importDependencies: importDependencies,
583 exportDependencies: exportDependencies, 590 exportDependencies: exportDependencies,
584 exportNames: exportNames, 591 exportNames: exportNames,
585 numPrelinkedDependencies: dependencies.length); 592 numPrelinkedDependencies: dependencies.length);
586 } 593 }
587 594
588 /** 595 /**
589 * Resolve [relativeUri] relative to [sourceUri]. Works correctly if 596 * Resolve [relativeUri] relative to [containingUri]. Return `null` if
590 * [sourceUri] is also relative. 597 * [relativeUri] is invalid or empty, so cannot be resolved.
591 */ 598 */
592 String resolveUri(String sourceUri, String relativeUri) { 599 String resolveUri(String containingUri, String relativeUri) {
593 if (sourceUri == null) { 600 if (relativeUri == '') {
594 return relativeUri; 601 return null;
595 } else { 602 }
596 return resolveRelativeUri(Uri.parse(sourceUri), Uri.parse(relativeUri)) 603 try {
597 .toString(); 604 Uri containingUriObj = Uri.parse(containingUri);
605 Uri relativeUriObj = Uri.parse(relativeUri);
606 return resolveRelativeUri(containingUriObj, relativeUriObj).toString();
607 } on FormatException {
608 return null;
598 } 609 }
599 } 610 }
600 611
601 /** 612 /**
602 * Return the URI of the first configuration from the given [configurations] 613 * Return the URI of the first configuration from the given [configurations]
603 * which condition is satisfied, or the [defaultUri]. 614 * which condition is satisfied, or the [defaultUri].
604 */ 615 */
605 String _selectUri( 616 String _selectUri(
606 String defaultUri, List<UnlinkedConfiguration> configurations) { 617 String defaultUri, List<UnlinkedConfiguration> configurations) {
607 for (UnlinkedConfiguration configuration in configurations) { 618 for (UnlinkedConfiguration configuration in configurations) {
608 if (getDeclaredVariable(configuration.name) == configuration.value) { 619 if (getDeclaredVariable(configuration.name) == configuration.value) {
609 return configuration.uri; 620 return configuration.uri;
610 } 621 }
611 } 622 }
612 return defaultUri; 623 return defaultUri;
613 } 624 }
614 } 625 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698