| 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 28 matching lines...) Expand all Loading... |
| 39 | 39 |
| 40 final AnalysisContext _context = | 40 final AnalysisContext _context = |
| 41 AnalysisEngine.instance.createAnalysisContext(); | 41 AnalysisEngine.instance.createAnalysisContext(); |
| 42 | 42 |
| 43 /// Transform for which this is currently updating, or null when not updating. | 43 /// Transform for which this is currently updating, or null when not updating. |
| 44 Transform _currentTransform; | 44 Transform _currentTransform; |
| 45 | 45 |
| 46 /// The currently resolved library, or null if unresolved. | 46 /// The currently resolved library, or null if unresolved. |
| 47 LibraryElement _entryLibrary; | 47 LibraryElement _entryLibrary; |
| 48 | 48 |
| 49 /// Future indicating when this resolver is done in the current phase. |
| 50 Future _lastPhaseComplete = new Future.value(); |
| 51 |
| 52 /// Completer for wrapping up the current phase. |
| 53 Completer _currentPhaseComplete; |
| 54 |
| 49 /// Handler for all Dart SDK (dart:) sources. | 55 /// Handler for all Dart SDK (dart:) sources. |
| 50 DirectoryBasedDartSdk _dartSdk; | 56 DirectoryBasedDartSdk _dartSdk; |
| 51 | 57 |
| 52 /// Creates a resolver that will resolve the Dart code starting at | 58 /// Creates a resolver that will resolve the Dart code starting at |
| 53 /// [entryPoint]. | 59 /// [entryPoint]. |
| 54 /// | 60 /// |
| 55 /// [sdkDir] is the root directory of the Dart SDK, for resolving dart: | 61 /// [sdkDir] is the root directory of the Dart SDK, for resolving dart: |
| 56 /// imports. | 62 /// imports. |
| 57 ResolverImpl(this.entryPoint, String sdkDir, {AnalysisOptions options}) { | 63 ResolverImpl(this.entryPoint, String sdkDir, {AnalysisOptions options}) { |
| 58 if (options == null) { | 64 if (options == null) { |
| 59 options = new AnalysisOptionsImpl() | 65 options = new AnalysisOptionsImpl() |
| 60 ..cacheSize = 256 // # of sources to cache ASTs for. | 66 ..cacheSize = 256 // # of sources to cache ASTs for. |
| 61 ..preserveComments = false | 67 ..preserveComments = false |
| 62 ..analyzeFunctionBodies = true; | 68 ..analyzeFunctionBodies = true; |
| 63 } | 69 } |
| 64 _context.analysisOptions = options; | 70 _context.analysisOptions = options; |
| 65 | 71 |
| 66 _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir)); | 72 _dartSdk = new _DirectoryBasedDartSdkProxy(new JavaFile(sdkDir)); |
| 67 _dartSdk.context.analysisOptions = options; | 73 _dartSdk.context.analysisOptions = options; |
| 68 | 74 |
| 69 _context.sourceFactory = new SourceFactory.con2([ | 75 _context.sourceFactory = new SourceFactory.con2([ |
| 70 new DartUriResolverProxy(_dartSdk), | 76 new DartUriResolverProxy(_dartSdk), |
| 71 new _AssetUriResolver(this)]); | 77 new _AssetUriResolver(this)]); |
| 72 } | 78 } |
| 73 | 79 |
| 74 LibraryElement get entryLibrary => _entryLibrary; | 80 LibraryElement get entryLibrary => _entryLibrary; |
| 75 | 81 |
| 82 Future<Resolver> resolve(Transform transform) { |
| 83 // Can only have one resolve in progress at a time, so chain the current |
| 84 // resolution to be after the last one. |
| 85 var phaseComplete = new Completer(); |
| 86 var future = _lastPhaseComplete.then((_) { |
| 87 _currentPhaseComplete = phaseComplete; |
| 76 | 88 |
| 77 /// Update the status of all the sources referenced by the entryPoint and | 89 return _performResolve(transform); |
| 78 /// update the resolved library. | 90 }).then((_) => this); |
| 79 /// | 91 // Advance the lastPhaseComplete to be done when this phase is all done. |
| 80 /// This will be invoked automatically by [ResolverTransformer]. Only one | 92 _lastPhaseComplete = phaseComplete.future; |
| 81 /// transformer may update this at a time. | 93 return future; |
| 82 Future updateSources(Transform transform) { | 94 } |
| 95 |
| 96 void release() { |
| 97 if (_currentPhaseComplete == null) { |
| 98 throw new StateError('Releasing without current lock.'); |
| 99 } |
| 100 _currentPhaseComplete.complete(null); |
| 101 _currentPhaseComplete = null; |
| 102 |
| 103 // Clear out the entry lib since it should not be referenced after release. |
| 104 _entryLibrary = null; |
| 105 } |
| 106 |
| 107 Future _performResolve(Transform transform) { |
| 83 if (_currentTransform != null) { | 108 if (_currentTransform != null) { |
| 84 throw new StateError('Cannot be accessed by concurrent transforms'); | 109 throw new StateError('Cannot be accessed by concurrent transforms'); |
| 85 } | 110 } |
| 86 _currentTransform = transform; | 111 _currentTransform = transform; |
| 87 // Clear this out and update once all asset changes have been processed. | |
| 88 _entryLibrary = null; | |
| 89 | 112 |
| 90 // Basic approach is to start at the first file, update it's contents | 113 // Basic approach is to start at the first file, update it's contents |
| 91 // and see if it changed, then walk all files accessed by it. | 114 // and see if it changed, then walk all files accessed by it. |
| 92 var visited = new Set<AssetId>(); | 115 var visited = new Set<AssetId>(); |
| 93 var visiting = new FutureGroup(); | 116 var visiting = new FutureGroup(); |
| 94 | 117 |
| 95 void processAsset(AssetId assetId) { | 118 void processAsset(AssetId assetId) { |
| 96 visited.add(assetId); | 119 visited.add(assetId); |
| 97 | 120 |
| 98 visiting.add(transform.readInputAsString(assetId).then((contents) { | 121 visiting.add(transform.readInputAsString(assetId).then((contents) { |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 | 487 |
| 465 bool get isInSystemLibrary => _proxy.isInSystemLibrary; | 488 bool get isInSystemLibrary => _proxy.isInSystemLibrary; |
| 466 } | 489 } |
| 467 | 490 |
| 468 /// Get an asset ID for a URL relative to another source asset. | 491 /// Get an asset ID for a URL relative to another source asset. |
| 469 AssetId _resolve(AssetId source, String url, TransformLogger logger, | 492 AssetId _resolve(AssetId source, String url, TransformLogger logger, |
| 470 Span span) { | 493 Span span) { |
| 471 if (url == null || url == '') return null; | 494 if (url == null || url == '') return null; |
| 472 var uri = Uri.parse(url); | 495 var uri = Uri.parse(url); |
| 473 | 496 |
| 497 // Workaround for dartbug.com/17156- pub transforms package: imports from |
| 498 // files of the transformers package to have absolute /packages/ URIs. |
| 499 if (uri.scheme == '' && path.isAbsolute(url) |
| 500 && uri.pathSegments[0] == 'packages') { |
| 501 uri = Uri.parse('package:${uri.pathSegments.skip(1).join(path.separator)}'); |
| 502 } |
| 503 |
| 474 if (uri.scheme == 'package') { | 504 if (uri.scheme == 'package') { |
| 475 var segments = new List.from(uri.pathSegments); | 505 var segments = new List.from(uri.pathSegments); |
| 476 var package = segments[0]; | 506 var package = segments[0]; |
| 477 segments[0] = 'lib'; | 507 segments[0] = 'lib'; |
| 478 return new AssetId(package, segments.join(path.separator)); | 508 return new AssetId(package, segments.join(path.separator)); |
| 479 } | 509 } |
| 480 // Dart SDK libraries do not have assets. | 510 // Dart SDK libraries do not have assets. |
| 481 if (uri.scheme == 'dart') return null; | 511 if (uri.scheme == 'dart') return null; |
| 482 | 512 |
| 483 if (uri.host != '' || uri.scheme != '' || path.isAbsolute(url)) { | 513 if (uri.host != '' || uri.scheme != '' || path.isAbsolute(url)) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 | 568 |
| 539 /** | 569 /** |
| 540 * A Future that complets with a List of the values from all the added | 570 * A Future that complets with a List of the values from all the added |
| 541 * tasks, when they have all completed. | 571 * tasks, when they have all completed. |
| 542 * | 572 * |
| 543 * If any task fails, this Future will receive the error. Only the first | 573 * If any task fails, this Future will receive the error. Only the first |
| 544 * error will be sent to the Future. | 574 * error will be sent to the Future. |
| 545 */ | 575 */ |
| 546 Future<List<E>> get future => _completer.future; | 576 Future<List<E>> get future => _completer.future; |
| 547 } | 577 } |
| OLD | NEW |