| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library code_transformer.src.resolver_impl; | 5 library code_transformer.src.resolver_impl; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
| 9 import 'package:analyzer/src/generated/element.dart'; | 9 import 'package:analyzer/src/generated/element.dart'; |
| 10 import 'package:analyzer/src/generated/engine.dart'; | 10 import 'package:analyzer/src/generated/engine.dart'; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 options = new AnalysisOptionsImpl() | 62 options = new AnalysisOptionsImpl() |
| 63 ..cacheSize = 256 // # of sources to cache ASTs for. | 63 ..cacheSize = 256 // # of sources to cache ASTs for. |
| 64 ..preserveComments = false | 64 ..preserveComments = false |
| 65 ..analyzeFunctionBodies = true; | 65 ..analyzeFunctionBodies = true; |
| 66 } | 66 } |
| 67 _context.analysisOptions = options; | 67 _context.analysisOptions = options; |
| 68 | 68 |
| 69 _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir)); | 69 _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir)); |
| 70 _dartSdk.context.analysisOptions = options; | 70 _dartSdk.context.analysisOptions = options; |
| 71 | 71 |
| 72 _context.sourceFactory = new SourceFactory.con2([ | 72 _context.sourceFactory = new SourceFactory([ |
| 73 new DartUriResolverProxy(_dartSdk), | 73 new DartUriResolverProxy(_dartSdk), |
| 74 new _AssetUriResolver(this)]); | 74 new _AssetUriResolver(this)]); |
| 75 } | 75 } |
| 76 | 76 |
| 77 LibraryElement get entryLibrary => _entryLibrary; | 77 LibraryElement get entryLibrary => _entryLibrary; |
| 78 | 78 |
| 79 Future<Resolver> resolve(Transform transform) { | 79 Future<Resolver> resolve(Transform transform) { |
| 80 // Can only have one resolve in progress at a time, so chain the current | 80 // Can only have one resolve in progress at a time, so chain the current |
| 81 // resolution to be after the last one. | 81 // resolution to be after the last one. |
| 82 var phaseComplete = new Completer(); | 82 var phaseComplete = new Completer(); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 TextEditTransaction createTextEditTransaction(Element element) { | 234 TextEditTransaction createTextEditTransaction(Element element) { |
| 235 if (element.source is! _AssetBasedSource) return null; | 235 if (element.source is! _AssetBasedSource) return null; |
| 236 | 236 |
| 237 _AssetBasedSource source = element.source; | 237 _AssetBasedSource source = element.source; |
| 238 // Cannot modify assets in other packages. | 238 // Cannot modify assets in other packages. |
| 239 if (source.assetId.package != entryPoint.package) return null; | 239 if (source.assetId.package != entryPoint.package) return null; |
| 240 | 240 |
| 241 var sourceFile = _getSourceFile(element); | 241 var sourceFile = _getSourceFile(element); |
| 242 if (sourceFile == null) return null; | 242 if (sourceFile == null) return null; |
| 243 | 243 |
| 244 return new TextEditTransaction(source.contents, sourceFile); | 244 return new TextEditTransaction(source.rawContents, sourceFile); |
| 245 } | 245 } |
| 246 | 246 |
| 247 /// Gets the SourceFile for the source of the element. | 247 /// Gets the SourceFile for the source of the element. |
| 248 SourceFile _getSourceFile(Element element) { | 248 SourceFile _getSourceFile(Element element) { |
| 249 var assetId = getSourceAssetId(element); | 249 var assetId = getSourceAssetId(element); |
| 250 if (assetId == null) return null; | 250 if (assetId == null) return null; |
| 251 | 251 |
| 252 var importUri = _getSourceUri(element, from: entryPoint); | 252 var importUri = _getSourceUri(element, from: entryPoint); |
| 253 var spanPath = importUri != null ? importUri.toString() : assetId.path; | 253 var spanPath = importUri != null ? importUri.toString() : assetId.path; |
| 254 return new SourceFile.text(spanPath, sources[assetId].contents); | 254 return new SourceFile.text(spanPath, sources[assetId].rawContents); |
| 255 } | 255 } |
| 256 } | 256 } |
| 257 | 257 |
| 258 /// Implementation of Analyzer's Source for Barback based assets. | 258 /// Implementation of Analyzer's Source for Barback based assets. |
| 259 class _AssetBasedSource extends Source { | 259 class _AssetBasedSource extends Source { |
| 260 | 260 |
| 261 /// Asset ID where this source can be found. | 261 /// Asset ID where this source can be found. |
| 262 final AssetId assetId; | 262 final AssetId assetId; |
| 263 | 263 |
| 264 /// The resolver this is being used in. | 264 /// The resolver this is being used in. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 _dependentAssets = compilationUnit.directives | 296 _dependentAssets = compilationUnit.directives |
| 297 .where((d) => (d is ImportDirective || d is PartDirective || | 297 .where((d) => (d is ImportDirective || d is PartDirective || |
| 298 d is ExportDirective)) | 298 d is ExportDirective)) |
| 299 .map((d) => _resolve(assetId, d.uri.stringValue, | 299 .map((d) => _resolve(assetId, d.uri.stringValue, |
| 300 _logger, _getSpan(d))) | 300 _logger, _getSpan(d))) |
| 301 .where((id) => id != null).toSet(); | 301 .where((id) => id != null).toSet(); |
| 302 return true; | 302 return true; |
| 303 } | 303 } |
| 304 | 304 |
| 305 /// Contents of the file. | 305 /// Contents of the file. |
| 306 String get contents => _contents; | 306 TimestampedData<String> get contents => |
| 307 new TimestampedData<String>(modificationStamp, _contents); |
| 308 |
| 309 /// Contents of the file. |
| 310 String get rawContents => _contents; |
| 307 | 311 |
| 308 /// Logger for the current transform. | 312 /// Logger for the current transform. |
| 309 /// | 313 /// |
| 310 /// Only valid while the resolver is updating assets. | 314 /// Only valid while the resolver is updating assets. |
| 311 TransformLogger get _logger => _resolver._currentTransform.logger; | 315 TransformLogger get _logger => _resolver._currentTransform.logger; |
| 312 | 316 |
| 313 /// Gets all imports/parts/exports which resolve to assets (non-Dart files). | 317 /// Gets all imports/parts/exports which resolve to assets (non-Dart files). |
| 314 Iterable<AssetId> get dependentAssets => _dependentAssets; | 318 Iterable<AssetId> get dependentAssets => _dependentAssets; |
| 315 | 319 |
| 316 bool exists() => true; | 320 bool exists() => true; |
| 317 | 321 |
| 318 bool operator ==(Object other) => | 322 bool operator ==(Object other) => |
| 319 other is _AssetBasedSource && assetId == other.assetId; | 323 other is _AssetBasedSource && assetId == other.assetId; |
| 320 | 324 |
| 321 int get hashCode => assetId.hashCode; | 325 int get hashCode => assetId.hashCode; |
| 322 | 326 |
| 323 void getContents(Source_ContentReceiver receiver) { | 327 void getContentsToReceiver(Source_ContentReceiver receiver) { |
| 324 receiver.accept(contents, modificationStamp); | 328 receiver.accept(rawContents, modificationStamp); |
| 325 } | 329 } |
| 326 | 330 |
| 327 String get encoding => | 331 String get encoding => |
| 328 "${uriKind.encoding}${assetId.package}/${assetId.path}"; | 332 "${uriKind.encoding}${assetId.package}/${assetId.path}"; |
| 329 | 333 |
| 330 String get fullName => assetId.toString(); | 334 String get fullName => assetId.toString(); |
| 331 | 335 |
| 332 int get modificationStamp => _revision; | 336 int get modificationStamp => _revision; |
| 333 | 337 |
| 334 String get shortName => path.basename(assetId.path); | 338 String get shortName => path.basename(assetId.path); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 352 return source; | 356 return source; |
| 353 } | 357 } |
| 354 | 358 |
| 355 /// For logging errors. | 359 /// For logging errors. |
| 356 Span _getSpan(ASTNode node) => _sourceFile.span(node.offset, node.end); | 360 Span _getSpan(ASTNode node) => _sourceFile.span(node.offset, node.end); |
| 357 /// For logging errors. | 361 /// For logging errors. |
| 358 SourceFile get _sourceFile { | 362 SourceFile get _sourceFile { |
| 359 var uri = getSourceUri(_resolver.entryPoint); | 363 var uri = getSourceUri(_resolver.entryPoint); |
| 360 var path = uri != null ? uri.toString() : assetId.path; | 364 var path = uri != null ? uri.toString() : assetId.path; |
| 361 | 365 |
| 362 return new SourceFile.text(path, contents); | 366 return new SourceFile.text(path, rawContents); |
| 363 } | 367 } |
| 364 | 368 |
| 365 /// Gets a URI which would be appropriate for importing this file. | 369 /// Gets a URI which would be appropriate for importing this file. |
| 366 /// | 370 /// |
| 367 /// Note that this file may represent a non-importable file such as a part. | 371 /// Note that this file may represent a non-importable file such as a part. |
| 368 Uri getSourceUri([AssetId from]) { | 372 Uri getSourceUri([AssetId from]) { |
| 369 if (!assetId.path.startsWith('lib/')) { | 373 if (!assetId.path.startsWith('lib/')) { |
| 370 // Cannot do absolute imports of non lib-based assets. | 374 // Cannot do absolute imports of non lib-based assets. |
| 371 if (from == null) return null; | 375 if (from == null) return null; |
| 372 | 376 |
| 373 if (assetId.package != from.package) return null; | 377 if (assetId.package != from.package) return null; |
| 374 return new Uri( | 378 return new Uri( |
| 375 path: path.relative(assetId.path, from: path.dirname(from.path))); | 379 path: path.relative(assetId.path, from: path.dirname(from.path))); |
| 376 } | 380 } |
| 377 | 381 |
| 378 return Uri.parse('package:${assetId.package}/${assetId.path.substring(4)}'); | 382 return Uri.parse('package:${assetId.package}/${assetId.path.substring(4)}'); |
| 379 } | 383 } |
| 380 } | 384 } |
| 381 | 385 |
| 382 /// Implementation of Analyzer's UriResolver for Barback based assets. | 386 /// Implementation of Analyzer's UriResolver for Barback based assets. |
| 383 class _AssetUriResolver implements UriResolver { | 387 class _AssetUriResolver implements UriResolver { |
| 384 final ResolverImpl _resolver; | 388 final ResolverImpl _resolver; |
| 385 _AssetUriResolver(this._resolver); | 389 _AssetUriResolver(this._resolver); |
| 386 | 390 |
| 387 Source resolveAbsolute(ContentCache contentCache, Uri uri) { | 391 Source resolveAbsolute(Uri uri) { |
| 388 var assetId = _resolve(null, uri.toString(), logger, null); | 392 var assetId = _resolve(null, uri.toString(), logger, null); |
| 389 var source = _resolver.sources[assetId]; | 393 var source = _resolver.sources[assetId]; |
| 390 /// All resolved assets should be available by this point. | 394 /// All resolved assets should be available by this point. |
| 391 if (source == null) { | 395 if (source == null) { |
| 392 logger.error('Unable to find asset for "$uri"'); | 396 logger.error('Unable to find asset for "$uri"'); |
| 393 } | 397 } |
| 394 return source; | 398 return source; |
| 395 } | 399 } |
| 396 | 400 |
| 397 Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) => | 401 Source fromEncoding(UriKind kind, Uri uri) => |
| 398 throw new UnsupportedError('fromEncoding is not supported'); | 402 throw new UnsupportedError('fromEncoding is not supported'); |
| 399 | 403 |
| 400 Uri restoreAbsolute(Source source) => | 404 Uri restoreAbsolute(Source source) => |
| 401 throw new UnsupportedError('restoreAbsolute is not supported'); | 405 throw new UnsupportedError('restoreAbsolute is not supported'); |
| 402 | 406 |
| 403 TransformLogger get logger => _resolver._currentTransform.logger; | 407 TransformLogger get logger => _resolver._currentTransform.logger; |
| 404 } | 408 } |
| 405 | 409 |
| 406 | 410 |
| 407 /// Dart SDK which wraps all Dart sources to ensure they are tracked with Uris. | 411 /// Dart SDK which wraps all Dart sources to ensure they are tracked with Uris. |
| 408 /// | 412 /// |
| 409 /// Just a simple wrapper to make it easy to make sure that all sources we | 413 /// Just a simple wrapper to make it easy to make sure that all sources we |
| 410 /// encounter are either _AssetBasedSource or _DartSourceProxy. | 414 /// encounter are either _AssetBasedSource or _DartSourceProxy. |
| 411 class _DirectoryBasedDartSdkProxy extends DirectoryBasedDartSdk { | 415 class _DirectoryBasedDartSdkProxy extends DirectoryBasedDartSdk { |
| 412 _DirectoryBasedDartSdkProxy(JavaFile sdkDirectory) : super(sdkDirectory); | 416 _DirectoryBasedDartSdkProxy(JavaFile sdkDirectory) : super(sdkDirectory); |
| 413 | 417 |
| 414 Source mapDartUri(String dartUri) => | 418 Source mapDartUri(String dartUri) => |
| 415 _DartSourceProxy.wrap(super.mapDartUri(dartUri), Uri.parse(dartUri)); | 419 _DartSourceProxy.wrap(super.mapDartUri(dartUri), Uri.parse(dartUri)); |
| 416 } | 420 } |
| 417 | 421 |
| 418 | 422 |
| 419 /// Dart SDK resolver which wraps all Dart sources to ensure they are tracked | 423 /// Dart SDK resolver which wraps all Dart sources to ensure they are tracked |
| 420 /// with URIs. | 424 /// with URIs. |
| 421 class DartUriResolverProxy implements DartUriResolver { | 425 class DartUriResolverProxy implements DartUriResolver { |
| 422 final DartUriResolver _proxy; | 426 final DartUriResolver _proxy; |
| 423 DartUriResolverProxy(DirectoryBasedDartSdk sdk) : | 427 DartUriResolverProxy(DirectoryBasedDartSdk sdk) : |
| 424 _proxy = new DartUriResolver(sdk); | 428 _proxy = new DartUriResolver(sdk); |
| 425 | 429 |
| 426 Source resolveAbsolute(ContentCache contentCache, Uri uri) => | 430 Source resolveAbsolute(Uri uri) => |
| 427 _DartSourceProxy.wrap(_proxy.resolveAbsolute(contentCache, uri), uri); | 431 _DartSourceProxy.wrap(_proxy.resolveAbsolute(uri), uri); |
| 428 | 432 |
| 429 DartSdk get dartSdk => _proxy.dartSdk; | 433 DartSdk get dartSdk => _proxy.dartSdk; |
| 430 | 434 |
| 431 Source fromEncoding(ContentCache contentCache, UriKind kind, Uri uri) => | 435 Source fromEncoding(UriKind kind, Uri uri) => |
| 432 throw new UnsupportedError('fromEncoding is not supported'); | 436 throw new UnsupportedError('fromEncoding is not supported'); |
| 433 | 437 |
| 434 Uri restoreAbsolute(Source source) => | 438 Uri restoreAbsolute(Source source) => |
| 435 throw new UnsupportedError('restoreAbsolute is not supported'); | 439 throw new UnsupportedError('restoreAbsolute is not supported'); |
| 436 } | 440 } |
| 437 | 441 |
| 438 /// Source file for dart: sources which track the sources with dart: URIs. | 442 /// Source file for dart: sources which track the sources with dart: URIs. |
| 439 /// | 443 /// |
| 440 /// This is primarily to support [Resolver.getImportUri] for Dart SDK (dart:) | 444 /// This is primarily to support [Resolver.getImportUri] for Dart SDK (dart:) |
| 441 /// based libraries. | 445 /// based libraries. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 461 return wrap(_proxy.resolveRelative(relativeUri), uri); | 465 return wrap(_proxy.resolveRelative(relativeUri), uri); |
| 462 } | 466 } |
| 463 | 467 |
| 464 bool exists() => _proxy.exists(); | 468 bool exists() => _proxy.exists(); |
| 465 | 469 |
| 466 bool operator ==(Object other) => | 470 bool operator ==(Object other) => |
| 467 (other is _DartSourceProxy && _proxy == other._proxy); | 471 (other is _DartSourceProxy && _proxy == other._proxy); |
| 468 | 472 |
| 469 int get hashCode => _proxy.hashCode; | 473 int get hashCode => _proxy.hashCode; |
| 470 | 474 |
| 471 void getContents(Source_ContentReceiver receiver) { | 475 void getContentsToReceiver(Source_ContentReceiver receiver) { |
| 472 _proxy.getContents(receiver); | 476 _proxy.getContentsToReceiver(receiver); |
| 473 } | 477 } |
| 474 | 478 |
| 479 TimestampedData<String> get contents => _proxy.contents; |
| 480 |
| 475 String get encoding => _proxy.encoding; | 481 String get encoding => _proxy.encoding; |
| 476 | 482 |
| 477 String get fullName => _proxy.fullName; | 483 String get fullName => _proxy.fullName; |
| 478 | 484 |
| 479 int get modificationStamp => _proxy.modificationStamp; | 485 int get modificationStamp => _proxy.modificationStamp; |
| 480 | 486 |
| 481 String get shortName => _proxy.shortName; | 487 String get shortName => _proxy.shortName; |
| 482 | 488 |
| 483 UriKind get uriKind => _proxy.uriKind; | 489 UriKind get uriKind => _proxy.uriKind; |
| 484 | 490 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 | 571 |
| 566 /** | 572 /** |
| 567 * A Future that complets with a List of the values from all the added | 573 * A Future that complets with a List of the values from all the added |
| 568 * tasks, when they have all completed. | 574 * tasks, when they have all completed. |
| 569 * | 575 * |
| 570 * If any task fails, this Future will receive the error. Only the first | 576 * If any task fails, this Future will receive the error. Only the first |
| 571 * error will be sent to the Future. | 577 * error will be sent to the Future. |
| 572 */ | 578 */ |
| 573 Future<List<E>> get future => _completer.future; | 579 Future<List<E>> get future => _completer.future; |
| 574 } | 580 } |
| OLD | NEW |