[Toolshed] Array parsing (#6864)

* Add parsing for arrays of values via ValueArray<T>.

* oops forgot command description

* add valarr to engine toolshed perms, fix stupidness, remove useless code in parser

* make optional not suck

* support for skipping optional parameters

* Switch to List<T> because I'm dumb and that just works™

* remove optional stuff to separate into its own PR

* Remove ValArr command

`valarr int [ 1, 2 ]` can just be replaced with ` val List<int> [ 1, 2 ]` or ` val int[] [ 1, 2 ]`

* Fix namespace

* Add support for array parsing

* Make ListTypeParser output nullable

* Pass ListLengthAttribute in the CommandArgument struct

The current method of trying to fetch the attribute for argument doesn't actually work. i.e., the argIndex calculation isn't always correct. This is still kinda janky and I hate it, but it should work better.

* Fix empty list parsing, add tests

* rename flag, and clarify description

* More tests

---------

Co-authored-by: ElectroJr <leonsfriedrich@gmail.com>
This commit is contained in:
neomoth
2026-08-22 21:29:33 +00:00
committed by GitHub
co-authored by ElectroJr
parent 9aaa01cb07
commit dcde669baa
11 changed files with 345 additions and 9 deletions
@@ -231,3 +231,25 @@ internal sealed class TestExplicitImplCommand : ToolshedCommand
[CommandImplementation]
public int Impl2() => 2;
}
[ToolshedCommand]
internal sealed class TestArrayParseCommand : ToolshedCommand
{
[CommandImplementation]
public int[] Impl(int[] val) => val;
}
[ToolshedCommand]
internal sealed class TestListParseCommand : ToolshedCommand
{
[CommandImplementation]
public List<int> Impl(List<int> val) => val;
}
[ToolshedCommand]
internal sealed class TestListLengthCommand : ToolshedCommand
{
[CommandImplementation]
public List<int> Impl([ListLength(MinLength = 1, MaxLength = 2)] List<int> val) => val;
}
@@ -402,6 +402,35 @@ internal sealed class ToolshedTests : ToolshedTest
});
}
[Test]
public async Task TestArrayParsing()
{
await Server.WaitAssertion(() =>
{
AssertResult("testarrayparse []", Array.Empty<int>());
AssertResult("testarrayparse [ ]", Array.Empty<int>());
AssertResult("testarrayparse [1]", new[] {1});
AssertResult("testarrayparse [1,2]", new[] {1, 2});
AssertResult("testarrayparse [ 1 , 2 ]", new[] {1, 2});
AssertCompletionSingle("testarrayparse ", "[");
AssertCompletionContains("testarrayparse [ 1 ", "]", ",");
ParseError<ExpectedTokenError>("testarrayparse [ 1 ");
AssertResult("testlistparse []", new List<int>());
AssertResult("testlistparse [1]", new List<int> {1});
AssertResult("testlistparse [1,2]", new List<int> {1, 2});
AssertResult("testlistparse [ 1 , 2 ]", new List<int> {1, 2});
AssertCompletionSingle("testlistparse ", "[");
AssertCompletionContains("testlistparse [ 1 ", "]", ",");
AssertResult("testlistlength [ 1 ]", new[] {1});
AssertResult("testlistlength [ 1, 2 ]", new[] {1, 2});
ParseError<NotEnoughElementsError>("testlistlength [ ]");
ParseError<TooManyElementsError>("testlistlength [ 1, 2, 3 ]");
});
}
[Test]
public async Task TestCompletions()
{