Skip to content

Commit 4a82c9e

Browse files
authored
introduce CompletionContext.Empty, remove Symbol.GetCompletions(void) (#1954)
* introduce static CompletionContext.Empty: * cache it so it does not get created more than once * make it public so it can be reused by our users who write tests * use it places where it can improve performance (including benchmarks, which should not include this allocation) * remove Symbol.GetCompletions(void)
1 parent 18027bd commit 4a82c9e

File tree

7 files changed

+27
-23
lines changed

7 files changed

+27
-23
lines changed

src/System.CommandLine.ApiCompatibility.Tests/ApiCompatibilityApprovalTests.System_CommandLine_api_is_not_changed.approved.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ System.CommandLine
246246
public System.Boolean IsHidden { get; set; }
247247
public System.String Name { get; set; }
248248
public System.Collections.Generic.IEnumerable<Symbol> Parents { get; }
249-
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions()
250249
public System.Collections.Generic.IEnumerable<System.CommandLine.Completions.CompletionItem> GetCompletions(System.CommandLine.Completions.CompletionContext context)
251250
public System.String ToString()
252251
System.CommandLine.Binding
@@ -273,6 +272,7 @@ System.CommandLine.Binding
273272
public System.Boolean TryGetValue(IValueDescriptor valueDescriptor, BindingContext bindingContext, ref System.Object& boundValue)
274273
System.CommandLine.Completions
275274
public abstract class CompletionContext
275+
public static CompletionContext Empty { get; }
276276
public System.CommandLine.ParseResult ParseResult { get; }
277277
public System.String WordToComplete { get; }
278278
public class CompletionItem, System.IEquatable<CompletionItem>

src/System.CommandLine.Benchmarks/CommandLine/Perf_Suggestions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System.Collections.Generic;
5+
using System.CommandLine.Completions;
56
using System.Linq;
67
using BenchmarkDotNet.Attributes;
78
using BenchmarkDotNet.Engines;
@@ -43,7 +44,7 @@ public void Setup_FromSymbol()
4344
[Benchmark]
4445
public void SuggestionsFromSymbol()
4546
{
46-
_testSymbol.GetCompletions().Consume(new Consumer());
47+
_testSymbol.GetCompletions(CompletionContext.Empty).Consume(new Consumer());
4748
}
4849

4950
[GlobalSetup(Target = nameof(SuggestionsFromParseResult))]

src/System.CommandLine.Tests/CompletionTests.cs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) .NET Foundation and contributors. All rights reserved.
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

4+
using System.CommandLine.Completions;
45
using System.CommandLine.Parsing;
56
using System.CommandLine.Tests.Utility;
67
using System.IO;
@@ -27,7 +28,7 @@ public void Option_GetCompletions_returns_argument_completions_if_configured()
2728
var option = new Option<string>("--hello")
2829
.AddCompletions("one", "two", "three");
2930

30-
var completions = option.GetCompletions();
31+
var completions = option.GetCompletions(CompletionContext.Empty);
3132

3233
completions
3334
.Select(item => item.Label)
@@ -45,7 +46,7 @@ public void Command_GetCompletions_returns_available_option_aliases()
4546
new Option<string>("--three", "option three")
4647
};
4748

48-
var completions = command.GetCompletions();
49+
var completions = command.GetCompletions(CompletionContext.Empty);
4950

5051
completions
5152
.Select(item => item.Label)
@@ -69,7 +70,7 @@ public void Command_GetCompletions_returns_available_option_aliases_for_global_o
6970

7071
rootCommand.AddGlobalOption(new Option<string>("--three", "option three"));
7172

72-
var completions = subcommand.GetCompletions();
73+
var completions = subcommand.GetCompletions(CompletionContext.Empty);
7374

7475
completions
7576
.Select(item => item.Label)
@@ -87,7 +88,7 @@ public void Command_GetCompletions_returns_available_subcommands()
8788
new Command("three")
8889
};
8990

90-
var completions = command.GetCompletions();
91+
var completions = command.GetCompletions(CompletionContext.Empty);
9192

9293
completions
9394
.Select(item => item.Label)
@@ -104,7 +105,7 @@ public void Command_GetCompletions_returns_available_subcommands_and_option_alia
104105
new Option<string>("--option")
105106
};
106107

107-
var completions = command.GetCompletions();
108+
var completions = command.GetCompletions(CompletionContext.Empty);
108109

109110
completions.Select(item => item.Label)
110111
.Should()
@@ -125,7 +126,7 @@ public void Command_GetCompletions_returns_available_subcommands_and_option_alia
125126
}
126127
};
127128

