| Index: pkg/code_transformers/lib/src/resolver_impl.dart
|
| diff --git a/pkg/code_transformers/lib/src/resolver_impl.dart b/pkg/code_transformers/lib/src/resolver_impl.dart
|
| index 9d0cb2d0924718eee1fad8207876a8356bcc4de1..df7a450b87c3064deee2a1aeb44697a86de05697 100644
|
| --- a/pkg/code_transformers/lib/src/resolver_impl.dart
|
| +++ b/pkg/code_transformers/lib/src/resolver_impl.dart
|
| @@ -35,17 +35,14 @@ class ResolverImpl implements Resolver {
|
| final Map<AssetId, _AssetBasedSource> sources =
|
| <AssetId, _AssetBasedSource>{};
|
|
|
| - /// The Dart entry point file where parsing begins.
|
| - final AssetId entryPoint;
|
| -
|
| final AnalysisContext _context =
|
| AnalysisEngine.instance.createAnalysisContext();
|
|
|
| /// Transform for which this is currently updating, or null when not updating.
|
| Transform _currentTransform;
|
|
|
| - /// The currently resolved library, or null if unresolved.
|
| - LibraryElement _entryLibrary;
|
| + /// The currently resolved entry libraries, or null if nothing is resolved.
|
| + List<LibraryElement> _entryLibraries;
|
|
|
| /// Future indicating when this resolver is done in the current phase.
|
| Future _lastPhaseComplete = new Future.value();
|
| @@ -56,12 +53,9 @@ class ResolverImpl implements Resolver {
|
| /// Handler for all Dart SDK (dart:) sources.
|
| DirectoryBasedDartSdk _dartSdk;
|
|
|
| - /// Creates a resolver that will resolve the Dart code starting at
|
| - /// [entryPoint].
|
| - ///
|
| - /// [sdkDir] is the root directory of the Dart SDK, for resolving dart:
|
| - /// imports.
|
| - ResolverImpl(this.entryPoint, String sdkDir, {AnalysisOptions options}) {
|
| + /// Creates a resolver, where [sdkDir] is the root directory of the Dart SDK,
|
| + /// for resolving `dart:*` imports.
|
| + ResolverImpl(String sdkDir, {AnalysisOptions options}) {
|
| if (options == null) {
|
| options = new AnalysisOptionsImpl()
|
| ..cacheSize = 256 // # of sources to cache ASTs for.
|
| @@ -78,16 +72,19 @@ class ResolverImpl implements Resolver {
|
| new _AssetUriResolver(this)]);
|
| }
|
|
|
| - LibraryElement get entryLibrary => _entryLibrary;
|
| + LibraryElement getLibrary(AssetId assetId) {
|
| + var source = sources[assetId];
|
| + return source == null ? null : _context.computeLibraryElement(source);
|
| + }
|
|
|
| - Future<Resolver> resolve(Transform transform) {
|
| + Future<Resolver> resolve(Transform transform, [List<AssetId> entryPoints]) {
|
| // Can only have one resolve in progress at a time, so chain the current
|
| // resolution to be after the last one.
|
| var phaseComplete = new Completer();
|
| var future = _lastPhaseComplete.then((_) {
|
| _currentPhaseComplete = phaseComplete;
|
| -
|
| - return _performResolve(transform);
|
| + return _performResolve(transform,
|
| + entryPoints == null ? [transform.primaryInput.id] : entryPoints);
|
| }).then((_) => this);
|
| // Advance the lastPhaseComplete to be done when this phase is all done.
|
| _lastPhaseComplete = phaseComplete.future;
|
| @@ -101,11 +98,12 @@ class ResolverImpl implements Resolver {
|
| _currentPhaseComplete.complete(null);
|
| _currentPhaseComplete = null;
|
|
|
| - // Clear out the entry lib since it should not be referenced after release.
|
| - _entryLibrary = null;
|
| + // Clear out libraries since they should not be referenced after release.
|
| + _entryLibraries = null;
|
| + _currentTransform = null;
|
| }
|
|
|
| - Future _performResolve(Transform transform) {
|
| + Future _performResolve(Transform transform, List<AssetId> entryPoints) {
|
| if (_currentTransform != null) {
|
| throw new StateError('Cannot be accessed by concurrent transforms');
|
| }
|
| @@ -135,7 +133,7 @@ class ResolverImpl implements Resolver {
|
| sources.remove(assetId);
|
| }));
|
| }
|
| - processAsset(entryPoint);
|
| + entryPoints.forEach(processAsset);
|
|
|
| // Once we have all asset sources updated with the new contents then
|
| // resolve everything.
|
| @@ -150,13 +148,15 @@ class ResolverImpl implements Resolver {
|
|
|
| // Update the analyzer context with the latest sources
|
| _context.applyChanges(changeSet);
|
| - // Resolve the AST
|
| - _entryLibrary = _context.computeLibraryElement(sources[entryPoint]);
|
| - _currentTransform = null;
|
| + // Force resolve each entry point (the getter will ensure the library is
|
| + // computed first).
|
| + _entryLibraries = entryPoints
|
| + .map((id) => _context.computeLibraryElement(sources[id])).toList();
|
| });
|
| }
|
|
|
| - Iterable<LibraryElement> get libraries => entryLibrary.visibleLibraries;
|
| + Iterable<LibraryElement> get libraries =>
|
| + _entryLibraries.expand((lib) => lib.visibleLibraries).toSet();
|
|
|
| LibraryElement getLibraryByName(String libraryName) =>
|
| libraries.firstWhere((l) => l.name == libraryName, orElse: () => null);
|
| @@ -230,7 +230,7 @@ class ResolverImpl implements Resolver {
|
| }
|
|
|
| Span getSourceSpan(Element element) {
|
| - var sourceFile = _getSourceFile(element);
|
| + var sourceFile = getSourceFile(element);
|
| if (sourceFile == null) return null;
|
| return sourceFile.span(element.node.offset, element.node.end);
|
| }
|
| @@ -238,22 +238,27 @@ class ResolverImpl implements Resolver {
|
| TextEditTransaction createTextEditTransaction(Element element) {
|
| if (element.source is! _AssetBasedSource) return null;
|
|
|
| + // Cannot edit unless there is an active transformer.
|
| + if (_currentTransform == null) return null;
|
| +
|
| _AssetBasedSource source = element.source;
|
| // Cannot modify assets in other packages.
|
| - if (source.assetId.package != entryPoint.package) return null;
|
| + if (source.assetId.package != _currentTransform.primaryInput.id.package) {
|
| + return null;
|
| + }
|
|
|
| - var sourceFile = _getSourceFile(element);
|
| + var sourceFile = getSourceFile(element);
|
| if (sourceFile == null) return null;
|
|
|
| return new TextEditTransaction(source.rawContents, sourceFile);
|
| }
|
|
|
| /// Gets the SourceFile for the source of the element.
|
| - SourceFile _getSourceFile(Element element) {
|
| + SourceFile getSourceFile(Element element) {
|
| var assetId = getSourceAssetId(element);
|
| if (assetId == null) return null;
|
|
|
| - var importUri = _getSourceUri(element, from: entryPoint);
|
| + var importUri = _getSourceUri(element);
|
| var spanPath = importUri != null ? importUri.toString() : assetId.path;
|
| return new SourceFile.text(spanPath, sources[assetId].rawContents);
|
| }
|
| @@ -361,7 +366,7 @@ class _AssetBasedSource extends Source {
|
| _getSourceFile(contents).span(node.offset, node.end);
|
| /// For logging errors.
|
| SourceFile _getSourceFile([String contents]) {
|
| - var uri = getSourceUri(_resolver.entryPoint);
|
| + var uri = getSourceUri();
|
| var path = uri != null ? uri.toString() : assetId.path;
|
| return new SourceFile.text(path, contents != null ? contents : rawContents);
|
| }
|
|
|