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

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

Issue 2353433002: Use configurations and declared variables to select import/export URIs during prelinking. (Closed)
Patch Set: Cache selected URI. Created 4 years, 3 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 | « pkg/analyzer/lib/src/summary/link.dart ('k') | pkg/analyzer/lib/src/summary/pub_summary.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 /**
11 * Create a [LinkedLibraryBuilder] corresponding to the given 11 * Create a [LinkedLibraryBuilder] corresponding to the given
12 * [definingUnit], which should be the defining compilation unit for a library. 12 * [definingUnit], which should be the defining compilation unit for a library.
13 * Compilation units referenced by the defining compilation unit via `part` 13 * Compilation units referenced by the defining compilation unit via `part`
14 * declarations will be retrieved using [getPart]. Public namespaces for 14 * declarations will be retrieved using [getPart]. Public namespaces for
15 * libraries referenced by the defining compilation unit via `import` 15 * 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(UnlinkedUnit definingUnit, GetPartCallback getPart,
20 GetImportCallback getImport) { 20 GetImportCallback getImport, GetDeclaredVariable getDeclaredVariable) {
21 return new _Prelinker(definingUnit, getPart, getImport).prelink(); 21 return new _Prelinker(definingUnit, getPart, getImport, getDeclaredVariable)
22 .prelink();
22 } 23 }
23 24
24 /** 25 /**
26 * Return the raw string value of the variable with the given [name],
27 * or `null` of the variable is not defined.
28 */
29 typedef String GetDeclaredVariable(String name);
30
31 /**
25 * Type of the callback used by the prelinker to obtain public namespace 32 * Type of the callback used by the prelinker to obtain public namespace
26 * information about libraries imported by the library to be prelinked (and 33 * information about libraries imported by the library to be prelinked (and
27 * the transitive closure of parts and exports reachable from those libraries). 34 * the transitive closure of parts and exports reachable from those libraries).
28 * [relativeUri] should be interpreted relative to the defining compilation 35 * [relativeUri] should be interpreted relative to the defining compilation
29 * unit of the library being prelinked. 36 * unit of the library being prelinked.
30 * 37 *
31 * If no file exists at the given uri, `null` should be returned. 38 * If no file exists at the given uri, `null` should be returned.
32 */ 39 */
33 typedef UnlinkedPublicNamespace GetImportCallback(String relativeUri); 40 typedef UnlinkedPublicNamespace GetImportCallback(String relativeUri);
34 41
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 * Helper class containing temporary data structures needed to prelink a single 121 * Helper class containing temporary data structures needed to prelink a single
115 * library. 122 * library.
116 * 123 *
117 * Note: throughout this class, a `null` value for a relative URI represents 124 * Note: throughout this class, a `null` value for a relative URI represents
118 * the defining compilation unit of the library being prelinked. 125 * the defining compilation unit of the library being prelinked.
119 */ 126 */
120 class _Prelinker { 127 class _Prelinker {
121 final UnlinkedUnit definingUnit; 128 final UnlinkedUnit definingUnit;
122 final GetPartCallback getPart; 129 final GetPartCallback getPart;
123 final GetImportCallback getImport; 130 final GetImportCallback getImport;
131 final GetDeclaredVariable getDeclaredVariable;
124 132
125 /** 133 /**
126 * Cache of values returned by [getImport]. 134 * Cache of values returned by [getImport].
127 */ 135 */
128 final Map<String, UnlinkedPublicNamespace> importCache = 136 final Map<String, UnlinkedPublicNamespace> importCache =
129 <String, UnlinkedPublicNamespace>{}; 137 <String, UnlinkedPublicNamespace>{};
130 138
131 /** 139 /**
132 * Cache of values returned by [getPart]. 140 * Cache of values returned by [getPart].
133 */ 141 */
(...skipping 20 matching lines...) Expand all
154 * corresponding entry in [dependencies]. 162 * corresponding entry in [dependencies].
155 */ 163 */
156 final Map<String, int> uriToDependency = <String, int>{null: 0}; 164 final Map<String, int> uriToDependency = <String, int>{null: 0};
157 165
158 /** 166 /**
159 * List of public namespaces corresponding to each entry in [dependencies]. 167 * List of public namespaces corresponding to each entry in [dependencies].
160 */ 168 */
161 final List<Map<String, _Meaning>> dependencyToPublicNamespace = 169 final List<Map<String, _Meaning>> dependencyToPublicNamespace =
162 <Map<String, _Meaning>>[null]; 170 <Map<String, _Meaning>>[null];
163 171
164 _Prelinker(this.definingUnit, this.getPart, this.getImport) { 172 _Prelinker(this.definingUnit, this.getPart, this.getImport,
173 this.getDeclaredVariable) {
165 partCache[null] = definingUnit; 174 partCache[null] = definingUnit;
166 importCache[null] = definingUnit.publicNamespace; 175 importCache[null] = definingUnit.publicNamespace;
167 } 176 }
168 177
169 /** 178 /**
170 * Compute the public namespace for the library whose URI is reachable from 179 * Compute the public namespace for the library whose URI is reachable from
171 * [definingUnit] via [relativeUri], by aggregating together public namespace 180 * [definingUnit] via [relativeUri], by aggregating together public namespace
172 * information from all of its parts. 181 * information from all of its parts.
173 */ 182 */
174 Map<String, _Meaning> aggregatePublicNamespace(String relativeUri) { 183 Map<String, _Meaning> aggregatePublicNamespace(String relativeUri) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 Map<String, _Meaning> exportNamespace = relativeUri == null 233 Map<String, _Meaning> exportNamespace = relativeUri == null
225 ? <String, _Meaning>{} 234 ? <String, _Meaning>{}
226 : aggregatePublicNamespace(relativeUri); 235 : aggregatePublicNamespace(relativeUri);
227 void chaseExports( 236 void chaseExports(
228 NameFilter filter, String relativeUri, Set<String> seenUris) { 237 NameFilter filter, String relativeUri, Set<String> seenUris) {
229 if (seenUris.add(relativeUri)) { 238 if (seenUris.add(relativeUri)) {
230 UnlinkedPublicNamespace exportedNamespace = 239 UnlinkedPublicNamespace exportedNamespace =
231 getImportCached(relativeUri); 240 getImportCached(relativeUri);
232 if (exportedNamespace != null) { 241 if (exportedNamespace != null) {
233 for (UnlinkedExportPublic export in exportedNamespace.exports) { 242 for (UnlinkedExportPublic export in exportedNamespace.exports) {
234 String exportUri = resolveUri(relativeUri, export.uri); 243 String relativeExportUri =
244 _selectUri(export.uri, export.configurations);
245 String exportUri = resolveUri(relativeUri, relativeExportUri);
235 NameFilter newFilter = filter.merge( 246 NameFilter newFilter = filter.merge(
236 new NameFilter.forUnlinkedCombinators(export.combinators)); 247 new NameFilter.forUnlinkedCombinators(export.combinators));
237 aggregatePublicNamespace(exportUri) 248 aggregatePublicNamespace(exportUri)
238 .forEach((String name, _Meaning meaning) { 249 .forEach((String name, _Meaning meaning) {
239 if (newFilter.accepts(name) && 250 if (newFilter.accepts(name) &&
240 !exportNamespace.containsKey(name)) { 251 !exportNamespace.containsKey(name)) {
241 exportNamespace[name] = meaning; 252 exportNamespace[name] = meaning;
242 } 253 }
243 }); 254 });
244 chaseExports(newFilter, exportUri, seenUris); 255 chaseExports(newFilter, exportUri, seenUris);
245 } 256 }
246 } 257 }
247 seenUris.remove(relativeUri); 258 seenUris.remove(relativeUri);
248 } 259 }
249 } 260 }
261
250 chaseExports(NameFilter.identity, relativeUri, new Set<String>()); 262 chaseExports(NameFilter.identity, relativeUri, new Set<String>());
251 return exportNamespace; 263 return exportNamespace;
252 } 264 }
253 265
254 /** 266 /**
255 * Extract all the names defined in [unit] (which is the [unitNum]th unit in 267 * Extract all the names defined in [unit] (which is the [unitNum]th unit in
256 * the library being prelinked) and store them in [privateNamespace]. 268 * the library being prelinked) and store them in [privateNamespace].
257 * Excludes names introduced by `import` statements. 269 * Excludes names introduced by `import` statements.
258 */ 270 */
259 void extractPrivateNames(UnlinkedUnit unit, int unitNum) { 271 void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 .map((String uri) => resolveUri(relativeUri, uri))); 390 .map((String uri) => resolveUri(relativeUri, uri)));
379 } 391 }
380 return result; 392 return result;
381 } 393 }
382 394
383 /** 395 /**
384 * Process a single `import` declaration in the library being prelinked. The 396 * Process a single `import` declaration in the library being prelinked. The
385 * return value is the index of the imported library in [dependencies]. 397 * return value is the index of the imported library in [dependencies].
386 */ 398 */
387 int handleImport(UnlinkedImport import) { 399 int handleImport(UnlinkedImport import) {
388 String uri = import.isImplicit ? 'dart:core' : import.uri; 400 String uri = import.isImplicit
401 ? 'dart:core'
402 : _selectUri(import.uri, import.configurations);
389 Map<String, _Meaning> targetNamespace = null; 403 Map<String, _Meaning> targetNamespace = null;
390 if (import.prefixReference != 0) { 404 if (import.prefixReference != 0) {
391 // The name introduced by an import declaration can't have a prefix of 405 // The name introduced by an import declaration can't have a prefix of
392 // its own. 406 // its own.
393 assert( 407 assert(
394 definingUnit.references[import.prefixReference].prefixReference == 0); 408 definingUnit.references[import.prefixReference].prefixReference == 0);
395 String prefix = definingUnit.references[import.prefixReference].name; 409 String prefix = definingUnit.references[import.prefixReference].name;
396 _Meaning prefixMeaning = privateNamespace[prefix]; 410 _Meaning prefixMeaning = privateNamespace[prefix];
397 if (prefixMeaning is _PrefixMeaning) { 411 if (prefixMeaning is _PrefixMeaning) {
398 targetNamespace = prefixMeaning.namespace; 412 targetNamespace = prefixMeaning.namespace;
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 if (import.prefixReference != 0) { 490 if (import.prefixReference != 0) {
477 privateNamespace.putIfAbsent( 491 privateNamespace.putIfAbsent(
478 units[0].references[import.prefixReference].name, 492 units[0].references[import.prefixReference].name,
479 () => new _PrefixMeaning()); 493 () => new _PrefixMeaning());
480 } 494 }
481 } 495 }
482 496
483 // Fill in imported and exported names. 497 // Fill in imported and exported names.
484 List<int> importDependencies = 498 List<int> importDependencies =
485 definingUnit.imports.map(handleImport).toList(); 499 definingUnit.imports.map(handleImport).toList();
486 List<int> exportDependencies = definingUnit.publicNamespace.exports 500 List<int> exportDependencies =
487 .map((UnlinkedExportPublic exp) => uriToDependency[exp.uri]) 501 definingUnit.publicNamespace.exports.map((UnlinkedExportPublic exp) {
488 .toList(); 502 String uri = _selectUri(exp.uri, exp.configurations);
503 return uriToDependency[uri];
504 }).toList();
489 505
490 // Link each compilation unit. 506 // Link each compilation unit.
491 List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList(); 507 List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
492 508
493 return new LinkedLibraryBuilder( 509 return new LinkedLibraryBuilder(
494 units: linkedUnits, 510 units: linkedUnits,
495 dependencies: dependencies, 511 dependencies: dependencies,
496 importDependencies: importDependencies, 512 importDependencies: importDependencies,
497 exportDependencies: exportDependencies, 513 exportDependencies: exportDependencies,
498 exportNames: exportNames, 514 exportNames: exportNames,
499 numPrelinkedDependencies: dependencies.length); 515 numPrelinkedDependencies: dependencies.length);
500 } 516 }
501 517
502 /** 518 /**
503 * Resolve [relativeUri] relative to [sourceUri]. Works correctly if 519 * Resolve [relativeUri] relative to [sourceUri]. Works correctly if
504 * [sourceUri] is also relative. 520 * [sourceUri] is also relative.
505 */ 521 */
506 String resolveUri(String sourceUri, String relativeUri) { 522 String resolveUri(String sourceUri, String relativeUri) {
507 if (sourceUri == null) { 523 if (sourceUri == null) {
508 return relativeUri; 524 return relativeUri;
509 } else { 525 } else {
510 return resolveRelativeUri(Uri.parse(sourceUri), Uri.parse(relativeUri)) 526 return resolveRelativeUri(Uri.parse(sourceUri), Uri.parse(relativeUri))
511 .toString(); 527 .toString();
512 } 528 }
513 } 529 }
530
531 /**
532 * Return the URI of the first configuration from the given [configurations]
533 * which condition is satisfied, or the [defaultUri].
534 */
535 String _selectUri(
536 String defaultUri, List<UnlinkedConfiguration> configurations) {
537 for (UnlinkedConfiguration configuration in configurations) {
538 if (getDeclaredVariable(configuration.name) == configuration.value) {
539 return configuration.uri;
540 }
541 }
542 return defaultUri;
543 }
514 } 544 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/summary/link.dart ('k') | pkg/analyzer/lib/src/summary/pub_summary.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698