128-
var completions = command.GetCompletions();
129+
var completions = command.GetCompletions(CompletionContext.Empty);
129130

130131
completions.Select(item => item.Label)
131132
.Should()
@@ -142,7 +143,7 @@ public void Command_GetCompletions_without_text_to_match_orders_alphabetically()
142143
new Command("andmyothersubcommand"),
143144
};
144145

145-
var completions = command.GetCompletions();
146+
var completions = command.GetCompletions(CompletionContext.Empty);
146147

147148
completions
148149
.Select(item => item.Label)
@@ -158,7 +159,7 @@ public void Command_GetCompletions_does_not_return_argument_names()
158159
new Argument<string>("the-argument")
159160
};
160161

161-
var completions = command.GetCompletions();
162+
var completions = command.GetCompletions(CompletionContext.Empty);
162163

163164
completions
164165
.Select(item => item.Label)
@@ -921,7 +922,7 @@ public void Completions_for_options_provide_a_description()
921922
var description = "The option before -y.";
922923
var option = new Option<string>("-x", description);
923924

924-
var completions = new RootCommand { option }.GetCompletions();
925+
var completions = new RootCommand { option }.GetCompletions(CompletionContext.Empty);
925926

926927
completions.Should().ContainSingle()
927928
.Which
@@ -936,7 +937,7 @@ public void Completions_for_subcommands_provide_a_description()
936937
var description = "The description for the subcommand";
937938
var subcommand = new Command("-x", description);
938939

939-
var completions = new RootCommand { subcommand }.GetCompletions();
940+
var completions = new RootCommand { subcommand }.GetCompletions(CompletionContext.Empty);
940941

941942
completions.Should().ContainSingle()
942943
.Which

src/System.CommandLine/Completions/CompletionContext.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ namespace System.CommandLine.Completions
1111
/// </summary>
1212
public abstract class CompletionContext
1313
{
14+
private static CompletionContext? _empty;
15+
1416
internal CompletionContext(ParseResult parseResult, string wordToComplete)
1517
{
1618
ParseResult = parseResult;
@@ -23,7 +25,11 @@ internal CompletionContext(ParseResult parseResult, string wordToComplete)
2325
/// The parse result for which completions are being requested.
2426
public ParseResult ParseResult { get; }
2527

26-
internal static CompletionContext Empty() => new TokenCompletionContext(ParseResult.Empty());
28+
/// <summary>
29+
/// Gets an empty CompletionContext.
30+
/// </summary>
31+
/// <remarks>Can be used for testing purposes.</remarks>
32+
public static CompletionContext Empty => _empty ??= new TokenCompletionContext(ParseResult.Empty());
2733

2834
/// <summary>
2935
/// Gets the text to be matched for completion, which can be used to filter a list of completions.

src/System.CommandLine/Help/HelpBuilder.Default.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,10 @@ public static string GetArgumentUsageLabel(Argument argument)
6464
}
6565

6666
string firstColumn;
67-
var completions = (argument is { } a
68-
? a.GetCompletions()
69-
: Array.Empty<CompletionItem>())
70-
.Select(item => item.Label)
71-
.ToArray();
67+
var completions = argument
68+
.GetCompletions(CompletionContext.Empty)
69+
.Select(item => item.Label)
70+
.ToArray();
7271

7372
var arg = argument;
7473
var helpName = arg?.HelpName ?? string.Empty;

src/System.CommandLine/Parsing/ParseResultVisitor.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.CommandLine.Binding;
6+
using System.CommandLine.Completions;
67
using System.CommandLine.Help;
78
using System.Linq;
89

@@ -522,7 +523,7 @@ private void ValidateAndConvertArgumentResult(ArgumentResult argumentResult)
522523
{
523524
if (argument.FirstParent?.Symbol is Option option)
524525
{
525-
var completions = option.GetCompletions().ToArray();
526+
var completions = option.GetCompletions(CompletionContext.Empty).ToArray();
526527

527528
if (completions.Length > 0)
528529
{

src/System.CommandLine/Symbol.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,6 @@ public IEnumerable<Symbol> Parents
8080
/// <summary>
8181
/// Gets completions for the symbol.
8282
/// </summary>
83-
public IEnumerable<CompletionItem> GetCompletions() =>
84-
GetCompletions(CompletionContext.Empty());
85-
86-
/// <inheritdoc />
8783
public abstract IEnumerable<CompletionItem> GetCompletions(CompletionContext context);
8884

8985
/// <inheritdoc/>

0 commit comments

Comments
 (0)