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

Unified Diff: pkg/code_transformers/lib/src/resolver_impl.dart

Issue 174053004: Revert "Adding package:code_transformers for unifying common transformers code" (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
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
deleted file mode 100644
index 9ac639954b565923ff676e0052a1d0ebbde0e204..0000000000000000000000000000000000000000
--- a/pkg/code_transformers/lib/src/resolver_impl.dart
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library code_transformer.src.resolver_impl;
-
-import 'dart:async';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/parser.dart' show Parser;
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:barback/barback.dart';
-import 'package:path/path.dart' as path;
-import 'package:source_maps/refactor.dart';
-import 'package:source_maps/span.dart' show SourceFile, Span;
-
-import 'resolver.dart';
-
-/// Resolves and updates an AST based on Barback-based assets.
-///
-/// This also provides a handful of useful APIs for traversing and working
-/// with the resolved AST.
-class ResolverImpl implements Resolver {
- /// Cache of all asset sources currently referenced.
- 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;
-
- /// 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}) {
- if (options == null) {
- options = new AnalysisOptionsImpl()
- ..cacheSize = 256 // # of sources to cache ASTs for.
- ..preserveComments = false
- ..analyzeFunctionBodies = true;
- }
- _context.analysisOptions = options;
-
- _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir));
- _dartSdk.context.analysisOptions = options;
-
- _context.sourceFactory = new SourceFactory.con2([
- new DartUriResolverProxy(_dartSdk),
- new _AssetUriResolver(this)]);
- }
-
- LibraryElement get entryLibrary => _entryLibrary;
-
-
- /// Update the status of all the sources referenced by the entryPoint and
- /// update the resolved library.
- ///
- /// This will be invoked automatically by [ResolverTransformer]. Only one
- /// transformer may update this at a time.
- Future updateSources(Transform transform) {
- if (_currentTransform != null) {
- throw new StateError('Cannot be accessed by concurrent transforms');
- }
- _currentTransform = transform;
- // Clear this out and update once all asset changes have been processed.
- _entryLibrary = null;
-
- // Basic approach is to start at the first file, update it's contents
- // and see if it changed, then walk all files accessed by it.
- var visited = new Set<AssetId>();
- var visiting = new FutureGroup();
-
- void processAsset(AssetId assetId) {
- visited.add(assetId);
-
- visiting.add(transform.readInputAsString(assetId).then((contents) {
- var source = sources[assetId];
- if (source == null) {
- source = new _AssetBasedSource(assetId, this);
- sources[assetId] = source;
- }
- source.updateContents(contents);
-
- source.dependentAssets
- .where((id) => !visited.contains(id))
- .forEach(processAsset);
-
- }, onError: (e) {
- _context.applyChanges(new ChangeSet()..removed(sources[assetId]));
- sources.remove(assetId);
- }));
- }
- processAsset(entryPoint);
-
- // Once we have all asset sources updated with the new contents then
- // resolve everything.
- return visiting.future.then((_) {
- var changeSet = new ChangeSet();
- var unreachableAssets = new Set.from(sources.keys).difference(visited);
- for (var unreachable in unreachableAssets) {
- changeSet.removed(sources[unreachable]);
- sources.remove(unreachable);
- }
-
- // Update the analyzer context with the latest sources
- _context.applyChanges(changeSet);
- // Resolve the AST
- _entryLibrary = _context.computeLibraryElement(sources[entryPoint]);
- _currentTransform = null;
- });
- }
-
- Iterable<LibraryElement> get libraries => entryLibrary.visibleLibraries;
-
- LibraryElement getLibraryByName(String libraryName) =>
- libraries.firstWhere((l) => l.name == libraryName, orElse: () => null);
-
- LibraryElement getLibraryByUri(Uri uri) =>
- libraries.firstWhere((l) => getImportUri(l) == uri, orElse: () => null);
-
- ClassElement getType(String typeName) {
- var dotIndex = typeName.lastIndexOf('.');
- var libraryName = dotIndex == -1 ? '' : typeName.substring(0, dotIndex);
-
- var className = dotIndex == -1 ?
- typeName : typeName.substring(dotIndex + 1);
-
- for (var lib in libraries.where((l) => l.name == libraryName)) {
- var type = lib.getType(className);
- if (type != null) return type;
- }
- return null;
- }
-
- Element getLibraryVariable(String variableName) {
- var dotIndex = variableName.lastIndexOf('.');
- var libraryName = dotIndex == -1 ? '' : variableName.substring(0, dotIndex);
-
- var name = dotIndex == -1 ?
- variableName : variableName.substring(dotIndex + 1);
-
- return libraries.where((lib) => lib.name == libraryName)
- .expand((lib) => lib.units)
- .expand((unit) => unit.topLevelVariables)
- .firstWhere((variable) => variable.name == name,
- orElse: () => null);
- }
-
- Element getLibraryFunction(String fnName) {
- var dotIndex = fnName.lastIndexOf('.');
- var libraryName = dotIndex == -1 ? '' : fnName.substring(0, dotIndex);
-
- var name = dotIndex == -1 ?
- fnName : fnName.substring(dotIndex + 1);
-
- return libraries.where((lib) => lib.name == libraryName)
- .expand((lib) => lib.units)
- .expand((unit) => unit.functions)
- .firstWhere((fn) => fn.name == name,
- orElse: () => null);
- }
-
- Uri getImportUri(LibraryElement lib, {AssetId from}) =>
- _getSourceUri(lib, from: from);
-
-
- /// Similar to getImportUri but will get the part URI for parts rather than
- /// the library URI.
- Uri _getSourceUri(Element element, {AssetId from}) {
- var source = element.source;
- if (source is _AssetBasedSource) {
- return source.getSourceUri(from);
- } else if (source is _DartSourceProxy) {
- return source.uri;
- }
- // Should not be able to encounter any other source types.
- throw new StateError('Unable to resolve URI for ${source.runtimeType}');
- }
-
- AssetId getSourceAssetId(Element element) {
- var source = element.source;
- if (source is _AssetBasedSource) return source.assetId;
- return null;
- }
-
- Span getSourceSpan(Element element) {
- var sourceFile = _getSourceFile(element);
- if (sourceFile == null) return null;
- return sourceFile.span(element.node.offset, element.node.end);
- }
-
- TextEditTransaction createTextEditTransaction(Element element) {
- if (element.source is! _AssetBasedSource) return null;
-
- _AssetBasedSource source = element.source;
- // Cannot modify assets in other packages.
- if (source.assetId.package != entryPoint.package) return null;
-
- var sourceFile = _getSourceFile(element);
- if (sourceFile == null) return null;
-
- return new TextEditTransaction(source.contents, sourceFile);
- }
-
- /// Gets the SourceFile for the source of the element.
- SourceFile _getSourceFile(Element element) {
- var assetId = getSourceAssetId(element);
- if (assetId == null) return null;
-
- var importUri = _getSourceUri(element, from: entryPoint);
- var spanPath = importUri != null ? importUri.toString() : assetId.path;
- return new SourceFile.text(spanPath, sources[assetId].contents);
- }
-}
-
-/// Implementation of Analyzer's Source for Barback based assets.
-class _AssetBasedSource extends Source {
-
- /// Asset ID where this source can be found.
- final AssetId assetId;
-
- /// The resolver this is being used in.
- final ResolverImpl _resolver;
-
- /// Cache of dependent asset IDs, to avoid re-parsing the AST.
- Iterable<AssetId> _dependentAssets;
-
- /// The current revision of the file, incremented only when file changes.
- int _revision = 0;
-
- /// The file contents.
- String _contents;
-
- _AssetBasedSource(this.assetId, this._resolver);
-
- /// Update the contents of this file with [contents].
- ///
- /// Returns true if the contents of this asset have changed.
- bool updateContents(String contents) {
- if (contents == _contents) return false;
- var added = _contents == null;
- _contents = contents;
- ++_revision;
- // Invalidate the imports so we only parse the AST when needed.
- _dependentAssets = null;
-
- if (added) {
- _resolver._context.applyChanges(new ChangeSet()..added(this));
- } else {
- _resolver._context.applyChanges(new ChangeSet()..changed(this));
- }
-
- var compilationUnit = _resolver._context.parseCompilationUnit(this);
- _dependentAssets = compilationUnit.directives
- .where((d) => (d is ImportDirective || d is PartDirective ||
- d is ExportDirective))
- .map((d) => _resolve(assetId, d.uri.stringValue,
- _logger, _getSpan(d)))
- .where((id) => id != null).toSet();
- return true;
- }
-
- /// Contents of the file.
- String get contents => _contents;
-
- /// Logger for the current transform.
- ///
- /// Only valid while the resolver is updating assets.
- TransformLogger get _logger => _resolver._currentTransform.logger;
-
- /// Gets all imports/parts/exports which resolve to assets (non-Dart files).
- Iterable<AssetId> get dependentAssets => _dependentAssets;
-
- bool exists() => true;
-
- bool operator ==(Object other) =>
- other is _AssetBasedSource && assetId == other.assetId;
-
- int get hashCode => assetId.hashCode;
-
- void getContents(Source_ContentReceiver receiver) {
- receiver.accept(contents, modificationStamp);
- }
-
- String get encoding =>
- "${uriKind.encoding}${assetId.package}/${assetId.path}";
-
- String get fullName => assetId.toString();
-
- int get modificationStamp => _revision;
-
- String get shortName => path.basename(assetId.path);
-
- UriKind get uriKind {
- if (assetId.path.startsWith('lib/')) return UriKind.PACKAGE_URI;
- return UriKind.FILE_URI;
- }
-
- bool get isInSystemLibrary => false;
-
- Source resolveRelative(Uri relativeUri) {
- var id = _resolve(assetId, relativeUri.toString(), _logger, null);
- if (id == null) return null;
-
- // The entire AST should have been parsed and loaded at this point.
- var source = _resolver.sources[id];
- if (source == null) {
- _logger.error('Could not load asset $id');
- }
- return source;
- }
-
- /// For logging errors.
- Span _getSpan(ASTNode node) => _sourceFile.span(node.offset, node.end);
- /// For logging errors.
- SourceFile get _sourceFile {
- var uri = getSourceUri(_resolver.entryPoint);
- var path = uri != null ? uri.toString() : assetId.path;
-
- return new SourceFile.text(path, contents);
- }
-
- /// Gets a URI which would be appropriate for importing this file.
- ///
- /// Note that this file may represent a non-importable file such as a part.
- Uri getSourceUri([AssetId from]) {
- if (!assetId.path.startsWith('lib/')) {
- // Cannot do absolute imports of non lib-based assets.
- if (from == null) return null;
-
- if (assetId.package != from.package) return null;
- return new Uri(
- path: path.relative(assetId.path, from: path.dirname(from.path)));
- }
-
- return Uri.parse('package:${assetId.package}/${assetId.path.substring(4)}');
- }
-}
-
-/// Implementation of Analyzer's UriResolver for Barback based assets.
-class _AssetUriResolver implements UriResolver {
- final ResolverImpl _resolver;
- _AssetUriResolver(this._resolver);
-
- Source resolveAbsolute(ContentCache contentCache, Uri uri) {
- var assetId = _resolve(null, uri.toString(), logger, null);
- var source = _resolver.sources[assetId];
- /// All resolved assets should be available by this point.
- if (source == null) {
- logger.error('Unable to find asset for "$uri"');
- }
- return source;
- }
-
- Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) =>
- throw new UnsupportedError('fromEncoding is not supported');
-
- Uri restoreAbsolute(Source source) =>
- throw new UnsupportedError('restoreAbsolute is not supported');
-
- TransformLogger get logger => _resolver._currentTransform.logger;
-}
-
-
-/// Dart SDK which wraps all Dart sources to ensure they are tracked with Uris.
-///
-/// Just a simple wrapper to make it easy to make sure that all sources we
-/// encounter are either _AssetBasedSource or _DartSourceProxy.
-class _DirectoryBasedDartSdkProxy extends DirectoryBasedDartSdk {
- _DirectoryBasedDartSdkProxy(JavaFile sdkDirectory) : super(sdkDirectory);
-
- Source mapDartUri(String dartUri) =>
- _DartSourceProxy.wrap(super.mapDartUri(dartUri), Uri.parse(dartUri));
-}
-
-
-/// Dart SDK resolver which wraps all Dart sources to ensure they are tracked
-/// with URIs.
-class DartUriResolverProxy implements DartUriResolver {
- final DartUriResolver _proxy;
- DartUriResolverProxy(DirectoryBasedDartSdk sdk) :
- _proxy = new DartUriResolver(sdk);
-
- Source resolveAbsolute(ContentCache contentCache, Uri uri) =>
- _DartSourceProxy.wrap(_proxy.resolveAbsolute(contentCache, uri), uri);
-
- DartSdk get dartSdk => _proxy.dartSdk;
-
- Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) =>
- throw new UnsupportedError('fromEncoding is not supported');
-
- Uri restoreAbsolute(Source source) =>
- throw new UnsupportedError('restoreAbsolute is not supported');
-}
-
-/// Source file for dart: sources which track the sources with dart: URIs.
-///
-/// This is primarily to support [Resolver.getImportUri] for Dart SDK (dart:)
-/// based libraries.
-class _DartSourceProxy implements Source {
-
- /// Absolute URI which this source can be imported from
- final Uri uri;
-
- /// Underlying source object.
- final Source _proxy;
-
- _DartSourceProxy(this._proxy, this.uri);
-
- /// Ensures that [source] is a _DartSourceProxy.
- static _DartSourceProxy wrap(Source source, Uri uri) {
- if (source == null || source is _DartSourceProxy) return source;
- return new _DartSourceProxy(source, uri);
- }
-
- Source resolveRelative(Uri relativeUri) {
- // Assume that the type can be accessed via this URI, since these
- // should only be parts for dart core files.
- return wrap(_proxy.resolveRelative(relativeUri), uri);
- }
-
- bool exists() => _proxy.exists();
-
- bool operator ==(Object other) =>
- (other is _DartSourceProxy && _proxy == other._proxy);
-
- int get hashCode => _proxy.hashCode;
-
- void getContents(Source_ContentReceiver receiver) {
- _proxy.getContents(receiver);
- }
-
- String get encoding => _proxy.encoding;
-
- String get fullName => _proxy.fullName;
-
- int get modificationStamp => _proxy.modificationStamp;
-
- String get shortName => _proxy.shortName;
-
- UriKind get uriKind => _proxy.uriKind;
-
- bool get isInSystemLibrary => _proxy.isInSystemLibrary;
-}
-
-/// Get an asset ID for a URL relative to another source asset.
-AssetId _resolve(AssetId source, String url, TransformLogger logger,
- Span span) {
- if (url == null || url == '') return null;
- var urlBuilder = path.url;
- var uri = Uri.parse(url);
-
- if (uri.scheme == 'package') {
- var segments = new List.from(uri.pathSegments);
- var package = segments[0];
- segments[0] = 'lib';
- return new AssetId(package, segments.join(urlBuilder.separator));
- }
- // Dart SDK libraries do not have assets.
- if (uri.scheme == 'dart') return null;
-
- if (uri.host != '' || uri.scheme != '' || urlBuilder.isAbsolute(url)) {
- logger.error('absolute paths not allowed: "$url"', span: span);
- return null;
- }
-
- var targetPath = urlBuilder.normalize(
- urlBuilder.join(urlBuilder.dirname(source.path), url));
- return new AssetId(source.package, targetPath);
-}
-
-
-/// A completer that waits until all added [Future]s complete.
-// TODO(blois): Copied from quiver. Remove from here when it gets
-// added to dart:core. (See #6626.)
-class FutureGroup<E> {
- static const _FINISHED = -1;
-
- int _pending = 0;
- Future _failedTask;
- final Completer<List> _completer = new Completer<List>();
- final List results = [];
-
- /** Gets the task that failed, if any. */
- Future get failedTask => _failedTask;
-
- /**
- * Wait for [task] to complete.
- *
- * If this group has already been marked as completed, a [StateError] will be
- * thrown.
- *
- * If this group has a [failedTask], new tasks will be ignored, because the
- * error has already been signaled.
- */
- void add(Future task) {
- if (_failedTask != null) return;
- if (_pending == _FINISHED) throw new StateError("Future already completed");
-
- _pending++;
- var i = results.length;
- results.add(null);
- task.then((res) {
- results[i] = res;
- if (_failedTask != null) return;
- _pending--;
- if (_pending == 0) {
- _pending = _FINISHED;
- _completer.complete(results);
- }
- }, onError: (e, s) {
- if (_failedTask != null) return;
- _failedTask = task;
- _completer.completeError(e, s);
- });
- }
-
- /**
- * A Future that complets with a List of the values from all the added
- * tasks, when they have all completed.
- *
- * If any task fails, this Future will receive the error. Only the first
- * error will be sent to the Future.
- */
- Future<List<E>> get future => _completer.future;
-}
« no previous file with comments | « pkg/code_transformers/lib/src/resolver.dart ('k') | pkg/code_transformers/lib/src/resolver_transformer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698