Skip to content

Conversation

dusrdev
Copy link

@dusrdev dusrdev commented Oct 3, 2025

Bug

Before these changes, the generated code would incorrectly bind anything to required postional arguments (parameters decorated with Argument attribute) - this includes options.

For example:

args = ["--dry-run"];

ConsoleApp.Run(args, ([Argument] string path, bool dryRun) => {
	Console.WriteLine($"path = {path}");
	Console.WriteLine($"dryRun = {dryRun}");
});

Would print:

path = --dry-run
dryRun = False

Which is invalid, and should fail because "path" is missing.

Fix

  • Update Emitter.EmitRun so named options are handled before positional [Argument] parameters:
    • Emit an argumentPosition counter that advances only when a non-option token is consumed, keeping positional slots aligned with the number of positional values actually provided.
    • Treat a token as an option only when it looks like -x/--name (exclude negative numbers) and run the existing switch to parse it; when a match occurs, set optionMatched and continue so the token never reaches positional binding.
    • Fall through to the positional logic only for true non-option tokens, preserving the existing “unknown argument” exception path.
  • Extend RunTest.cs with four regression tests that cover the original single-argument case, multiple positional arguments, an [Argument] with a default value, and a command that mixes [Argument] with a params array, demonstrating the new parser behavior across common patterns.

Tests

All 104 generator tests (including the 4 new ones) pass.

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.

1 participant