OLD | NEW |
---|---|
(Empty) | |
1 # Introduction | |
2 | |
3 The purpose of this page is to give you an overview of what an analyzer plugin | |
4 is and what it can do. | |
5 | |
6 ## What is a plugin? | |
7 | |
8 An analyzer plugin is a piece of code that communicates with the analysis server | |
9 to provide additional analysis support. The additional support is often specific | |
10 to a package or set of packages. For example, there is a plugin that provides | |
11 analysis specific to the Angular framework. Plugins are not required to be | |
12 specific to a package, but if the additional analysis is general enough, we | |
13 would urge you to consider contributing it back to the Dart project so that | |
14 everyone can more easily benefit from your work. | |
15 | |
16 Plugins are written in Dart. They are executed by the analysis server by running | |
17 them in the same VM as the analysis server but each plugin is run in a separate | |
devoncarew
2017/08/01 22:19:16
analysis server, but
Brian Wilkerson
2017/08/02 14:45:16
Done
| |
18 isolate. The analysis server communicates with the plugins using a wire protocol | |
19 that is specified in the [plugin API][pluginapi] document. This API is similar | |
20 to the API used by the analysis server to communicate with clients. | |
21 | |
22 The API consists of three kinds of communication. When the analysis server needs | |
23 information from the plugin, or needs to pass information to the plugin, it | |
24 sends a *request*. The plugin is required to answer every request with a | |
25 *response*. If the request was a request for information, then the response will | |
26 contain the requested information. Otherwise, the response is merely an | |
27 acknowledgement that the request was received. In addition, the plugin can send | |
28 a *notification* to the server to provide information to the server. | |
29 | |
30 ## What can plugins do? | |
31 | |
32 The scope of what a plugin can do is defined by the [plugin API][pluginapi], but | |
33 it's useful to start with a high level overview. | |
34 | |
35 ### Lifecycle management | |
36 | |
37 The API includes support for managing the lifecycle of a plugin. There is no | |
38 guarantee about when plugins will be started or stopped relative to either the | |
39 server or to each other. | |
40 | |
41 When a plugin is first started, the analysis server will send a | |
42 `plugin.versionCheck` request to the plugin to verify that the plugin is using | |
43 the same version of the API as the server and therefore can communicate with the | |
44 server. This exchange also serves to communicate some other information between | |
45 the two participants. | |
46 | |
47 When the server is asked to shut down, it will send a `plugin.shutdown` request | |
48 to the plugin to shut it down. This gives the plugin an opportunity to release | |
49 system resources or perform any other necessary actions. If a plugin encounters | |
50 an error that causes it to need to shut down, it should send a `plugin.error` | |
51 notification to the server to indicate that it is doing so. | |
52 | |
53 ### Managing analysis | |
54 | |
55 The API includes support for managing which files are analyzed. There is no | |
56 requirement for when a plugin should perform the analysis, but to optimize the | |
57 user experience plugins should provide information to the server as quickly as | |
58 possible. | |
59 | |
60 The analysis server sends an `analysis.setContextRoots` request to plugins to | |
61 tell them which files to analyze. Each `ContextRoot` indicates the root | |
62 directory containing the files to be analyzed (included) and any files and | |
63 directories within the root that should *not* be analyzed (excluded). Plugins | |
64 can read and use excluded files in the process of analyzing included files, but | |
65 should not report results for excluded files. | |
66 | |
67 In order to improve the user experience, the analysis server will send an | |
68 `analysis.setPriorityFiles` request to specify which files should take priority | |
69 over other files. These are typically the files that are open and visible in the | |
70 client. | |
71 | |
72 The analysis server will send an `analysis.handleWatchEvents` request to the | |
73 plugin when one or more files (within a context root) have been modified. The | |
74 plugin is expected to re-analyze those files in order to update the results for | |
75 those files. | |
76 | |
77 The analysis server will send an `analysis.updateContent` request when the user | |
78 has edited a file but the edited content has not yet been written to disk. This | |
79 allows the plugin to provide analysis results as the user is typing. | |
80 | |
81 ### Requesting Analysis Results | |
82 | |
83 In order to accommodate the workflow of clients, there are two ways for the | |
84 server to request analysis results from a plugin. | |
85 | |
86 First, the server can send a request to request specific results for a specific | |
87 file. This is typically used for client-side functionality that the user has to | |
88 explicitly request and that clients will not retain long term. For example, | |
89 there is a request to get code completion suggestions. These requests are | |
90 discussed below. | |
91 | |
92 For functionality that is always available, or for results that can change | |
93 without the client being aware that new data should be requested, there is a | |
94 subscription model. The server will send an `analysis.setSubscriptions` request | |
95 to the plugin. This request tells the plugin which results should be sent to the | |
96 server when the results become available. The plugin does not send any results | |
97 in the response to the request, but instead is expected to send a notification | |
98 to the server when the results have been computed. The notifications that can be | |
99 requested are also discussed below. | |
100 | |
101 If the server has explicitly requested results, either by a request or by a | |
102 subscription, the plugin should provide those results even if the file is an | |
103 excluded file. This exception to the general rule does *not* apply to the | |
104 implicit subscription for diagnostics. | |
105 | |
106 Plugins should *not* send analysis results that duplicate the information | |
107 computed by the analysis server itself. The expectation is for plugins to | |
108 extend this information, not replicate it. | |
109 | |
110 ### Diagnostics | |
111 | |
112 Plugins can generate diagnostics to make users aware of problems in the code | |
113 that they have written. Diagnostics are typically displayed in the editor region | |
114 and might also be displayed in a separate diagnostics view or as decorations on | |
115 a directory structure view. | |
116 | |
117 Plugins are expected to send any diagnostics that they generate for any of the | |
118 analyzed files (files that are included in a context root and not excluded). | |
119 Essentially, there is an implicit subscription for errors for all (non-excluded) | |
120 files. The plugin should send the errors in an `analysis.errors` notification. | |
121 | |
122 ### Semantic highlighting | |
123 | |
124 Highlight information is used to color the content of the editor view. | |
125 | |
126 If the server has subscribed for highlighting information in some set of files, | |
127 then the plugin should send the information in an `analysis.highlights` | |
128 notification whenever the information needs to be updated. | |
129 | |
130 ### Navigation | |
131 | |
132 Navigation information is used by clients to allow users to navigate to the | |
133 location at which an identifier is defined. | |
134 | |
135 Navigation information can be requested both by an `analysis.getNavigation` | |
136 request and by a subscription. If the server has subscribed for navigation | |
137 information in some set of files, the the plugin should send the information in | |
138 an `analysis.navigation` notification whenever the information needs to be | |
139 updated. | |
140 | |
141 There is a tutorial explaining how to implement [navigation][navigation]. | |
142 | |
143 ### Mark occurrences | |
144 | |
145 Occurrences information is used by clients to highlight (or mark) all uses | |
146 within a given file of a single identifier when the user selects one use of that | |
147 identifier. | |
148 | |
149 If the server has subscribed for occurrences information in some set of files, | |
150 then the plugin should send the information in an `analysis.occurrences` | |
151 notification whenever the information needs to be updated. | |
152 | |
153 ### Outline | |
154 | |
155 Outline information is typically used by clients to provide a tree indicating | |
156 the nesting structure of declarations within the code. | |
157 | |
158 If the server has subscribed for outline information in some set of files, then | |
159 the plugin should send the information in an `analysis.outline` notification | |
160 whenever the information needs to be updated. | |
161 | |
162 ### Folding | |
163 | |
164 Folding information is used to allow users to collapse regions of text. | |
165 | |
166 If the server has subscribed for folding information in some set of files, then | |
167 the plugin should send the information in an `analysis.folding` notification | |
168 whenever the information needs to be updated. | |
169 | |
170 ### Code completion | |
171 | |
172 Code completion suggestions are used to provide possible completions at some | |
173 point in the text. | |
174 | |
175 When the client request completion suggestions, the server will send a | |
176 `completion.getSuggestions` request. The plugin should only send suggestions | |
177 that would not also be returned by the server. | |
178 | |
179 There is a tutorial explaining how to implement [code completion][completion]. | |
180 | |
181 ### Fixes and assists | |
182 | |
183 Fixes and assists are a set of edits that users can choose to have applied to | |
184 the code. They differ from a refactoring in that they cannot request additional | |
185 information from the user. For example, a rename refactoring needs to know the | |
186 new name, which requires prompting the user, and hence could not be implemented | |
187 as either a fix or an assist. | |
188 | |
189 Fixes are associated with specific diagnostics, and hence should only be | |
190 generated if the diagnostics with which they are associated have been generated. | |
191 For example, if a diagnostic has been produced to indicate that a required | |
192 semicolon is missing, a fix might be generated to insert a semicolon. | |
193 | |
194 The analysis server will request fixes by sending an `edit.getFixes` request. | |
195 | |
196 Plugins should provide fixes for as many of the diagnostics they generate as | |
197 possible, but only when those fixes provide value to the user. (For example, a | |
198 fix to insert a semicolon is arguably harder to use than simply typing the | |
199 semicolon would be, and therefore is of questionable value.) | |
200 | |
201 There is a tutorial explaining how to implement [fixes][fixes]. | |
202 | |
203 Assists are generally context-specific and hence should only be generated if the | |
204 cursor is in the right context. For example, if there is an assist to convert an | |
205 expression-style function body (one introduced by `=>`) into a block-style | |
206 function body, it should only be generated if the cursor is within an | |
207 expression-style function body. | |
208 | |
209 The analysis server will request assists by sending an `edit.getAssists` | |
210 request. | |
211 | |
212 There is a tutorial explaining how to implement [assists][assists]. | |
213 | |
214 [assists]: assists.md | |
215 [completion]: completion.md | |
216 [fixes]: fixes.md | |
217 [navigation]: navigation.md | |
218 [pluginapi]: https://htmlpreview.github.io/?https://github.com/dart-lang/sdk/blo b/master/pkg/analyzer_plugin/doc/api.html | |
OLD | NEW |