@c4a/extract-go 0.7.4 → 0.7.8
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/index.js +107 -6
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -12099,6 +12099,44 @@ function functionSignature(node2) {
|
|
|
12099
12099
|
function symbolId(filePath, kind, qualifiedName) {
|
|
12100
12100
|
return `go:${filePath}#${kind}:${qualifiedName}`;
|
|
12101
12101
|
}
|
|
12102
|
+
function declaredParameters(node2) {
|
|
12103
|
+
if (node2 === null)
|
|
12104
|
+
return [];
|
|
12105
|
+
if (node2.type !== "parameter_list")
|
|
12106
|
+
return [{ name: "", type: node2.text, optional: false, rest: false }];
|
|
12107
|
+
return node2.namedChildren.flatMap((parameter) => {
|
|
12108
|
+
const type = parameter.childForFieldName("type");
|
|
12109
|
+
if (type === null)
|
|
12110
|
+
return [];
|
|
12111
|
+
const names = parameter.namedChildren.filter((child) => child.type === "identifier" && child.id !== type.id);
|
|
12112
|
+
const rest = parameter.type === "variadic_parameter_declaration";
|
|
12113
|
+
return (names.length === 0 ? [""] : names.map((name) => name.text)).map((name) => ({
|
|
12114
|
+
name,
|
|
12115
|
+
type: type.text,
|
|
12116
|
+
optional: rest,
|
|
12117
|
+
rest
|
|
12118
|
+
}));
|
|
12119
|
+
});
|
|
12120
|
+
}
|
|
12121
|
+
function declaredFields(node2, filePath) {
|
|
12122
|
+
const list = node2.namedChildren.find((child) => child.type === "field_declaration_list");
|
|
12123
|
+
return (list?.namedChildren ?? []).flatMap((field) => {
|
|
12124
|
+
if (field.type !== "field_declaration")
|
|
12125
|
+
return [];
|
|
12126
|
+
const type = field.childForFieldName("type");
|
|
12127
|
+
if (type === null)
|
|
12128
|
+
return [];
|
|
12129
|
+
const names = field.namedChildren.filter((child) => child.type === "field_identifier");
|
|
12130
|
+
const tag = field.childForFieldName("tag")?.text;
|
|
12131
|
+
return (names.length === 0 ? [type.text] : names.map((name) => name.text)).map((name) => ({
|
|
12132
|
+
name,
|
|
12133
|
+
type: type.text,
|
|
12134
|
+
embedded: names.length === 0,
|
|
12135
|
+
location: locationFor(filePath, field),
|
|
12136
|
+
...tag === undefined ? {} : { tag }
|
|
12137
|
+
}));
|
|
12138
|
+
});
|
|
12139
|
+
}
|
|
12102
12140
|
function extractSymbols(root, filePath, packageName, exportedOnly) {
|
|
12103
12141
|
const symbols = [];
|
|
12104
12142
|
for (const node2 of root.namedChildren) {
|
|
@@ -12119,6 +12157,8 @@ function extractSymbols(root, filePath, packageName, exportedOnly) {
|
|
|
12119
12157
|
...receiver ? { receiver } : {},
|
|
12120
12158
|
exported: isExported(name),
|
|
12121
12159
|
signature: functionSignature(node2),
|
|
12160
|
+
parameters: declaredParameters(node2.childForFieldName("parameters")),
|
|
12161
|
+
results: declaredParameters(node2.childForFieldName("result")),
|
|
12122
12162
|
...doc ? { doc } : {},
|
|
12123
12163
|
location: locationFor(filePath, node2)
|
|
12124
12164
|
});
|
|
@@ -12140,6 +12180,7 @@ function extractSymbols(root, filePath, packageName, exportedOnly) {
|
|
|
12140
12180
|
package: packageName,
|
|
12141
12181
|
exported: isExported(name),
|
|
12142
12182
|
signature: compact(`type ${name} ${typeNode.text}`),
|
|
12183
|
+
...kind2 === "struct" ? { fields: declaredFields(typeNode, filePath) } : {},
|
|
12143
12184
|
...doc ? { doc } : {},
|
|
12144
12185
|
location: locationFor(filePath, spec)
|
|
12145
12186
|
});
|
|
@@ -12189,7 +12230,7 @@ function unquoteGoString(value) {
|
|
|
12189
12230
|
return trimmed.slice(1, -1);
|
|
12190
12231
|
}
|
|
12191
12232
|
}
|
|
12192
|
-
function extractImports(root) {
|
|
12233
|
+
function extractImports(root, filePath) {
|
|
12193
12234
|
const imports = [];
|
|
12194
12235
|
for (const spec of descendants(root, "import_spec")) {
|
|
12195
12236
|
const pathNode = spec.childForFieldName("path") ?? spec.namedChildren.find((child) => child.type.endsWith("string_literal"));
|
|
@@ -12198,7 +12239,7 @@ function extractImports(root) {
|
|
|
12198
12239
|
continue;
|
|
12199
12240
|
const explicitAlias = spec.childForFieldName("name")?.text;
|
|
12200
12241
|
const alias = explicitAlias && explicitAlias !== "." && explicitAlias !== "_" ? explicitAlias : importPath.split("/").at(-1) ?? importPath;
|
|
12201
|
-
imports.push({ alias, path: importPath });
|
|
12242
|
+
imports.push({ alias, path: importPath, location: locationFor(filePath, spec) });
|
|
12202
12243
|
}
|
|
12203
12244
|
return imports.sort((left, right) => left.alias.localeCompare(right.alias) || left.path.localeCompare(right.path));
|
|
12204
12245
|
}
|
|
@@ -12320,7 +12361,7 @@ function indexGoSource(source, filePath, options = {}) {
|
|
|
12320
12361
|
throw new Error(`Go parser returned no syntax tree for ${filePath}`);
|
|
12321
12362
|
const root = tree.rootNode;
|
|
12322
12363
|
const packageName = descendants(root, "package_identifier")[0]?.text ?? "unknown";
|
|
12323
|
-
const imports = extractImports(root);
|
|
12364
|
+
const imports = extractImports(root, filePath);
|
|
12324
12365
|
const relations = extractCallsAndRoutes(root, filePath, imports);
|
|
12325
12366
|
return {
|
|
12326
12367
|
path: filePath,
|
|
@@ -12365,6 +12406,18 @@ function symbolInfo(filePath, symbol) {
|
|
|
12365
12406
|
line: symbol.location.startLine,
|
|
12366
12407
|
endLine: symbol.location.endLine,
|
|
12367
12408
|
signature: symbol.signature,
|
|
12409
|
+
...symbol.parameters === undefined ? {} : { params: symbol.parameters },
|
|
12410
|
+
...symbol.results === undefined ? {} : { returnType: symbol.results.map((item) => item.type).join(", ") || null },
|
|
12411
|
+
...symbol.fields === undefined ? {} : { members: symbol.fields.map((field) => ({
|
|
12412
|
+
name: field.name,
|
|
12413
|
+
kind: "prop" /* Prop */,
|
|
12414
|
+
visibility: /^[A-Z]/u.test(field.name) ? "exported" /* Exported */ : "internal" /* Internal */,
|
|
12415
|
+
file: filePath,
|
|
12416
|
+
line: field.location.startLine,
|
|
12417
|
+
endLine: field.location.endLine,
|
|
12418
|
+
typeAnnotation: field.type,
|
|
12419
|
+
...field.tag === undefined ? {} : { doc: field.tag }
|
|
12420
|
+
})) },
|
|
12368
12421
|
...symbol.doc ? { doc: symbol.doc } : {}
|
|
12369
12422
|
};
|
|
12370
12423
|
}
|
|
@@ -12432,6 +12485,18 @@ class GoPlugin {
|
|
|
12432
12485
|
const indexed = indexGoSource(source, entry.path, { exportedOnly: false });
|
|
12433
12486
|
files.push({ path: entry.path, language: "go", lines: indexed.lines });
|
|
12434
12487
|
symbols.push(...indexed.symbols.map((symbol) => symbolInfo(entry.path, symbol)));
|
|
12488
|
+
for (const imported of indexed.imports) {
|
|
12489
|
+
relations.push({
|
|
12490
|
+
type: "imports" /* Imports */,
|
|
12491
|
+
from: entry.path,
|
|
12492
|
+
to: imported.path,
|
|
12493
|
+
isExternal: true,
|
|
12494
|
+
grounding: "code" /* Code */,
|
|
12495
|
+
confidence: 1,
|
|
12496
|
+
source: "ast" /* Ast */,
|
|
12497
|
+
...imported.location === undefined ? {} : { line: imported.location.startLine }
|
|
12498
|
+
});
|
|
12499
|
+
}
|
|
12435
12500
|
for (const call of indexed.calls) {
|
|
12436
12501
|
if (!call.enclosingSymbol)
|
|
12437
12502
|
continue;
|
|
@@ -12454,7 +12519,14 @@ class GoPlugin {
|
|
|
12454
12519
|
file: entry.path,
|
|
12455
12520
|
line: route.location.startLine,
|
|
12456
12521
|
endLine: route.location.endLine,
|
|
12457
|
-
signature: `${route.method} ${route.path} -> ${route.handler}
|
|
12522
|
+
signature: `${route.method} ${route.path} -> ${route.handler}`,
|
|
12523
|
+
registration: {
|
|
12524
|
+
kind: "http",
|
|
12525
|
+
method: route.method,
|
|
12526
|
+
key: route.path,
|
|
12527
|
+
handler: route.handler,
|
|
12528
|
+
middleware: route.middleware
|
|
12529
|
+
}
|
|
12458
12530
|
});
|
|
12459
12531
|
}
|
|
12460
12532
|
}
|
|
@@ -12595,7 +12667,17 @@ var relationSourceSchema = exports_external.enum([
|
|
|
12595
12667
|
var packageKindSchema2 = exports_external.enum(Object.values(PackageKind));
|
|
12596
12668
|
var symbolParamSchema = exports_external.object({
|
|
12597
12669
|
name: exports_external.string().min(1),
|
|
12598
|
-
type: exports_external.string().min(1).nullable()
|
|
12670
|
+
type: exports_external.string().min(1).nullable(),
|
|
12671
|
+
optional: exports_external.boolean().optional(),
|
|
12672
|
+
rest: exports_external.boolean().optional(),
|
|
12673
|
+
defaultValue: exports_external.string().optional()
|
|
12674
|
+
});
|
|
12675
|
+
var registrationSchema = exports_external.object({
|
|
12676
|
+
kind: exports_external.enum(["http", "schedule", "event"]),
|
|
12677
|
+
key: exports_external.string(),
|
|
12678
|
+
handler: exports_external.string(),
|
|
12679
|
+
method: exports_external.string().optional(),
|
|
12680
|
+
middleware: exports_external.array(exports_external.string())
|
|
12599
12681
|
});
|
|
12600
12682
|
var symbolInfoSchema = exports_external.lazy(() => exports_external.object({
|
|
12601
12683
|
name: exports_external.string().min(1),
|
|
@@ -12606,6 +12688,14 @@ var symbolInfoSchema = exports_external.lazy(() => exports_external.object({
|
|
|
12606
12688
|
endLine: exports_external.number().int().positive(),
|
|
12607
12689
|
members: exports_external.array(symbolInfoSchema).optional(),
|
|
12608
12690
|
params: exports_external.array(symbolParamSchema).optional(),
|
|
12691
|
+
optional: exports_external.boolean().optional(),
|
|
12692
|
+
readonly: exports_external.boolean().optional(),
|
|
12693
|
+
defaultValue: exports_external.string().optional(),
|
|
12694
|
+
typeParameters: exports_external.string().optional(),
|
|
12695
|
+
overloads: exports_external.array(exports_external.string()).optional(),
|
|
12696
|
+
publicEntrypoints: exports_external.array(exports_external.string()).optional(),
|
|
12697
|
+
contractResolution: exports_external.enum(["resolved", "declaration-only"]).optional(),
|
|
12698
|
+
registration: registrationSchema.optional(),
|
|
12609
12699
|
returnType: exports_external.string().min(1).nullable().optional(),
|
|
12610
12700
|
typeAnnotation: exports_external.string().min(1).nullable().optional(),
|
|
12611
12701
|
extends: exports_external.string().min(1).nullable().optional(),
|
|
@@ -12620,6 +12710,7 @@ var relationInfoSchema = exports_external.object({
|
|
|
12620
12710
|
type: relationTypeSchema,
|
|
12621
12711
|
from: exports_external.string().min(1),
|
|
12622
12712
|
to: exports_external.string().min(1),
|
|
12713
|
+
file: exports_external.string().min(1).optional(),
|
|
12623
12714
|
isExternal: exports_external.boolean(),
|
|
12624
12715
|
grounding: groundingSchema,
|
|
12625
12716
|
confidence: exports_external.number().min(0).max(1),
|
|
@@ -12900,6 +12991,8 @@ function semanticExtractionPayload(extraction) {
|
|
|
12900
12991
|
};
|
|
12901
12992
|
}
|
|
12902
12993
|
function relationSourceFile(relation, symbols, filePaths) {
|
|
12994
|
+
if (relation.file !== undefined)
|
|
12995
|
+
return filePaths.has(relation.file) ? relation.file : null;
|
|
12903
12996
|
if (filePaths.has(relation.from))
|
|
12904
12997
|
return relation.from;
|
|
12905
12998
|
const candidates = symbols.filter((symbol) => symbol.name === relation.from);
|
|
@@ -12981,6 +13074,10 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
12981
13074
|
}
|
|
12982
13075
|
const facts = [];
|
|
12983
13076
|
if (coverageFile.disposition === "analyzed" && fileInfo) {
|
|
13077
|
+
const source = invocation.source_files?.[normalizedPath];
|
|
13078
|
+
if (invocation.source_files !== undefined && source === undefined) {
|
|
13079
|
+
throw new TypeError(`Analyzed file ${normalizedPath} has no scoped source text`);
|
|
13080
|
+
}
|
|
12984
13081
|
facts.push(fact2({
|
|
12985
13082
|
sourceRef: invocation.authorized_scope.source_ref,
|
|
12986
13083
|
moduleRef: invocation.module_ref,
|
|
@@ -12988,7 +13085,11 @@ function extractionResultToEvidenceAdapterResult(extraction, invocation) {
|
|
|
12988
13085
|
qualifiedItemPath: "file",
|
|
12989
13086
|
kind: "source-file",
|
|
12990
13087
|
signature: { path: normalizedPath, language: fileInfo.language },
|
|
12991
|
-
payload: fileInfo
|
|
13088
|
+
payload: source === undefined ? fileInfo : {
|
|
13089
|
+
...fileInfo,
|
|
13090
|
+
line: 1,
|
|
13091
|
+
endLine: source.split(/\r\n|\r|\n/u).length
|
|
13092
|
+
},
|
|
12992
13093
|
denominator: ownsDenominators ? "eligible-file" : "none"
|
|
12993
13094
|
}));
|
|
12994
13095
|
facts.push(fact2({
|