Chromium Code Reviews| 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 | 6 |
| 7 import 'package:analyzer/dart/ast/ast.dart'; | 7 import 'package:analyzer/dart/ast/ast.dart'; |
| 8 import 'package:analyzer/error/error.dart'; | 8 import 'package:analyzer/error/error.dart'; |
| 9 import 'package:analyzer/file_system/file_system.dart'; | |
| 10 import 'package:analyzer/src/dart/analysis/byte_store.dart'; | 9 import 'package:analyzer/src/dart/analysis/byte_store.dart'; |
| 11 import 'package:analyzer/src/generated/source.dart'; | 10 import 'package:analyzer/src/generated/source.dart'; |
| 12 | 11 |
| 13 /** | 12 /** |
| 14 * This class computes [AnalysisResult]s for Dart files. | 13 * This class computes [AnalysisResult]s for Dart files. |
| 14 * | |
| 15 * Let the set of "explicitly analyzed files" denote the set of paths that have | |
| 16 * been passed to [addFile] but not subsequently passed to [removeFile]. Let | |
| 17 * the "current analysis results" denote the map from the set of explicitly | |
| 18 * analyzed files to the most recent [AnalysisResult] delivered to [results] | |
| 19 * for each file. Let the "current file state" represent a map from file path | |
| 20 * to the file contents most recently read from that file, or fetched from the | |
| 21 * content cache (considering all possible possible file paths, regardless of | |
| 22 * whether they're in the set of explicitly analyzed files). Let the | |
| 23 * "analysis state" be either "analyzing" or "idle". | |
| 24 * | |
| 25 * (These are theoretical constructs; they may not necessarily reflect data | |
| 26 * structures maintained explicitly by the driver). | |
| 27 * | |
| 28 * Then we make the following guarantees: | |
| 29 * | |
| 30 * - Whenever the analysis state is idle, the current analysis results are | |
| 31 * consistent with the current file state. | |
| 32 * | |
| 33 * - A call to [addFile] or [changeFile] causes the analysis state to | |
| 34 * transition to "analyzing", and schedules the contents of the given | |
| 35 * files to be read into the current file state prior to the next time | |
| 36 * the analysis state transitions back to "idle". | |
| 37 * | |
| 38 * - If at any time the client stops making calls to [addFile], [changeFile], | |
| 39 * and [removeFile], the analysis state will eventually transition back to | |
| 40 * "idle" after a finite amount of processing. | |
| 41 * | |
| 42 * As a result of these guarantees, a client may ensure that the analysis | |
| 43 * results are "eventually consistent" with the file system by simply calling | |
| 44 * [changeFile] any time the contents of a file on the file system have changed. | |
|
Brian Wilkerson
2016/10/25 17:34:16
I assume a call to removeFile could transition the
scheglov
2016/10/25 18:53:31
I'd like to have the only place where we switch fr
Brian Wilkerson
2016/10/26 06:49:14
That would be nice, but if we add a file, schedule
scheglov
2016/10/26 16:39:59
The driver will transition to idle when there is n
| |
| 45 * | |
| 46 * | |
| 47 * TODO(scheglov) Clean up the list of implicitly analyzed files. | |
| 15 */ | 48 */ |
| 16 class AnalysisDriver { | 49 class AnalysisDriver { |
| 17 /** | 50 /** |
| 18 * The byte storage to get and put serialized data. | 51 * The byte storage to get and put serialized data. |
| 19 * | 52 * |
| 20 * It can be shared between other [AnalysisDriver]s. | 53 * It can be shared with other [AnalysisDriver]s. |
| 21 */ | 54 */ |
| 22 final ByteStore _byteStore; | 55 final ByteStore _byteStore; |
| 23 | 56 |
| 24 /** | 57 /** |
| 25 * The [SourceFactory] is used to resolve URIs to paths and restore URIs | 58 * The [SourceFactory] is used to resolve URIs to paths and restore URIs |
| 26 * from file paths. | 59 * from file paths. |
| 27 */ | 60 */ |
| 28 final SourceFactory _sourceFactory; | 61 final SourceFactory _sourceFactory; |
| 29 | 62 |
| 30 /** | 63 /** |
| 31 * This [ContentCache] is consulted for a file content before reading | 64 * This [ContentCache] is consulted for a file content before reading |
| 32 * the content from the file. | 65 * the content from the file. |
| 33 */ | 66 */ |
| 34 final ContentCache _contentCache; | 67 final ContentCache _contentCache; |
| 35 | 68 |
| 36 AnalysisDriver(this._byteStore, this._sourceFactory, this._contentCache); | 69 AnalysisDriver(this._byteStore, this._sourceFactory, this._contentCache); |
| 37 | 70 |
| 38 /** | 71 /** |
| 39 * Set the list of files that the driver should try to analyze sooner. | 72 * Set the list of files that the driver should try to analyze sooner. |
| 40 * | 73 * |
| 41 * Every path in the list must be absolute and normalized. | 74 * Every path in the list must be absolute and normalized. |
| 42 * | 75 * |
| 43 * The driver will produce the results through the [results] stream. The | 76 * The driver will produce the results through the [results] stream. The |
| 44 * exact order in which results are produced is not defined, neither | 77 * exact order in which results are produced is not defined, neither |
| 45 * between priority files, not between them and not priority files. | 78 * between priority files, nor between priority and non-priority files. |
| 46 */ | 79 */ |
| 47 void set priorityFiles(List<String> priorityPaths) { | 80 void set priorityFiles(List<String> priorityPaths) { |
| 48 // TODO(scheglov) implement | 81 // TODO(scheglov) implement |
| 49 } | 82 } |
| 50 | 83 |
| 51 /** | 84 /** |
| 52 * Return the [Stream] that produces [AnalysisResult]s for added files. | 85 * Return the [Stream] that produces [AnalysisResult]s for added files. |
| 53 * | 86 * |
| 54 * Analysis starts when the client starts listening to the stream, and stops | 87 * Analysis starts when the client starts listening to the stream, and stops |
| 55 * when the client cancels the subscription. | 88 * when the client cancels the subscription. |
| 56 * | 89 * |
| 57 * Analysis is eventual, the driver will try to produce results that are at | 90 * When the client starts listening, the analysis state transitions to |
| 58 * some point more consistent with the state of the files, but does not | 91 * "analyzing" and an analysis result is produced for every added file prior |
| 59 * guarantee that this will ever happen. | 92 * to the next time the analysis state transitions to "idle". |
| 93 * | |
| 94 * Invocation of [addFile] or [changeFile] might result in producing more | |
| 95 * analysis results that reflect the new current file state. | |
| 60 * | 96 * |
| 61 * More than one result might be produced for the same file, even if the | 97 * More than one result might be produced for the same file, even if the |
| 62 * client does not change the state of the files. | 98 * client does not change the state of the files. |
| 63 * | 99 * |
| 64 * Results might be produced even for files that have never been added | 100 * Results might be produced even for files that have never been added |
| 65 * using [addFile], for example when [getResult] was called for a file. | 101 * using [addFile], for example when [getResult] was called for a file. |
| 66 */ | 102 */ |
| 67 Stream<AnalysisResult> get results async* { | 103 Stream<AnalysisResult> get results async* { |
| 68 // TODO(scheglov) implement | 104 // TODO(scheglov) implement |
| 69 } | 105 } |
| 70 | 106 |
| 71 /** | 107 /** |
| 72 * Add the file with the given [path] to the set of files to analyze. | 108 * Add the file with the given [path] to the set of files to analyze. |
| 73 * | 109 * |
| 74 * The [path] must be absolute and normalized. | 110 * The [path] must be absolute and normalized. |
| 75 * | 111 * |
| 76 * The results of analysis are eventually produced by the [results] stream. | 112 * The results of analysis are eventually produced by the [results] stream. |
| 77 */ | 113 */ |
| 78 void addFile(String path) { | 114 void addFile(String path) { |
| 79 // TODO(scheglov) implement | 115 // TODO(scheglov) implement |
| 80 } | 116 } |
| 81 | 117 |
| 82 /** | 118 /** |
| 83 * The file with the given [path] might have changed - updated, added or | 119 * The file with the given [path] might have changed - updated, added or |
| 84 * removed. Or not, we don't know. Or it might have, but then changed back. | 120 * removed. Or not, we don't know. Or it might have, but then changed back. |
| 85 * | 121 * |
| 86 * The [path] must be absolute and normalized. | 122 * The [path] must be absolute and normalized. |
| 87 * | 123 * |
| 88 * The driver might use this information to decide that new analysis results | 124 * The [path] can be any file - explicitly or implicitly analyzed, or neither. |
| 89 * should be produced, but does not guarantee this, nor for the given file, | 125 * |
| 90 * nor for any other file. | 126 * Causes the analysis state to transition to "analyzing" (if it is not in |
| 127 * that state already). Schedules the file contents for [path] to be read | |
| 128 * into the current file state prior to the next time the analysis state | |
| 129 * transitions to "idle". | |
| 91 * | 130 * |
| 92 * Invocation of this method will not prevent a [Future] returned from | 131 * Invocation of this method will not prevent a [Future] returned from |
| 93 * [getResult] from completing with a result, and does not guarantee that the | 132 * [getResult] from completing with a result, but the result is not |
| 94 * result will reflect the state of the file at the moment before, at or | 133 * guaranteed to be consistent with the new current file state after this |
| 95 * after the invocation of [changeFile]. | 134 * [changeFile] invocation. |
| 96 */ | 135 */ |
| 97 void changeFile(String path) { | 136 void changeFile(String path) { |
| 98 // TODO(scheglov) implement | 137 // TODO(scheglov) implement |
| 99 } | 138 } |
| 100 | 139 |
| 101 /** | 140 /** |
| 102 * Return the [Future] that completes with a [AnalysisResult] for the file | 141 * Return the [Future] that completes with a [AnalysisResult] for the file |
| 103 * with the given [path]. | 142 * with the given [path]. |
| 104 * | 143 * |
| 105 * The [path] must be absolute and normalized. | 144 * The [path] must be absolute and normalized. |
| 106 * | 145 * |
| 107 * The result is not guaranteed to be produced for the state of the file | 146 * The [path] can be any file - explicitly or implicitly analyzed, or neither. |
| 108 * which is closest to the moment of the invocation. But if the client | 147 * |
| 109 * continues invoking this method, eventually one of the invocations will | 148 * Causes the analysis state to transition to "analyzing" (if it is not in |
|
Brian Wilkerson
2016/10/25 17:34:16
Will it always transition, or is there room here f
scheglov
2016/10/25 18:53:31
As I see getResult(), it always returns the resolv
| |
| 110 * return a [Future] that completes with the result that is closer to the | 149 * that state already), the driver will read the file and produce the analysis |
| 111 * state of the files. | 150 * result for it, which is consistent with the current file state (including |
| 151 * the new state of the file), prior to the next time the analysis state | |
| 152 * transitions to "idle". | |
| 112 */ | 153 */ |
| 113 Future<AnalysisResult> getResult(String path) { | 154 Future<AnalysisResult> getResult(String path) { |
| 114 // TODO(scheglov) implement | 155 // TODO(scheglov) implement |
| 115 throw new UnimplementedError(); | 156 throw new UnimplementedError(); |
| 116 } | 157 } |
| 117 | 158 |
| 118 /** | 159 /** |
| 119 * Remove the file with the given [path] from the list of files to analyze. | 160 * Remove the file with the given [path] from the list of files to analyze. |
| 120 * | 161 * |
| 121 * The [path] must be absolute and normalized. | 162 * The [path] must be absolute and normalized. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 169 final CompilationUnit unit; | 210 final CompilationUnit unit; |
| 170 | 211 |
| 171 /** | 212 /** |
| 172 * The full list of computed analysis errors, both syntactic and semantic. | 213 * The full list of computed analysis errors, both syntactic and semantic. |
| 173 */ | 214 */ |
| 174 final List<AnalysisError> errors; | 215 final List<AnalysisError> errors; |
| 175 | 216 |
| 176 AnalysisResult(this.path, this.uri, this.content, this.contentHash, this.unit, | 217 AnalysisResult(this.path, this.uri, this.content, this.contentHash, this.unit, |
| 177 this.errors); | 218 this.errors); |
| 178 } | 219 } |
| OLD | NEW |