Skip to content

Add C#: methods, accessors, top-level statements, and minimal-API endpoints - #18

Open
kheisoty wants to merge 1 commit into
unclebob:masterfrom
kheisoty:csharp
Open

kheisoty wants to merge 1 commit into
unclebob:masterfrom
kheisoty:csharp

Conversation

@kheisoty

Copy link
Copy Markdown

C# joins the languages crapper scores

tree-sitter-language-pack already ships the C# grammar, so this is a language module, discovery, and a coverage runner, with no new dependency.

What is an entry

  • Methods with a body: a block or an => expression. Abstract methods, extern, and interface signatures are not.
  • Property, indexer, and event accessors with a body, and expression-bodied properties, under the names the compiler gives them: get_Count, set_Item, add_Changed.
  • Top-level statements, as one entry <Main>$, keyed under the project's root namespace (RootNamespace in the nearest .csproj, else the project file's name) so two projects' Program.cs do not share a key.
  • Each minimal-API endpoint registered with a lambda (MapGet, MapPost, MapPut, MapPatch, MapDelete, Map, MapMethods) is its own entry named GET /users, with #2 for a second lambda on the same route, and its decisions are not charged to the enclosing entry. This is the Express rule from typescript.py; _claim moved to treesitter.py as claim_name so both share it.
  • Constructors, operators, and finalizers are omitted, as crap4java omits constructors. Lambdas and local functions stay inside the enclosing entry.

What is a decision

crap4java's set spelled in C#: if, for, foreach, while, do, catch and its when filter, ?:, each switch section and its when guard, each switch-expression arm, && / ||; plus ??, ?., and and / or inside a pattern.

Discovery

.cs is csharp. obj/ is skipped (generated AssemblyInfo.cs, GlobalUsings.cs). *Tests.cs, *Test.cs, and any .cs inside a *.Tests / *.Test directory are test code.

Coverage

dotnet test <target> --collect:"XPlat Code Coverage" --results-directory target/coverage/csharp -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=lcov, once per .sln at the root, else once per test project. coverlet writes coverage.info; the runner renames it to lcov.info for the existing LCOV loader. A missing coverlet.collector reference is reported and scores 0%, like the other languages' missing tools.

Verification

  • tests/test_csharp.py (10 tests) pins every rule above against small sources, plus the obj/test-file discovery; test_runners.py gains 5 tests for targets, the command vector, the rename, and the warnings; test_languages.py and test_cli.py gain the C# rows. pytest: 161 passed (the Babashka-dependent snapshot test was not run on this machine).
  • Ran end to end on a .NET 10 solution of 57 files / 9.4k lines with 456 xUnit tests: 227 entries, coverage read from coverlet's LCOV, <Main>$ and 25 endpoint lambdas scored. One lambda's CC was checked by hand against the source (3 if, 1 ?:, 4 catch, 1 || → 10).

Note

mutator finds functions through crapper.discover and crapper.languages, so with this change it will see .cs files but has no test plan for them; a C# plan there would compile per mutant, which is what Stryker.NET exists to avoid. Happy to add a "skip csharp" guard in mutator if you prefer.

🤖 Generated with Claude Code

…points

languages/csharp.py scores methods with a body (a block or `=> expression`),
property, indexer, and event accessors under the compiler's names (`get_Count`,
`set_Item`, `add_Changed`), top-level statements as `<Main>$` in `Program`, and
each endpoint lambda registered with MapGet/MapPost/MapPut/MapPatch/MapDelete/
Map/MapMethods as its own entry named `GET /path`, the Express rule. Lambdas and
local functions stay inside the enclosing entry; constructors, operators, and
finalizers are omitted as crap4java omits constructors. Decisions are crap4java's
spelled in C#, plus `??`, `?.`, `when` filters and guards, switch-expression
arms, and `and` / `or` in patterns.

discover: `.cs` is csharp, `obj/` holds generated sources and is skipped, and
`*Tests.cs`, `*Test.cs`, and files inside a `*.Tests` project are test code.

runners: `dotnet test --collect:"XPlat Code Coverage"` with coverlet's LCOV
format, per solution at the root or per test project, written under
target/coverage/csharp and renamed from coverage.info to lcov.info for the loader.

claim_name moves from typescript.py to treesitter.py so both route rules share it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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