analyzer_plugin: Introduce messages/types for plugin analysis status
There is no code in this CL that _uses_ the new AnalysisStatus
Notification or type, but landing it is important, so that I can test
plugins which will use the analyzer_plugin package from pub.
Change-Id: I31f835d5f7b8bda3781a6962d37f1f769b22852e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/404702
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analyzer_plugin/CHANGELOG.md b/pkg/analyzer_plugin/CHANGELOG.md
index d243c8a..2368dbe 100644
--- a/pkg/analyzer_plugin/CHANGELOG.md
+++ b/pkg/analyzer_plugin/CHANGELOG.md
@@ -2,6 +2,8 @@
- Remove `elementName()` from `RangeFactory`. Use `fragmentName()` instead.
- Breaking changes to `DartFileEditBuilder` and `DartEditBuilder`.
- Breaking changes to `AnalyzerConverter`.
+- Support for a plugin to send an `AnalysisStatus` notification, featuring an
+ `isAnalyzing` `bool` field.
## 0.12.0
- Breaking changes to `DartFileEditBuilder`: `convertFunctionFromSyncToAsync`
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index 6c4271d..d75922d 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -138,6 +138,7 @@
+
<h3>Requests</h3><dl><dt class="request"><a name="request_plugin.versionCheck">plugin.versionCheck</a></dt><dd><div class="box"><pre>request: {
"id": String
"method": "plugin.versionCheck"
@@ -262,6 +263,26 @@
The stack trace associated with the generation of the error, used for
debugging the plugin.
</p>
+ </dd></dl></dd><dt class="notification"><a name="notification_plugin.status">plugin.status</a></dt><dd><div class="box"><pre>notification: {
+ "event": "plugin.status"
+ "params": {
+ "<b>analysis</b>": <span style="color:#999999">optional</span> <a href="#type_AnalysisStatus">AnalysisStatus</a>
+ }
+}</pre></div>
+ <p>
+ Reports the current status of the plugin. Parameters are omitted if there
+ has been no change in the status represented by that parameter.
+ </p>
+ <p>
+ Only used for "new" analyzer plugins. Legacy plugins should not use
+ this type.
+ </p>
+
+ <h4>parameters:</h4><dl><dt class="field"><b>analysis: <a href="#type_AnalysisStatus">AnalysisStatus</a><span style="color:#999999"> (optional)</span></b></dt><dd>
+
+ <p>
+ The current status of analysis (whether analysis is being performed).
+ </p>
</dd></dl></dd></dl>
<h2 class="domain"><a name="domain_analysis">analysis domain</a></h2>
<p>
@@ -844,6 +865,7 @@
+
<dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
<p>
A directive to begin overlaying the contents of a file. The supplied
@@ -957,7 +979,19 @@
related to a specific list of files.
</p>
- <dl><dt class="value">FOLDING</dt><dt class="value">HIGHLIGHTS</dt><dt class="value">NAVIGATION</dt><dt class="value">OCCURRENCES</dt><dt class="value">OUTLINE</dt></dl></dd><dt class="typeDefinition"><a name="type_ChangeContentOverlay">ChangeContentOverlay: object</a></dt><dd>
+ <dl><dt class="value">FOLDING</dt><dt class="value">HIGHLIGHTS</dt><dt class="value">NAVIGATION</dt><dt class="value">OCCURRENCES</dt><dt class="value">OUTLINE</dt></dl></dd><dt class="typeDefinition"><a name="type_AnalysisStatus">AnalysisStatus: object</a></dt><dd>
+ <p>
+ An indication of the current state of analysis.
+ </p>
+ <p>
+ Only used for "new" analyzer plugins. Legacy plugins should not use
+ this type.
+ </p>
+
+ <dl><dt class="field"><b>isAnalyzing: bool</b></dt><dd>
+
+ <p>True if analysis is currently being performed.</p>
+ </dd></dl></dd><dt class="typeDefinition"><a name="type_ChangeContentOverlay">ChangeContentOverlay: object</a></dt><dd>
<p>
A directive to modify an existing file content overlay. One or more ranges
of text are deleted from the old file content overlay and replaced with
@@ -2379,6 +2413,6 @@
</p>
</dd></dl></dd></dl>
<h2 class="domain"><a name="index">Index</a></h2>
-<h3>Domains</h3><h4>plugin (<a href="#domain_plugin">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_plugin.versionCheck">versionCheck</a></li><li><a href="#request_plugin.shutdown">shutdown</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_plugin.error">error</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.handleWatchEvents">handleWatchEvents</a></li><li><a href="#request_analysis.setContextRoots">setContextRoots</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getFixes">getFixes</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextRoot">ContextRoot</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PrioritizedSourceChange">PrioritizedSourceChange</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_WatchEvent">WatchEvent</a></li><li><a href="#type_WatchEventType">WatchEventType</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+<h3>Domains</h3><h4>plugin (<a href="#domain_plugin">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_plugin.versionCheck">versionCheck</a></li><li><a href="#request_plugin.shutdown">shutdown</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_plugin.error">error</a></li><li><a href="#notification_plugin.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.handleWatchEvents">handleWatchEvents</a></li><li><a href="#request_analysis.setContextRoots">setContextRoots</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getFixes">getFixes</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextRoot">ContextRoot</a></li><li><a href="#type_DiagnosticMessage">DiagnosticMessage</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PrioritizedSourceChange">PrioritizedSourceChange</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_WatchEvent">WatchEvent</a></li><li><a href="#type_WatchEventType">WatchEventType</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
</body>
</html>
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_constants.dart b/pkg/analyzer_plugin/lib/protocol/protocol_constants.dart
index 51857ecf..f6ab4f8 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_constants.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_constants.dart
@@ -84,6 +84,8 @@
const String PLUGIN_NOTIFICATION_ERROR_IS_FATAL = 'isFatal';
const String PLUGIN_NOTIFICATION_ERROR_MESSAGE = 'message';
const String PLUGIN_NOTIFICATION_ERROR_STACK_TRACE = 'stackTrace';
+const String PLUGIN_NOTIFICATION_STATUS = 'plugin.status';
+const String PLUGIN_NOTIFICATION_STATUS_ANALYSIS = 'analysis';
const String PLUGIN_REQUEST_SHUTDOWN = 'plugin.shutdown';
const String PLUGIN_REQUEST_VERSION_CHECK = 'plugin.versionCheck';
const String PLUGIN_REQUEST_VERSION_CHECK_BYTE_STORE_PATH = 'byteStorePath';
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
index aa3e59b..4534c27 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_generated.dart
@@ -1337,6 +1337,59 @@
int get hashCode => 218088493;
}
+/// AnalysisStatus
+///
+/// {
+/// "isAnalyzing": bool
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class AnalysisStatus implements HasToJson {
+ /// True if analysis is currently being performed.
+ bool isAnalyzing;
+
+ AnalysisStatus(this.isAnalyzing);
+
+ factory AnalysisStatus.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object? json,
+ {ClientUriConverter? clientUriConverter}) {
+ json ??= {};
+ if (json is Map) {
+ bool isAnalyzing;
+ if (json.containsKey('isAnalyzing')) {
+ isAnalyzing = jsonDecoder.decodeBool(
+ '$jsonPath.isAnalyzing', json['isAnalyzing']);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'isAnalyzing');
+ }
+ return AnalysisStatus(isAnalyzing);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'AnalysisStatus', json);
+ }
+ }
+
+ @override
+ Map<String, Object> toJson({ClientUriConverter? clientUriConverter}) {
+ var result = <String, Object>{};
+ result['isAnalyzing'] = isAnalyzing;
+ return result;
+ }
+
+ @override
+ String toString() => json.encode(toJson(clientUriConverter: null));
+
+ @override
+ bool operator ==(other) {
+ if (other is AnalysisStatus) {
+ return isAnalyzing == other.isAnalyzing;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode => isAnalyzing.hashCode;
+}
+
/// analysis.updateContent params
///
/// {
@@ -3623,6 +3676,74 @@
int get hashCode => 9389109;
}
+/// plugin.status params
+///
+/// {
+/// "analysis": optional AnalysisStatus
+/// }
+///
+/// Clients may not extend, implement or mix-in this class.
+class PluginStatusParams implements HasToJson {
+ /// The current status of analysis (whether analysis is being performed).
+ AnalysisStatus? analysis;
+
+ PluginStatusParams({this.analysis});
+
+ factory PluginStatusParams.fromJson(
+ JsonDecoder jsonDecoder, String jsonPath, Object? json,
+ {ClientUriConverter? clientUriConverter}) {
+ json ??= {};
+ if (json is Map) {
+ AnalysisStatus? analysis;
+ if (json.containsKey('analysis')) {
+ analysis = AnalysisStatus.fromJson(
+ jsonDecoder, '$jsonPath.analysis', json['analysis'],
+ clientUriConverter: clientUriConverter);
+ }
+ return PluginStatusParams(analysis: analysis);
+ } else {
+ throw jsonDecoder.mismatch(jsonPath, 'plugin.status params', json);
+ }
+ }
+
+ factory PluginStatusParams.fromNotification(Notification notification,
+ {ClientUriConverter? clientUriConverter}) {
+ return PluginStatusParams.fromJson(
+ ResponseDecoder(null), 'params', notification.params,
+ clientUriConverter: clientUriConverter);
+ }
+
+ @override
+ Map<String, Object> toJson({ClientUriConverter? clientUriConverter}) {
+ var result = <String, Object>{};
+ var analysis = this.analysis;
+ if (analysis != null) {
+ result['analysis'] =
+ analysis.toJson(clientUriConverter: clientUriConverter);
+ }
+ return result;
+ }
+
+ Notification toNotification({ClientUriConverter? clientUriConverter}) {
+ return Notification(
+ 'plugin.status', toJson(clientUriConverter: clientUriConverter));
+ }
+
+ @override
+ String toString() => json.encode(toJson(clientUriConverter: null));
+
+ @override
+ bool operator ==(other) {
+ if (other is PluginStatusParams) {
+ return analysis == other.analysis;
+ }
+ return false;
+ }
+
+ @override
+ int get hashCode => analysis.hashCode;
+}
+
/// plugin.versionCheck params
///
/// {
diff --git a/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart b/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart
index a8348e8..5189e4e 100644
--- a/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart
+++ b/pkg/analyzer_plugin/test/integration/support/integration_test_methods.dart
@@ -119,6 +119,22 @@
/// Stream controller for [onPluginError].
late StreamController<PluginErrorParams> _onPluginError;
+ /// Reports the current status of the plugin. Parameters are omitted if there
+ /// has been no change in the status represented by that parameter.
+ ///
+ /// Only used for "new" analyzer plugins. Legacy plugins should not use this
+ /// type.
+ ///
+ /// Parameters
+ ///
+ /// analysis: AnalysisStatus (optional)
+ ///
+ /// The current status of analysis (whether analysis is being performed).
+ late Stream<PluginStatusParams> onPluginStatus;
+
+ /// Stream controller for [onPluginStatus].
+ late StreamController<PluginStatusParams> _onPluginStatus;
+
/// Return the navigation information associated with the given region of the
/// given file. If the navigation information for the given file has not yet
/// been computed, or the most recently computed navigation information for
@@ -661,6 +677,8 @@
void initializeInttestMixin() {
_onPluginError = StreamController<PluginErrorParams>(sync: true);
onPluginError = _onPluginError.stream.asBroadcastStream();
+ _onPluginStatus = StreamController<PluginStatusParams>(sync: true);
+ onPluginStatus = _onPluginStatus.stream.asBroadcastStream();
_onAnalysisErrors = StreamController<AnalysisErrorsParams>(sync: true);
onAnalysisErrors = _onAnalysisErrors.stream.asBroadcastStream();
_onAnalysisFolding = StreamController<AnalysisFoldingParams>(sync: true);
@@ -688,6 +706,11 @@
_onPluginError
.add(PluginErrorParams.fromJson(decoder, 'params', params));
break;
+ case 'plugin.status':
+ outOfTestExpect(params, isPluginStatusParams);
+ _onPluginStatus
+ .add(PluginStatusParams.fromJson(decoder, 'params', params));
+ break;
case 'analysis.errors':
outOfTestExpect(params, isAnalysisErrorsParams);
_onAnalysisErrors
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index b6775a8..efbc056 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -106,6 +106,14 @@
final Matcher isAnalysisService = MatchesEnum('AnalysisService',
['FOLDING', 'HIGHLIGHTS', 'NAVIGATION', 'OCCURRENCES', 'OUTLINE']);
+/// AnalysisStatus
+///
+/// {
+/// "isAnalyzing": bool
+/// }
+final Matcher isAnalysisStatus = LazyMatcher(
+ () => MatchesJsonObject('AnalysisStatus', {'isAnalyzing': isBool}));
+
/// ChangeContentOverlay
///
/// {
@@ -1324,6 +1332,15 @@
/// plugin.shutdown result
final Matcher isPluginShutdownResult = isNull;
+/// plugin.status params
+///
+/// {
+/// "analysis": optional AnalysisStatus
+/// }
+final Matcher isPluginStatusParams = LazyMatcher(() => MatchesJsonObject(
+ 'plugin.status params', null,
+ optionalFields: {'analysis': isAnalysisStatus}));
+
/// plugin.versionCheck params
///
/// {
diff --git a/pkg/analyzer_plugin/tool/spec/plugin_spec.html b/pkg/analyzer_plugin/tool/spec/plugin_spec.html
index 9984810..f5eb7f6 100644
--- a/pkg/analyzer_plugin/tool/spec/plugin_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/plugin_spec.html
@@ -144,6 +144,24 @@
</field>
</params>
</notification>
+ <notification event="status">
+ <p>
+ Reports the current status of the plugin. Parameters are omitted if there
+ has been no change in the status represented by that parameter.
+ </p>
+ <p>
+ Only used for "new" analyzer plugins. Legacy plugins should not use
+ this type.
+ </p>
+ <params>
+ <field name="analysis" optional="true">
+ <ref>AnalysisStatus</ref>
+ <p>
+ The current status of analysis (whether analysis is being performed).
+ </p>
+ </field>
+ </params>
+ </notification>
</domain>
<domain name="analysis">
<p>
@@ -873,6 +891,28 @@
<value><code>OUTLINE</code></value>
</enum>
</type>
+ <type name="AnalysisStatus">
+ <p>
+ An indication of the current state of analysis.
+ </p>
+ <p>
+ Only used for "new" analyzer plugins. Legacy plugins should not use
+ this type.
+ </p>
+ <object>
+ <field name="isAnalyzing">
+ <ref>bool</ref>
+ <p>True if analysis is currently being performed.</p>
+ </field>
+ <!--<field name="analysisTarget" optional="true">
+ <ref>String</ref>
+ <p>
+ The name of the current target of analysis. This field is
+ omitted if analyzing is false.
+ </p>
+ </field>-->
+ </object>
+ </type>
<type name="ContextRoot">
<p>
A description of an analysis context.