From 13138d2d11ed850b4310029aeaaad526516014a3 Mon Sep 17 00:00:00 2001 From: tmat Date: Fri, 6 Feb 2026 13:14:29 -0800 Subject: [PATCH 1/3] Lock around access to s_dynamicSymbols --- .../DynamicSymbolExtensions.cs | 50 +++++++------------ 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs b/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs index c59d18c7bec1..d762a51d3fde 100644 --- a/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs +++ b/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs @@ -6,50 +6,34 @@ namespace System.CommandLine.StaticCompletions; /// public static class DynamicSymbolExtensions { + private static readonly Lock s_guard = new(); + /// /// The state that is used to track which symbols are dynamic. /// private static readonly Dictionary s_dynamicSymbols = []; - extension(Option option) + extension(Symbol option) { /// /// Indicates whether this option requires a dynamic call into the dotnet process to compute completions. /// public bool IsDynamic { - get => s_dynamicSymbols.GetValueOrDefault(option, false); - set => s_dynamicSymbols[option] = value; - } - - /// - /// Mark this option as requiring dynamic completions. - /// - /// - public Option RequiresDynamicCompletion() - { - option.IsDynamic = true; - return option; - } - } - - extension(Argument argument) - { - /// Indicates whether this argument requires a dynamic call into the dotnet process to compute completions. - public bool IsDynamic - { - get => s_dynamicSymbols.GetValueOrDefault(argument, false); - set => s_dynamicSymbols[argument] = value; - } - - /// - /// Mark this argument as requiring dynamic completions. - /// - /// - public Argument RequiresDynamicCompletion() - { - argument.IsDynamic = true; - return argument; + get + { + lock (s_guard) + { + return s_dynamicSymbols.GetValueOrDefault(option, false); + } + } + set + { + lock (s_guard) + { + s_dynamicSymbols[option] = value; + } + } } } } From 646c716df407a8ccf6c87039e151a412f5e9925f Mon Sep 17 00:00:00 2001 From: tmat Date: Fri, 6 Feb 2026 13:18:05 -0800 Subject: [PATCH 2/3] Specialize --- .../DynamicSymbolExtensions.cs | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs b/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs index d762a51d3fde..84bf0b49c8b4 100644 --- a/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs +++ b/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs @@ -13,7 +13,7 @@ public static class DynamicSymbolExtensions /// private static readonly Dictionary s_dynamicSymbols = []; - extension(Symbol option) + extension(Option option) { /// /// Indicates whether this option requires a dynamic call into the dotnet process to compute completions. @@ -36,4 +36,28 @@ public bool IsDynamic } } } + + extension(Argument option) + { + /// + /// Indicates whether this argument requires a dynamic call into the dotnet process to compute completions. + /// + public bool IsDynamic + { + get + { + lock (s_guard) + { + return s_dynamicSymbols.GetValueOrDefault(option, false); + } + } + set + { + lock (s_guard) + { + s_dynamicSymbols[option] = value; + } + } + } + } } From 00d6bc689f870f64637f8c3703fa35a6d4d60e62 Mon Sep 17 00:00:00 2001 From: tmat Date: Fri, 6 Feb 2026 13:19:44 -0800 Subject: [PATCH 3/3] Rename --- .../DynamicSymbolExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs b/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs index 84bf0b49c8b4..18c7275540da 100644 --- a/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs +++ b/src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs @@ -37,7 +37,7 @@ public bool IsDynamic } } - extension(Argument option) + extension(Argument argument) { /// /// Indicates whether this argument requires a dynamic call into the dotnet process to compute completions. @@ -48,14 +48,14 @@ public bool IsDynamic { lock (s_guard) { - return s_dynamicSymbols.GetValueOrDefault(option, false); + return s_dynamicSymbols.GetValueOrDefault(argument, false); } } set { lock (s_guard) { - s_dynamicSymbols[option] = value; + s_dynamicSymbols[argument] = value; } } }