| 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 9322ccd5f8af4f7d409342c36fff0b9141478acc..9f6b5cd2fb7d337ad028637534d7468fa52feca7 100644
|
| --- a/pkg/code_transformers/lib/src/resolver_impl.dart
|
| +++ b/pkg/code_transformers/lib/src/resolver_impl.dart
|
| @@ -31,18 +31,12 @@ 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;
|
| -
|
| /// Future indicating when this resolver is done in the current phase.
|
| Future _lastPhaseComplete = new Future.value();
|
|
|
| @@ -52,12 +46,11 @@ 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}) {
|
| + List<LibraryElement> _entryLibraries;
|
| +
|
| + /// 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.
|
| @@ -74,16 +67,16 @@ class ResolverImpl implements Resolver {
|
| new _AssetUriResolver(this)]);
|
| }
|
|
|
| - LibraryElement get entryLibrary => _entryLibrary;
|
| + LibraryElement getLibrary(AssetId assetId) => sources[assetId].libraryElement;
|
|
|
| - 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;
|
| @@ -97,11 +90,11 @@ 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.
|
| + sources.values.forEach((source) { source._libraryElement = null; });
|
| }
|
|
|
| - Future _performResolve(Transform transform) {
|
| + Future _performResolve(Transform transform, List<AssetId> entryPoints) {
|
| if (_currentTransform != null) {
|
| throw new StateError('Cannot be accessed by concurrent transforms');
|
| }
|
| @@ -132,7 +125,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.
|
| @@ -146,13 +139,16 @@ class ResolverImpl implements Resolver {
|
|
|
| // Update the analyzer context with the latest sources
|
| _context.applyChanges(changeSet);
|
| - // Resolve the AST
|
| - _entryLibrary = _context.computeLibraryElement(sources[entryPoint]);
|
| + // Force resolve each entry point (the getter will ensure the library is
|
| + // computed first).
|
| + _entryLibraries =
|
| + entryPoints.map((e) => sources[e].libraryElement).toList();
|
| _currentTransform = null;
|
| });
|
| }
|
|
|
| - Iterable<LibraryElement> get libraries => entryLibrary.visibleLibraries;
|
| + Iterable<LibraryElement> get libraries =>
|
| + _entryLibraries.expand((e) => e.visibleLibraries);
|
|
|
| LibraryElement getLibraryByName(String libraryName) =>
|
| libraries.firstWhere((l) => l.name == libraryName, orElse: () => null);
|
| @@ -226,7 +222,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);
|
| }
|
| @@ -234,22 +230,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);
|
| }
|
| @@ -273,6 +274,15 @@ class _AssetBasedSource extends Source {
|
| /// The file contents.
|
| String _contents;
|
|
|
| + LibraryElement _libraryElement;
|
| +
|
| + LibraryElement get libraryElement {
|
| + if (_libraryElement == null) {
|
| + _libraryElement = _resolver._context.computeLibraryElement(this);
|
| + }
|
| + return _libraryElement;
|
| + }
|
| +
|
| _AssetBasedSource(this.assetId, this._resolver);
|
|
|
| /// Update the contents of this file with [contents].
|
| @@ -360,7 +370,7 @@ class _AssetBasedSource extends Source {
|
| Span _getSpan(AstNode node) => _sourceFile.span(node.offset, node.end);
|
| /// For logging errors.
|
| SourceFile get _sourceFile {
|
| - var uri = getSourceUri(_resolver.entryPoint);
|
| + var uri = getSourceUri();
|
| var path = uri != null ? uri.toString() : assetId.path;
|
|
|
| return new SourceFile.text(path, rawContents);
|
|
|