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 |