@descryy/adapter-csharp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The C# `LanguageAdapter` — all seven methods, breadth tier.
3
+ *
4
+ * The fifth language over the shared tree-sitter harness, and again nothing in
5
+ * `@descryy/adapter-treesitter` changed to accommodate it.
6
+ *
7
+ * `IMPLEMENTS` and `INHERITS` are both claimed, and DEC-084 is what makes the
8
+ * second honest: C# writes `class A : B, IC` without saying which entry is the
9
+ * class, but the language guarantees at most one base class and requires it
10
+ * first — so only one entry per class declaration is ever ambiguous, and the
11
+ * `IFoo` naming convention is never read.
12
+ */
13
+ import { type LanguageAdapter, type ResolutionLevel } from "@descryy/ir";
14
+ import { toRepoRelative } from "@descryy/adapter-common";
15
+ import { LANGUAGE } from "./extract.ts";
16
+ export declare const ADAPTER_ID = "adapter-csharp";
17
+ export declare const ADAPTER_VERSION = "0.1.0";
18
+ export declare const DEFAULT_CSHARP_GLOBS: readonly ["**/*.cs"];
19
+ export interface CsharpAdapterOptions {
20
+ readonly globs?: readonly string[];
21
+ readonly maxResolution?: ResolutionLevel;
22
+ }
23
+ export interface CsharpAdapter extends LanguageAdapter {
24
+ readonly id: string;
25
+ readonly version: string;
26
+ }
27
+ export declare function createCsharpAdapter(options?: CsharpAdapterOptions): CsharpAdapter;
28
+ /** Content hash of a repo-relative file, for `FileRef`. */
29
+ export declare function hashOf(root: string, relative: string): string;
30
+ export { LANGUAGE, toRepoRelative };
31
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAOH,OAAO,EAML,KAAK,eAAe,EAGpB,KAAK,eAAe,EAKrB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAyB,cAAc,EAAwB,MAAM,yBAAyB,CAAC;AAatG,OAAO,EAAW,QAAQ,EAAmB,MAAM,cAAc,CAAC;AAElE,eAAO,MAAM,UAAU,mBAAmB,CAAC;AAC3C,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,oBAAoB,sBAAuB,CAAC;AAUzD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;CAC1C;AA4BD,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CA0OrF;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,263 @@
1
+ /**
2
+ * The C# `LanguageAdapter` — all seven methods, breadth tier.
3
+ *
4
+ * The fifth language over the shared tree-sitter harness, and again nothing in
5
+ * `@descryy/adapter-treesitter` changed to accommodate it.
6
+ *
7
+ * `IMPLEMENTS` and `INHERITS` are both claimed, and DEC-084 is what makes the
8
+ * second honest: C# writes `class A : B, IC` without saying which entry is the
9
+ * class, but the language guarantees at most one base class and requires it
10
+ * first — so only one entry per class declaration is ever ambiguous, and the
11
+ * `IFoo` naming convention is never read.
12
+ */
13
+ import { createHash } from "node:crypto";
14
+ import { createRequire } from "node:module";
15
+ import { existsSync, readFileSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { CLIENT_BASE_EXTRACTOR, CLIENT_CALL_EXTRACTOR, ORM_EXTRACTOR, ROUTE_EXTRACTOR, } from "@descryy/ir";
18
+ import { discover, isolateFile, toRepoRelative } from "@descryy/adapter-common";
19
+ import { parserFor, parseText } from "@descryy/adapter-treesitter";
20
+ import { readFile as readCsFile } from "./parse.js";
21
+ import { nullableDirectives, resolveNullable } from "./nullability.js";
22
+ import { assemblyCollisions, csharpProjects, hasSolution, isBuildOutput, projectOf, } from "./projects.js";
23
+ import { extract, LANGUAGE } from "./extract.js";
24
+ export const ADAPTER_ID = "adapter-csharp";
25
+ export const ADAPTER_VERSION = "0.1.0";
26
+ export const DEFAULT_CSHARP_GLOBS = ["**/*.cs"];
27
+ const PRODUCED_BY = `${ADAPTER_ID}@${ADAPTER_VERSION}`;
28
+ function grammarPath() {
29
+ const beside = join(import.meta.dirname, "tree-sitter-c_sharp.wasm");
30
+ if (existsSync(beside))
31
+ return beside;
32
+ return createRequire(import.meta.url).resolve("tree-sitter-c-sharp/tree-sitter-c_sharp.wasm");
33
+ }
34
+ export function createCsharpAdapter(options = {}) {
35
+ const globs = options.globs ?? DEFAULT_CSHARP_GLOBS;
36
+ const ceiling = options.maxResolution ?? 2;
37
+ let session;
38
+ let parser;
39
+ const filesUnder = (root) => discover(root.absolutePath, globs).filter((file) => !isBuildOutput(file));
40
+ return {
41
+ id: ADAPTER_ID,
42
+ version: ADAPTER_VERSION,
43
+ async detect(root) {
44
+ const files = filesUnder(root);
45
+ const evidence = [];
46
+ if (files.length > 0)
47
+ evidence.push(`${files.length} .cs files outside bin/ and obj/`);
48
+ const projects = csharpProjects(root.absolutePath, files);
49
+ if (projects.length > 0) {
50
+ evidence.push(`${projects.length} .csproj file(s)${hasSolution(root.absolutePath) ? ", with a solution" : ""}`);
51
+ for (const caveat of projects.flatMap((project) => project.caveats))
52
+ evidence.push(caveat);
53
+ for (const collision of assemblyCollisions(projects))
54
+ evidence.push(collision);
55
+ }
56
+ else if (files.length > 0) {
57
+ // Caps what identity can be: without a project there is no assembly, and
58
+ // two namespaces that collide have nothing to separate them.
59
+ evidence.push("no .csproj found — files belong to no assembly and cannot be separated by project");
60
+ }
61
+ return { detected: files.length > 0, roots: files.length > 0 ? [root.absolutePath] : [], evidence };
62
+ },
63
+ capabilities() {
64
+ return {
65
+ maxResolution: ceiling,
66
+ /**
67
+ * `API_ROUTE`, `API_ENDPOINT` and `MODEL` are claimed because the
68
+ * ASP.NET and EF Core extractors earn them from **declarations** — an
69
+ * attribute the framework acts on, a `DbSet<T>`, an
70
+ * `IEntityTypeConfiguration<T>` — never from a name. DEC-043's objection
71
+ * was to the name heuristic, not to the node types.
72
+ *
73
+ * `DTO` stays absent, and golden 07's note says why: `Order` and
74
+ * `CreateOrderRequest` are structurally identical in the corpus and
75
+ * separable only by their names. A mapping distinguishes the model;
76
+ * nothing distinguishes the DTO, so nothing claims it.
77
+ *
78
+ * `frameworkExtractors` and `frameworkCapabilities` are declared
79
+ * together, in the change that ships the extractors. `capabilities.ts`
80
+ * has landed, so the names come from its closed set rather than being
81
+ * invented here.
82
+ *
83
+ * `USES_API` and `client-call-extractor` are both claimed. `client.ts`
84
+ * (DEC-241 §4) reads `HttpClient`'s verb methods — `GetAsync`,
85
+ * `PostAsJsonAsync`, etc — whose path is the call's own first argument,
86
+ * the same structurally-straightforward shape Java's `RestTemplate`
87
+ * extracts from, mints real `USES_API` edges for a repository-relative
88
+ * literal path, and files a ledger row for every other shape (a
89
+ * pre-built `HttpRequestMessage` via `SendAsync`, a non-literal path,
90
+ * another origin, or a bare relative path this reader cannot place).
91
+ *
92
+ * `client-base-extractor` (DEC-164, patterns 08a/08b/08c) is now
93
+ * claimed too — the first adapter in this project to build it.
94
+ * `client-base.ts`'s own header has the full account; in short,
95
+ * every `USES_API` edge now carries `attrs.clientBase`, `resolved`
96
+ * when the receiver traces to `WebApplicationFactory<T>.CreateClient()`
97
+ * (ASP.NET's own integration-test client, whose documented default
98
+ * `BaseAddress` is the application under test — 100% of jellyfin's
99
+ * and eShopOnWeb's real `USES_API` population goes through exactly
100
+ * this receiver) and `none` otherwise, unchanged from this adapter's
101
+ * pre-DEC-164 behaviour. `unresolved` — a base-setting mechanism
102
+ * found but unreadable — is part of the contract and never produced
103
+ * by this build: the one registration shape with real corpus
104
+ * evidence (`AddHttpClient<T>(o => o.BaseAddress = new("..."))`,
105
+ * `dotnet/eShop`, 4 sites) feeds call sites already blocked by string
106
+ * interpolation, a separate and larger gap, so resolving it would
107
+ * move zero measured edges. `IHttpClientFactory.CreateClient(name)`'s
108
+ * named-client form is a different, real, unaddressed DI shape —
109
+ * every such call was invisible before this row and stays exactly
110
+ * as invisible after it.
111
+ */
112
+ nodeTypes: ["MODULE", "CLASS", "FUNCTION", "TEST_CASE", "API_ROUTE", "API_ENDPOINT", "MODEL"],
113
+ edgeTypes: ["IMPORTS", "CALLS", "TESTS", "INHERITS", "IMPLEMENTS", "USES_TYPE", "SERVES_API", "USES_API"],
114
+ hasCallHierarchy: false,
115
+ hasTypeHierarchy: false,
116
+ /**
117
+ * Directories this ecosystem installs dependencies or build output into —
118
+ * DEC-110's end state. The engine used to hold `node_modules`/`vendor`/`target`
119
+ * in a hardcoded list; it holds none of them now and consumes this instead.
120
+ *
121
+ * `projects.ts` already excludes all four — `obj/` in particular would put a second
122
+ * copy of every generated source in the graph, "the same reason Go excludes
123
+ * vendor/".
124
+ *
125
+ * Names only — the walk matches one path component, so a path or glob matches
126
+ * nothing. Nothing dotted — those are skipped structurally already.
127
+ */
128
+ noiseDirectories: ["bin", "obj", "packages", "node_modules"],
129
+ frameworkExtractors: ["aspnetcore", "efcore", "client-call-extractor", "client-base-extractor"],
130
+ frameworkCapabilities: [ROUTE_EXTRACTOR, ORM_EXTRACTOR, CLIENT_CALL_EXTRACTOR, CLIENT_BASE_EXTRACTOR],
131
+ };
132
+ },
133
+ async prepare(ctx) {
134
+ // Sorted, so which part of a partial type is primary is a property of the
135
+ // repository rather than of filesystem order — DEC-083 requires it.
136
+ const files = [...filesUnder(ctx.root)].sort();
137
+ parser ??= await parserFor(grammarPath());
138
+ const projects = csharpProjects(ctx.root.absolutePath, files);
139
+ const units = [];
140
+ const failures = [];
141
+ const unfinished = [];
142
+ const withoutProject = new Set();
143
+ const sources = new Map();
144
+ for (const file of files) {
145
+ if (ctx.signal.aborted)
146
+ break;
147
+ let text;
148
+ try {
149
+ text = readFileSync(join(ctx.root.absolutePath, file), "utf8");
150
+ }
151
+ catch (error) {
152
+ failures.push({ kind: "unreadable", file, detail: error instanceof Error ? error.message : String(error) });
153
+ continue;
154
+ }
155
+ const outcome = parseText(parser, file, text);
156
+ if (outcome.tree === undefined) {
157
+ if (outcome.failure !== undefined)
158
+ failures.push(outcome.failure);
159
+ continue;
160
+ }
161
+ // Isolated: a throw in the walk used to cost the run rather than the file.
162
+ const read = isolateFile(file, () => readCsFile(outcome.tree.rootNode, file, outcome.tree.rootNode.hasError));
163
+ outcome.tree.delete();
164
+ if (read.failure !== undefined) {
165
+ unfinished.push(read.failure);
166
+ continue;
167
+ }
168
+ const unit = read.value;
169
+ const project = projectOf(projects, file);
170
+ if (project === undefined)
171
+ withoutProject.add(file);
172
+ units.push({ ...unit, assembly: project?.assembly ?? "" });
173
+ sources.set(file, text);
174
+ }
175
+ const reached = units.length === 0 ? 0 : ceiling;
176
+ session = {
177
+ root: ctx.root,
178
+ files,
179
+ units,
180
+ reached,
181
+ failures,
182
+ unfinished,
183
+ projects,
184
+ withoutProject: [...withoutProject],
185
+ sources,
186
+ };
187
+ return reached;
188
+ },
189
+ async parseFiles(files) {
190
+ const byFile = new Map((session?.units ?? []).map((unit) => [unit.file, unit]));
191
+ return files.map((file) => ({ file, tree: byFile.get(file.path) ?? {} }));
192
+ },
193
+ extractNodes() {
194
+ return current().nodes;
195
+ },
196
+ extractEdges() {
197
+ return current().edges;
198
+ },
199
+ async emit(ctx) {
200
+ const reached = await this.prepare(ctx);
201
+ const active = session;
202
+ const extraction = current();
203
+ const failedFiles = new Set([...active.failures.map((f) => f.file), ...active.unfinished.map((f) => f.file)]);
204
+ return {
205
+ repo: ctx.root.repo,
206
+ ...(ctx.root.workspace === undefined ? {} : { workspace: ctx.root.workspace }),
207
+ commitSha: ctx.root.commitSha,
208
+ producedBy: PRODUCED_BY,
209
+ sourceFiles: active.files.filter((f) => !failedFiles.has(f)),
210
+ skippedFiles: [
211
+ ...active.failures.map((f) => ({ file: f.file, reason: f.kind, detail: f.detail })),
212
+ // `other`: it parsed, and what failed is our walk of it. The detail says which.
213
+ ...active.unfinished.map((f) => ({ file: f.file, reason: "other", detail: f.detail })),
214
+ ],
215
+ reachedResolution: reached,
216
+ nodes: extraction.nodes,
217
+ edges: extraction.edges,
218
+ unresolved: extraction.unresolved,
219
+ };
220
+ },
221
+ async dispose() {
222
+ session = undefined;
223
+ parser?.delete();
224
+ parser = undefined;
225
+ },
226
+ };
227
+ function current() {
228
+ const active = session;
229
+ if (active === undefined || active.units.length === 0) {
230
+ return { nodes: [], edges: [], unresolved: [] };
231
+ }
232
+ return extract({
233
+ repo: active.root.repo,
234
+ scope: { repo: active.root.repo, ...(active.root.workspace === undefined ? {} : { workspace: active.root.workspace }) },
235
+ producedBy: PRODUCED_BY,
236
+ reached: active.reached,
237
+ files: active.units,
238
+ sources: active.sources,
239
+ // Only this layer holds the projects and the imported props, which are two
240
+ // of DEC-180 §1's three sources. Passing a resolver rather than the raw
241
+ // values keeps the precedence in one place.
242
+ nullableContextOf: (file) => {
243
+ const project = projectOf(active.projects, file);
244
+ return resolveNullable({
245
+ directives: nullableDirectives(active.sources.get(file) ?? ""),
246
+ project: project?.nullable ?? "absent",
247
+ directoryProps: project?.directoryProps ?? "absent",
248
+ }, Number.MAX_SAFE_INTEGER).context;
249
+ },
250
+ });
251
+ }
252
+ }
253
+ /** Content hash of a repo-relative file, for `FileRef`. */
254
+ export function hashOf(root, relative) {
255
+ try {
256
+ return createHash("sha256").update(readFileSync(join(root, relative))).digest("hex").slice(0, 32);
257
+ }
258
+ catch {
259
+ return "";
260
+ }
261
+ }
262
+ export { LANGUAGE, toRepoRelative };
263
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * The HTTP-route framework extractor for C# — ASP.NET Core.
3
+ *
4
+ * **An `API_ROUTE` is a framework claim, and this file is where it is earned.**
5
+ * DEC-128 §1 fixed the rules before extraction; **DEC-181 amended them** after
6
+ * re-counting in the unit the rules decide, and that amendment is most of what
7
+ * is load-bearing here.
8
+ *
9
+ * ## The evidence is on an ancestor and the subject is the descendant
10
+ *
11
+ * DEC-128 §1a admits a method carrying `[HttpGet]` on a controller, where a
12
+ * controller is `[ApiController]` or a `ControllerBase` base. Counted in files:
13
+ *
14
+ * | corpus | files with a verb attribute | directly admissible | **need the base chain** |
15
+ * | --- | --- | --- | --- |
16
+ * | `jellyfin` | 62 | **1** | **61** |
17
+ * | `Ocelot` | 9 | 9 | 0 |
18
+ * | `eShopOnWeb` | 4 | 3 | 1 |
19
+ *
20
+ * Every `jellyfin` controller is `class XController : BaseJellyfinApiController`,
21
+ * and the base carries `[ApiController]` and `[Route("[controller]")]`. **A reader
22
+ * checking the class itself admits 1 of 62 and emits nothing for ~400 verb
23
+ * attributes** — a silent recall hole, which the precision apparatus is
24
+ * structurally blind to.
25
+ *
26
+ * This is the **third instance of one construct class**: the evidence sits on an
27
+ * ancestor and the subject is the descendant. JPA's `@MappedSuperclass` cost a
28
+ * third of an entity population; this is 98% of a corpus. It is checked for by
29
+ * name now rather than met by surprise.
30
+ *
31
+ * ## `[controller]` expands against the SUBJECT class, not the declaring one
32
+ *
33
+ * The `[Route("[controller]")]` governing 61 `jellyfin` controllers is declared
34
+ * **once, on the base**. A reader expanding the token where it finds the
35
+ * attribute produces `BaseJellyfinApi` sixty-one times — **one wrong template,
36
+ * sixty-one routes**. That is a wrong answer where the recall hole above is only
37
+ * a silence, and rule 2 does not treat them the same.
38
+ *
39
+ * The template is inherited; the *name substituted into it* never is.
40
+ *
41
+ * ## A derived `[Route]` REPLACES an inherited one — it does not join
42
+ *
43
+ * `ActivityLogController` carries `[Route("System/ActivityLog")]` while
44
+ * inheriting `[Route("[controller]")]`. ASP.NET takes the most-derived; they do
45
+ * not concatenate.
46
+ *
47
+ * §1a *does* join a class template to a method template, and the two joins look
48
+ * alike — which is the trap. **Before reusing a composition rule on a new pair,
49
+ * establish that the new pair composes at all.** Class↔method concatenates;
50
+ * class↔base overrides.
51
+ *
52
+ * ## Both mechanisms, counted apart
53
+ *
54
+ * | corpus | verb attributes | `Map*` | `MapGroup` |
55
+ * | --- | --- | --- | --- |
56
+ * | `jellyfin` | 400 | 0 | 0 |
57
+ * | `Ocelot` | 19 | 3 | 0 |
58
+ * | `eShopOnWeb` | 26 | 7 | 0 |
59
+ * | `CleanArchitecture` | **0** | **15** | **1** |
60
+ *
61
+ * `CleanArchitecture` is attribute-free and `jellyfin` is minimal-API-free, so an
62
+ * extractor supporting one mechanism scores zero on a whole corpus rather than a
63
+ * degraded number. Counted separately so a total miss cannot average into a
64
+ * healthy-looking figure. **`MapGroup` has one witness in the entire control set**
65
+ * — stated rather than discovered later, because a rule with one witness is not
66
+ * measured.
67
+ */
68
+ import type { CsFile } from "./parse.ts";
69
+ export interface AspNetRoute {
70
+ readonly method: string;
71
+ /** The joined template, normalised. `{id:int}` and `{id?}` both give `{param}`. */
72
+ readonly template: string;
73
+ /** The template before normalisation, for the ledger. */
74
+ readonly written: string;
75
+ readonly line: number;
76
+ readonly file: string;
77
+ /** The declaring type's nesting path plus the handler name. */
78
+ readonly handlerPath: readonly string[];
79
+ readonly mechanism: "attribute" | "minimal";
80
+ readonly framework: string;
81
+ }
82
+ /**
83
+ * A class whose own controller status could not be determined because an
84
+ * ancestor's base name left the analysed set (an external NuGet package, most
85
+ * often `Ardalis.ApiEndpoints`). See {@link AspNetCensus.unresolvedBaseSites}.
86
+ */
87
+ export interface AspNetUnresolvedBaseSite {
88
+ /** Nesting path including the class's own name, outermost first. */
89
+ readonly path: readonly string[];
90
+ readonly file: string;
91
+ readonly line: number;
92
+ /** The base name the chain could not resolve. */
93
+ readonly base: string;
94
+ }
95
+ export interface AspNetCensus {
96
+ readonly routes: readonly AspNetRoute[];
97
+ /** Controllers whose own declaration carried the evidence. */
98
+ readonly admittedDirectly: number;
99
+ /** Controllers admitted only by walking the base chain. DEC-181 §1. */
100
+ readonly admittedViaBaseChain: number;
101
+ /** Base names that resolve to more than one analysed type; the walk stops. */
102
+ readonly ambiguousBaseNames: readonly string[];
103
+ /** Base names that leave the analysed set; not assumed to reach ControllerBase. */
104
+ readonly baseChainsLeftAnalysedSet: number;
105
+ /**
106
+ * **Which** base names left the set, with a count each.
107
+ *
108
+ * A bare total is not actionable. `eShopOnWeb` reports 30 chains leaving the
109
+ * analysed set and at least one of them —
110
+ * `EndpointBaseAsync.WithRequest<T>.WithActionResult<T>` from
111
+ * `Ardalis.ApiEndpoints` — is a **real controller base serving real routes**
112
+ * that this graph does not have.
113
+ *
114
+ * The gap is not closable by reading the name: admitting a class because its
115
+ * base is *called* something ending in `Endpoint` is the name rule this
116
+ * project forbids, and it is what pattern 15 exists to punish. Closing it
117
+ * honestly needs the package analysed, and dependencies are never installed
118
+ * here. So it is **named** instead, which is the difference between a
119
+ * disclosed gap a reader can act on and a number they cannot.
120
+ */
121
+ readonly unresolvedBases: readonly {
122
+ readonly name: string;
123
+ readonly count: number;
124
+ }[];
125
+ /**
126
+ * The same population as {@link unresolvedBases}, per site rather than
127
+ * aggregated by base name — what `extract.ts` actually ledgers. D-FIX-3's
128
+ * own finding: before this field existed, `unresolvedBases`'s aggregate
129
+ * count was computed correctly and never reached `emit()`'s own
130
+ * `unresolved: UnresolvedRef[]` — a real refusal, silently dropped between
131
+ * this census and the graph a caller actually reads. See `extract.ts`'s
132
+ * own `SERVES_API` ledger call for where this closes.
133
+ */
134
+ readonly unresolvedBaseSites: readonly AspNetUnresolvedBaseSite[];
135
+ /** Mapping sites whose path is not a literal. Refused, per DEC-128 §1. */
136
+ readonly refusedNonLiteral: number;
137
+ /** `[controller]` tokens expanded, and tokens this reader does not know. */
138
+ readonly tokensExpanded: number;
139
+ readonly tokensUnknown: number;
140
+ /** `MapGroup` calls whose prefix is a literal and was bound to a variable. */
141
+ readonly mapGroupsSeen: number;
142
+ /**
143
+ * `Map*` sites whose receiver is not a known group in a file that declares
144
+ * groups. Refused, because the route may belong to one.
145
+ *
146
+ * DEC-128 §1b: *"where that is unavailable the route is emitted with its
147
+ * suffix only and flagged unresolved, never silently as if the suffix were the
148
+ * whole path."* The first version of this file emitted suffix-only with no
149
+ * flag — a violation of the rule this lane wrote, found by adding the corpus
150
+ * the gap register said was missing.
151
+ */
152
+ readonly minimalRefusedUnknownGroup: number;
153
+ }
154
+ /**
155
+ * Does this file import ASP.NET's routing surface? Provenance, not spelling.
156
+ *
157
+ * **A `global using` counts and is in force across the assembly**, which is how
158
+ * modern C# is written — .NET 6 onward emits an implicit global-usings file per
159
+ * project. `efcore.ts` records the measured cost of ignoring it: nine `DbSet<T>`
160
+ * read as zero because the `using` sat three files away.
161
+ *
162
+ * Scoped by assembly, because a global using in one project does not reach
163
+ * another.
164
+ */
165
+ export declare function importsAspNet(file: CsFile, globalsByAssembly?: ReadonlyMap<string, boolean>): boolean;
166
+ /**
167
+ * Normalise a route template to its joinable form.
168
+ *
169
+ * `{id}`, `{id:int}`, `{id:guid}`, `{id?}` and `{*rest}` all serve the same URL
170
+ * shape and must mint the same endpoint id, or a caller in another language
171
+ * joins to nothing. Golden 04's note names `{id:guid}` explicitly.
172
+ *
173
+ * The *written* form is kept beside this one. Identity normalises and fidelity
174
+ * preserves; collapsing to one deletes a fact that surfaces as a clean zero
175
+ * somewhere else.
176
+ */
177
+ export declare function normaliseTemplate(written: string): string;
178
+ /**
179
+ * Expand `[controller]`, `[action]` and `[area]` against the **subject**.
180
+ *
181
+ * `subject` is the most-derived class the route is being computed for, never the
182
+ * class that declared the attribute — see the file comment. `[controller]` drops
183
+ * the `Controller` suffix, which is the framework's own rule and the one place a
184
+ * class name legitimately enters a path.
185
+ *
186
+ * A token this reader does not know yields `undefined`: the route is refused and
187
+ * logged rather than emitted with a guessed path.
188
+ */
189
+ export declare function expandTokens(template: string, subject: string, action: string): {
190
+ expanded: string;
191
+ tokens: number;
192
+ } | undefined;
193
+ export interface AspNetInput {
194
+ readonly files: readonly {
195
+ readonly parsed: CsFile;
196
+ readonly source: string;
197
+ }[];
198
+ }
199
+ /**
200
+ * Every route the batch declares, with the admission accounting reported.
201
+ *
202
+ * Cross-file by necessity: the evidence making a class a controller is usually on
203
+ * a base declared elsewhere. Same shape as JPA's mapped-superclass walk, for the
204
+ * same construct.
205
+ */
206
+ export declare function aspNetRoutes(input: AspNetInput): AspNetCensus;
207
+ //# sourceMappingURL=aspnetcore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aspnetcore.d.ts","sourceRoot":"","sources":["../src/aspnetcore.ts"],"names":[],"mappings":"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"}