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 |