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
2 changes: 1 addition & 1 deletion src/ConsoleAppFramework/Command.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ string Core(ITypeSymbol type, bool nullable)
{
if (elementType.AllInterfaces.Any(x => x.EqualsUnconstructedGenericType(parsable)))
{
return $"if ({incrementIndex}!TrySplitParse(commandArgs[i], {outArgVar})) {{ ThrowArgumentParseFailed(\"{argumentName}\", commandArgs[i]); }}{elseExpr}";
return $"if ({incrementIndex}!TrySplitParse(commandArgs[i], arg{argCount})) {{ ThrowArgumentParseFailed(\"{argumentName}\", commandArgs[i]); }}{elseExpr}";
}
}
break;
Expand Down
15 changes: 10 additions & 5 deletions src/ConsoleAppFramework/ConsoleAppBaseCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace ConsoleAppFramework;
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;

""";

Expand All @@ -37,6 +38,7 @@ namespace ConsoleAppFramework;
using System.Runtime.CompilerServices;
using System.Diagnostics.CodeAnalysis;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;

#if !USE_EXTERNAL_CONSOLEAPP_ABSTRACTIONS

Expand Down Expand Up @@ -296,28 +298,29 @@ static bool TryParseParamsArray<T>(ReadOnlySpan<string> args, ref T[] result, re
return true;
}

static bool TrySplitParse<T>(ReadOnlySpan<char> s, out T[] result)
static bool TrySplitParse<T>(ReadOnlySpan<char> s, List<T> result)
where T : ISpanParsable<T>
{
T[] array = default(T[]);
if (s.StartsWith("["))
{
try
{
result = System.Text.Json.JsonSerializer.Deserialize<T[]>(s, JsonSerializerOptions)!;
array = System.Text.Json.JsonSerializer.Deserialize<T[]>(s, JsonSerializerOptions)!;
result.AddRange(array);
return true;
}
catch
{
result = default!;
return false;
}
}

var count = s.Count(',') + 1;
result = new T[count];
array = new T[count];

var source = s;
var destination = result.AsSpan();
var destination = array.AsSpan();
Span<Range> ranges = stackalloc Range[Math.Min(count, 128)];

while (true)
Expand Down Expand Up @@ -349,6 +352,8 @@ static bool TrySplitParse<T>(ReadOnlySpan<char> s, out T[] result)
}
}

result.AddRange(array);

return true;
}

Expand Down
20 changes: 17 additions & 3 deletions src/ConsoleAppFramework/Emitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,18 @@ public void EmitRun(SourceBuilder sb, CommandWithId commandWithId, bool isRunAsy
var parameter = command.Parameters[i];
if (parameter.IsParsable)
{
var defaultValue = parameter.IsParams ? $"({parameter.ToTypeDisplayString()})[]"
if (parameter.Type.TypeKind == TypeKind.Array && !parameter.IsParams)
{
sb.AppendLine($"var arg{i} = new List<{((IArrayTypeSymbol)parameter.Type.TypeSymbol).ElementType.ToFullyQualifiedFormatDisplayString()}>();");
}
else
{
var defaultValue = parameter.IsParams ? $"({parameter.ToTypeDisplayString()})[]"
: parameter.HasDefaultValue ? parameter.DefaultValueToString()
: $"default({parameter.Type.ToFullyQualifiedFormatDisplayString()})";
sb.AppendLine($"var arg{i} = {defaultValue};");
sb.AppendLine($"var arg{i} = {defaultValue};");
}

if (parameter.RequireCheckArgumentParsed)
{
sb.AppendLine($"var arg{i}Parsed = false;");
Expand Down Expand Up @@ -348,7 +356,13 @@ public void EmitRun(SourceBuilder sb, CommandWithId commandWithId, bool isRunAsy

// invoke for sync/async, void/int
sb.AppendLine();
var methodArguments = string.Join(", ", command.Parameters.Select((x, i) => $"arg{i}!"));
var methodArguments = string.Join(", ", command.Parameters.Select((x, i) =>
{
if (x.IsParsable && x.Type.TypeKind == TypeKind.Array && !x.IsParams)
return $"arg{i}.ToArray()";
else
return $"arg{i}!";
}));
string invokeCommand;
if (command.CommandMethodInfo == null)
{
Expand Down
12 changes: 12 additions & 0 deletions tests/ConsoleAppFramework.GeneratorTests/ArrayParseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ public async Task ParseArray()
await verifier.Execute(code, args: $"--ix {largeIntArray} --sx a,b,c,d,e", expected: $"[{expectedIntArray}][a, b, c, d, e]");
}

[Test]
public async Task RepeatArguments()
{
var code = """
ConsoleApp.Run(args, (int[] number) =>
{
Console.Write("[" + string.Join(", ", number) + "]");
});
""";
await verifier.Execute(code, args: "--number 1 --number 2 --number 3 --number 4 --number 5", expected: "[1, 2, 3, 4, 5]");
}

[Test]
public async Task JsonArray()
{
Expand Down
Loading