@@ -57,6 +57,7 @@ base mixin DartAnalyzerSupport on ToolsSupport, LoggingSupport {
57
57
unsupportedReason ?? = await _initializeAnalyzerLspServer ();
58
58
if (unsupportedReason == null ) {
59
59
registerTool (analyzeFilesTool, _analyzeFiles);
60
+ registerTool (resolveWorkspaceSymbolTool, _resolveWorkspaceSymbol);
60
61
}
61
62
62
63
// Don't call any methods on the client until we are fully initialized
@@ -129,6 +130,39 @@ base mixin DartAnalyzerSupport on ToolsSupport, LoggingSupport {
129
130
diagnostics: lsp.DiagnosticWorkspaceClientCapabilities (
130
131
refreshSupport: true ,
131
132
),
133
+ symbol: lsp.WorkspaceSymbolClientCapabilities (
134
+ symbolKind:
135
+ lsp.WorkspaceSymbolClientCapabilitiesSymbolKind (
136
+ valueSet: [
137
+ lsp.SymbolKind .Array ,
138
+ lsp.SymbolKind .Boolean ,
139
+ lsp.SymbolKind .Class ,
140
+ lsp.SymbolKind .Constant ,
141
+ lsp.SymbolKind .Constructor ,
142
+ lsp.SymbolKind .Enum ,
143
+ lsp.SymbolKind .EnumMember ,
144
+ lsp.SymbolKind .Event ,
145
+ lsp.SymbolKind .Field ,
146
+ lsp.SymbolKind .File ,
147
+ lsp.SymbolKind .Function ,
148
+ lsp.SymbolKind .Interface ,
149
+ lsp.SymbolKind .Key ,
150
+ lsp.SymbolKind .Method ,
151
+ lsp.SymbolKind .Module ,
152
+ lsp.SymbolKind .Namespace ,
153
+ lsp.SymbolKind .Null ,
154
+ lsp.SymbolKind .Number ,
155
+ lsp.SymbolKind .Obj ,
156
+ lsp.SymbolKind .Operator ,
157
+ lsp.SymbolKind .Package ,
158
+ lsp.SymbolKind .Property ,
159
+ lsp.SymbolKind .Str ,
160
+ lsp.SymbolKind .Struct ,
161
+ lsp.SymbolKind .TypeParameter ,
162
+ lsp.SymbolKind .Variable ,
163
+ ],
164
+ ),
165
+ ),
132
166
),
133
167
textDocument: lsp.TextDocumentClientCapabilities (
134
168
publishDiagnostics:
@@ -148,16 +182,31 @@ base mixin DartAnalyzerSupport on ToolsSupport, LoggingSupport {
148
182
}
149
183
150
184
if (initializeResult != null ) {
185
+ // Checks that we can set workspaces on the LSP server.
151
186
final workspaceSupport =
152
187
initializeResult.capabilities.workspace? .workspaceFolders;
153
188
if (workspaceSupport? .supported != true ) {
154
189
error ?? = 'Workspaces are not supported by the LSP server' ;
155
- }
156
- if (workspaceSupport ? .changeNotifications ? . valueEquals ( true ) != true ) {
190
+ } else if (workspaceSupport ? .changeNotifications ? . valueEquals ( true ) !=
191
+ true ) {
157
192
error ?? =
158
193
'Workspace change notifications are not supported by the LSP '
159
194
'server' ;
160
195
}
196
+
197
+ // Checks that we resolve workspace symbols.
198
+ final workspaceSymbolProvider =
199
+ initializeResult.capabilities.workspaceSymbolProvider;
200
+ final symbolProvidersSupported =
201
+ workspaceSymbolProvider != null &&
202
+ workspaceSymbolProvider.map (
203
+ (b) => b,
204
+ (options) => options.resolveProvider == true ,
205
+ );
206
+ if (! symbolProvidersSupported) {
207
+ error ?? =
208
+ 'Workspace symbol resolution is not supported by the LSP server' ;
209
+ }
161
210
}
162
211
163
212
if (error != null ) {
@@ -199,6 +248,20 @@ base mixin DartAnalyzerSupport on ToolsSupport, LoggingSupport {
199
248
return CallToolResult (content: messages);
200
249
}
201
250
251
+ /// Implementation of the [resolveWorkspaceSymbolTool] , resolves a given
252
+ /// symbol or symbols in a workspace.
253
+ Future <CallToolResult > _resolveWorkspaceSymbol (
254
+ CallToolRequest request,
255
+ ) async {
256
+ await _doneAnalyzing? .future;
257
+ final query = request.arguments! ['query' ] as String ;
258
+ final result = await _lspConnection.sendRequest (
259
+ lsp.Method .workspace_symbol.toString (),
260
+ lsp.WorkspaceSymbolParams (query: query).toJson (),
261
+ );
262
+ return CallToolResult (content: [TextContent (text: jsonEncode (result))]);
263
+ }
264
+
202
265
/// Handles `$/analyzerStatus` events, which tell us when analysis starts and
203
266
/// stops.
204
267
void _handleAnalyzerStatus (Parameters params) {
@@ -268,7 +331,25 @@ base mixin DartAnalyzerSupport on ToolsSupport, LoggingSupport {
268
331
static final analyzeFilesTool = Tool (
269
332
name: 'analyze_files' ,
270
333
description: 'Analyzes the entire project for errors.' ,
271
- inputSchema: ObjectSchema (),
334
+ inputSchema: Schema .object (),
335
+ );
336
+
337
+ @visibleForTesting
338
+ static final resolveWorkspaceSymbolTool = Tool (
339
+ name: 'resolve_workspace_symbol' ,
340
+ description: 'Look up a symbol or symbols in all workspaces by name.' ,
341
+ inputSchema: Schema .object (
342
+ properties: {
343
+ 'query' : Schema .string (
344
+ description:
345
+ 'Queries are matched based on a case-insensitive partial name '
346
+ 'match, and do not support complex pattern matching, regexes, '
347
+ 'or scoped lookups.' ,
348
+ ),
349
+ },
350
+ required : ['query' ],
351
+ ),
352
+ annotations: ToolAnnotations (title: 'Project search' , readOnlyHint: true ),
272
353
);
273
354
}
274
355
0 commit comments