@opensip-cli/graph-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.
Files changed (72) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +31 -0
  4. package/dist/__tests__/branch-coverage-2.test.d.ts +21 -0
  5. package/dist/__tests__/branch-coverage-2.test.d.ts.map +1 -0
  6. package/dist/__tests__/branch-coverage-2.test.js +187 -0
  7. package/dist/__tests__/branch-coverage-2.test.js.map +1 -0
  8. package/dist/__tests__/branch-coverage.test.d.ts +17 -0
  9. package/dist/__tests__/branch-coverage.test.d.ts.map +1 -0
  10. package/dist/__tests__/branch-coverage.test.js +136 -0
  11. package/dist/__tests__/branch-coverage.test.js.map +1 -0
  12. package/dist/__tests__/cache-key.test.d.ts +5 -0
  13. package/dist/__tests__/cache-key.test.d.ts.map +1 -0
  14. package/dist/__tests__/cache-key.test.js +45 -0
  15. package/dist/__tests__/cache-key.test.js.map +1 -0
  16. package/dist/__tests__/depends-on-emission.test.d.ts +13 -0
  17. package/dist/__tests__/depends-on-emission.test.d.ts.map +1 -0
  18. package/dist/__tests__/depends-on-emission.test.js +215 -0
  19. package/dist/__tests__/depends-on-emission.test.js.map +1 -0
  20. package/dist/__tests__/discover.test.d.ts +5 -0
  21. package/dist/__tests__/discover.test.d.ts.map +1 -0
  22. package/dist/__tests__/discover.test.js +59 -0
  23. package/dist/__tests__/discover.test.js.map +1 -0
  24. package/dist/__tests__/parse.test.d.ts +5 -0
  25. package/dist/__tests__/parse.test.d.ts.map +1 -0
  26. package/dist/__tests__/parse.test.js +59 -0
  27. package/dist/__tests__/parse.test.js.map +1 -0
  28. package/dist/__tests__/resolve.test.d.ts +18 -0
  29. package/dist/__tests__/resolve.test.d.ts.map +1 -0
  30. package/dist/__tests__/resolve.test.js +205 -0
  31. package/dist/__tests__/resolve.test.js.map +1 -0
  32. package/dist/__tests__/walk.test.d.ts +10 -0
  33. package/dist/__tests__/walk.test.d.ts.map +1 -0
  34. package/dist/__tests__/walk.test.js +163 -0
  35. package/dist/__tests__/walk.test.js.map +1 -0
  36. package/dist/body-digest.d.ts +20 -0
  37. package/dist/body-digest.d.ts.map +1 -0
  38. package/dist/body-digest.js +139 -0
  39. package/dist/body-digest.js.map +1 -0
  40. package/dist/cache-key.d.ts +17 -0
  41. package/dist/cache-key.d.ts.map +1 -0
  42. package/dist/cache-key.js +18 -0
  43. package/dist/cache-key.js.map +1 -0
  44. package/dist/discover.d.ts +24 -0
  45. package/dist/discover.d.ts.map +1 -0
  46. package/dist/discover.js +33 -0
  47. package/dist/discover.js.map +1 -0
  48. package/dist/index.d.ts +43 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +46 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/parse.d.ts +17 -0
  53. package/dist/parse.d.ts.map +1 -0
  54. package/dist/parse.js +14 -0
  55. package/dist/parse.js.map +1 -0
  56. package/dist/resolve.d.ts +32 -0
  57. package/dist/resolve.d.ts.map +1 -0
  58. package/dist/resolve.js +294 -0
  59. package/dist/resolve.js.map +1 -0
  60. package/dist/rule-hints.d.ts +16 -0
  61. package/dist/rule-hints.d.ts.map +1 -0
  62. package/dist/rule-hints.js +62 -0
  63. package/dist/rule-hints.js.map +1 -0
  64. package/dist/walk-metadata.d.ts +22 -0
  65. package/dist/walk-metadata.d.ts.map +1 -0
  66. package/dist/walk-metadata.js +96 -0
  67. package/dist/walk-metadata.js.map +1 -0
  68. package/dist/walk.d.ts +47 -0
  69. package/dist/walk.d.ts.map +1 -0
  70. package/dist/walk.js +278 -0
  71. package/dist/walk.js.map +1 -0
  72. package/package.json +55 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Go file discovery.
