Skip to content

Commit 6b093da

Browse files
committed
Clean up some IEnumerables
It's so sad we can't use `IAsyncEnumerable`.
1 parent cee7033 commit 6b093da

File tree

5 files changed

+63
-85
lines changed

5 files changed

+63
-85
lines changed

src/PowerShellEditorServices/Services/CodeLens/ReferencesCodeLensProvider.cs

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
using System;
54
using System.Collections.Generic;
65
using System.Text;
76
using System.Threading;
@@ -21,8 +20,6 @@ namespace Microsoft.PowerShell.EditorServices.CodeLenses
2120
/// </summary>
2221
internal class ReferencesCodeLensProvider : ICodeLensProvider
2322
{
24-
private static readonly Location[] s_emptyLocationArray = Array.Empty<Location>();
25-
2623
/// <summary>
2724
/// The document symbol provider to supply symbols to generate the code lenses.
2825
/// </summary>
@@ -102,49 +99,33 @@ public async Task<CodeLens> ResolveCodeLens(
10299
codeLens.Range.Start.Line + 1,
103100
codeLens.Range.Start.Character + 1);
104101

105-
IEnumerable<SymbolReference> referencesResult =
106-
await _symbolsService.ScanForReferencesOfSymbolAsync(
107-
foundSymbol, cancellationToken).ConfigureAwait(false);
108-
109-
Location[] referenceLocations;
110-
if (referencesResult == null)
111-
{
112-
referenceLocations = s_emptyLocationArray;
113-
}
114-
else
102+
List<Location> acc = new();
103+
foreach (SymbolReference foundReference in await _symbolsService.ScanForReferencesOfSymbolAsync(
104+
foundSymbol, cancellationToken).ConfigureAwait(false))
115105
{
116-
List<Location> acc = new();
117-
foreach (SymbolReference foundReference in referencesResult)
106+
// We only show lenses on declarations, so we exclude those from the references.
107+
if (foundReference.IsDeclaration)
118108
{
119-
// This async method is pretty dense with synchronous code
120-
// so it's helpful to add some yields.
121-
await Task.Yield();
122-
cancellationToken.ThrowIfCancellationRequested();
123-
124-
// We only show lenses on declarations, so we exclude those from the references.
125-
if (foundReference.IsDeclaration)
126-
{
127-
continue;
128-
}
129-
130-
DocumentUri uri = DocumentUri.From(foundReference.FilePath);
131-
// For any vscode-notebook-cell, we need to ignore the backing file on disk.
132-
if (uri.Scheme == "file" &&
133-
scriptFile.DocumentUri.Scheme == "vscode-notebook-cell" &&
134-
uri.Path == scriptFile.DocumentUri.Path)
135-
{
136-
continue;
137-
}
109+
continue;
110+
}
138111

139-
acc.Add(new Location
140-
{
141-
Uri = uri,
142-
Range = foundReference.NameRegion.ToRange()
143-
});
112+
DocumentUri uri = DocumentUri.From(foundReference.FilePath);
113+
// For any vscode-notebook-cell, we need to ignore the backing file on disk.
114+
if (uri.Scheme == "file" &&
115+
scriptFile.DocumentUri.Scheme == "vscode-notebook-cell" &&
116+
uri.Path == scriptFile.DocumentUri.Path)
117+
{
118+
continue;
144119
}
145-
referenceLocations = acc.ToArray();
120+
121+
acc.Add(new Location
122+
{
123+
Uri = uri,
124+
Range = foundReference.NameRegion.ToRange()
125+
});
146126
}
147127

128+
Location[] referenceLocations = acc.ToArray();
148129
return new CodeLens
149130
{
150131
Data = codeLens.Data,

src/PowerShellEditorServices/Services/Symbols/SymbolsService.cs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,13 @@ public IEnumerable<SymbolReference> FindSymbolsInFile(ScriptFile scriptFile)
114114
{
115115
Validate.IsNotNull(nameof(scriptFile), scriptFile);
116116

117-
List<SymbolReference> symbols = new();
118117
foreach (IDocumentSymbolProvider symbolProvider in GetDocumentSymbolProviders())
119118
{
120-
// TODO: Each provider needs to set the source line and filepath.
121-
symbols.AddRange(symbolProvider.ProvideDocumentSymbols(scriptFile));
119+
foreach (SymbolReference symbol in symbolProvider.ProvideDocumentSymbols(scriptFile))
120+
{
121+
yield return symbol;
122+
}
122123
}
123-
124-
return symbols;
125124
}
126125

127126
/// <summary>
@@ -155,15 +154,15 @@ private static string[] GetIdentifiers(string symbolName, SymbolType symbolType,
155154

156155
/// <summary>
157156
/// Finds all the references of a symbol in the workspace, resolving aliases.
158-
/// TODO: Make it not return a nullable.
157+
/// TODO: One day use IAsyncEnumerable.
159158
/// </summary>
160-
public async Task<IEnumerable<SymbolReference>?> ScanForReferencesOfSymbolAsync(
159+
public async Task<IEnumerable<SymbolReference>> ScanForReferencesOfSymbolAsync(
161160
SymbolReference symbol,
162161
CancellationToken cancellationToken = default)
163162
{
164163
if (symbol is null)
165164
{
166-
return null;
165+
return Enumerable.Empty<SymbolReference>();
167166
}
168167

169168
// TODO: Should we handle aliases at a lower level?
@@ -181,7 +180,6 @@ private static string[] GetIdentifiers(string symbolName, SymbolType symbolType,
181180
await ScanWorkspacePSFiles(cancellationToken).ConfigureAwait(false);
182181

183182
List<SymbolReference> symbols = new();
184-
185183
string[] allIdentifiers = GetIdentifiers(targetName, symbol.SymbolType, aliases);
186184

187185
foreach (ScriptFile file in _workspaceService.GetOpenedFiles())
@@ -191,7 +189,8 @@ private static string[] GetIdentifiers(string symbolName, SymbolType symbolType,
191189
await Task.Yield();
192190
cancellationToken.ThrowIfCancellationRequested();
193191

194-
if (!file.References.TryGetReferences(targetIdentifier, out ConcurrentBag<SymbolReference>? references))
192+
_ = file.References.TryGetReferences(targetIdentifier, out ConcurrentBag<SymbolReference>? references);
193+
if (references is null)
195194
{
196195
continue;
197196
}
@@ -301,33 +300,45 @@ await CommandHelpers.GetCommandInfoAsync(
301300

302301
/// <summary>
303302
/// Finds the possible definitions of the symbol in the file or workspace.
303+
/// TODO: One day use IAsyncEnumerable.
304+
/// TODO: Fix searching for definition of built-in commands.
305+
/// TODO: Fix "definition" of dot-source (maybe?)
304306
/// </summary>
305307
public async Task<IEnumerable<SymbolReference>> GetDefinitionOfSymbolAsync(
306308
ScriptFile scriptFile,
307309
SymbolReference symbol,
308310
CancellationToken cancellationToken = default)
309311
{
310-
if (scriptFile.References.TryGetReferences(symbol.SymbolName, out ConcurrentBag<SymbolReference>? symbols))
312+
List<SymbolReference> declarations = new();
313+
_ = scriptFile.References.TryGetReferences(symbol.SymbolName, out ConcurrentBag<SymbolReference>? symbols);
314+
if (symbols is not null)
311315
{
312-
IEnumerable<SymbolReference> possibleLocalDeclarations = symbols.Where((i) => i.IsDeclaration);
313-
if (possibleLocalDeclarations.Any())
316+
foreach (SymbolReference foundReference in symbols)
314317
{
315-
_logger.LogDebug($"Found possible declarations ${possibleLocalDeclarations}");
316-
return possibleLocalDeclarations;
318+
if (foundReference.IsDeclaration)
319+
{
320+
_logger.LogDebug($"Found possible declaration in same file ${foundReference}");
321+
declarations.Add(foundReference);
322+
}
317323
}
318324
}
319325

320-
IEnumerable<SymbolReference>? allSymbols = await ScanForReferencesOfSymbolAsync(
321-
symbol,
322-
cancellationToken).ConfigureAwait(false);
323-
324-
IEnumerable<SymbolReference> possibleDeclarations = allSymbols.Where((i) => i.IsDeclaration);
325-
_logger.LogDebug($"Found possible declarations ${possibleDeclarations}");
326+
if (declarations.Any())
327+
{
328+
return declarations;
329+
}
326330

327-
return possibleDeclarations;
331+
foreach (SymbolReference foundReference in await ScanForReferencesOfSymbolAsync(
332+
symbol, cancellationToken).ConfigureAwait(false))
333+
{
334+
if (foundReference.IsDeclaration)
335+
{
336+
_logger.LogDebug($"Found possible declaration in workspace ${foundReference}");
337+
declarations.Add(foundReference);
338+
}
339+
}
328340

329-
// TODO: Fix searching for definition of built-in commands.
330-
// TODO: Fix "definition" of dot-source (maybe?)
341+
return declarations;
331342
}
332343

333344
private async Task ScanWorkspacePSFiles(CancellationToken cancellationToken = default)

src/PowerShellEditorServices/Services/TextDocument/Handlers/DefinitionHandler.cs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,10 @@ public override async Task<LocationOrLocationLinks> Handle(DefinitionParams requ
4444
request.Position.Character + 1);
4545

4646
List<LocationOrLocationLink> definitionLocations = new();
47-
if (foundSymbol != null)
47+
if (foundSymbol is not null)
4848
{
49-
IEnumerable<SymbolReference> foundDefinitions = await _symbolsService.GetDefinitionOfSymbolAsync(
50-
scriptFile,
51-
foundSymbol,
52-
cancellationToken).ConfigureAwait(false);
53-
54-
foreach (SymbolReference foundDefinition in foundDefinitions)
49+
foreach (SymbolReference foundDefinition in await _symbolsService.GetDefinitionOfSymbolAsync(
50+
scriptFile, foundSymbol, cancellationToken).ConfigureAwait(false))
5551
{
5652
definitionLocations.Add(
5753
new LocationOrLocationLink(

src/PowerShellEditorServices/Services/TextDocument/Handlers/ReferencesHandler.cs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,9 @@ public override async Task<LocationContainer> Handle(ReferenceParams request, Ca
4141
request.Position.Line + 1,
4242
request.Position.Character + 1);
4343

44-
IEnumerable<SymbolReference> referencesResult =
45-
await _symbolsService.ScanForReferencesOfSymbolAsync(
46-
foundSymbol, cancellationToken).ConfigureAwait(false);
47-
48-
if (referencesResult is null)
49-
{
50-
return new LocationContainer();
51-
}
52-
5344
List<Location> locations = new();
54-
foreach (SymbolReference foundReference in referencesResult)
45+
foreach (SymbolReference foundReference in await _symbolsService.ScanForReferencesOfSymbolAsync(
46+
foundSymbol, cancellationToken).ConfigureAwait(false))
5547
{
5648
// Respect the request's setting to include declarations.
5749
if (!request.Context.IncludeDeclaration && foundReference.IsDeclaration)

src/PowerShellEditorServices/Services/Workspace/WorkspaceService.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Collections.Concurrent;
66
using System.Collections.Generic;
77
using System.IO;
8-
using System.Linq;
98
using System.Security;
109
using System.Text;
1110
using Microsoft.Extensions.FileSystemGlobbing;
@@ -275,10 +274,9 @@ public ScriptFile GetFileBuffer(DocumentUri documentUri, string initialBuffer)
275274
}
276275

277276
/// <summary>
278-
/// Gets an array of all opened ScriptFiles in the workspace.
277+
/// Gets an IEnumerable of all opened ScriptFiles in the workspace.
279278
/// </summary>
280-
/// <returns>An array of all opened ScriptFiles in the workspace.</returns>
281-
public ScriptFile[] GetOpenedFiles() => workspaceFiles.Values.ToArray();
279+
public IEnumerable<ScriptFile> GetOpenedFiles() => workspaceFiles.Values;
282280

283281
/// <summary>
284282
/// Closes a currently open script file with the given file path.

0 commit comments

Comments
 (0)