-
Notifications
You must be signed in to change notification settings - Fork 234
/
Copy pathWorkspaceSymbolsHandler.cs
103 lines (85 loc) · 4.16 KB
/
WorkspaceSymbolsHandler.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.PowerShell.EditorServices.Services;
using Microsoft.PowerShell.EditorServices.Services.Symbols;
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Client.Capabilities;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Workspace;
namespace Microsoft.PowerShell.EditorServices.Handlers
{
internal class PsesWorkspaceSymbolsHandler : WorkspaceSymbolsHandlerBase
{
private readonly ILogger _logger;
private readonly SymbolsService _symbolsService;
private readonly WorkspaceService _workspaceService;
public PsesWorkspaceSymbolsHandler(ILoggerFactory loggerFactory, SymbolsService symbols, WorkspaceService workspace)
{
_logger = loggerFactory.CreateLogger<PsesWorkspaceSymbolsHandler>();
_symbolsService = symbols;
_workspaceService = workspace;
}
protected override WorkspaceSymbolRegistrationOptions CreateRegistrationOptions(WorkspaceSymbolCapability capability, ClientCapabilities clientCapabilities) => new() { };
public override async Task<Container<SymbolInformation>> Handle(WorkspaceSymbolParams request, CancellationToken cancellationToken)
{
await _symbolsService.ScanWorkspacePSFiles(cancellationToken).ConfigureAwait(false);
List<SymbolInformation> symbols = new();
foreach (ScriptFile scriptFile in _workspaceService.GetOpenedFiles())
{
_logger.LogDebug($"Handling workspace symbols request for: {request.Query}");
IEnumerable<SymbolReference> foundSymbols = _symbolsService.FindSymbolsInFile(scriptFile);
// TODO: Need to compute a relative path that is based on common path for all workspace files
string containerName = Path.GetFileNameWithoutExtension(scriptFile.FilePath);
foreach (SymbolReference symbol in foundSymbols)
{
// This async method is pretty dense with synchronous code
// so it's helpful to add some yields.
await Task.Yield();
cancellationToken.ThrowIfCancellationRequested();
if (!symbol.IsDeclaration)
{
continue;
}
if (symbol.Type is SymbolType.Parameter)
{
continue;
}
if (!IsQueryMatch(request.Query, symbol.Name))
{
continue;
}
// Exclude Pester setup/teardown symbols as they're unnamed
if (symbol is PesterSymbolReference pesterSymbol &&
!PesterSymbolReference.IsPesterTestCommand(pesterSymbol.Command))
{
continue;
}
Location location = new()
{
Uri = DocumentUri.From(symbol.FilePath),
Range = symbol.NameRegion.ToRange()
};
// TODO: This should be a WorkplaceSymbol now as SymbolInformation is deprecated.
symbols.Add(new SymbolInformation
{
ContainerName = containerName,
Kind = SymbolTypeUtils.GetSymbolKind(symbol.Type),
Location = location,
Name = symbol.Name
});
}
}
return new Container<SymbolInformation>(symbols);
}
#region private Methods
private static bool IsQueryMatch(string query, string symbolName) => symbolName.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0;
#endregion
}
}