3
+ *
4
+ * Strategy mirrors graph-rust:
5
+ * 1. Locate `go.mod`. We do NOT parse it — recursive `.go` glob with
6
+ * vendor/ excluded handles single modules and most workspace
7
+ * layouts. Go workspace files (`go.work`) listing multiple
8
+ * modules would require parsing; that's a follow-up.
9
+ * 2. If no go.mod present, configPath is undefined; cacheKey falls
10
+ * back to the literal `no-config`.
11
+ * 3. Records go.sum (if present) as the fingerprint — prefers go.sum
12
+ * since it holds the resolved-dep hashes; falls back to go.mod.
13
+ *
14
+ * Excluded directories:
15
+ * - `vendor/` — Go's vendored-dep directory; semantically third-party.
16
+ * - `node_modules/` — rare in Go projects but defensive.
17
+ * - `.git/` — VCS metadata.
18
+ *
19
+ * The collect-loop / realpath-dedup / config-precedence scaffolding lives
20
+ * in `@opensip-cli/graph-adapter-common`; this module supplies only the
21
+ * Go-specific inputs (extension, excludes, config precedence, log tag).
22
+ */
23
+ export declare const discoverFiles: (input: import("@opensip-cli/graph").DiscoverInput) => import("@opensip-cli/graph").DiscoverOutput;
24
+ //# sourceMappingURL=discover.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,eAAO,MAAM,aAAa,oGAKxB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Go file discovery.
3
+ *
4
+ * Strategy mirrors graph-rust:
5
+ * 1. Locate `go.mod`. We do NOT parse it — recursive `.go` glob with
6
+ * vendor/ excluded handles single modules and most workspace
7
+ * layouts. Go workspace files (`go.work`) listing multiple
8
+ * modules would require parsing; that's a follow-up.
9
+ * 2. If no go.mod present, configPath is undefined; cacheKey falls
10
+ * back to the literal `no-config`.
11
+ * 3. Records go.sum (if present) as the fingerprint — prefers go.sum
12
+ * since it holds the resolved-dep hashes; falls back to go.mod.
13
+ *
14
+ * Excluded directories:
15
+ * - `vendor/` — Go's vendored-dep directory; semantically third-party.
16
+ * - `node_modules/` — rare in Go projects but defensive.
17
+ * - `.git/` — VCS metadata.
18
+ *
19
+ * The collect-loop / realpath-dedup / config-precedence scaffolding lives
20
+ * in `@opensip-cli/graph-adapter-common`; this module supplies only the
21
+ * Go-specific inputs (extension, excludes, config precedence, log tag).
22
+ */
23
+ import { createDiscover } from '@opensip-cli/graph-adapter-common';
24
+ const EXCLUDED_DIR_GLOBS = ['**/vendor/**', '**/node_modules/**', '**/.git/**'];
25
+ // Prefer go.sum (resolved deps with hashes) over go.mod (intent).
26
+ const CONFIG_CANDIDATES = ['go.sum', 'go.mod'];
27
+ export const discoverFiles = createDiscover({
28
+ extension: 'go',
29
+ excludedDirGlobs: EXCLUDED_DIR_GLOBS,
30
+ configCandidates: CONFIG_CANDIDATES,
31
+ languageId: 'go',
32
+ });
33
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,MAAM,kBAAkB,GAAsB,CAAC,cAAc,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAC;AAEnG,kEAAkE;AAClE,MAAM,iBAAiB,GAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAElE,MAAM,CAAC,MAAM,aAAa,GAAG,cAAc,CAAC;IAC1C,SAAS,EAAE,IAAI;IACf,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,iBAAiB;IACnC,UAAU,EAAE,IAAI;CACjB,CAAC,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * @opensip-cli/graph — Go language adapter.
3
+ *
4
+ * Sibling of graph-rust and graph-python. Backed by tree-sitter-go.
5
+ *
6
+ * Per-rule fidelity: same name-based resolution profile as Python/Rust.
7
+ * Mostly `'medium'` for single-match identifiers; `'low'` for ambiguous
8
+ * matches. The adapter has no symbol table, so method-on-instance,
9
+ * package-qualified call, and free-function call are distinguishable
10
+ * at the AST shape level but cannot be type-narrowed without a real
11
+ * type checker.
12
+ *
13
+ * File layout mirrors graph-rust/:
14
+ * discoverFiles → ./discover.ts (go.mod / go.sum + glob fallback)
15
+ * parseProject → ./parse.ts
16
+ * walkProject → ./walk.ts
17
+ * resolveCallSites → ./resolve.ts
18
+ * cacheKey → ./cache-key.ts (`go-…`)
19
+ * ruleHints → ./rule-hints.ts
20
+ */
21
+ import { resolveCallSites as goResolveCallSites } from './resolve.js';
22
+ import { walkProject as goWalkProject } from './walk.js';
23
+ export declare const goGraphAdapter: {
24
+ id: string;
25
+ fileExtensions: string[];
26
+ displayName: string;
27
+ discoverFiles: (input: import("@opensip-cli/graph").DiscoverInput) => import("@opensip-cli/graph").DiscoverOutput;
28
+ parseProject: (input: import("@opensip-cli/graph").ParseInput) => import("@opensip-cli/graph").ParseOutput<import("@opensip-cli/graph-adapter-common").TreeSitterParsedProject>;
29
+ walkProject: typeof goWalkProject;
30
+ resolveCallSites: typeof goResolveCallSites;
31
+ cacheKey: (input: import("@opensip-cli/graph").CacheKeyInput) => string;
32
+ ruleHints: import("@opensip-cli/graph").RuleHints;
33
+ };
34
+ /** Plugin discovery contract: exported as `adapter` for runtime registration. */
35
+ export { goGraphAdapter as adapter };
36
+ export declare const metadata: {
37
+ readonly id: string;
38
+ readonly displayName: string;
39
+ readonly fileExtensions: string[];
40
+ };
41
+ export type { GoParsedProject } from './parse.js';
42
+ export { goRuleHints } from './rule-hints.js';
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,gBAAgB,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AAKzD,eAAO,MAAM,cAAc;;;;;;;;;;CAUsB,CAAC;AAElD,iFAAiF;AACjF,OAAO,EAAE,cAAc,IAAI,OAAO,EAAE,CAAC;AACrC,eAAO,MAAM,QAAQ;;;;CAIX,CAAC;AAEX,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @opensip-cli/graph — Go language adapter.
3
+ *
4
+ * Sibling of graph-rust and graph-python. Backed by tree-sitter-go.
5
+ *
6
+ * Per-rule fidelity: same name-based resolution profile as Python/Rust.
7
+ * Mostly `'medium'` for single-match identifiers; `'low'` for ambiguous
8
+ * matches. The adapter has no symbol table, so method-on-instance,
9
+ * package-qualified call, and free-function call are distinguishable
10
+ * at the AST shape level but cannot be type-narrowed without a real
11
+ * type checker.
12
+ *
13
+ * File layout mirrors graph-rust/:
14
+ * discoverFiles → ./discover.ts (go.mod / go.sum + glob fallback)
15
+ * parseProject → ./parse.ts
16
+ * walkProject → ./walk.ts
17
+ * resolveCallSites → ./resolve.ts
18
+ * cacheKey → ./cache-key.ts (`go-…`)
19
+ * ruleHints → ./rule-hints.ts
20
+ */
21
+ import { cacheKey as goCacheKey } from './cache-key.js';
22
+ import { discoverFiles as goDiscoverFiles } from './discover.js';
23
+ import { parseProject as goParseProject } from './parse.js';
24
+ import { resolveCallSites as goResolveCallSites } from './resolve.js';
25
+ import { goRuleHints } from './rule-hints.js';
26
+ import { walkProject as goWalkProject } from './walk.js';
27
+ export const goGraphAdapter = {
28
+ id: 'go',
29
+ fileExtensions: ['.go'],
30
+ displayName: 'Go',
31
+ discoverFiles: goDiscoverFiles,
32
+ parseProject: goParseProject,
33
+ walkProject: goWalkProject,
34
+ resolveCallSites: goResolveCallSites,
35
+ cacheKey: goCacheKey,
36
+ ruleHints: goRuleHints,
37
+ };
38
+ /** Plugin discovery contract: exported as `adapter` for runtime registration. */
39
+ export { goGraphAdapter as adapter };
40
+ export const metadata = {
41
+ id: goGraphAdapter.id,
42
+ displayName: goGraphAdapter.displayName,
43
+ fileExtensions: goGraphAdapter.fileExtensions,
44
+ };
45
+ export { goRuleHints } from './rule-hints.js';
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,aAAa,IAAI,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,YAAY,IAAI,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,gBAAgB,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,WAAW,IAAI,aAAa,EAAE,MAAM,WAAW,CAAC;AAKzD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,EAAE,EAAE,IAAI;IACR,cAAc,EAAE,CAAC,KAAK,CAAC;IACvB,WAAW,EAAE,IAAI;IACjB,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;CACyB,CAAC;AAElD,iFAAiF;AACjF,OAAO,EAAE,cAAc,IAAI,OAAO,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,EAAE,EAAE,cAAc,CAAC,EAAE;IACrB,WAAW,EAAE,cAAc,CAAC,WAAW;IACvC,cAAc,EAAE,cAAc,CAAC,cAAc;CACrC,CAAC;AAGX,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Go parseProject — consumes `@opensip-cli/lang-go` (ADR-0010).
3
+ *
4
+ * `lang-go` is the canonical Go parse substrate: it owns the vendored
5
+ * tree-sitter-go grammar and produces the `{ tree, source }` parsed-file shape.
6
+ * The graph adapter no longer loads a grammar of its own; it binds the shared
7
+ * `createParseProjectFromAdapter` driver to `goAdapter`. The parsed-project
8
+ * shape and the downstream walk/resolve are unchanged.
9
+ */
10
+ import { type TreeSitterParsedFile, type TreeSitterParsedProject } from '@opensip-cli/graph-adapter-common';
11
+ /** Parsed Go source file: tree-sitter parse tree plus original source text. */
12
+ export type GoParsedFile = TreeSitterParsedFile;
13
+ /** Parsed Go project: map of file path → {@link GoParsedFile}. */
14
+ export type GoParsedProject = TreeSitterParsedProject<GoParsedFile>;
15
+ /** Parses every Go source file in the input set into a {@link GoParsedProject}. */
16
+ export declare const parseProject: (input: import("@opensip-cli/graph").ParseInput) => import("@opensip-cli/graph").ParseOutput<TreeSitterParsedProject>;
17
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC7B,MAAM,mCAAmC,CAAC;AAG3C,+EAA+E;AAC/E,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEhD,kEAAkE;AAClE,MAAM,MAAM,eAAe,GAAG,uBAAuB,CAAC,YAAY,CAAC,CAAC;AAEpE,mFAAmF;AACnF,eAAO,MAAM,YAAY,uHAA2C,CAAC"}
package/dist/parse.js ADDED
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Go parseProject — consumes `@opensip-cli/lang-go` (ADR-0010).
3
+ *
4
+ * `lang-go` is the canonical Go parse substrate: it owns the vendored
5
+ * tree-sitter-go grammar and produces the `{ tree, source }` parsed-file shape.
6
+ * The graph adapter no longer loads a grammar of its own; it binds the shared
7
+ * `createParseProjectFromAdapter` driver to `goAdapter`. The parsed-project
8
+ * shape and the downstream walk/resolve are unchanged.
9
+ */
10
+ import { createParseProjectFromAdapter, } from '@opensip-cli/graph-adapter-common';
11
+ import { goAdapter } from '@opensip-cli/lang-go';
12
+ /** Parses every Go source file in the input set into a {@link GoParsedProject}. */
13
+ export const parseProject = createParseProjectFromAdapter(goAdapter);
14
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,6BAA6B,GAG9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAQjD,mFAAmF;AACnF,MAAM,CAAC,MAAM,YAAY,GAAG,6BAA6B,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Go resolveCallSites — name-based catalog lookup.
3
+ *
4
+ * Tree-sitter has no symbol table, so we resolve by simple name. For
5
+ * each call site:
6
+ *
7
+ * 1. Decode the called expression. Four shapes matter:
8
+ * - `foo(args)` — identifier; target is `foo`.
9
+ * - `obj.Method(args)` — selector_expression; target is the
10
+ * trailing `field_identifier`.
11
+ * - `pkg.Func(args)` — same shape; AST-indistinguishable
12
+ * from method calls without a type
13
+ * checker. We use the field name.
14
+ * - `Type{}.method(args)` — selector_expression on a
15
+ * composite_literal; we still extract
16
+ * the field name.
17
+ *
18
+ * 2. Look up matching catalog entries by simple name. Confidence
19
+ * ladder mirrors graph-python (no receiver-type narrowing in
20
+ * tree-sitter-go because the receiver type can't be known without
21
+ * type info):
22
+ * - 0 matches → `to: []`, resolution `'unknown'`, confidence `'low'`
23
+ * - 1 match → `to: [hash]`, resolution `'static'`, confidence `'medium'`
24
+ * - N matches → `to: [allHashes]`, resolution `'method-dispatch'`,
25
+ * confidence `'low'`
26
+ *
27
+ * Per I-4: this function does NOT mutate the input catalog.
28
+ */
29
+ import type { GoParsedProject } from './parse.js';
30
+ import type { ResolveInput, ResolveOutput } from '@opensip-cli/graph';
31
+ export declare function resolveCallSites(input: ResolveInput<GoParsedProject>): ResolveOutput;
32
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAcH,OAAO,KAAK,EAAgB,eAAe,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAOV,YAAY,EACZ,aAAa,EACd,MAAM,oBAAoB,CAAC;AAkB5B,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,CAAC,eAAe,CAAC,GAAG,aAAa,CAsCpF"}
@@ -0,0 +1,294 @@
1
+ // @fitness-ignore-file unbounded-memory -- reads single source files at a time during catalog resolution; per-file memory bounded by source size
2
+ /**
3
+ * Go resolveCallSites — name-based catalog lookup.
4
+ *
5
+ * Tree-sitter has no symbol table, so we resolve by simple name. For
6
+ * each call site:
7
+ *
8
+ * 1. Decode the called expression. Four shapes matter:
9
+ * - `foo(args)` — identifier; target is `foo`.
10
+ * - `obj.Method(args)` — selector_expression; target is the
11
+ * trailing `field_identifier`.
12
+ * - `pkg.Func(args)` — same shape; AST-indistinguishable
13
+ * from method calls without a type
14
+ * checker. We use the field name.
15
+ * - `Type{}.method(args)` — selector_expression on a
16
+ * composite_literal; we still extract
17
+ * the field name.
18
+ *
19
+ * 2. Look up matching catalog entries by simple name. Confidence
20
+ * ladder mirrors graph-python (no receiver-type narrowing in
21
+ * tree-sitter-go because the receiver type can't be known without
22
+ * type info):
23
+ * - 0 matches → `to: []`, resolution `'unknown'`, confidence `'low'`
24
+ * - 1 match → `to: [hash]`, resolution `'static'`, confidence `'medium'`
25
+ * - N matches → `to: [allHashes]`, resolution `'method-dispatch'`,
26
+ * confidence `'low'`
27
+ *
28
+ * Per I-4: this function does NOT mutate the input catalog.
29
+ */
30
+ import { readFileSync } from 'node:fs';
31
+ import { join, posix } from 'node:path';
32
+ import { logger } from '@opensip-cli/core';
33
+ import { appendEdge, createMutableStats, pushCreationEdge, truncateForCallEdge, } from '@opensip-cli/graph';
34
+ import { buildNameIndex } from '@opensip-cli/graph-adapter-common';
35
+ function goPosition(node, file) {
36
+ return {
37
+ line: node.startPosition.row + 1,
38
+ column: node.startPosition.column,
39
+ text: file.source.slice(node.startIndex, node.endIndex),
40
+ };
41
+ }
42
+ export function resolveCallSites(input) {
43
+ logger.info({ evt: 'graph.edges.start', module: 'graph:edges:go' });
44
+ const byName = buildNameIndex(input.catalog.functions);
45
+ const edgesByOwner = new Map();
46
+ const stats = createMutableStats();
47
+ const sink = { edgesByOwner, stats };
48
+ for (const r of input.callSites) {
49
+ const node = r.nodeRef;
50
+ const file = r.sourceFileRef;
51
+ if (r.kind === 'creation') {
52
+ if (r.childHash === undefined)
53
+ continue;
54
+ pushCreationEdge(goPosition(node, file), r.ownerHash, r.childHash, sink);
55
+ continue;
56
+ }
57
+ pushCallEdge(node, file, r.ownerHash, byName, sink);
58
+ }
59
+ const finalStats = {
60
+ totalCallSites: stats.totalCallSites,
61
+ resolvedHigh: stats.resolvedHigh,
62
+ resolvedMedium: stats.resolvedMedium,
63
+ resolvedLow: stats.resolvedLow,
64
+ unresolved: stats.unresolved,
65
+ };
66
+ logger.info({ evt: 'graph.edges.complete', module: 'graph:edges:go', ...finalStats });
67
+ // Phase 4 (DEC-498): resolve dependency sites if any. Mirrors the
68
+ // Python adapter's resolveDependencies pattern, adapted to Go's
69
+ // `go.mod`-mediated module-path resolution.
70
+ const dependenciesByOwner = input.dependencySites && input.dependencySites.length > 0
71
+ ? resolveDependencies(input.dependencySites, input.catalog, input.projectDirAbs)
72
+ : undefined;
73
+ return dependenciesByOwner === undefined
74
+ ? { edgesByOwner, stats: finalStats }
75
+ : { edgesByOwner, dependenciesByOwner, stats: finalStats };
76
+ }
77
+ /**
78
+ * Resolve Go import sites to target module-init bodyHashes. Imports
79
+ * resolving to a same-module source file (via `go.mod`'s declared
80
+ * module path) map to that package directory's module-init occurrences;
81
+ * imports resolving to stdlib (`fmt`, `os`, …), third-party (`github.com/
82
+ * external/lib`), or unresolvable shapes produce unresolved
83
+ * `DependencyEdge` entries with `to: []` and the raw specifier carried
84
+ * in `specifier` for downstream attribution.
85
+ *
86
+ * Resolution rules:
87
+ *
88
+ * 1. Read `go.mod` from `projectDirAbs`. The first `module <path>`
89
+ * line declares the module's own path. If `go.mod` is missing or
90
+ * unparseable, ALL imports go unresolved.
91
+ *
92
+ * 2. Build a `filePath → module-init bodyHash` map from the catalog.
93
+ *
94
+ * 3. For each dependency site, classify the import path:
95
+ * - **Internal** — starts with `<module-path>/` (or equals it):
96
+ * strip the module-path prefix to get a project-relative
97
+ * package-directory path. `to` is every catalog module-init
98
+ * occurrence whose `filePath` lives inside that directory (Go
99
+ * packages can span multiple files — `pkg/foo/foo.go`,
100
+ * `pkg/foo/helpers.go`).
101
+ * - **External** — doesn't start with module path (stdlib like
102
+ * `fmt`, third-party like `github.com/x/y`, or relative-style
103
+ * `./pkg` / `../foo` not common in modern Go): `to: []`.
104
+ *
105
+ * 4. Blank imports (`_ "path"`) and dot imports (`. "path"`) resolve
106
+ * the same as plain imports — the prefix only affects Go's import
107
+ * semantics, not the dependency target.
108
+ *
109
+ * Phase 4 of opensip's substrate consolidation (DEC-498).
110
+ */
111
+ function resolveDependencies(sites, catalog, projectDirAbs) {
112
+ const modulePath = readGoModulePath(projectDirAbs);
113
+ // Build filePath → module-init bodyHash map. Catalog occurrences carry
114
+ // project-relative POSIX filePath; module-init kind is filtered.
115
+ const moduleInitByFilePath = new Map();
116
+ for (const occs of Object.values(catalog.functions)) {
117
+ if (!occs)
118
+ continue;
119
+ for (const o of occs) {
120
+ if (o.kind === 'module-init')
121
+ moduleInitByFilePath.set(o.filePath, o.bodyHash);
122
+ }
123
+ }
124
+ const out = new Map();
125
+ for (const site of sites) {
126
+ const to = resolveGoImportPath(site.specifier, modulePath, moduleInitByFilePath);
127
+ const edge = {
128
+ to,
129
+ line: site.line,
130
+ column: site.column,
131
+ specifier: site.specifier,
132
+ };
133
+ const existing = out.get(site.ownerHash);
134
+ if (existing === undefined) {
135
+ out.set(site.ownerHash, [edge]);
136
+ }
137
+ else {
138
+ existing.push(edge);
139
+ }
140
+ }
141
+ return out;
142
+ }
143
+ /**
144
+ * Extract the module path from `go.mod`. We do a line-grep on `^module
145
+ * <path>$` rather than parse the full grammar — replace directives,
146
+ * vendor blocks, retract statements, and toolchain lines are all
147
+ * out-of-scope for v1. Returns `null` when `go.mod` is missing or no
148
+ * `module` line is found.
149
+ *
150
+ * Edge cases NOT handled (deferred): `replace` directives that retarget
151
+ * a module path, `go.work` multi-module workspaces (each module's own
152
+ * `go.mod` is read independently in this v1).
153
+ */
154
+ function readGoModulePath(projectDirAbs) {
155
+ let content;
156
+ try {
157
+ content = readFileSync(join(projectDirAbs, 'go.mod'), 'utf8');
158
+ }
159
+ catch {
160
+ // @fitness-ignore-next-line error-handling-quality -- missing/unreadable go.mod is the expected "no module path" signal for projects that aren't a Go module; caller treats null as "skip module-path resolution".
161
+ return null;
162
+ }
163
+ for (const rawLine of content.split('\n')) {
164
+ const line = rawLine.trim();
165
+ // Skip comments and blank lines.
166
+ if (line.length === 0 || line.startsWith('//'))
167
+ continue;
168
+ // `module <path>` — capture the bare path. Quoted form `module "<path>"`
169
+ // is legal in go.mod; strip optional quotes.
170
+ const match = /^module\s+("([^"]+)"|(\S+))\s*$/.exec(line);
171
+ if (match)
172
+ return match[2] ?? match[3] ?? null;
173
+ }
174
+ return null;
175
+ }
176
+ /**
177
+ * Resolve one Go import path to its target module-init bodyHash(es).
178
+ * Returns `[]` when the import is external (stdlib, third-party, or
179
+ * unresolvable relative).
180
+ *
181
+ * Multi-file packages: a single import like `"github.com/me/myproj/pkg/foo"`
182
+ * corresponds to the DIRECTORY `pkg/foo/`, which may contain `foo.go`,
183
+ * `helpers.go`, etc. The returned `to` array includes every matching
184
+ * module-init bodyHash — the engine model's polymorphic-targets case.
185
+ */
186
+ function resolveGoImportPath(specifier, modulePath, moduleInitByFilePath) {
187
+ if (modulePath === null)
188
+ return [];
189
+ // Internal: import path equals or is rooted under the module path.
190
+ if (specifier === modulePath) {
191
+ return collectGoPackageMembers('', moduleInitByFilePath);
192
+ }
193
+ const prefix = `${modulePath}/`;
194
+ if (!specifier.startsWith(prefix))
195
+ return [];
196
+ // The package-directory path is the import path with the module
197
+ // prefix stripped. Forward-slashes are canonical in both go import
198
+ // paths and catalog filePaths.
199
+ const packageDir = specifier.slice(prefix.length);
200
+ return collectGoPackageMembers(packageDir, moduleInitByFilePath);
201
+ }
202
+ /**
203
+ * Enumerate every module-init in the catalog whose filePath sits
204
+ * directly inside `packageDir`. Go's package = directory, with `.go`
205
+ * files at the directory's top level (subdirectories are separate
206
+ * packages). Excludes `_test.go` files from production-import targets?
207
+ * NO — the catalog already carries every walked `.go`, and `_test.go`
208
+ * files belong to the same package directory at the AST level; we
209
+ * include them as edge targets and let downstream rules filter by
210
+ * `inTestFile` if needed.
211
+ */
212
+ function collectGoPackageMembers(packageDir, moduleInitByFilePath) {
213
+ // packageDir is empty when the module path itself is imported. In
214
+ // that case, the package members live directly at the project root.
215
+ const out = [];
216
+ for (const [filePath, hash] of moduleInitByFilePath) {
217
+ if (!filePath.endsWith('.go'))
218
+ continue;
219
+ const dir = posix.dirname(filePath);
220
+ const normalizedDir = dir === '.' ? '' : dir;
221
+ if (normalizedDir === packageDir)
222
+ out.push(hash);
223
+ }
224
+ return out;
225
+ }
226
+ function pushCallEdge(node, file, ownerHash, byName, sink) {
227
+ const { edgesByOwner, stats } = sink;
228
+ stats.totalCallSites++;
229
+ const target = extractCallTargetName(node);
230
+ const pos = goPosition(node, file);
231
+ const truncated = truncateForCallEdge(pos.text);
232
+ const discarded = isReturnValueDiscarded(node);
233
+ const edge = buildGoCallEdge(target, byName, {
234
+ line: pos.line,
235
+ column: pos.column,
236
+ text: truncated,
237
+ discarded,
238
+ });
239
+ appendEdge(edgesByOwner, ownerHash, edge);
240
+ stats.apply(edge);
241
+ }
242
+ function buildGoCallEdge(target, byName, loc) {
243
+ if (target === null) {
244
+ return { to: [], ...loc, resolution: 'unknown', confidence: 'low' };
245
+ }
246
+ const matches = byName.get(target);
247
+ if (!matches || matches.length === 0) {
248
+ return { to: [], ...loc, resolution: 'unknown', confidence: 'low' };
249
+ }
250
+ if (matches.length === 1) {
251
+ return { to: [...matches], ...loc, resolution: 'static', confidence: 'medium' };
252
+ }
253
+ return { to: [...matches], ...loc, resolution: 'method-dispatch', confidence: 'low' };
254
+ }
255
+ /**
256
+ * Decode a `call_expression` node's target into a simple name. Returns
257
+ * null when we don't recognize the shape (e.g. type assertion call,
258
+ * map index call) — those become unresolved edges.
259
+ */
260
+ function extractCallTargetName(node) {
261
+ // tree-sitter-go `call_expression` has a `function` field for the callee.
262
+ const fn = node.childForFieldName('function');
263
+ if (!fn)
264
+ return null;
265
+ if (fn.type === 'identifier')
266
+ return fn.text;
267
+ if (fn.type === 'selector_expression') {
268
+ const field = fn.childForFieldName('field');
269
+ return field ? field.text : null;
270
+ }
271
+ // Other shapes (index_expression, parenthesized_expression, etc.) —
272
+ // not common for the call-graph rules we ship today.
273
+ return null;
274
+ }
275
+ /**
276
+ * The call's return value is discarded when the call expression is
277
+ * the entire expression of an expression_statement. Go's `go foo()`
278
+ * and `defer foo()` statements also discard the return.
279
+ */
280
+ function isReturnValueDiscarded(node) {
281
+ let parent = node.parent;
282
+ while (parent) {
283
+ if (parent.type === 'parenthesized_expression') {
284
+ parent = parent.parent;
285
+ continue;
286
+ }
287
+ return (parent.type === 'expression_statement' ||
288
+ parent.type === 'go_statement' ||
289
+ parent.type === 'defer_statement');
290
+ }
291
+ /* v8 ignore next */
292
+ return false;
293
+ }
294
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../src/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Go rule hints — language-specific signals for rules.
3
+ *
4
+ * `isTestFile` is file-path-based: Go convention enforces `*_test.go`
5
+ * via the `go test` toolchain, so this predicate is exact for the test
6
+ * concept. No directory convention exists in Go (tests live next to
7
+ * source).
8
+ *
9
+ * Throw-syntax analogue: Go's structural error-propagation is
10
+ * `panic(...)`. The `?` / `try!()` analogue doesn't exist; `return err`
11
+ * is the conventional error path but is too varied syntactically for a
12
+ * regex.
13
+ */
14
+ import type { RuleHints } from '@opensip-cli/graph';
15
+ export declare const goRuleHints: RuleHints;
16
+ //# sourceMappingURL=rule-hints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-hints.d.ts","sourceRoot":"","sources":["../src/rule-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA8CpD,eAAO,MAAM,WAAW,EAAE,SAKzB,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Go rule hints — language-specific signals for rules.
3
+ *
4
+ * `isTestFile` is file-path-based: Go convention enforces `*_test.go`
5
+ * via the `go test` toolchain, so this predicate is exact for the test
6
+ * concept. No directory convention exists in Go (tests live next to
7
+ * source).
8
+ *
9
+ * Throw-syntax analogue: Go's structural error-propagation is
10
+ * `panic(...)`. The `?` / `try!()` analogue doesn't exist; `return err`
11
+ * is the conventional error path but is too varied syntactically for a
12
+ * regex.
13
+ */
14
+ import { isTestFile } from './walk.js';
15
+ const GO_SIDE_EFFECT_PRIMITIVES = [
16
+ 'fmt.Print',
17
+ 'fmt.Println',
18
+ 'fmt.Printf',
19
+ 'fmt.Fprint',
20
+ 'fmt.Fprintln',
21
+ 'fmt.Fprintf',
22
+ 'log.Print',
23
+ 'log.Println',
24
+ 'log.Printf',
25
+ 'log.Fatal',
26
+ 'log.Fatalln',
27
+ 'log.Fatalf',
28
+ 'log.Panic',
29
+ 'log.Panicln',
30
+ 'log.Panicf',
31
+ 'os.Exit',
32
+ 'os.Setenv',
33
+ 'os.Unsetenv',
34
+ 'os.Remove',
35
+ 'os.RemoveAll',
36
+ 'os.Create',
37
+ 'os.WriteFile',
38
+ 'os.ReadFile',
39
+ 'os.Mkdir',
40
+ 'os.MkdirAll',
41
+ 'time.Sleep',
42
+ 'rand.Int',
43
+ 'rand.Intn',
44
+ 'rand.Float64',
45
+ ];
46
+ // Go's structural throw analogue is `panic(...)`. `return err` is also
47
+ // an error path but is too varied to capture via regex.
48
+ const GO_THROW_REGEX = /\bpanic\s*\(/;
49
+ const GO_GENERATED_FILE_PATTERNS = [
50
+ '**/vendor/**',
51
+ '**/*.pb.go',
52
+ '**/*_generated.go',
53
+ '**/*.gen.go',
54
+ '**/zz_generated_*.go',
55
+ ];
56
+ export const goRuleHints = {
57
+ isTestFile,
58
+ generatedFilePatterns: GO_GENERATED_FILE_PATTERNS,
59
+ sideEffectPrimitives: GO_SIDE_EFFECT_PRIMITIVES,
60
+ throwSyntaxRegex: GO_THROW_REGEX,
61
+ };
62
+ //# sourceMappingURL=rule-hints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-hints.js","sourceRoot":"","sources":["../src/rule-hints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAIvC,MAAM,yBAAyB,GAAsB;IACnD,WAAW;IACX,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;IACb,WAAW;IACX,aAAa;IACb,YAAY;IACZ,WAAW;IACX,aAAa;IACb,YAAY;IACZ,WAAW;IACX,aAAa;IACb,YAAY;IACZ,SAAS;IACT,WAAW;IACX,aAAa;IACb,WAAW;IACX,cAAc;IACd,WAAW;IACX,cAAc;IACd,aAAa;IACb,UAAU;IACV,aAAa;IACb,YAAY;IACZ,UAAU;IACV,WAAW;IACX,cAAc;CACf,CAAC;AAEF,uEAAuE;AACvE,wDAAwD;AACxD,MAAM,cAAc,GAAG,cAAc,CAAC;AAEtC,MAAM,0BAA0B,GAAsB;IACpD,cAAc;IACd,YAAY;IACZ,mBAAmB;IACnB,aAAa;IACb,sBAAsB;CACvB,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAc;IACpC,UAAU;IACV,qBAAqB,EAAE,0BAA0B;IACjD,oBAAoB,EAAE,yBAAyB;IAC/C,gBAAgB,EAAE,cAAc;CACjC,CAAC"}