OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:collection'; | 6 import 'dart:collection'; |
7 import 'dart:convert'; | 7 import 'dart:convert'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 final _explicitFiles = new LinkedHashSet<String>(); | 121 final _explicitFiles = new LinkedHashSet<String>(); |
122 | 122 |
123 /** | 123 /** |
124 * The set of files that are currently scheduled for analysis. | 124 * The set of files that are currently scheduled for analysis. |
125 */ | 125 */ |
126 final _filesToAnalyze = new LinkedHashSet<String>(); | 126 final _filesToAnalyze = new LinkedHashSet<String>(); |
127 | 127 |
128 /** | 128 /** |
129 * The current file state. | 129 * The current file state. |
130 * | 130 * |
131 * It maps file paths to MD5 hash of the file content. | 131 * It maps file paths to the MD5 hash of the file content. |
132 */ | 132 */ |
133 final _fileContentHashMap = <String, String>{}; | 133 final _fileContentHashMap = <String, String>{}; |
134 | 134 |
135 /** | 135 /** |
136 * Mapping from library URIs to the linked hash of the library. | |
137 */ | |
138 final _linkedHashMap = <Uri, String>{}; | |
Paul Berry
2016/10/24 11:51:47
My comments about nomenclature from the last patch
scheglov
2016/10/24 17:44:37
Acknowledged.
I renamed them together.
| |
139 | |
140 /** | |
136 * TODO(scheglov) document and improve | 141 * TODO(scheglov) document and improve |
137 */ | 142 */ |
138 final _hasWorkStreamController = new StreamController<String>(); | 143 final _hasWorkStreamController = new StreamController<String>(); |
139 | 144 |
140 AnalysisDriver(this._logger, this._resourceProvider, this._byteStore, | 145 AnalysisDriver(this._logger, this._resourceProvider, this._byteStore, |
141 this._contentCache, this._sourceFactory, this._analysisOptions) { | 146 this._contentCache, this._sourceFactory, this._analysisOptions) { |
142 _sdkBundle = _sourceFactory.dartSdk.getLinkedBundle(); | 147 _sdkBundle = _sourceFactory.dartSdk.getLinkedBundle(); |
143 } | 148 } |
144 | 149 |
145 /** | 150 /** |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
226 * transitions to "idle". | 231 * transitions to "idle". |
227 * | 232 * |
228 * Invocation of this method will not prevent a [Future] returned from | 233 * Invocation of this method will not prevent a [Future] returned from |
229 * [getResult] from completing with a result, but the result is not | 234 * [getResult] from completing with a result, but the result is not |
230 * guaranteed to be consistent with the new current file state after this | 235 * guaranteed to be consistent with the new current file state after this |
231 * [changeFile] invocation. | 236 * [changeFile] invocation. |
232 */ | 237 */ |
233 void changeFile(String path) { | 238 void changeFile(String path) { |
234 // TODO(scheglov) Don't clear, schedule API signature validation. | 239 // TODO(scheglov) Don't clear, schedule API signature validation. |
235 _fileContentHashMap.clear(); | 240 _fileContentHashMap.clear(); |
241 _linkedHashMap.clear(); | |
236 _filesToAnalyze.add(path); | 242 _filesToAnalyze.add(path); |
237 _filesToAnalyze.addAll(_explicitFiles); | 243 _filesToAnalyze.addAll(_explicitFiles); |
238 // TODO(scheglov) name?! | 244 // TODO(scheglov) name?! |
239 _hasWorkStreamController.add('do it!'); | 245 _hasWorkStreamController.add('do it!'); |
240 } | 246 } |
241 | 247 |
242 /** | 248 /** |
243 * Return the [Future] that completes with a [AnalysisResult] for the file | 249 * Return the [Future] that completes with a [AnalysisResult] for the file |
244 * with the given [path]. | 250 * with the given [path]. |
245 * | 251 * |
(...skipping 24 matching lines...) Expand all Loading... | |
270 */ | 276 */ |
271 void removeFile(String path) { | 277 void removeFile(String path) { |
272 _explicitFiles.remove(path); | 278 _explicitFiles.remove(path); |
273 _filesToAnalyze.remove(path); | 279 _filesToAnalyze.remove(path); |
274 } | 280 } |
275 | 281 |
276 /** | 282 /** |
277 * TODO(scheglov) replace with actual [AnalysisResult] computing. | 283 * TODO(scheglov) replace with actual [AnalysisResult] computing. |
278 */ | 284 */ |
279 List<String> _computeAndPrintErrors(_File file) { | 285 List<String> _computeAndPrintErrors(_File file) { |
286 // TODO(scheglov) Computing resolved unit fails for these units. | |
287 // pkg/analyzer/lib/plugin/embedded_resolver_provider.dart | |
288 // pkg/analyzer/lib/plugin/embedded_resolver_provider.dart | |
289 if (file.path.endsWith( | |
290 'pkg/analyzer/lib/plugin/embedded_resolver_provider.dart') || | |
291 file.path.endsWith('pkg/analyzer/lib/source/embedder.dart') || | |
292 file.path.endsWith('pkg/analyzer/lib/src/generated/ast.dart') || | |
293 file.path.endsWith('pkg/analyzer/lib/src/generated/element.dart') || | |
294 file.path | |
295 .endsWith('pkg/analyzer/lib/src/generated/element_handle.dart') || | |
296 file.path.endsWith('pkg/analyzer/lib/src/generated/error.dart') || | |
297 file.path.endsWith('pkg/analyzer/lib/src/generated/scanner.dart') || | |
298 file.path.endsWith('pkg/analyzer/lib/src/generated/sdk_io.dart') || | |
299 file.path.endsWith('pkg/analyzer/lib/src/generated/visitors.dart') || | |
300 file.path.endsWith('pkg/analyzer/test/generated/constant_test.dart') || | |
301 file.path.endsWith('pkg/analyzer/test/source/embedder_test.dart')) { | |
302 return []; | |
303 } | |
304 | |
280 List<String> errorStrings = _logger.run('Compute errors $file', () { | 305 List<String> errorStrings = _logger.run('Compute errors $file', () { |
281 LibraryContext libraryContext = _createLibraryContext(file); | 306 LibraryContext libraryContext = _createLibraryContext(file); |
282 | 307 |
283 String errorsKey; | 308 String errorsKey; |
284 { | 309 { |
285 ApiSignature signature = new ApiSignature(); | 310 ApiSignature signature = new ApiSignature(); |
286 signature.addString(libraryContext.node.linkedHash); | 311 signature.addString(libraryContext.node.linkedHash); |
287 signature.addString(file.contentHash); | 312 signature.addString(file.contentHash); |
288 errorsKey = '${signature.toHex()}.errors'; | 313 errorsKey = '${signature.toHex()}.errors'; |
289 } | 314 } |
290 | 315 |
291 { | 316 { |
292 List<int> bytes = _byteStore.get(errorsKey); | 317 List<int> bytes = _byteStore.get(errorsKey); |
293 if (bytes != null) { | 318 if (bytes != null) { |
294 fb.BufferContext bp = new fb.BufferContext.fromBytes(bytes); | 319 fb.BufferContext bp = new fb.BufferContext.fromBytes(bytes); |
295 int table = bp.derefObject(0); | 320 int table = bp.derefObject(0); |
296 return const fb.ListReader<String>(const fb.StringReader()) | 321 return const fb.ListReader<String>(const fb.StringReader()) |
297 .vTableGet(bp, table, 0); | 322 .vTableGet(bp, table, 0); |
298 } | 323 } |
299 } | 324 } |
300 | 325 |
301 AnalysisContext analysisContext = _createAnalysisContext(libraryContext); | 326 AnalysisContext analysisContext = _createAnalysisContext(libraryContext); |
302 analysisContext.resolveCompilationUnit2( | 327 analysisContext.setContents(file.source, file.content); |
303 libraryContext.file.source, libraryContext.file.source); | |
304 try { | 328 try { |
329 // Compute resolved unit. | |
330 // _logger.runTimed('Computed resolved unit', () { | |
Paul Berry
2016/10/24 11:51:47
Why is this code commented out? Either remove or
scheglov
2016/10/24 17:44:37
We don't actually compute full analysis results ye
| |
331 // analysisContext.resolveCompilationUnit2( | |
332 // libraryContext.file.source, libraryContext.file.source); | |
333 // }); | |
334 // Compute errors. | |
305 List<AnalysisError> errors; | 335 List<AnalysisError> errors; |
306 try { | 336 try { |
307 errors = _logger.runTimed('Computed errors', () { | 337 errors = _logger.runTimed('Computed errors', () { |
308 return analysisContext.computeErrors(file.source); | 338 return analysisContext.computeErrors(file.source); |
309 }); | 339 }); |
310 } catch (e, st) { | 340 } catch (e, st) { |
311 // TODO(scheglov) why does it fail? | 341 // TODO(scheglov) why does it fail? |
312 // Caused by Bad state: Unmatched TypeParameterElementImpl T | 342 // Caused by Bad state: Unmatched TypeParameterElementImpl T |
313 errors = []; | 343 errors = []; |
314 } | 344 } |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
867 } | 897 } |
868 return _dependencies; | 898 return _dependencies; |
869 } | 899 } |
870 | 900 |
871 @override | 901 @override |
872 int get hashCode => uri.hashCode; | 902 int get hashCode => uri.hashCode; |
873 | 903 |
874 bool get isReady => linked != null; | 904 bool get isReady => linked != null; |
875 | 905 |
876 String get linkedHash { | 906 String get linkedHash { |
877 if (_linkedHash == null) { | 907 _linkedHash ??= driver._linkedHashMap.putIfAbsent(uri, () { |
878 if (transitiveDependencies == null) { | 908 computeTransitiveDependencies(); |
879 computeTransitiveDependencies(); | |
880 } | |
881 | 909 |
882 // Add all unlinked API signatures. | 910 // Add all unlinked API signatures. |
883 List<String> signatures = <String>[]; | 911 List<String> signatures = <String>[]; |
884 signatures.add(driver._sdkBundle.apiSignature); | 912 signatures.add(driver._sdkBundle.apiSignature); |
885 transitiveDependencies | 913 transitiveDependencies |
886 .map((node) => node.unlinkedBundles) | 914 .map((node) => node.unlinkedBundles) |
887 .expand((bundles) => bundles) | 915 .expand((bundles) => bundles) |
888 .map((bundle) => bundle.apiSignature) | 916 .map((bundle) => bundle.apiSignature) |
889 .forEach(signatures.add); | 917 .forEach(signatures.add); |
890 signatures.sort(); | 918 signatures.sort(); |
891 | 919 |
892 // Combine into a single hash. | 920 // Combine into a single hash. |
893 ApiSignature signature = new ApiSignature(); | 921 ApiSignature signature = new ApiSignature(); |
894 signature.addString(uri.toString()); | 922 signature.addString(uri.toString()); |
895 signatures.forEach(signature.addString); | 923 signatures.forEach(signature.addString); |
896 _linkedHash = signature.toHex(); | 924 return signature.toHex(); |
897 } | 925 }); |
898 return _linkedHash; | 926 return _linkedHash; |
899 } | 927 } |
900 | 928 |
901 bool operator ==(other) { | 929 bool operator ==(other) { |
902 return other is _LibraryNode && other.uri == uri; | 930 return other is _LibraryNode && other.uri == uri; |
903 } | 931 } |
904 | 932 |
905 void computeTransitiveDependencies() { | 933 void computeTransitiveDependencies() { |
906 if (transitiveDependencies == null) { | 934 if (transitiveDependencies == null) { |
907 transitiveDependencies = new Set<_LibraryNode>(); | 935 transitiveDependencies = new Set<_LibraryNode>(); |
908 | 936 |
909 void appendDependencies(_LibraryNode node) { | 937 void appendDependencies(_LibraryNode node) { |
910 if (transitiveDependencies.add(node)) { | 938 if (transitiveDependencies.add(node)) { |
911 node.dependencies.forEach(appendDependencies); | 939 node.dependencies.forEach(appendDependencies); |
912 } | 940 } |
913 } | 941 } |
914 | 942 |
915 appendDependencies(this); | 943 appendDependencies(this); |
916 } | 944 } |
917 } | 945 } |
918 | 946 |
919 @override | 947 @override |
920 String toString() => uri.toString(); | 948 String toString() => uri.toString(); |
921 } | 949 } |
OLD | NEW |