| OLD | NEW |
| 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/summary/format.dart'; | 5 import 'package:analyzer/src/summary/format.dart'; |
| 6 import 'package:analyzer/src/summary/name_filter.dart'; | 6 import 'package:analyzer/src/summary/name_filter.dart'; |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * Create a [PrelinkedLibraryBuilder] corresponding to the given | 9 * Create a [PrelinkedLibraryBuilder] corresponding to the given |
| 10 * [definingUnit], which should be the defining compilation unit for a library. | 10 * [definingUnit], which should be the defining compilation unit for a library. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 | 63 |
| 64 /** | 64 /** |
| 65 * If the entity being referred to is generic, the number of type parameters | 65 * If the entity being referred to is generic, the number of type parameters |
| 66 * it accepts. Otherwise zero. | 66 * it accepts. Otherwise zero. |
| 67 */ | 67 */ |
| 68 final int numTypeParameters; | 68 final int numTypeParameters; |
| 69 | 69 |
| 70 _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters); | 70 _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters); |
| 71 | 71 |
| 72 /** | 72 /** |
| 73 * Encode this [_Meaning] as a [PrelinkedExportName], using the given [name]. |
| 74 */ |
| 75 PrelinkedExportName encodeExportName(String name) { |
| 76 return encodePrelinkedExportName( |
| 77 name: name, dependency: dependency, unit: unit, kind: kind); |
| 78 } |
| 79 |
| 80 /** |
| 73 * Encode this [_Meaning] as a [PrelinkedReference]. | 81 * Encode this [_Meaning] as a [PrelinkedReference]. |
| 74 */ | 82 */ |
| 75 PrelinkedReferenceBuilder encode() { | 83 PrelinkedReferenceBuilder encodeReference() { |
| 76 return encodePrelinkedReference( | 84 return encodePrelinkedReference( |
| 77 unit: unit, | 85 unit: unit, |
| 78 kind: kind, | 86 kind: kind, |
| 79 dependency: dependency, | 87 dependency: dependency, |
| 80 numTypeParameters: numTypeParameters); | 88 numTypeParameters: numTypeParameters); |
| 81 } | 89 } |
| 82 } | 90 } |
| 83 | 91 |
| 84 /** | 92 /** |
| 85 * A [_Meaning] representing a prefix introduced by an import directive. | 93 * A [_Meaning] representing a prefix introduced by an import directive. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 178 } | 186 } |
| 179 | 187 |
| 180 dependencyToPublicNamespace.add(aggregated); | 188 dependencyToPublicNamespace.add(aggregated); |
| 181 return aggregated; | 189 return aggregated; |
| 182 } | 190 } |
| 183 | 191 |
| 184 /** | 192 /** |
| 185 * Compute the export namespace for the library whose URI is reachable from | 193 * Compute the export namespace for the library whose URI is reachable from |
| 186 * [definingUnit] via [relativeUri], by aggregating together public namespace | 194 * [definingUnit] via [relativeUri], by aggregating together public namespace |
| 187 * information from the library and the transitive closure of its exports. | 195 * information from the library and the transitive closure of its exports. |
| 196 * |
| 197 * If [relativeUri] is `null` (meaning the export namespace of [definingUnit] |
| 198 * should be computed), then names defined in [definingUnit] are ignored. |
| 188 */ | 199 */ |
| 189 Map<String, _Meaning> computeExportNamespace(String relativeUri) { | 200 Map<String, _Meaning> computeExportNamespace(String relativeUri) { |
| 190 Map<String, _Meaning> exportNamespace = | 201 Map<String, _Meaning> exportNamespace = relativeUri == null |
| 191 aggregatePublicNamespace(relativeUri); | 202 ? <String, _Meaning>{} |
| 203 : aggregatePublicNamespace(relativeUri); |
| 192 void chaseExports( | 204 void chaseExports( |
| 193 NameFilter filter, String relativeUri, Set<String> seenUris) { | 205 NameFilter filter, String relativeUri, Set<String> seenUris) { |
| 194 if (seenUris.add(relativeUri)) { | 206 if (seenUris.add(relativeUri)) { |
| 195 UnlinkedPublicNamespace exportedNamespace = | 207 UnlinkedPublicNamespace exportedNamespace = |
| 196 getImportCached(relativeUri); | 208 getImportCached(relativeUri); |
| 197 if (exportedNamespace != null) { | 209 if (exportedNamespace != null) { |
| 198 for (UnlinkedExportPublic export in exportedNamespace.exports) { | 210 for (UnlinkedExportPublic export in exportedNamespace.exports) { |
| 199 String exportUri = resolveUri(relativeUri, export.uri); | 211 String exportUri = resolveUri(relativeUri, export.uri); |
| 212 NameFilter newFilter = filter.merge( |
| 213 new NameFilter.forUnlinkedCombinators(export.combinators)); |
| 200 aggregatePublicNamespace(exportUri) | 214 aggregatePublicNamespace(exportUri) |
| 201 .forEach((String name, _Meaning meaning) { | 215 .forEach((String name, _Meaning meaning) { |
| 202 if (filter.accepts(name) && !exportNamespace.containsKey(name)) { | 216 if (newFilter.accepts(name) && |
| 217 !exportNamespace.containsKey(name)) { |
| 203 exportNamespace[name] = meaning; | 218 exportNamespace[name] = meaning; |
| 204 } | 219 } |
| 205 }); | 220 }); |
| 206 chaseExports( | 221 chaseExports(newFilter, exportUri, seenUris); |
| 207 filter.merge( | |
| 208 new NameFilter.forUnlinkedCombinators(export.combinators)), | |
| 209 exportUri, | |
| 210 seenUris); | |
| 211 } | 222 } |
| 212 } | 223 } |
| 213 seenUris.remove(relativeUri); | 224 seenUris.remove(relativeUri); |
| 214 } | 225 } |
| 215 } | 226 } |
| 216 chaseExports(NameFilter.identity, relativeUri, new Set<String>()); | 227 chaseExports(NameFilter.identity, relativeUri, new Set<String>()); |
| 217 return exportNamespace; | 228 return exportNamespace; |
| 218 } | 229 } |
| 219 | 230 |
| 220 /** | 231 /** |
| (...skipping 10 matching lines...) Expand all Loading... |
| 231 } | 242 } |
| 232 for (UnlinkedEnum enm in unit.enums) { | 243 for (UnlinkedEnum enm in unit.enums) { |
| 233 privateNamespace.putIfAbsent( | 244 privateNamespace.putIfAbsent( |
| 234 enm.name, | 245 enm.name, |
| 235 () => | 246 () => |
| 236 new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0, 0)); | 247 new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0, 0)); |
| 237 } | 248 } |
| 238 for (UnlinkedExecutable executable in unit.executables) { | 249 for (UnlinkedExecutable executable in unit.executables) { |
| 239 privateNamespace.putIfAbsent( | 250 privateNamespace.putIfAbsent( |
| 240 executable.name, | 251 executable.name, |
| 241 () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0, | 252 () => new _Meaning( |
| 253 unitNum, |
| 254 executable.kind == UnlinkedExecutableKind.functionOrMethod |
| 255 ? PrelinkedReferenceKind.topLevelFunction |
| 256 : PrelinkedReferenceKind.topLevelPropertyAccessor, |
| 257 0, |
| 242 executable.typeParameters.length)); | 258 executable.typeParameters.length)); |
| 243 } | 259 } |
| 244 for (UnlinkedTypedef typedef in unit.typedefs) { | 260 for (UnlinkedTypedef typedef in unit.typedefs) { |
| 245 privateNamespace.putIfAbsent( | 261 privateNamespace.putIfAbsent( |
| 246 typedef.name, | 262 typedef.name, |
| 247 () => new _Meaning(unitNum, PrelinkedReferenceKind.typedef, 0, | 263 () => new _Meaning(unitNum, PrelinkedReferenceKind.typedef, 0, |
| 248 typedef.typeParameters.length)); | 264 typedef.typeParameters.length)); |
| 249 } | 265 } |
| 250 for (UnlinkedVariable variable in unit.variables) { | 266 for (UnlinkedVariable variable in unit.variables) { |
| 251 privateNamespace.putIfAbsent(variable.name, | 267 privateNamespace.putIfAbsent( |
| 252 () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0, 0)); | 268 variable.name, |
| 269 () => new _Meaning( |
| 270 unitNum, PrelinkedReferenceKind.topLevelPropertyAccessor, 0, 0)); |
| 271 if (!(variable.isConst || variable.isFinal)) { |
| 272 privateNamespace.putIfAbsent( |
| 273 variable.name + '=', |
| 274 () => new _Meaning(unitNum, |
| 275 PrelinkedReferenceKind.topLevelPropertyAccessor, 0, 0)); |
| 276 } |
| 253 } | 277 } |
| 254 } | 278 } |
| 255 | 279 |
| 256 /** | 280 /** |
| 257 * Filter the export namespace for the library whose URI is reachable from | 281 * Filter the export namespace for the library whose URI is reachable from |
| 258 * [definingUnit] via [relativeUri], retaining only those names accepted by | 282 * [definingUnit] via [relativeUri], retaining only those names accepted by |
| 259 * [combinators], and store the resulting names in [result]. Names that | 283 * [combinators], and store the resulting names in [result]. Names that |
| 260 * already exist in [result] are not overwritten. | 284 * already exist in [result] are not overwritten. |
| 261 */ | 285 */ |
| 262 void filterExportNamespace(String relativeUri, | 286 void filterExportNamespace(String relativeUri, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 // Prefix references must always point to proper prefixes. | 372 // Prefix references must always point to proper prefixes. |
| 349 assert(namespace != null); | 373 assert(namespace != null); |
| 350 } else { | 374 } else { |
| 351 namespace = privateNamespace; | 375 namespace = privateNamespace; |
| 352 } | 376 } |
| 353 _Meaning meaning = namespace[reference.name]; | 377 _Meaning meaning = namespace[reference.name]; |
| 354 if (meaning != null) { | 378 if (meaning != null) { |
| 355 if (meaning is _PrefixMeaning) { | 379 if (meaning is _PrefixMeaning) { |
| 356 prefixNamespaces[i] = meaning.namespace; | 380 prefixNamespaces[i] = meaning.namespace; |
| 357 } | 381 } |
| 358 references.add(meaning.encode()); | 382 references.add(meaning.encodeReference()); |
| 359 } else { | 383 } else { |
| 360 references.add( | 384 references.add( |
| 361 encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved)); | 385 encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved)); |
| 362 } | 386 } |
| 363 } | 387 } |
| 364 return encodePrelinkedUnit(references: references); | 388 return encodePrelinkedUnit(references: references); |
| 365 } | 389 } |
| 366 | 390 |
| 367 /** | 391 /** |
| 368 * Form the [PrelinkedLibrary] for the [definingUnit] that was passed to the | 392 * Form the [PrelinkedLibrary] for the [definingUnit] that was passed to the |
| 369 * constructor. | 393 * constructor. |
| 370 */ | 394 */ |
| 371 PrelinkedLibraryBuilder prelink() { | 395 PrelinkedLibraryBuilder prelink() { |
| 372 // Gather up the unlinked summaries for all the compilation units in the | 396 // Gather up the unlinked summaries for all the compilation units in the |
| 373 // library. | 397 // library. |
| 374 List<UnlinkedUnit> units = getUnitUris(null).map(getPartCached).toList(); | 398 List<UnlinkedUnit> units = getUnitUris(null).map(getPartCached).toList(); |
| 375 | 399 |
| 376 // Create the private namespace for the library by gathering all the names | 400 // Create the private namespace for the library by gathering all the names |
| 377 // defined in its compilation units. | 401 // defined in its compilation units. |
| 378 for (int unitNum = 0; unitNum < units.length; unitNum++) { | 402 for (int unitNum = 0; unitNum < units.length; unitNum++) { |
| 379 UnlinkedUnit unit = units[unitNum]; | 403 UnlinkedUnit unit = units[unitNum]; |
| 380 if (unit != null) { | 404 if (unit != null) { |
| 381 extractPrivateNames(unit, unitNum); | 405 extractPrivateNames(unit, unitNum); |
| 382 } | 406 } |
| 383 } | 407 } |
| 384 | 408 |
| 409 // Fill in exported names. This must be done before filling in prefixes |
| 410 // defined in import declarations, because prefixes shouldn't shadow |
| 411 // exports. |
| 412 List<PrelinkedExportNameBuilder> exportNames = |
| 413 <PrelinkedExportNameBuilder>[]; |
| 414 computeExportNamespace(null).forEach((String name, _Meaning meaning) { |
| 415 if (!privateNamespace.containsKey(name)) { |
| 416 exportNames.add(meaning.encodeExportName(name)); |
| 417 } |
| 418 }); |
| 419 |
| 385 // Fill in prefixes defined in import declarations. | 420 // Fill in prefixes defined in import declarations. |
| 386 for (UnlinkedImport import in units[0].imports) { | 421 for (UnlinkedImport import in units[0].imports) { |
| 387 if (import.prefixReference != 0) { | 422 if (import.prefixReference != 0) { |
| 388 privateNamespace.putIfAbsent( | 423 privateNamespace.putIfAbsent( |
| 389 units[0].references[import.prefixReference].name, | 424 units[0].references[import.prefixReference].name, |
| 390 () => new _PrefixMeaning()); | 425 () => new _PrefixMeaning()); |
| 391 } | 426 } |
| 392 } | 427 } |
| 393 | 428 |
| 394 // Fill in imported names. | 429 // Fill in imported names. |
| 395 List<int> importDependencies = | 430 List<int> importDependencies = |
| 396 definingUnit.imports.map(handleImport).toList(); | 431 definingUnit.imports.map(handleImport).toList(); |
| 397 | 432 |
| 398 // Link each compilation unit. | 433 // Link each compilation unit. |
| 399 List<PrelinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList(); | 434 List<PrelinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList(); |
| 400 | 435 |
| 401 return encodePrelinkedLibrary( | 436 return encodePrelinkedLibrary( |
| 402 units: linkedUnits, | 437 units: linkedUnits, |
| 403 dependencies: dependencies, | 438 dependencies: dependencies, |
| 404 importDependencies: importDependencies); | 439 importDependencies: importDependencies, |
| 440 exportNames: exportNames); |
| 405 } | 441 } |
| 406 | 442 |
| 407 /** | 443 /** |
| 408 * Resolve [relativeUri] relative to [sourceUri]. Works correctly if | 444 * Resolve [relativeUri] relative to [sourceUri]. Works correctly if |
| 409 * [sourceUri] is also relative. | 445 * [sourceUri] is also relative. |
| 410 */ | 446 */ |
| 411 String resolveUri(String sourceUri, String relativeUri) { | 447 String resolveUri(String sourceUri, String relativeUri) { |
| 412 if (sourceUri == null) { | 448 if (sourceUri == null) { |
| 413 return relativeUri; | 449 return relativeUri; |
| 414 } else { | 450 } else { |
| 415 return Uri.parse(sourceUri).resolve(relativeUri).toString(); | 451 return Uri.parse(sourceUri).resolve(relativeUri).toString(); |
| 416 } | 452 } |
| 417 } | 453 } |
| 418 } | 454 } |
| OLD | NEW |