@descryy/adapter-go 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.
- package/dist/adapter.d.ts +26 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +247 -0
- package/dist/adapter.js.map +1 -0
- package/dist/client.d.ts +114 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +342 -0
- package/dist/client.js.map +1 -0
- package/dist/extract.d.ts +54 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +871 -0
- package/dist/extract.js.map +1 -0
- package/dist/grpc.d.ts +62 -0
- package/dist/grpc.d.ts.map +1 -0
- package/dist/grpc.js +112 -0
- package/dist/grpc.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/modules.d.ts +37 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +83 -0
- package/dist/modules.js.map +1 -0
- package/dist/parse.d.ts +215 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +890 -0
- package/dist/parse.js.map +1 -0
- package/dist/routes.d.ts +92 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +661 -0
- package/dist/routes.js.map +1 -0
- package/dist/tree-sitter-go.wasm +0 -0
- package/package.json +35 -0
package/dist/client.js
ADDED
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The caller's half of the HTTP boundary: `USES_API`, golden pattern 08.
|
|
3
|
+
*
|
|
4
|
+
* `SERVES_API` is minted in `routes.ts`/`extract.ts` from a route registration.
|
|
5
|
+
* This reads the other end — an outbound call with a statically knowable path —
|
|
6
|
+
* and mints the **same** `API_ENDPOINT` node from the same `endpointQsp`, so the
|
|
7
|
+
* two join without either side knowing the other ran (DEC-115).
|
|
8
|
+
*
|
|
9
|
+
* FUNCTION ──USES_API──▶ API_ENDPOINT ◀──SERVES_API── API_ROUTE
|
|
10
|
+
*
|
|
11
|
+
* ## Structured like `routes.ts`, not like Java's `client.ts`
|
|
12
|
+
*
|
|
13
|
+
* Java's client reader walks `JavaRef` — a flat, already-collected list of
|
|
14
|
+
* references with a `firstStringArgument` field captured at parse time. Go has
|
|
15
|
+
* no equivalent: `GoRef` keeps a short `raw` summary but not positional argument
|
|
16
|
+
* access, because nothing before this needed it. `net/http.NewRequest(method,
|
|
17
|
+
* url, body)` needs **two** literal positions read out of one call — the verb
|
|
18
|
+
* and the path both — so this reads `call_expression` nodes directly off the
|
|
19
|
+
* tree, the same shape `routes.ts`'s `readCall` already uses for the provider
|
|
20
|
+
* side of this exact boundary.
|
|
21
|
+
*
|
|
22
|
+
* ## Three shapes, one budget
|
|
23
|
+
*
|
|
24
|
+
* | shape | evidence |
|
|
25
|
+
* | --- | --- |
|
|
26
|
+
* | `http.Get(url)` / `Head` / `Post` / `PostForm` | the receiver is the `net/http` package itself, resolved through the file's own import table |
|
|
27
|
+
* | `client.Get(url)` / `Head` / `Post` / `PostForm` / `Do(req)` | the receiver's **declared type** is `http.Client` (pointer stripped), from a parameter, a `:=` composite literal, or a `var` |
|
|
28
|
+
* | `http.NewRequest(method, url, body)` / `NewRequestWithContext(ctx, method, url, body)` | the receiver is the `net/http` package; verb **and** path are both this call's own arguments — the verb as a string literal or one of `net/http`'s own exported `Method*` constants, the path as a string literal |
|
|
29
|
+
*
|
|
30
|
+
* `Do(req)` is refused unconditionally, never traced back to whatever built
|
|
31
|
+
* `req` — the same shape Java's `OkHttpClient`/`java.net.http.HttpClient`
|
|
32
|
+
* builder-client rows are refused for (D-FIX-3): the request is a separately
|
|
33
|
+
* constructed object, and reading through a builder chain to find where it was
|
|
34
|
+
* built is a different, larger row. `NewRequest`'s own call is a separate,
|
|
35
|
+
* independent extraction site — its literal arguments are read directly, never
|
|
36
|
+
* traced forward into whatever `.Do()` call eventually consumes the request it
|
|
37
|
+
* returns, so nothing here double-counts one HTTP call as two edges.
|
|
38
|
+
*
|
|
39
|
+
* ## Why the receiver's type must be written down
|
|
40
|
+
*
|
|
41
|
+
* `Get`, `Post`, `Do` are ordinary method names — a cache client, a mock, a
|
|
42
|
+
* test double could all have one. Admitting a call on the name alone would emit
|
|
43
|
+
* `USES_API` for anything shaped like `thing.Get(x)`, joining a caller to a
|
|
44
|
+
* route it never calls. So `client.*` is only admitted when the receiver's
|
|
45
|
+
* declared type resolves, through the import table, to `net/http.Client` —
|
|
46
|
+
* the same discipline `routes.ts` already holds for `NewServeMux`.
|
|
47
|
+
*
|
|
48
|
+
* ## The origin check, reused rather than re-derived
|
|
49
|
+
*
|
|
50
|
+
* `namesAnotherOrigin`/`relativePath` are copied verbatim from
|
|
51
|
+
* `adapter-java/src/client.ts` (via `adapter-csharp`'s DEC-260/261 fix): only an
|
|
52
|
+
* unambiguous absolute form (an explicit scheme, or `//host/...`) earns
|
|
53
|
+
* "another origin"; a bare relative path with no leading slash is `undetermined`
|
|
54
|
+
* — it may resolve against a `Client.BaseURL` this reader does not see, or it
|
|
55
|
+
* may not, and claiming either is a guess. This project has now found the
|
|
56
|
+
* identical latent bug in three languages that copied "does not start with a
|
|
57
|
+
* scheme" as sufficient evidence; the fourth and fifth (Rust, Ruby, PHP) reuse
|
|
58
|
+
* this same text rather than re-deriving it a fourth time.
|
|
59
|
+
*/
|
|
60
|
+
import { endpointQsp, nodeId } from "@descryy/ir";
|
|
61
|
+
const HTTP_PACKAGE = "net/http";
|
|
62
|
+
/** Convenience methods whose name states the verb, on either the package or a `*Client`. */
|
|
63
|
+
const VERB_METHODS = new Map([
|
|
64
|
+
["Get", "GET"],
|
|
65
|
+
["Head", "HEAD"],
|
|
66
|
+
["Post", "POST"],
|
|
67
|
+
["PostForm", "POST"],
|
|
68
|
+
]);
|
|
69
|
+
/**
|
|
70
|
+
* `net/http`'s own exported verb constants — `http.MethodGet`, and so on.
|
|
71
|
+
*
|
|
72
|
+
* Reading these is resolution, not inference: `http.MethodGet`'s value is
|
|
73
|
+
* fixed by the stdlib's own public API (RFC 7231's registered methods), the
|
|
74
|
+
* same way `http.NewServeMux` names a known constructor in `routes.ts`. This
|
|
75
|
+
* is the idiomatic form: on `gin` and `prometheus`, `http.NewRequest(http.MethodGet,
|
|
76
|
+
* ...)` outnumbers a bare `"GET"` string literal by a wide margin. Missing it
|
|
77
|
+
* would have meant refusing nearly every real `NewRequest` call in both
|
|
78
|
+
* corpora as "not a bare string literal" — technically true of the argument's
|
|
79
|
+
* *node type*, but not of what the source actually states.
|
|
80
|
+
*/
|
|
81
|
+
const HTTP_METHOD_CONSTANTS = new Map([
|
|
82
|
+
["MethodGet", "GET"],
|
|
83
|
+
["MethodHead", "HEAD"],
|
|
84
|
+
["MethodPost", "POST"],
|
|
85
|
+
["MethodPut", "PUT"],
|
|
86
|
+
["MethodPatch", "PATCH"],
|
|
87
|
+
["MethodDelete", "DELETE"],
|
|
88
|
+
["MethodConnect", "CONNECT"],
|
|
89
|
+
["MethodOptions", "OPTIONS"],
|
|
90
|
+
["MethodTrace", "TRACE"],
|
|
91
|
+
]);
|
|
92
|
+
const CAPABILITY_GAP = { blockedBy: null, refusalClass: "capability-gap" };
|
|
93
|
+
const VARIES_PER_CALL = { blockedBy: null, refusalClass: "varies-per-call" };
|
|
94
|
+
/** `os.Getenv("X")`, `os.LookupEnv("X")` — the stdlib's own env-read functions. */
|
|
95
|
+
const ENV_READ_PATTERNS = [/^os\.Getenv\(\s*"[^"]*"\s*\)$/, /^os\.LookupEnv\(\s*"[^"]*"\s*\)$/];
|
|
96
|
+
/** Same heuristic as every other adapter's — see `adapter-rust/src/client.ts`'s doc. */
|
|
97
|
+
function argumentKindOf(text) {
|
|
98
|
+
if (text.endsWith(")") && text.includes("("))
|
|
99
|
+
return "call";
|
|
100
|
+
if (text.includes("+"))
|
|
101
|
+
return "concatenation";
|
|
102
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(text))
|
|
103
|
+
return "field";
|
|
104
|
+
return "other";
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Why an argument node could not be read as a literal path — a bare
|
|
108
|
+
* identifier that is the enclosing function's own input parameter, a known
|
|
109
|
+
* environment-read call, or something this reader does not trace.
|
|
110
|
+
*/
|
|
111
|
+
function diagnoseArgument(text, parameterNames) {
|
|
112
|
+
if (text === undefined)
|
|
113
|
+
return CAPABILITY_GAP;
|
|
114
|
+
const trimmed = text.trim();
|
|
115
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(trimmed) && parameterNames.has(trimmed))
|
|
116
|
+
return VARIES_PER_CALL;
|
|
117
|
+
if (ENV_READ_PATTERNS.some((pattern) => pattern.test(trimmed))) {
|
|
118
|
+
return { blockedBy: trimmed, refusalClass: "value-unknown" };
|
|
119
|
+
}
|
|
120
|
+
return { ...CAPABILITY_GAP, argumentKind: argumentKindOf(trimmed) };
|
|
121
|
+
}
|
|
122
|
+
/** The text of a string literal, or `undefined` for anything assembled elsewhere. */
|
|
123
|
+
function literalOf(node) {
|
|
124
|
+
if (node === null)
|
|
125
|
+
return undefined;
|
|
126
|
+
if (node.type !== "interpreted_string_literal" && node.type !== "raw_string_literal")
|
|
127
|
+
return undefined;
|
|
128
|
+
const text = node.text;
|
|
129
|
+
if (text.includes("\\"))
|
|
130
|
+
return undefined;
|
|
131
|
+
return text.replace(/^["`]|["`]$/g, "");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A path this reader will claim: repository-relative, no scheme, no assembly.
|
|
135
|
+
*
|
|
136
|
+
* Copied from `adapter-java`/`adapter-csharp`'s `client.ts` — see this file's
|
|
137
|
+
* own header for why re-derivation is exactly what this row was told not to do.
|
|
138
|
+
*/
|
|
139
|
+
function relativePath(value) {
|
|
140
|
+
if (!value.startsWith("/"))
|
|
141
|
+
return undefined;
|
|
142
|
+
if (value.startsWith("//"))
|
|
143
|
+
return undefined;
|
|
144
|
+
const cut = value.indexOf("?");
|
|
145
|
+
return cut === -1 ? value : value.slice(0, cut);
|
|
146
|
+
}
|
|
147
|
+
/** A literal that unambiguously names a *different* origin. Copied, not re-derived. */
|
|
148
|
+
function namesAnotherOrigin(value) {
|
|
149
|
+
return /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(value) || value.startsWith("//");
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Does `base` (as written at a call site) resolve to `net/http` through this
|
|
153
|
+
* file's own import table? The alias may not be `http` — `import xhttp "net/http"`
|
|
154
|
+
* is legal Go, and the import table is exactly what already resolves it.
|
|
155
|
+
*/
|
|
156
|
+
function isHttpPackage(base, unit) {
|
|
157
|
+
return unit.imports.get(base) === HTTP_PACKAGE;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* A verb, from either a string literal (`"GET"`, case-normalised) or one of
|
|
161
|
+
* `net/http`'s own exported constants (`http.MethodGet`) — see
|
|
162
|
+
* {@link HTTP_METHOD_CONSTANTS}.
|
|
163
|
+
*/
|
|
164
|
+
function verbOf(node, unit) {
|
|
165
|
+
const literal = literalOf(node);
|
|
166
|
+
if (literal !== undefined)
|
|
167
|
+
return literal.toUpperCase();
|
|
168
|
+
if (node === null || node.type !== "selector_expression")
|
|
169
|
+
return undefined;
|
|
170
|
+
const operand = node.childForFieldName("operand");
|
|
171
|
+
const field = node.childForFieldName("field");
|
|
172
|
+
if (operand === null || field === null || operand.type !== "identifier")
|
|
173
|
+
return undefined;
|
|
174
|
+
if (!isHttpPackage(operand.text, unit))
|
|
175
|
+
return undefined;
|
|
176
|
+
return HTTP_METHOD_CONSTANTS.get(field.text);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Does a written type name (pointer already stripped by `baseTypeName`, e.g.
|
|
180
|
+
* `"http.Client"` or `"xhttp.Client"`) resolve to `net/http.Client`?
|
|
181
|
+
*
|
|
182
|
+
* `baseTypeName` returns a `qualified_type`'s text verbatim — whatever
|
|
183
|
+
* qualifier the source actually wrote — so the qualifier is resolved through
|
|
184
|
+
* the import table exactly as {@link isHttpPackage} does for a package-level
|
|
185
|
+
* call, rather than string-matched against the literal text `"http.Client"`.
|
|
186
|
+
*/
|
|
187
|
+
function isHttpClientType(written, unit) {
|
|
188
|
+
if (written === null || written === undefined)
|
|
189
|
+
return false;
|
|
190
|
+
const cut = written.indexOf(".");
|
|
191
|
+
if (cut === -1)
|
|
192
|
+
return false;
|
|
193
|
+
const qualifier = written.slice(0, cut);
|
|
194
|
+
const name = written.slice(cut + 1);
|
|
195
|
+
return name === "Client" && unit.imports.get(qualifier) === HTTP_PACKAGE;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Every outbound HTTP call in one function body, with a ledger row for each
|
|
199
|
+
* refusal.
|
|
200
|
+
*
|
|
201
|
+
* `locals` is the function's **already-fully-walked** local table — parameters
|
|
202
|
+
* and `:=`/`var` declarations alike — so a `*http.Client` parameter and a
|
|
203
|
+
* `client := &http.Client{}` local are both visible with no separate pass. It
|
|
204
|
+
* is read, never written: this module adds no new declarations to it.
|
|
205
|
+
*/
|
|
206
|
+
export function readGoClientCalls(body, unit, locals, isTest, parameterNames = new Set()) {
|
|
207
|
+
const calls = [];
|
|
208
|
+
const refusals = [];
|
|
209
|
+
const callerKind = isTest ? "test" : "production";
|
|
210
|
+
const admit = (method, verb, rawUrl, line) => {
|
|
211
|
+
const template = relativePath(rawUrl);
|
|
212
|
+
if (template !== undefined) {
|
|
213
|
+
calls.push({ method, verb, template, line, callerKind });
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (namesAnotherOrigin(rawUrl)) {
|
|
217
|
+
refusals.push({
|
|
218
|
+
raw: `${method}(${rawUrl})`,
|
|
219
|
+
line,
|
|
220
|
+
reason: `an HTTP call to \`${rawUrl}\`, which names another origin rather than a path in this repository. A scope boundary, not a gap.`,
|
|
221
|
+
blockedBy: null,
|
|
222
|
+
refusalClass: "out-of-scope",
|
|
223
|
+
});
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
refusals.push({
|
|
227
|
+
raw: `${method}(${rawUrl})`,
|
|
228
|
+
line,
|
|
229
|
+
reason: `an HTTP call to \`${rawUrl}\`, a relative path with no leading slash. This reader cannot tell ` +
|
|
230
|
+
`whether it resolves inside this repository — against a base URL this call site does not state ` +
|
|
231
|
+
`— or elsewhere, so neither an endpoint nor a scope boundary is claimed.`,
|
|
232
|
+
// Not a per-call value and not a named blocking expression either —
|
|
233
|
+
// this reader just cannot see the base configuration.
|
|
234
|
+
...CAPABILITY_GAP,
|
|
235
|
+
});
|
|
236
|
+
};
|
|
237
|
+
const readCall = (call) => {
|
|
238
|
+
const callee = call.childForFieldName("function");
|
|
239
|
+
if (callee === null || callee.type !== "selector_expression")
|
|
240
|
+
return;
|
|
241
|
+
const base = callee.childForFieldName("operand");
|
|
242
|
+
const member = callee.childForFieldName("field");
|
|
243
|
+
if (base === null || member === null || base.type !== "identifier")
|
|
244
|
+
return;
|
|
245
|
+
const method = member.text;
|
|
246
|
+
const line = call.startPosition.row + 1;
|
|
247
|
+
const args = call.childForFieldName("arguments");
|
|
248
|
+
const receiverIsPackage = isHttpPackage(base.text, unit);
|
|
249
|
+
const receiverIsClient = isHttpClientType(locals.get(base.text), unit);
|
|
250
|
+
if (!receiverIsPackage && !receiverIsClient)
|
|
251
|
+
return;
|
|
252
|
+
if (method === "NewRequest" || method === "NewRequestWithContext") {
|
|
253
|
+
if (!receiverIsPackage)
|
|
254
|
+
return;
|
|
255
|
+
// `NewRequest(method, url, body)` / `NewRequestWithContext(ctx, method, url, body)`.
|
|
256
|
+
const skip = method === "NewRequestWithContext" ? 1 : 0;
|
|
257
|
+
const methodArg = args?.namedChild(skip) ?? null;
|
|
258
|
+
const urlArg = args?.namedChild(skip + 1) ?? null;
|
|
259
|
+
const verb = verbOf(methodArg, unit);
|
|
260
|
+
const rawUrl = literalOf(urlArg);
|
|
261
|
+
if (verb === undefined || rawUrl === undefined) {
|
|
262
|
+
refusals.push({
|
|
263
|
+
raw: `${base.text}.${method}(...)`,
|
|
264
|
+
line,
|
|
265
|
+
reason: `an HTTP request construction whose method is neither a bare string literal nor one of ` +
|
|
266
|
+
`net/http's own exported Method constants, or whose URL is not a bare string literal — a ` +
|
|
267
|
+
`variable, a concatenation, or an expression this reader does not evaluate.`,
|
|
268
|
+
// The URL is the argument DEC-242 cares about naming; a bad verb
|
|
269
|
+
// with a fine URL has nothing to name and stays capability-gap.
|
|
270
|
+
...(rawUrl === undefined ? diagnoseArgument(urlArg?.text, parameterNames) : CAPABILITY_GAP),
|
|
271
|
+
});
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
admit(`${base.text}.${method}`, verb, rawUrl, line);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
if (method === "Do") {
|
|
278
|
+
if (!receiverIsClient)
|
|
279
|
+
return;
|
|
280
|
+
refusals.push({
|
|
281
|
+
raw: `${base.text}.Do(...)`,
|
|
282
|
+
line,
|
|
283
|
+
reason: `an HTTP call through a *http.Client, via a *http.Request built in a separate expression — ` +
|
|
284
|
+
`this adapter reads only \`http.NewRequest\`/\`http.NewRequestWithContext\`'s own literal ` +
|
|
285
|
+
`arguments, not a request assembled elsewhere and passed in.`,
|
|
286
|
+
...CAPABILITY_GAP,
|
|
287
|
+
});
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const verb = VERB_METHODS.get(method);
|
|
291
|
+
if (verb === undefined)
|
|
292
|
+
return;
|
|
293
|
+
// `Get`/`Head`/`Post`/`PostForm` all take the URL as their first argument.
|
|
294
|
+
const urlArg = args?.namedChild(0) ?? null;
|
|
295
|
+
const rawUrl = literalOf(urlArg);
|
|
296
|
+
if (rawUrl === undefined) {
|
|
297
|
+
refusals.push({
|
|
298
|
+
raw: `${base.text}.${method}(...)`,
|
|
299
|
+
line,
|
|
300
|
+
reason: `an HTTP call through ${receiverIsPackage ? "the net/http package" : "a *http.Client"} whose ` +
|
|
301
|
+
`path is not a bare string literal — a variable, a concatenation, or an expression this ` +
|
|
302
|
+
`reader does not evaluate.`,
|
|
303
|
+
...diagnoseArgument(urlArg?.text, parameterNames),
|
|
304
|
+
});
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
admit(`${base.text}.${method}`, verb, rawUrl, line);
|
|
308
|
+
};
|
|
309
|
+
const visit = (node) => {
|
|
310
|
+
if (node.type === "call_expression")
|
|
311
|
+
readCall(node);
|
|
312
|
+
for (let i = 0; i < node.namedChildCount; i += 1) {
|
|
313
|
+
const child = node.namedChild(i);
|
|
314
|
+
if (child !== null)
|
|
315
|
+
visit(child);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
visit(body);
|
|
319
|
+
return { calls, refusals };
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The `API_ENDPOINT` a call joins to — minted identically to the route side.
|
|
323
|
+
*
|
|
324
|
+
* Shares `endpointQsp` with `extract.ts`'s `SERVES_API` block, so the two ids
|
|
325
|
+
* agree exactly. DEC-115's one hard constraint: two producers that mint
|
|
326
|
+
* different ids for the same route do not conflict, they silently fail to join.
|
|
327
|
+
*/
|
|
328
|
+
export function endpointFor(scope, call, producedBy, normalise) {
|
|
329
|
+
const template = normalise(call.template);
|
|
330
|
+
return {
|
|
331
|
+
id: nodeId(scope, "API_ENDPOINT", endpointQsp(call.verb, call.template), null),
|
|
332
|
+
type: "API_ENDPOINT",
|
|
333
|
+
name: `${call.verb} ${template}`,
|
|
334
|
+
file: null,
|
|
335
|
+
range: null,
|
|
336
|
+
language: null,
|
|
337
|
+
producedBy,
|
|
338
|
+
resolution: 2,
|
|
339
|
+
attrs: { method: call.verb, pathTemplate: template },
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Go files to Canonical IR.
|
|
3
|
+
*
|
|
4
|
+
* ## The package is the unit, and that changes resolution rather than identity
|
|
5
|
+
*
|
|
6
|
+
* Files in one Go package share a namespace completely: an unqualified name in
|
|
7
|
+
* one file resolves to a declaration in another that never mentions it. So the
|
|
8
|
+
* resolver's first scope is not the file but the package, which is the opposite
|
|
9
|
+
* of Java and TypeScript, where a file must import what it uses.
|
|
10
|
+
*
|
|
11
|
+
* Identity is the easy half. A package's import path is a declared name that
|
|
12
|
+
* other code writes verbatim, so `qsp = importPath::Symbol` needs none of the
|
|
13
|
+
* anchor inference TypeScript needs (DEC-047) or the source-set disambiguation
|
|
14
|
+
* Java needs. Go states it.
|
|
15
|
+
*
|
|
16
|
+
* ## What is deliberately not claimed
|
|
17
|
+
*
|
|
18
|
+
* **Interface satisfaction.** Go's is structural: a type implements an interface
|
|
19
|
+
* by having the right methods, and nothing in the source says so. Computing it
|
|
20
|
+
* needs full method-set comparison, which is R3 evidence, and guessing it from
|
|
21
|
+
* name similarity would be exactly the kind of edge that corrupts every layer
|
|
22
|
+
* above. `IMPLEMENTS` is therefore never emitted, and `capabilities()` says so.
|
|
23
|
+
* Embedding *is* explicit and becomes `INHERITS`.
|
|
24
|
+
*
|
|
25
|
+
* `:=` with anything but a composite literal, dot imports, and any receiver that
|
|
26
|
+
* is not a written name all go to the ledger with their reason.
|
|
27
|
+
*/
|
|
28
|
+
import { type IdentityScope, type IREdge, type IRNode, type ResolutionLevel, type UnresolvedRef } from "@descryy/ir";
|
|
29
|
+
import type { GoFile } from "./parse.ts";
|
|
30
|
+
export declare const LANGUAGE = "go";
|
|
31
|
+
declare const REASONS: {
|
|
32
|
+
readonly outside: string;
|
|
33
|
+
readonly unmodelled: string;
|
|
34
|
+
readonly untypedReceiver: string;
|
|
35
|
+
readonly dotImport: string;
|
|
36
|
+
readonly noImportPath: string;
|
|
37
|
+
readonly unknownName: "no declaration for this name in the package, its imports, or the analysed set.";
|
|
38
|
+
readonly routeIdCollision: string;
|
|
39
|
+
};
|
|
40
|
+
export interface ExtractInput {
|
|
41
|
+
readonly repo: string;
|
|
42
|
+
readonly scope: IdentityScope;
|
|
43
|
+
readonly producedBy: string;
|
|
44
|
+
readonly reached: ResolutionLevel;
|
|
45
|
+
readonly files: readonly GoFile[];
|
|
46
|
+
}
|
|
47
|
+
export interface Extraction {
|
|
48
|
+
readonly nodes: readonly IRNode[];
|
|
49
|
+
readonly edges: readonly IREdge[];
|
|
50
|
+
readonly unresolved: readonly UnresolvedRef[];
|
|
51
|
+
}
|
|
52
|
+
export declare function extract(input: ExtractInput): Extraction;
|
|
53
|
+
export { REASONS };
|
|
54
|
+
//# sourceMappingURL=extract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAOL,KAAK,aAAa,EAClB,KAAK,MAAM,EACX,KAAK,MAAM,EACX,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,MAAM,EAA6C,MAAM,YAAY,CAAC;AAGpF,eAAO,MAAM,QAAQ,OAAO,CAAC;AAI7B,QAAA,MAAM,OAAO;;;;;;;;CAqBH,CAAC;AAEX,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;CAC/C;AAoDD,wBAAgB,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,CA40BvD;AAED,OAAO,EAAE,OAAO,EAAE,CAAC"}
|