Skip to content

Avoid mutable global state#52883

Closed
tmat wants to merge 2 commits intodotnet:release/10.0.3xxfrom
tmat:DynamicCommands
Closed

Avoid mutable global state#52883
tmat wants to merge 2 commits intodotnet:release/10.0.3xxfrom
tmat:DynamicCommands

Conversation

@tmat
Copy link
Copy Markdown
Member

@tmat tmat commented Feb 6, 2026

The implementation of IsDynamic extension property mutated global state and was not thread-safe.
This could cause state corruption when commands are created in parallel, e.g. in unit tests.

Removes global state and instead defines ExtendedArgument<T> and ExtendedOption<T> that allow setting the flag on select symbols.

Copilot AI review requested due to automatic review settings February 6, 2026 20:29
@tmat
Copy link
Copy Markdown
Member Author

tmat commented Feb 6, 2026

@MiYanni ptal

@baronfel
Copy link
Copy Markdown
Member

baronfel commented Feb 6, 2026

Please don't do this - we can't use subclasses to contain behavior because it introduces diamond dependencies, and we have several permutations of cross cutting S.CL extensibility behavior.

@tmat
Copy link
Copy Markdown
Member Author

tmat commented Feb 6, 2026

Which other extensions do we have?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a thread-safety issue in System.CommandLine.StaticCompletions where IsDynamic metadata was tracked via mutable global state. It replaces that approach with explicit symbol types (ExtendedArgument<T>, ExtendedOption<T>) that carry the IsDynamic flag on the symbol instance.

Changes:

  • Added IExtendedSymbol plus ExtendedOption<T> / ExtendedArgument<T> to hold IsDynamic per symbol instance.
  • Removed the prior DynamicSymbolExtensions implementation that used a global dictionary for dynamic symbol state.
  • Updated several CLI option/argument factories to construct ExtendedOption<T> / ExtendedArgument<T>.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/System.CommandLine.StaticCompletions/shells/PowershellShellProvider.cs Updates dynamic-argument detection to use IExtendedSymbol rather than the old extension property.
src/System.CommandLine.StaticCompletions/ExtendedSymbols.cs Introduces IExtendedSymbol, ExtendedOption<T>, ExtendedArgument<T>, and a Symbol IsDynamic extension getter.
src/System.CommandLine.StaticCompletions/DynamicSymbolExtensions.cs Removes the previous global-dictionary-based IsDynamic implementation.
src/Cli/Microsoft.DotNet.Cli.Definitions/Common/TargetPlatformOptions.cs Switches runtime option creation to ExtendedOption<string>.
src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonOptions.cs Switches several common options to ExtendedOption<T>.
src/Cli/Microsoft.DotNet.Cli.Definitions/Common/CommonArguments.cs Switches package identity arguments to ExtendedArgument<T>.
src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Restore/RestoreCommandDefinition.cs Switches restore runtime option creation to ExtendedOption<IEnumerable<string>>.
src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Reference/ReferenceAddCommandDefinition.cs Switches framework option creation to ExtendedOption<string>.
src/Cli/Microsoft.DotNet.Cli.Definitions/Commands/Package/PackageAddCommandDefinition.cs Switches version option creation to ExtendedOption<string>.

Comment thread src/System.CommandLine.StaticCompletions/ExtendedSymbols.cs
Comment thread src/System.CommandLine.StaticCompletions/ExtendedSymbols.cs
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@baronfel
Copy link
Copy Markdown
Member

baronfel commented Feb 6, 2026

Which other extensions do we have?

We've got the forwarding stuff at minimum, and help descriptions for the same symbol per-command IIRC?

@baronfel
Copy link
Copy Markdown
Member

baronfel commented Feb 6, 2026

Closing because I merged #52887

@baronfel baronfel closed this Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants