Skip to content

Implement support for #133 ([AsParameters]) + help text fixes#238

Open
dusrdev wants to merge 5 commits intoCysharp:masterfrom
dusrdev:AsParameters
Open

Implement support for #133 ([AsParameters]) + help text fixes#238
dusrdev wants to merge 5 commits intoCysharp:masterfrom
dusrdev:AsParameters

Conversation

@dusrdev
Copy link
Contributor

@dusrdev dusrdev commented Feb 13, 2026

Summary

  • Added first-class support for grouping command parameters into a single record via [AsParameters].
  • Expanded grouped constructor parameters into normal CLI-bound parameters during source generation, then re-hydrated the record at invocation time.
  • Included two help text quality fixes discovered during implementation:
  • Fixed option suffix spacing ([Required] / [Default: ...]) when option description is empty.
  • Fixed XML <summary> multi-line normalization so multi-line command summaries render correctly in help output.

New capability: [AsParameters]

  • Introduced [AsParameters] attribute support on command parameters.
  • Supported usage across ConsoleApp.Run, method references, ConsoleAppBuilder.Add(...), and class command registration.
  • Implemented generator pipeline support to distinguish:
  • Runtime parameters (actual delegate/method signature).
  • Effective parse parameters (flattened parameter list used for CLI parsing/help/validation).
  • Added explicit expansion mapping metadata (AsParametersBinding) to map runtime parameter index to flattened constructor parameter indexes.
  • Emission now:
  • Parses flattened parameters exactly like regular parameters.
  • Performs validation against the correct ParameterInfo source (method parameter vs expanded constructor parameter).
  • Constructs the target record (new TargetType(...)) and passes it into the original command signature.

Supported behavior for expanded constructor parameters

  • Normal option binding semantics (name conversion, required/default behavior).
  • [Argument] ordering support.
  • [FromServices] and [FromKeyedServices] resolution.
  • DataAnnotations validation attributes.
  • [Hidden] and [HideDefaultValue] help behavior.
  • Custom parser attributes implementing IArgumentParser<T>.
  • XML <param> aliases/descriptions applied from constructor parameter docs.
  • Mixing with regular command parameters, CancellationToken, ConsoleAppContext, multiple [AsParameters] parameters, and global options.

Guardrails and diagnostics

  • Added diagnostics specific to [AsParameters]:
  • CAF019: target must be a record class.
  • CAF020: target must have exactly one public instance constructor.
  • CAF021: nested [AsParameters] is not supported on constructor parameters.
  • CAF022: params constructor parameters are not supported.
  • Added duplicate option/alias detection across the effective flattened parameter set:
  • CAF023: duplicate option name or alias.
  • Extended existing doc-comment parameter-name mismatch validation (CAF015) to constructor XML params used by [AsParameters].

Help text fixes (added during this work)

  • Option suffix spacing fix:
  • CommandHelpBuilder now appends a separating space before [Required] / [Default: ...] only when description text is non-empty.
  • This prevents extra spacing artifacts and keeps help formatting consistent for blank-description options.
  • Multi-line summary rendering fix:
  • RoslynExtensions.GetSummary() now normalizes summary text line-by-line.
  • Trims leading/trailing blank lines and preserves intentional line breaks in multi-line <summary> blocks.
  • Produces cleaner, stable help output for multi-line command descriptions.

Tests

  • Added comprehensive AsParametersTest coverage including:
  • Basic flatten/invoke.
  • Defaults and nullable defaults.
  • Validation behavior.
  • Services and keyed services.
  • Help parity against equivalent expanded signatures.
  • Method references, builder registration, class registration.
  • Interop with argument ordering, cancellation token, context, global options, custom parsers, hidden/default-hidden settings, and multiple [AsParameters] instances.
  • Added diagnostics tests for CAF019-CAF023 and constructor doc-comment mismatch.
  • Added help regression test for multi-line summary output.
  • Updated expected help snapshots for spacing changes from the option suffix formatting fix.

Documentation

  • Added new README section: AsParameters.
  • Included usage example, XML alias/description example, and current constraints.

Notes for reviewers

  • This change does not introduce a separate AsParameters-specific parser/emitter/help pipeline.
  • The implementation reuses the existing parsing/help/validation/generation flow by introducing EffectiveParseParameters (a flattened view of parameters).
  • Runtime signature shape is preserved via Parameters; only the final invocation path adds a rehydration step (new TargetType(...)) before calling the original method/delegate.
  • The key internal refactor is therefore a data-model split (runtime vs effective parse parameters), not a parallel processing stack.

Closes #133

@dusrdev dusrdev marked this pull request as ready for review February 13, 2026 15:58
@neuecc
Copy link
Member

neuecc commented Feb 17, 2026

Thank you.
I want to prioritize consistency in naming (and behavior), so I think this is preferable to #237.
Please give me a little time to review the code.

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.

Add support for [AsParameters] attribute

2 participants