Fixes problems with extension blocks and params keyword

There is currently a bug in the .NET SDK that will emit false CS8620
warnings for extension block members using the `params` keyword.

This commit fixes the warning by converting these methods to
old-fashioned extension methods.

For more information see: https://github.com/dotnet/roslyn/issues/80024
This commit is contained in:
Patrik Svensson
2026-01-06 22:49:07 +01:00
committed by Patrik Svensson
parent cf13ced8f6
commit f6e1368cd4
11 changed files with 491 additions and 446 deletions

View File

@@ -17,12 +17,6 @@
<PolyArgumentExceptions>true</PolyArgumentExceptions>
</PropertyGroup>
<!-- Due to a bug in the .NET SDK (10.0.101), a false positive CS8620 warning is emitted -->
<!-- when "params" are used together with extension blocks -->
<PropertyGroup>
<NoWarn>$(NoWarn);CS8620</NoWarn>
</PropertyGroup>
<!-- Earlier (<10.0.100) SDK throws on extension blocks -->
<PropertyGroup Condition="'$(TargetFramework)' != 'net10.0'">
<NoWarn>$(NoWarn);AD0001</NoWarn>

View File

@@ -66,3 +66,98 @@ public static partial class AnsiConsole
return _factory.Create(settings);
}
}
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
public static partial class AnsiConsole
{
/// <summary>
/// Writes the text representation of the specified array of objects,
/// to the console using the specified format information.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Write(string format, params object[] args)
{
Write(CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// to the console using the specified format information.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Write(IFormatProvider provider, string format, params object[] args)
{
Console.Write(string.Format(provider, format, args), CurrentStyle);
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// followed by the current line terminator, to the console
/// using the specified format information.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void WriteLine(string format, params object[] args)
{
WriteLine(CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// followed by the current line terminator, to the console
/// using the specified format information.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
{
Console.WriteLine(string.Format(provider, format, args), CurrentStyle);
}
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Markup(string format, params object[] args)
{
Console.Markup(format, args);
}
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Markup(IFormatProvider provider, string format, params object[] args)
{
Console.Markup(provider, format, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void MarkupLine(string format, params object[] args)
{
Console.MarkupLine(format, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void MarkupLine(IFormatProvider provider, string format, params object[] args)
{
Console.MarkupLine(provider, format, args);
}
}

View File

@@ -2,6 +2,64 @@ namespace Spectre.Console;
public static partial class AnsiConsoleExtensions
{
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="console">The console to write to.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Markup(this IAnsiConsole console, string format, params object[] args)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
Markup(console, CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="console">The console to write to.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Markup(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
Markup(console, string.Format(provider, format, args));
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="console">The console to write to.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void MarkupLine(this IAnsiConsole console, string format, params object[] args)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
MarkupLine(console, CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="console">The console to write to.</param>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void MarkupLine(this IAnsiConsole console, IFormatProvider provider, string format, params object[] args)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
Markup(console, provider, format + Environment.NewLine, args);
}
extension(AnsiConsole)
{
/// <summary>
@@ -13,16 +71,6 @@ public static partial class AnsiConsoleExtensions
AnsiConsole.Console.Markup(value);
}
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Markup(string format, params object[] args)
{
AnsiConsole.Console.Markup(format, args);
}
/// <summary>
/// Writes the specified markup to the console.
/// <para/>
@@ -41,17 +89,6 @@ public static partial class AnsiConsoleExtensions
AnsiConsole.Console.MarkupInterpolated(value);
}
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Markup(IFormatProvider provider, string format, params object[] args)
{
AnsiConsole.Console.Markup(provider, format, args);
}
/// <summary>
/// Writes the specified markup to the console.
/// <para/>
@@ -80,16 +117,6 @@ public static partial class AnsiConsoleExtensions
AnsiConsole.Console.MarkupLine(value);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void MarkupLine(string format, params object[] args)
{
AnsiConsole.Console.MarkupLine(format, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// <para/>
@@ -108,17 +135,6 @@ public static partial class AnsiConsoleExtensions
AnsiConsole.Console.MarkupLineInterpolated(value);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void MarkupLine(IFormatProvider provider, string format, params object[] args)
{
AnsiConsole.Console.MarkupLine(provider, format, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// <para/>
@@ -142,16 +158,6 @@ public static partial class AnsiConsoleExtensions
/// <param name="console">The console to write to.</param>
extension(IAnsiConsole console)
{
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public void Markup(string format, params object[] args)
{
Markup(console, CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the specified markup to the console.
/// <para/>
@@ -170,17 +176,6 @@ public static partial class AnsiConsoleExtensions
MarkupInterpolated(console, CultureInfo.CurrentCulture, value);
}
/// <summary>
/// Writes the specified markup to the console.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public void Markup(IFormatProvider provider, string format, params object[] args)
{
Markup(console, string.Format(provider, format, args));
}
/// <summary>
/// Writes the specified markup to the console.
/// <para/>
@@ -209,16 +204,6 @@ public static partial class AnsiConsoleExtensions
console.Write(MarkupParser.Parse(value));
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public void MarkupLine(string format, params object[] args)
{
MarkupLine(console, CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// <para/>
@@ -246,17 +231,6 @@ public static partial class AnsiConsoleExtensions
Markup(console, value + Environment.NewLine);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public void MarkupLine(IFormatProvider provider, string format, params object[] args)
{
Markup(console, provider, format + Environment.NewLine, args);
}
/// <summary>
/// Writes the specified markup, followed by the current line terminator, to the console.
/// <para/>

View File

@@ -10,7 +10,7 @@ public static partial class AnsiConsoleExtensions
/// <param name="value">The value to write.</param>
public static void Write(string value)
{
Write(value, AnsiConsole.CurrentStyle);
AnsiConsole.Write(value, AnsiConsole.CurrentStyle);
}
/// <summary>
@@ -219,29 +219,6 @@ public static partial class AnsiConsoleExtensions
AnsiConsole.Console.Write(value[index].ToString(provider), AnsiConsole.CurrentStyle);
}
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// to the console using the specified format information.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Write(string format, params object[] args)
{
Write(CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// to the console using the specified format information.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void Write(IFormatProvider provider, string format, params object[] args)
{
AnsiConsole.Console.Write(string.Format(provider, format, args), AnsiConsole.CurrentStyle);
}
}
extension(IAnsiConsole console)

View File

@@ -237,31 +237,6 @@ public static partial class AnsiConsoleExtensions
AnsiConsole.Console.WriteLine();
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// followed by the current line terminator, to the console
/// using the specified format information.
/// </summary>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void WriteLine(string format, params object[] args)
{
WriteLine(CultureInfo.CurrentCulture, format, args);
}
/// <summary>
/// Writes the text representation of the specified array of objects,
/// followed by the current line terminator, to the console
/// using the specified format information.
/// </summary>
/// <param name="provider">An object that supplies culture-specific formatting information.</param>
/// <param name="format">A composite format string.</param>
/// <param name="args">An array of objects to write.</param>
public static void WriteLine(IFormatProvider provider, string format, params object[] args)
{
AnsiConsole.Console.WriteLine(string.Format(provider, format, args), AnsiConsole.CurrentStyle);
}
}
extension(IAnsiConsole console)

View File

@@ -16,6 +16,54 @@ public interface IHasTreeNodes
/// </summary>
public static class HasTreeNodeExtensions
{
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="obj">The object to add the tree node to.</param>
/// <param name="nodes">The tree nodes to add.</param>
public static void AddNodes(this IHasTreeNodes obj, params string[] nodes)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes.Select(node => new TreeNode(new Markup(node))));
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="obj">The object to add the tree node to.</param>
/// <param name="nodes">The tree nodes to add.</param>
public static void AddNodes(this IHasTreeNodes obj, params IRenderable[] nodes)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes.Select(node => new TreeNode(node)));
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="obj">The object to add the tree node to.</param>
/// <param name="nodes">The tree nodes to add.</param>
public static void AddNodes(this IHasTreeNodes obj, params TreeNode[] nodes)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes);
}
/// <param name="obj">The object to add the tree node to.</param>
/// <typeparam name="T">An object with tree nodes.</typeparam>
extension<T>(T obj) where T : IHasTreeNodes
@@ -27,11 +75,7 @@ public static class HasTreeNodeExtensions
/// <returns>The added tree node.</returns>
public TreeNode AddNode(string markup)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(markup);
return AddNode(obj, new Markup(markup));
@@ -44,11 +88,7 @@ public static class HasTreeNodeExtensions
/// <returns>The added tree node.</returns>
public TreeNode AddNode(IRenderable renderable)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(renderable);
var node = new TreeNode(renderable);
@@ -63,108 +103,44 @@ public static class HasTreeNodeExtensions
/// <returns>The added tree node.</returns>
public TreeNode AddNode(TreeNode node)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(node);
obj.Nodes.Add(node);
return node;
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="nodes">The tree nodes to add.</param>
public void AddNodes(params string[] nodes)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes.Select(node => new TreeNode(new Markup(node))));
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="nodes">The tree nodes to add.</param>
public void AddNodes(IEnumerable<string> nodes)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes.Select(node => new TreeNode(new Markup(node))));
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="nodes">The tree nodes to add.</param>
public void AddNodes(params IRenderable[] nodes)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes.Select(node => new TreeNode(node)));
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="nodes">The tree nodes to add.</param>
public void AddNodes(IEnumerable<IRenderable> nodes)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes.Select(node => new TreeNode(node)));
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="nodes">The tree nodes to add.</param>
public void AddNodes(params TreeNode[] nodes)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes);
}
/// <summary>
/// Add multiple tree nodes.
/// </summary>
/// <param name="nodes">The tree nodes to add.</param>
public void AddNodes(IEnumerable<TreeNode> nodes)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}
ArgumentNullException.ThrowIfNull(obj);
ArgumentNullException.ThrowIfNull(nodes);
obj.Nodes.AddRange(nodes);

View File

@@ -171,18 +171,18 @@ public sealed class Progress
/// </summary>
public static class ProgressExtensions
{
/// <param name="progress">The <see cref="Progress"/> instance.</param>
extension(Progress progress)
{
/// <summary>
/// Sets the columns to be used for an <see cref="Progress"/> instance.
/// </summary>
/// <param name="progress">The <see cref="Progress"/> instance.</param>
/// <param name="columns">The columns to use.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Progress Columns(params ProgressColumn[] columns)
public static Progress Columns(this Progress progress, params ProgressColumn[] columns)
{
ArgumentNullException.ThrowIfNull(progress);
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(progress);
ArgumentNullException.ThrowIfNull(columns);
if (!columns.Any())
@@ -196,6 +196,9 @@ public static class ProgressExtensions
return progress;
}
/// <param name="progress">The <see cref="Progress"/> instance.</param>
extension(Progress progress)
{
/// <summary>
/// Sets an optional hook to intercept rendering.
/// </summary>
@@ -204,7 +207,6 @@ public static class ProgressExtensions
public Progress UseRenderHook(Func<IRenderable, IReadOnlyList<ProgressTask>, IRenderable> renderHook)
{
progress.RenderHook = renderHook;
return progress;
}
@@ -217,9 +219,7 @@ public static class ProgressExtensions
public Progress AutoRefresh(bool enabled)
{
ArgumentNullException.ThrowIfNull(progress);
progress.AutoRefresh = enabled;
return progress;
}
@@ -233,9 +233,7 @@ public static class ProgressExtensions
public Progress AutoClear(bool enabled)
{
ArgumentNullException.ThrowIfNull(progress);
progress.AutoClear = enabled;
return progress;
}
@@ -249,9 +247,7 @@ public static class ProgressExtensions
public Progress HideCompleted(bool enabled)
{
ArgumentNullException.ThrowIfNull(progress);
progress.HideCompleted = enabled;
return progress;
}
}

View File

@@ -95,7 +95,8 @@ public sealed class MultiSelectionPrompt<T> : IPrompt<List<T>>, IListPromptStrat
// Create the list prompt
var prompt = new ListPrompt<T>(console, this);
var converter = Converter ?? TypeConverterHelper.ConvertToString;
var result = await prompt.Show(Tree, converter, Mode, false, false, PageSize, WrapAround, cancellationToken).ConfigureAwait(false);
var result = await prompt.Show(Tree, converter, Mode, false, false, PageSize, WrapAround, cancellationToken)
.ConfigureAwait(false);
if (Mode == SelectionMode.Leaf)
{
@@ -248,9 +249,12 @@ public sealed class MultiSelectionPrompt<T> : IPrompt<List<T>>, IListPromptStrat
var style = current ? highlightStyle : Style.Plain;
var indent = new string(' ', item.Node.Depth * 2);
var prompt = item.Index == cursorIndex ? ListPromptConstants.Arrow : new string(' ', ListPromptConstants.Arrow.Length);
var prompt = item.Index == cursorIndex
? ListPromptConstants.Arrow
: new string(' ', ListPromptConstants.Arrow.Length);
var text = (Converter ?? TypeConverterHelper.ConvertToString)?.Invoke(item.Node.Data) ?? item.Node.Data.ToString() ?? "?";
var text = (Converter ?? TypeConverterHelper.ConvertToString)?.Invoke(item.Node.Data) ??
item.Node.Data.ToString() ?? "?";
if (current)
{
text = text.RemoveMarkup().EscapeMarkup();
@@ -285,6 +289,56 @@ public sealed class MultiSelectionPrompt<T> : IPrompt<List<T>>, IListPromptStrat
/// </summary>
public static class MultiSelectionPromptExtensions
{
/// <summary>
/// Adds multiple choices.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static MultiSelectionPrompt<T> AddChoices<T>(
this MultiSelectionPrompt<T> obj,
params T[] choices) where T : notnull
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
foreach (var choice in choices)
{
obj.AddChoice(choice);
}
return obj;
}
/// <summary>
/// Adds multiple grouped choices.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="group">The group.</param>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static MultiSelectionPrompt<T> AddChoiceGroup<T>(
this MultiSelectionPrompt<T> obj,
T group, params T[] choices) where T : notnull
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
var root = obj.AddChoice(group);
foreach (var choice in choices)
{
root.AddChild(choice);
}
return obj;
}
/// <param name="obj">The prompt.</param>
/// <typeparam name="T">The prompt result type.</typeparam>
extension<T>(MultiSelectionPrompt<T> obj) where T : notnull
@@ -320,23 +374,6 @@ public static class MultiSelectionPromptExtensions
return obj;
}
/// <summary>
/// Adds multiple choices.
/// </summary>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public MultiSelectionPrompt<T> AddChoices(params T[] choices)
{
ArgumentNullException.ThrowIfNull(obj);
foreach (var choice in choices)
{
obj.AddChoice(choice);
}
return obj;
}
/// <summary>
/// Adds multiple choices.
/// </summary>
@@ -373,25 +410,6 @@ public static class MultiSelectionPromptExtensions
return obj;
}
/// <summary>
/// Adds multiple grouped choices.
/// </summary>
/// <param name="group">The group.</param>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public MultiSelectionPrompt<T> AddChoiceGroup(T group, params T[] choices)
{
ArgumentNullException.ThrowIfNull(obj);
var root = obj.AddChoice(group);
foreach (var choice in choices)
{
root.AddChild(choice);
}
return obj;
}
/// <summary>
/// Marks an item as selected.
/// </summary>

View File

@@ -235,6 +235,55 @@ public sealed class SelectionPrompt<T> : IPrompt<T>, IListPromptStrategy<T>
/// </summary>
public static class SelectionPromptExtensions
{
/// <summary>
/// Adds multiple choices.
/// </summary>
/// <param name="obj">The prompt.</param>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static SelectionPrompt<T> AddChoices<T>(
this SelectionPrompt<T> obj,
params T[] choices) where T : notnull
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
foreach (var choice in choices)
{
obj.AddChoice(choice);
}
return obj;
}
/// <summary>
/// Adds multiple grouped choices.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="group">The group.</param>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static SelectionPrompt<T> AddChoiceGroup<T>(
this SelectionPrompt<T> obj,
T group, params T[] choices) where T : notnull
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(obj);
var root = obj.AddChoice(group);
foreach (var choice in choices)
{
root.AddChild(choice);
}
return obj;
}
/// <param name="obj">The prompt.</param>
/// <typeparam name="T">The prompt result type.</typeparam>
extension<T>(SelectionPrompt<T> obj) where T : notnull
@@ -252,23 +301,6 @@ public static class SelectionPromptExtensions
return obj;
}
/// <summary>
/// Adds multiple choices.
/// </summary>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public SelectionPrompt<T> AddChoices(params T[] choices)
{
ArgumentNullException.ThrowIfNull(obj);
foreach (var choice in choices)
{
obj.AddChoice(choice);
}
return obj;
}
/// <summary>
/// Adds multiple choices.
/// </summary>
@@ -305,25 +337,6 @@ public static class SelectionPromptExtensions
return obj;
}
/// <summary>
/// Adds multiple grouped choices.
/// </summary>
/// <param name="group">The group.</param>
/// <param name="choices">The choices to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public SelectionPrompt<T> AddChoiceGroup(T group, params T[] choices)
{
ArgumentNullException.ThrowIfNull(obj);
var root = obj.AddChoice(group);
foreach (var choice in choices)
{
root.AddChild(choice);
}
return obj;
}
/// <summary>
/// Sets the title.
/// </summary>

View File

@@ -146,6 +146,46 @@ public sealed class Grid : JustInTimeRenderable, IExpandable, IAlignable
/// </summary>
public static class GridExtensions
{
/// <summary>
/// Adds a new row to the grid.
/// </summary>
/// <param name="grid">The grid to add the column to.</param>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Grid AddRow(this Grid grid, params string[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(grid);
ArgumentNullException.ThrowIfNull(columns);
grid.AddRow(columns.Select(column => new Markup(column)).ToArray<IRenderable>());
return grid;
}
/// <summary>
/// Adds a column to the grid.
/// </summary>
/// <param name="grid">The grid to add the column to.</param>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Grid AddColumns(this Grid grid, params GridColumn[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(grid);
ArgumentNullException.ThrowIfNull(columns);
foreach (var column in columns)
{
grid.AddColumn(column);
}
return grid;
}
/// <param name="grid">The grid to add the column to.</param>
extension(Grid grid)
{
@@ -166,25 +206,6 @@ public static class GridExtensions
return grid;
}
/// <summary>
/// Adds a column to the grid.
/// </summary>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Grid AddColumns(params GridColumn[] columns)
{
ArgumentNullException.ThrowIfNull(grid);
ArgumentNullException.ThrowIfNull(columns);
foreach (var column in columns)
{
grid.AddColumn(column);
}
return grid;
}
/// <summary>
/// Adds an empty row to the grid.
/// </summary>
@@ -200,21 +221,6 @@ public static class GridExtensions
return grid;
}
/// <summary>
/// Adds a new row to the grid.
/// </summary>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Grid AddRow(params string[] columns)
{
ArgumentNullException.ThrowIfNull(grid);
ArgumentNullException.ThrowIfNull(columns);
grid.AddRow(columns.Select(column => new Markup(column)).ToArray());
return grid;
}
/// <summary>
/// Sets the grid width.
/// </summary>

