Skip to content

Source generator: record generic-class arity violations during concrete-class discovery instead of re-enumerating #7352

Open

Description

@thomhurst

What

A follow-up to the Claude review on #7344 (concerns 2 and 3). In TestMetadataGenerator, the arity pass for a generic class with a generic method (IsGenericType && IsGenericMethod) rebuilds the set of concrete classes from three sources: the existing results, class-level [GenerateGenericTest] types, and class rows. This repeats the enumeration that CollectConcreteInstantiations already does, so the two can drift apart. The pass then adds the arity violations and puts them back in declaration order with SortByGenerateGenericTestOrder.

AddMethodViolation also searches results linearly with FirstOrDefault on every call, inside the per-class loop.

Shared validation rule

The review follow-up also covers DescribeGenerateGenericTestArityError in the generator and GetGenerateGenericTestArityError in reflection mode. Both check empty arguments, wrong count, then null/pointer types in the same order. Move that rule into the linked internal TUnit.Core/Helpers/GenerateGenericTestArityMessages.cs helper, with each mode supplying its type descriptions, so only the mode-specific type inspection remains separate. This code arrives in the still-open PR #7344; retain #7222 as the prerequisite.

Expected

  • Record each concrete class once, as the main loop discovers it, and add the arity violations at that point in declaration order, so the post-hoc sort is no longer needed.
  • Look up a class's violation entry in a dictionary keyed by concrete class name.
  • Share the arity-validation rule across both modes without changing error messages or their order.

The behavior must stay the same: the _7222 cases in tests/TUnit.TestProject and the Tests7222 and Tests7107 snapshots must not change.

Activity

  1. added
    enhancementNew feature or request
    performancePerformance optimization
    P3Low: cleanup, minor enhancement, or rare edge case
    on Nov 1, 2026
  2. thomhurst commented on Nov 2, 2026

    @thomhurst
    OwnerAuthor

    Triage: linked as blocked by #7222. The arity pass, AddMethodViolation and SortByGenerateGenericTestOrder this issue refactors exist only on PR #7344 (which closes #7222), not on origin/main yet.

  3. thomhurst commented on Nov 2, 2026

    @thomhurst
    OwnerAuthor

    Another follow-up from the Claude review of #7344 (comment 6570771848). DescribeGenerateGenericTestArityError in the generator and GetGenerateGenericTestArityError in reflection mode run the same checks in the same order: empty, wrong count, then null or pointer. Only the message text is shared, through TUnit.Core/Helpers/GenerateGenericTestArityMessages.cs. Move the rule into that helper as well, for example a Validate(methodName, IReadOnlyList<(string Name, bool IsInvalid)> args, int required) that each mode feeds its own type names, so the two checks cannot drift apart.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low: cleanup, minor enhancement, or rare edge caseenhancementNew feature or requestperformancePerformance optimization

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions