You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: latest/DafnyRef/Plugins.md
+90-13Lines changed: 90 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,18 +6,19 @@ without concern for verifying or compiling the program. Or it might modify the p
6
6
and then continue on with verification and compilation with the core Dafny tool. A user plugin might also be used
7
7
in the Language Server and thereby be available in the VSCode (or other) IDE.
8
8
9
-
_**This is an experimental aspect of Dafny.**
9
+
_**This is an experimental aspect of Dafny.**
10
10
The plugin API directly exposes the Dafny AST, which is constantly evolving.
11
11
Hence, always recompile your plugin against the binary of Dafny that will be importing your plugin._
12
12
13
-
Plugins are libraries linked to a `Dafny.dll` of the same version as the language server.
13
+
Plugins are libraries linked to a `Dafny.dll` of the same version as the Language Server.
14
14
A plugin typically defines:
15
15
16
16
* Zero or one class extending `Microsoft.Dafny.Plugins.PluginConfiguration`, which receives plugins arguments in its method `ParseArguments`, and
17
-
1) Can return a list of `Microsoft.Dafny.Plugins.Rewriter`s when its method `GetRewriters()` is called by Dafny,
18
-
2) Can return a list of `Microsoft.Dafny.Plugins.Compiler`s when its method `GetCompilers()` is called by Dafny,
19
-
3) If the configuration extends the subclass `Microsoft.Dafny.LanguageServer.Plugins.PluginConfiguration`,
20
-
then it can return a list of `Microsoft.Dafny.LanguageServer.Plugins.DafnyCodeActionProvider`s when its method `GetDafnyCodeActionProviders()` is called by the Dafny Language Server.
17
+
1. Can return a list of `Microsoft.Dafny.Plugins.Rewriter`s when its method `GetRewriters()` is called by Dafny,
18
+
2. Can return a list of `Microsoft.Dafny.Plugins.Compiler`s when its method `GetCompilers()` is called by Dafny,
19
+
3. If the configuration extends the subclass `Microsoft.Dafny.LanguageServer.Plugins.PluginConfiguration`:
20
+
1. Can return a list of `Microsoft.Dafny.LanguageServer.Plugins.DafnyCodeActionProvider`s when its method `GetDafnyCodeActionProviders()` is called by the Dafny Language Server.
21
+
2. Can return a modified version of `OmniSharp.Extensions.LanguageServer.Server.LanguageServerOptions` when its method `WithPluginHandlers()` is called by the Dafny Language Server.
21
22
22
23
* Zero or more classes extending `Microsoft.Dafny.Plugins.Rewriter`.
23
24
If a configuration class is provided, it is responsible for instantiating them and returning them in `GetRewriters()`.
@@ -29,6 +30,7 @@ A plugin typically defines:
29
30
Only a configuration class of type `Microsoft.Dafny.LanguageServer.Plugins.PluginConfiguration` can be responsible for instantiating them and returning them in `GetDafnyCodeActionProviders()`.
30
31
31
32
The most important methods of the class `Rewriter` that plugins override are
33
+
32
34
* (experimental) `PreResolve(ModuleDefinition)`: Here you can optionally modify the AST before it is resolved.
33
35
*`PostResolve(ModuleDefinition)`: This method is repeatedly called with every resolved and type-checked module, before verification.
34
36
Plugins override this method typically to report additional diagnostics.
@@ -38,11 +40,12 @@ Plugins are typically used to report additional diagnostics such as unsupported
38
40
39
41
Note that all plugin errors should use the original program's expressions' token and NOT `Token.NoToken`, else no error will be displayed in the IDE.
40
42
41
-
## 15.1. Code actions plugin tutorial
43
+
## 15.1. Language Server plugin tutorial
44
+
45
+
In this section, we will create a plugin that enhances the functionality of the Language Server.
46
+
We will start by showing the steps needed to create a plugin, followed by an example implementation that demonstrates how to provide more code actions and add custom request handlers.
42
47
43
-
In this section, we will create a plugin to provide more code actions to Dafny.
44
-
The code actions will be simple: Add a dummy comment in front of the first method name,
45
-
if the selection is on the line of the method.
48
+
### 15.1.1. Create plugin project
46
49
47
50
Assuming the Dafny source code is installed in the folder `dafny/`
48
51
start by creating an empty folder next to it, e.g. `PluginTutorial/`
@@ -51,22 +54,33 @@ start by creating an empty folder next to it, e.g. `PluginTutorial/`
51
54
mkdir PluginTutorial
52
55
cd PluginTutorial
53
56
```
57
+
54
58
Then, create a dotnet class project
59
+
55
60
```bash
56
61
dotnet new classlib
57
62
```
63
+
58
64
It will create a file `Class1.cs` that you can rename
65
+
59
66
```bash
60
-
mv Class1.cs PluginAddComment.cs
67
+
mv Class1.cs MyPlugin.cs
61
68
```
69
+
62
70
Open the newly created file `PluginTutorial.csproj`, and add the following after `</PropertyGroup>`:
Then, open the file `PluginAddComment.cs`, remove everything, and write the imports and a namespace:
81
+
This code action plugin will add a code action that allows you to place a dummy comment in front of the first method name, only if the selection is on the line of the method.
82
+
83
+
Open the file `MyPlugin.cs`, remove everything, and write the imports and a namespace:
70
84
71
85
```csharp
72
86
usingMicrosoft.Dafny;
@@ -76,18 +90,20 @@ using Microsoft.Dafny.LanguageServer.Language;
@@ -141,14 +160,72 @@ public class CustomDafnyCodeAction: DafnyCodeAction {
141
160
}
142
161
}
143
162
```
163
+
144
164
In that case, we could return:
165
+
145
166
```csharp
146
167
returnnewDafnyCodeAction[] {
147
168
newCustomDafnyCodeAction(firstTokenRange)
148
169
};
149
170
```
150
171
172
+
#### 15.1.2.2. Request handler plugin
173
+
174
+
This request handler plugin enhances the Language Server to support a request with a `TextDocumentIdentifier` as parameter, which will return a `bool` value denoting whether the provided `DocumentUri` has any `LoopStmt`'s in it.
175
+
176
+
Open the file `MyPlugin.cs`, remove everything, and write the imports and a namespace:
0 commit comments