View File

@@ -168,18 +168,18 @@ public sealed class Table : Renderable, IHasTableBorder, IExpandable, IAlignable
/// </summary>
public static class TableExtensions
{
/// <param name="table">The table to add the column to.</param>
extension(Table table)
{
/// <summary>
/// Adds multiple columns to the table.
/// </summary>
/// <param name="table">The table to add the column to.</param>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Table AddColumns(params TableColumn[] columns)
public static Table AddColumns(this Table table, params TableColumn[] columns)
{
ArgumentNullException.ThrowIfNull(table);
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(table);
ArgumentNullException.ThrowIfNull(columns);
foreach (var column in columns)
@@ -190,6 +190,99 @@ public static class TableExtensions
return table;
}
/// <summary>
/// Adds a row to the table.
/// </summary>
/// <param name="table">The table to add the column to.</param>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table AddRow(this Table table, params IRenderable[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(table);
return table.AddRow((IEnumerable<IRenderable>)columns);
}
/// <summary>
/// Adds multiple columns to the table.
/// </summary>
/// <param name="table">The table to add the column to.</param>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table AddColumns(this Table table, params string[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(table);
ArgumentNullException.ThrowIfNull(columns);
foreach (var column in columns)
{
AddColumn(table, column);
}
return table;
}
/// <summary>
/// Adds a row to the table.
/// </summary>
/// <param name="table">The table to add the column to.</param>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table AddRow(this Table table, params string[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(table);
ArgumentNullException.ThrowIfNull(columns);
table.AddRow(columns.Select(column => new Markup(column)).ToArray());
return table;
}
/// <summary>
/// Inserts a row in the table at the specified index.
/// </summary>
/// <param name="table">The table to add the column to.</param>
/// <param name="index">The index to insert the row at.</param>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table InsertRow(this Table table, int index, params IRenderable[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(table);
return InsertRow(table, index, (IEnumerable<IRenderable>)columns);
}
/// <summary>
/// Inserts a row in the table at the specified index.
/// </summary>
/// <param name="table">The table to add the column to.</param>
/// <param name="index">The index to insert the row at.</param>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static Table InsertRow(this Table table, int index, params string[] columns)
{
// TODO: This is here temporary due to a bug in the .NET SDK
// See issue: https://github.com/dotnet/roslyn/issues/80024
ArgumentNullException.ThrowIfNull(table);
return InsertRow(table, index, columns.Select(column => new Markup(column)));
}
/// <param name="table">The table to add the column to.</param>
extension(Table table)
{
/// <summary>
/// Adds a row to the table.
/// </summary>
@@ -205,18 +298,6 @@ public static class TableExtensions
return table;
}
/// <summary>
/// Adds a row to the table.
/// </summary>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Table AddRow(params IRenderable[] columns)
{
ArgumentNullException.ThrowIfNull(table);
return table.AddRow((IEnumerable<IRenderable>)columns);
}
/// <summary>
/// Adds an empty row to the table.
/// </summary>
@@ -250,40 +331,6 @@ public static class TableExtensions
return table;
}
/// <summary>
/// Adds multiple columns to the table.
/// </summary>
/// <param name="columns">The columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Table AddColumns(params string[] columns)
{
ArgumentNullException.ThrowIfNull(table);
ArgumentNullException.ThrowIfNull(columns);
foreach (var column in columns)
{
AddColumn(table, column);
}
return table;
}
/// <summary>
/// Adds a row to the table.
/// </summary>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Table AddRow(params string[] columns)
{
ArgumentNullException.ThrowIfNull(table);
ArgumentNullException.ThrowIfNull(columns);
table.AddRow(columns.Select(column => new Markup(column)).ToArray());
return table;
}
/// <summary>
/// Inserts a row in the table at the specified index.
/// </summary>
@@ -336,32 +383,6 @@ public static class TableExtensions
return table;
}
/// <summary>
/// Inserts a row in the table at the specified index.
/// </summary>
/// <param name="index">The index to insert the row at.</param>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Table InsertRow(int index, params IRenderable[] columns)
{
ArgumentNullException.ThrowIfNull(table);
return InsertRow(table, index, (IEnumerable<IRenderable>)columns);
}
/// <summary>
/// Inserts a row in the table at the specified index.
/// </summary>
/// <param name="index">The index to insert the row at.</param>
/// <param name="columns">The row columns to add.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public Table InsertRow(int index, params string[] columns)
{
ArgumentNullException.ThrowIfNull(table);
return InsertRow(table, index, columns.Select(column => new Markup(column)));
}
/// <summary>
/// Removes a row from the table with the specified index.
/// </summary>