Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public override AstVisitAction VisitCommand(CommandAst commandAst)

public override AstVisitAction VisitFunctionDefinition(FunctionDefinitionAst functionDefinitionAst)
{
// Treat filter the same as function: both get SymbolType.Function so they use the same
// function-like symbol kind. Document-symbol inclusion and child hierarchy are determined elsewhere.
SymbolType symbolType = functionDefinitionAst.IsWorkflow
? SymbolType.Workflow
: SymbolType.Function;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ $Script:ScriptVar2 = 2

function script:AFunction {}

filter AFilter {$_}
filter AFilter { $FilterVar = $_ }

function AnAdvancedFunction {
begin {
Expand Down
36 changes: 33 additions & 3 deletions test/PowerShellEditorServices.Test/Language/SymbolsServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Microsoft.PowerShell.EditorServices.Test.Shared.References;
using Microsoft.PowerShell.EditorServices.Test.Shared.SymbolDetails;
using Microsoft.PowerShell.EditorServices.Test.Shared.Symbols;
using Microsoft.PowerShell.EditorServices.Handlers;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using Xunit;
Expand Down Expand Up @@ -140,6 +141,21 @@ private IEnumerable<SymbolReference> FindSymbolsInFile(ScriptRegion scriptRegion
.OrderBy(symbol => symbol.ScriptRegion.ToRange().Start);
}

private async Task<IEnumerable<DocumentSymbol>> GetDocumentSymbols(ScriptRegion scriptRegion)
{
string path = TestUtilities.GetSharedPath(scriptRegion.File);
PsesDocumentSymbolHandler handler = new(NullLoggerFactory.Instance, workspace);
SymbolInformationOrDocumentSymbolContainer result = await handler.Handle(
new DocumentSymbolParams
{
TextDocument = new TextDocumentIdentifier { Uri = DocumentUri.FromFileSystemPath(path) }
},
CancellationToken.None);
return result
.Where(s => s.IsDocumentSymbol)
.Select(s => s.DocumentSymbol);
}

[Fact]
public async Task FindsParameterHintsOnCommand()
{
Expand Down Expand Up @@ -768,14 +784,14 @@ public async Task FindsDetailsForBuiltInCommand()
}

[Fact]
public void FindsSymbolsInFile()
public async Task FindsSymbolsInFile()
{
IEnumerable<SymbolReference> symbols = FindSymbolsInFile(FindSymbolsInMultiSymbolFile.SourceDetails);

Assert.Equal(7, symbols.Count(i => i.Type == SymbolType.Function));
Assert.Equal(8, symbols.Count(i => i.Type == SymbolType.Variable));
Assert.Equal(9, symbols.Count(i => i.Type == SymbolType.Variable));
Assert.Equal(4, symbols.Count(i => i.Type == SymbolType.Parameter));
Assert.Equal(12, symbols.Count(i => i.Id.StartsWith("var ")));
Assert.Equal(13, symbols.Count(i => i.Id.StartsWith("var ")));
Assert.Equal(2, symbols.Count(i => i.Id.StartsWith("prop ")));

SymbolReference symbol = symbols.First(i => i.Type == SymbolType.Function);
Expand All @@ -788,6 +804,20 @@ public void FindsSymbolsInFile()
Assert.Equal("filter AFilter ()", symbol.Name);
Assert.True(symbol.IsDeclaration);

// Verify that a variable declared inside a filter is tracked as a declaration,
// and that it is returned as a child of the filter in the LSP outline hierarchy.
symbol = Assert.Single(symbols, i => i.Id == "var FilterVar");
Assert.Equal("$FilterVar", symbol.Name);
Assert.True(symbol.IsDeclaration);

DocumentSymbol filterDocumentSymbol = Assert.Single(
await GetDocumentSymbols(FindSymbolsInMultiSymbolFile.SourceDetails),
i => i.Name == "filter AFilter ()");
DocumentSymbol filterVariableDocumentSymbol = Assert.Single(
filterDocumentSymbol.Children,
i => i.Name == "$FilterVar");
Assert.Equal(SymbolKind.Variable, filterVariableDocumentSymbol.Kind);

symbol = symbols.Last(i => i.Type == SymbolType.Variable);
Assert.Equal("var nestedVar", symbol.Id);
Assert.Equal("$nestedVar", symbol.Name);
Expand Down
Loading