agentmap 0.5.0 → 0.7.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/cli.js +12 -4
- package/dist/cli.js.map +1 -1
- package/dist/extract/definitions.d.ts.map +1 -1
- package/dist/extract/definitions.js +195 -316
- package/dist/extract/definitions.js.map +1 -1
- package/dist/extract/definitions.test.js +749 -20
- package/dist/extract/definitions.test.js.map +1 -1
- package/dist/extract/markdown.d.ts.map +1 -1
- package/dist/extract/markdown.js +13 -1
- package/dist/extract/markdown.js.map +1 -1
- package/dist/extract/marker.d.ts.map +1 -1
- package/dist/extract/marker.js +87 -6
- package/dist/extract/marker.js.map +1 -1
- package/dist/extract/marker.test.js +142 -4
- package/dist/extract/marker.test.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -1
- package/dist/index.js.map +1 -1
- package/dist/languages/cpp.d.ts +30 -0
- package/dist/languages/cpp.d.ts.map +1 -0
- package/dist/languages/cpp.js +116 -0
- package/dist/languages/cpp.js.map +1 -0
- package/dist/languages/go.d.ts +26 -0
- package/dist/languages/go.d.ts.map +1 -0
- package/dist/languages/go.js +65 -0
- package/dist/languages/go.js.map +1 -0
- package/dist/languages/index.d.ts +90 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +209 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/javascript.d.ts +18 -0
- package/dist/languages/javascript.d.ts.map +1 -0
- package/dist/languages/javascript.js +23 -0
- package/dist/languages/javascript.js.map +1 -0
- package/dist/languages/python.d.ts +23 -0
- package/dist/languages/python.d.ts.map +1 -0
- package/dist/languages/python.js +35 -0
- package/dist/languages/python.js.map +1 -0
- package/dist/languages/rust.d.ts +26 -0
- package/dist/languages/rust.d.ts.map +1 -0
- package/dist/languages/rust.js +65 -0
- package/dist/languages/rust.js.map +1 -0
- package/dist/languages/typescript.d.ts +30 -0
- package/dist/languages/typescript.d.ts.map +1 -0
- package/dist/languages/typescript.js +68 -0
- package/dist/languages/typescript.js.map +1 -0
- package/dist/languages/zig.d.ts +38 -0
- package/dist/languages/zig.d.ts.map +1 -0
- package/dist/languages/zig.js +104 -0
- package/dist/languages/zig.js.map +1 -0
- package/dist/map/builder.d.ts.map +1 -1
- package/dist/map/builder.js +4 -1
- package/dist/map/builder.js.map +1 -1
- package/dist/parser/languages.d.ts +2 -4
- package/dist/parser/languages.d.ts.map +1 -1
- package/dist/parser/languages.js +4 -29
- package/dist/parser/languages.js.map +1 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +27 -49
- package/dist/scanner.js.map +1 -1
- package/dist/types.d.ts +6 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -20,14 +20,15 @@ cli
|
|
|
20
20
|
.command('[dir]', 'Generate a YAML map of the codebase')
|
|
21
21
|
.option('-o, --output <file>', 'Write output to file (default: stdout)')
|
|
22
22
|
.option('-i, --ignore <pattern>', 'Ignore pattern (can be repeated)', { type: [] })
|
|
23
|
-
.option('-
|
|
23
|
+
.option('-f, --filter <pattern>', 'Filter pattern - only include matching files (can be repeated)', { type: [] })
|
|
24
24
|
.action(async (dir, options) => {
|
|
25
25
|
const targetDir = resolve(dir ?? '.');
|
|
26
26
|
try {
|
|
27
27
|
const map = await generateMap({
|
|
28
28
|
dir: targetDir,
|
|
29
29
|
ignore: options.ignore,
|
|
30
|
-
|
|
30
|
+
filter: options.filter,
|
|
31
|
+
diff: true,
|
|
31
32
|
});
|
|
32
33
|
// Check if map is empty (only has root key with empty object)
|
|
33
34
|
const rootKey = Object.keys(map)[0];
|
|
@@ -39,7 +40,8 @@ cli
|
|
|
39
40
|
const yaml = await generateMapYaml({
|
|
40
41
|
dir: targetDir,
|
|
41
42
|
ignore: options.ignore,
|
|
42
|
-
|
|
43
|
+
filter: options.filter,
|
|
44
|
+
diff: true,
|
|
43
45
|
});
|
|
44
46
|
if (options.output) {
|
|
45
47
|
await writeFile(options.output, yaml, 'utf8');
|
|
@@ -64,11 +66,12 @@ If you find well-separated packages, use the Task tool to process them concurren
|
|
|
64
66
|
|
|
65
67
|
For each package/area, identify the most important files - entry points, core modules, main utilities, and key abstractions.
|
|
66
68
|
|
|
67
|
-
For each important file, add a descriptive comment at the
|
|
69
|
+
For each important file, add a descriptive comment at the top (before any imports or code). The comment should:
|
|
68
70
|
- Be 2-4 lines describing what the file does and why it exists
|
|
69
71
|
- Use the appropriate comment style for the language (// for JS/TS, # for Python, //! for Rust modules, etc.)
|
|
70
72
|
- If the file is an entry point (CLI, main, server start, etc.), mark it as such in the description
|
|
71
73
|
- If the file already has a top comment, review and update it to be accurate and descriptive - don't skip it
|
|
74
|
+
- If the file has a shebang (#!/...), keep it as the first line and add the description comment immediately after
|
|
72
75
|
|
|
73
76
|
Examples:
|
|
74
77
|
|
|
@@ -84,6 +87,11 @@ Rust:
|
|
|
84
87
|
//! HTTP server module.
|
|
85
88
|
//! Entry point for the web API, configures routes and middleware.
|
|
86
89
|
|
|
90
|
+
With shebang (shell scripts, node CLI, etc.):
|
|
91
|
+
#!/usr/bin/env node
|
|
92
|
+
// CLI entrypoint for the build tool.
|
|
93
|
+
// Handles argument parsing and runs the build pipeline.
|
|
94
|
+
|
|
87
95
|
After adding comments to all important files, run \`npx -y agentmap\` to verify the files appear in the generated map.
|
|
88
96
|
|
|
89
97
|
You can run this prompt again anytime to keep file descriptions up to date as the codebase evolves.
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,+CAA+C;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEzD,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;AAE3B,MAAM,gBAAgB,GAAG;;;;;;;;;;CAUxB,CAAA;AAED,GAAG;KACA,OAAO,CAAC,OAAO,EAAE,qCAAqC,CAAC;KACvD,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,wBAAwB,EAAE,kCAAkC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KAClF,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/extract/definitions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAkB,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/extract/definitions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAkB,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAuCnF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,UAAU,EACpB,QAAQ,EAAE,QAAQ,GACjB,UAAU,EAAE,CAoCd"}
|
|
@@ -1,384 +1,263 @@
|
|
|
1
1
|
// Extract top-level definitions using tree-sitter.
|
|
2
|
+
import { FUNCTION_TYPES, CLASS_TYPES, STRUCT_TYPES, TRAIT_TYPES, INTERFACE_TYPES, TYPE_TYPES, ENUM_TYPES, CONST_TYPES, extractName, extractConstName, isExported, unwrapExport, isExtern, isZigConst, getZigTypeDeclaration, } from '../languages/index.js';
|
|
2
3
|
/**
|
|
3
4
|
* Minimum body lines for a function/class to be included in defs
|
|
4
5
|
*/
|
|
5
6
|
const MIN_BODY_LINES = 5;
|
|
6
|
-
/**
|
|
7
|
-
* Node types that represent functions per language
|
|
8
|
-
*/
|
|
9
|
-
const FUNCTION_TYPES = {
|
|
10
|
-
typescript: ['function_declaration', 'method_definition'],
|
|
11
|
-
javascript: ['function_declaration', 'method_definition'],
|
|
12
|
-
python: ['function_definition'],
|
|
13
|
-
rust: ['function_item'],
|
|
14
|
-
go: ['function_declaration', 'method_declaration'],
|
|
15
|
-
};
|
|
16
|
-
/**
|
|
17
|
-
* Node types that represent classes per language
|
|
18
|
-
*/
|
|
19
|
-
const CLASS_TYPES = {
|
|
20
|
-
typescript: ['class_declaration', 'abstract_class_declaration'],
|
|
21
|
-
javascript: ['class_declaration'],
|
|
22
|
-
python: ['class_definition'],
|
|
23
|
-
rust: ['struct_item', 'impl_item', 'trait_item'],
|
|
24
|
-
go: ['type_declaration'],
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Node types that represent interfaces per language
|
|
28
|
-
*/
|
|
29
|
-
const INTERFACE_TYPES = {
|
|
30
|
-
typescript: ['interface_declaration'],
|
|
31
|
-
javascript: [],
|
|
32
|
-
python: [],
|
|
33
|
-
rust: ['trait_item'],
|
|
34
|
-
go: [],
|
|
35
|
-
};
|
|
36
|
-
/**
|
|
37
|
-
* Node types that represent type aliases per language
|
|
38
|
-
*/
|
|
39
|
-
const TYPE_TYPES = {
|
|
40
|
-
typescript: ['type_alias_declaration'],
|
|
41
|
-
javascript: [],
|
|
42
|
-
python: [],
|
|
43
|
-
rust: ['type_item'],
|
|
44
|
-
go: ['type_declaration'],
|
|
45
|
-
};
|
|
46
|
-
/**
|
|
47
|
-
* Node types that represent enums per language
|
|
48
|
-
*/
|
|
49
|
-
const ENUM_TYPES = {
|
|
50
|
-
typescript: ['enum_declaration'],
|
|
51
|
-
javascript: [],
|
|
52
|
-
python: [],
|
|
53
|
-
rust: ['enum_item'],
|
|
54
|
-
go: [],
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* Node types that represent constants per language
|
|
58
|
-
*/
|
|
59
|
-
const CONST_TYPES = {
|
|
60
|
-
typescript: ['lexical_declaration'],
|
|
61
|
-
javascript: ['lexical_declaration'],
|
|
62
|
-
python: [], // Python constants handled separately
|
|
63
|
-
rust: ['const_item', 'static_item'],
|
|
64
|
-
go: ['const_declaration', 'var_declaration'],
|
|
65
|
-
};
|
|
66
|
-
/**
|
|
67
|
-
* Check if a node is an exported statement
|
|
68
|
-
*/
|
|
69
|
-
function isExported(node) {
|
|
70
|
-
return node.type === 'export_statement';
|
|
71
|
-
}
|
|
72
7
|
/**
|
|
73
8
|
* Extract top-level definitions from a syntax tree
|
|
74
9
|
*/
|
|
75
10
|
export function extractDefinitions(rootNode, language) {
|
|
76
11
|
const definitions = [];
|
|
77
12
|
const seenNames = new Set();
|
|
78
|
-
// Walk immediate children of root (top-level only)
|
|
79
13
|
for (let i = 0; i < rootNode.childCount; i++) {
|
|
80
14
|
const node = rootNode.child(i);
|
|
81
15
|
if (!node)
|
|
82
16
|
continue;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
17
|
+
// Handle C++ linkage_specification (extern "C" { ... })
|
|
18
|
+
if (language === 'cpp' && node.type === 'linkage_specification') {
|
|
19
|
+
for (let j = 0; j < node.childCount; j++) {
|
|
20
|
+
const inner = node.child(j);
|
|
21
|
+
if (!inner)
|
|
22
|
+
continue;
|
|
23
|
+
if (inner.type === 'extern' || inner.type === 'string_literal')
|
|
24
|
+
continue;
|
|
25
|
+
const defs = extractDefinition({ node: inner, language, forceExtern: true });
|
|
26
|
+
for (const def of defs) {
|
|
27
|
+
if (!seenNames.has(def.name)) {
|
|
28
|
+
definitions.push(def);
|
|
29
|
+
seenNames.add(def.name);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
continue;
|
|
90
34
|
}
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
seenNames.add(d.name);
|
|
35
|
+
const defs = extractDefinition({ node, language });
|
|
36
|
+
for (const def of defs) {
|
|
37
|
+
if (!seenNames.has(def.name)) {
|
|
38
|
+
definitions.push(def);
|
|
39
|
+
seenNames.add(def.name);
|
|
97
40
|
}
|
|
98
41
|
}
|
|
99
42
|
}
|
|
100
43
|
return definitions;
|
|
101
44
|
}
|
|
102
45
|
/**
|
|
103
|
-
* Extract
|
|
46
|
+
* Extract definition(s) from a single node.
|
|
47
|
+
* Handles export detection, unwrapping, and multiple declarations internally.
|
|
104
48
|
*/
|
|
105
|
-
function extractDefinition(
|
|
49
|
+
function extractDefinition(opts) {
|
|
50
|
+
const { node, language, forceExtern = false } = opts;
|
|
51
|
+
// Determine exported status and get actual node to process
|
|
52
|
+
let exported;
|
|
53
|
+
let actualNode;
|
|
54
|
+
let nodeIsExtern = forceExtern;
|
|
55
|
+
switch (language) {
|
|
56
|
+
case 'typescript':
|
|
57
|
+
case 'javascript':
|
|
58
|
+
exported = isExported(node, language);
|
|
59
|
+
actualNode = unwrapExport(node, language);
|
|
60
|
+
break;
|
|
61
|
+
case 'zig':
|
|
62
|
+
exported = isExported(node, language);
|
|
63
|
+
actualNode = node;
|
|
64
|
+
nodeIsExtern = nodeIsExtern || isExtern(node, language);
|
|
65
|
+
break;
|
|
66
|
+
case 'rust':
|
|
67
|
+
exported = isExported(node, language);
|
|
68
|
+
actualNode = node;
|
|
69
|
+
break;
|
|
70
|
+
case 'go':
|
|
71
|
+
// Go: exported determined per-name (uppercase = exported)
|
|
72
|
+
// We'll handle this in createDefinition
|
|
73
|
+
exported = false; // placeholder, resolved per-name
|
|
74
|
+
actualNode = node;
|
|
75
|
+
break;
|
|
76
|
+
case 'cpp':
|
|
77
|
+
exported = false; // C++ doesn't have module exports in this sense
|
|
78
|
+
actualNode = node;
|
|
79
|
+
nodeIsExtern = nodeIsExtern || isExtern(node, language);
|
|
80
|
+
break;
|
|
81
|
+
case 'python':
|
|
82
|
+
default:
|
|
83
|
+
exported = false;
|
|
84
|
+
actualNode = node;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
const results = [];
|
|
88
|
+
// Helper to resolve export status (Go uses name-based exports)
|
|
89
|
+
const resolveExported = (name) => {
|
|
90
|
+
if (language === 'go')
|
|
91
|
+
return isExported(node, language, name);
|
|
92
|
+
return exported;
|
|
93
|
+
};
|
|
94
|
+
// Helper to create a definition
|
|
95
|
+
const createDef = (name, type, startLine, endLine) => ({
|
|
96
|
+
name,
|
|
97
|
+
line: startLine,
|
|
98
|
+
endLine,
|
|
99
|
+
type,
|
|
100
|
+
exported: resolveExported(name),
|
|
101
|
+
...(nodeIsExtern ? { extern: true } : {})
|
|
102
|
+
});
|
|
106
103
|
const functionTypes = FUNCTION_TYPES[language];
|
|
107
104
|
const classTypes = CLASS_TYPES[language];
|
|
105
|
+
const structTypes = STRUCT_TYPES[language];
|
|
106
|
+
const traitTypes = TRAIT_TYPES[language];
|
|
108
107
|
const interfaceTypes = INTERFACE_TYPES[language];
|
|
109
108
|
const typeTypes = TYPE_TYPES[language];
|
|
110
109
|
const enumTypes = ENUM_TYPES[language];
|
|
111
110
|
const constTypes = CONST_TYPES[language];
|
|
112
111
|
// Functions
|
|
113
|
-
if (functionTypes.includes(
|
|
114
|
-
const name = extractName(
|
|
115
|
-
if (name && getBodyLineCount(
|
|
116
|
-
|
|
117
|
-
name,
|
|
118
|
-
line: node.startPosition.row + 1,
|
|
119
|
-
endLine: node.endPosition.row + 1,
|
|
120
|
-
type: 'function',
|
|
121
|
-
exported
|
|
122
|
-
};
|
|
112
|
+
if (functionTypes.includes(actualNode.type)) {
|
|
113
|
+
const name = extractName(actualNode, language);
|
|
114
|
+
if (name && getBodyLineCount(actualNode) > MIN_BODY_LINES) {
|
|
115
|
+
results.push(createDef(name, 'function', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
123
116
|
}
|
|
117
|
+
return results;
|
|
124
118
|
}
|
|
125
119
|
// Classes
|
|
126
|
-
if (classTypes.includes(
|
|
127
|
-
const name = extractName(
|
|
128
|
-
if (name && getBodyLineCount(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
120
|
+
if (classTypes.includes(actualNode.type)) {
|
|
121
|
+
const name = extractName(actualNode, language);
|
|
122
|
+
if (name && getBodyLineCount(actualNode) > MIN_BODY_LINES) {
|
|
123
|
+
results.push(createDef(name, 'class', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
124
|
+
}
|
|
125
|
+
return results;
|
|
126
|
+
}
|
|
127
|
+
// Structs
|
|
128
|
+
if (structTypes.includes(actualNode.type)) {
|
|
129
|
+
const name = extractName(actualNode, language);
|
|
130
|
+
if (name && getBodyLineCount(actualNode) > MIN_BODY_LINES) {
|
|
131
|
+
results.push(createDef(name, 'struct', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
132
|
+
}
|
|
133
|
+
return results;
|
|
134
|
+
}
|
|
135
|
+
// Traits
|
|
136
|
+
if (traitTypes.includes(actualNode.type)) {
|
|
137
|
+
const name = extractName(actualNode, language);
|
|
138
|
+
if (name && getBodyLineCount(actualNode) > MIN_BODY_LINES) {
|
|
139
|
+
results.push(createDef(name, 'trait', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
136
140
|
}
|
|
141
|
+
return results;
|
|
137
142
|
}
|
|
138
143
|
// Interfaces
|
|
139
|
-
if (interfaceTypes.includes(
|
|
140
|
-
const name = extractName(
|
|
144
|
+
if (interfaceTypes.includes(actualNode.type)) {
|
|
145
|
+
const name = extractName(actualNode, language);
|
|
141
146
|
if (name) {
|
|
142
|
-
|
|
143
|
-
name,
|
|
144
|
-
line: node.startPosition.row + 1,
|
|
145
|
-
endLine: node.endPosition.row + 1,
|
|
146
|
-
type: 'interface',
|
|
147
|
-
exported
|
|
148
|
-
};
|
|
147
|
+
results.push(createDef(name, 'interface', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
149
148
|
}
|
|
149
|
+
return results;
|
|
150
150
|
}
|
|
151
151
|
// Type aliases
|
|
152
|
-
if (typeTypes.includes(
|
|
153
|
-
const name = extractName(
|
|
152
|
+
if (typeTypes.includes(actualNode.type)) {
|
|
153
|
+
const name = extractName(actualNode, language);
|
|
154
154
|
if (name) {
|
|
155
|
-
|
|
156
|
-
name,
|
|
157
|
-
line: node.startPosition.row + 1,
|
|
158
|
-
endLine: node.endPosition.row + 1,
|
|
159
|
-
type: 'type',
|
|
160
|
-
exported
|
|
161
|
-
};
|
|
155
|
+
results.push(createDef(name, 'type', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
162
156
|
}
|
|
157
|
+
return results;
|
|
163
158
|
}
|
|
164
159
|
// Enums
|
|
165
|
-
if (enumTypes.includes(
|
|
166
|
-
const name = extractName(
|
|
160
|
+
if (enumTypes.includes(actualNode.type)) {
|
|
161
|
+
const name = extractName(actualNode, language);
|
|
167
162
|
if (name) {
|
|
168
|
-
|
|
169
|
-
name,
|
|
170
|
-
line: node.startPosition.row + 1,
|
|
171
|
-
endLine: node.endPosition.row + 1,
|
|
172
|
-
type: 'enum',
|
|
173
|
-
exported
|
|
174
|
-
};
|
|
163
|
+
results.push(createDef(name, 'enum', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
175
164
|
}
|
|
165
|
+
return results;
|
|
176
166
|
}
|
|
177
|
-
// Constants/variables
|
|
178
|
-
if (constTypes.includes(
|
|
179
|
-
//
|
|
180
|
-
if (
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (arrowFn && arrowFn.bodyLines > MIN_BODY_LINES) {
|
|
184
|
-
return {
|
|
185
|
-
name: arrowFn.name,
|
|
186
|
-
line: arrowFn.line,
|
|
187
|
-
endLine: arrowFn.endLine,
|
|
188
|
-
type: 'function',
|
|
189
|
-
exported: false
|
|
190
|
-
};
|
|
167
|
+
// Constants/variables
|
|
168
|
+
if (constTypes.includes(actualNode.type)) {
|
|
169
|
+
// Zig: pub const (may be struct/enum/union or plain const)
|
|
170
|
+
if (language === 'zig') {
|
|
171
|
+
if (!exported || !isZigConst(actualNode)) {
|
|
172
|
+
return results;
|
|
191
173
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
endLine: arrowFn.endLine,
|
|
201
|
-
type: 'function',
|
|
202
|
-
exported
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
// Otherwise it's a constant
|
|
206
|
-
const name = extractConstName(node, language);
|
|
207
|
-
if (name) {
|
|
208
|
-
return {
|
|
209
|
-
name,
|
|
210
|
-
line: node.startPosition.row + 1,
|
|
211
|
-
endLine: node.endPosition.row + 1,
|
|
212
|
-
type: 'const',
|
|
213
|
-
exported
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Extract multiple declarations from a single statement
|
|
221
|
-
*/
|
|
222
|
-
function extractMultipleDeclarations(node, language, exported) {
|
|
223
|
-
const defs = [];
|
|
224
|
-
// Handle lexical_declaration with multiple variable_declarators
|
|
225
|
-
if (node.type === 'lexical_declaration') {
|
|
226
|
-
if ((language === 'typescript' || language === 'javascript') && !exported) {
|
|
227
|
-
return defs;
|
|
174
|
+
const name = extractName(actualNode, language);
|
|
175
|
+
if (name) {
|
|
176
|
+
// Use specific type if struct/enum/union, otherwise const
|
|
177
|
+
const zigType = getZigTypeDeclaration(actualNode);
|
|
178
|
+
const type = zigType ?? 'const';
|
|
179
|
+
results.push(createDef(name, type, actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
180
|
+
}
|
|
181
|
+
return results;
|
|
228
182
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if (
|
|
233
|
-
|
|
234
|
-
if (
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
continue;
|
|
243
|
-
}
|
|
244
|
-
defs.push({
|
|
245
|
-
name: nameNode.text,
|
|
246
|
-
line: child.startPosition.row + 1,
|
|
247
|
-
endLine: child.endPosition.row + 1,
|
|
248
|
-
type,
|
|
249
|
-
exported,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
183
|
+
// TS/JS: handle arrow functions and multiple declarations
|
|
184
|
+
if (language === 'typescript' || language === 'javascript') {
|
|
185
|
+
// Non-exported: only include large arrow functions
|
|
186
|
+
if (!exported) {
|
|
187
|
+
const arrowFn = extractArrowFunction(actualNode);
|
|
188
|
+
if (arrowFn && arrowFn.bodyLines > MIN_BODY_LINES) {
|
|
189
|
+
results.push({
|
|
190
|
+
name: arrowFn.name,
|
|
191
|
+
line: arrowFn.line,
|
|
192
|
+
endLine: arrowFn.endLine,
|
|
193
|
+
type: 'function',
|
|
194
|
+
exported: false
|
|
195
|
+
});
|
|
252
196
|
}
|
|
197
|
+
return results;
|
|
253
198
|
}
|
|
199
|
+
// Exported: extract all declarations
|
|
200
|
+
return extractJSDeclarations({ node: actualNode, language, exported, isExtern: nodeIsExtern });
|
|
254
201
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
* Unwrap export statement to get the actual declaration
|
|
260
|
-
*/
|
|
261
|
-
function unwrapExport(node) {
|
|
262
|
-
if (node.type === 'export_statement') {
|
|
263
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
264
|
-
const child = node.child(i);
|
|
265
|
-
if (!child)
|
|
266
|
-
continue;
|
|
267
|
-
if (child.type !== 'export' && !child.type.includes('comment') && child.type !== 'default') {
|
|
268
|
-
return child;
|
|
269
|
-
}
|
|
202
|
+
// Other languages: simple const extraction
|
|
203
|
+
const name = extractConstName(actualNode, language);
|
|
204
|
+
if (name) {
|
|
205
|
+
results.push(createDef(name, 'const', actualNode.startPosition.row + 1, actualNode.endPosition.row + 1));
|
|
270
206
|
}
|
|
207
|
+
return results;
|
|
271
208
|
}
|
|
272
|
-
return
|
|
209
|
+
return results;
|
|
273
210
|
}
|
|
274
211
|
/**
|
|
275
|
-
* Extract
|
|
212
|
+
* Extract all declarations from a TS/JS lexical_declaration
|
|
213
|
+
* Handles: const a = 1, const b = () => {}, const c = 1, d = 2
|
|
276
214
|
*/
|
|
277
|
-
function
|
|
278
|
-
|
|
279
|
-
const
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
case 'go':
|
|
293
|
-
return extractGoName(node);
|
|
294
|
-
}
|
|
295
|
-
return null;
|
|
296
|
-
}
|
|
297
|
-
/**
|
|
298
|
-
* Extract name from a const/let declaration
|
|
299
|
-
*/
|
|
300
|
-
function extractConstName(node, language) {
|
|
301
|
-
if (language === 'typescript' || language === 'javascript') {
|
|
302
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
303
|
-
const child = node.child(i);
|
|
304
|
-
if (child?.type === 'variable_declarator') {
|
|
305
|
-
const nameNode = child.childForFieldName('name');
|
|
306
|
-
return nameNode?.text ?? null;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
if (language === 'rust') {
|
|
311
|
-
return extractName(node, language);
|
|
312
|
-
}
|
|
313
|
-
if (language === 'go') {
|
|
314
|
-
// Look for const_spec or var_spec
|
|
315
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
316
|
-
const child = node.child(i);
|
|
317
|
-
if (child?.type === 'const_spec' || child?.type === 'var_spec') {
|
|
318
|
-
const nameNode = child.childForFieldName('name');
|
|
319
|
-
return nameNode?.text ?? null;
|
|
320
|
-
}
|
|
215
|
+
function extractJSDeclarations(opts) {
|
|
216
|
+
const { node, exported, isExtern: nodeIsExtern } = opts;
|
|
217
|
+
const results = [];
|
|
218
|
+
if (node.type !== 'lexical_declaration') {
|
|
219
|
+
// Single const extraction fallback
|
|
220
|
+
const name = extractConstName(node, opts.language);
|
|
221
|
+
if (name) {
|
|
222
|
+
results.push({
|
|
223
|
+
name,
|
|
224
|
+
line: node.startPosition.row + 1,
|
|
225
|
+
endLine: node.endPosition.row + 1,
|
|
226
|
+
type: 'const',
|
|
227
|
+
exported,
|
|
228
|
+
...(nodeIsExtern ? { extern: true } : {})
|
|
229
|
+
});
|
|
321
230
|
}
|
|
231
|
+
return results;
|
|
322
232
|
}
|
|
323
|
-
return null;
|
|
324
|
-
}
|
|
325
|
-
function extractJSName(node) {
|
|
326
233
|
for (let i = 0; i < node.childCount; i++) {
|
|
327
234
|
const child = node.child(i);
|
|
328
|
-
if (
|
|
235
|
+
if (child?.type !== 'variable_declarator')
|
|
236
|
+
continue;
|
|
237
|
+
const nameNode = child.childForFieldName('name');
|
|
238
|
+
const valueNode = child.childForFieldName('value');
|
|
239
|
+
if (!nameNode)
|
|
240
|
+
continue;
|
|
241
|
+
const isArrowFn = valueNode?.type === 'arrow_function';
|
|
242
|
+
const type = isArrowFn ? 'function' : 'const';
|
|
243
|
+
// Skip small arrow functions
|
|
244
|
+
if (isArrowFn && valueNode && getBodyLineCount(valueNode) <= MIN_BODY_LINES) {
|
|
329
245
|
continue;
|
|
330
|
-
if (child.type === 'identifier' || child.type === 'type_identifier') {
|
|
331
|
-
return child.text;
|
|
332
|
-
}
|
|
333
|
-
if (child.type === 'property_identifier') {
|
|
334
|
-
return child.text;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return null;
|
|
338
|
-
}
|
|
339
|
-
function extractPythonName(node) {
|
|
340
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
341
|
-
const child = node.child(i);
|
|
342
|
-
if (child?.type === 'identifier') {
|
|
343
|
-
return child.text;
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
return null;
|
|
347
|
-
}
|
|
348
|
-
function extractRustName(node) {
|
|
349
|
-
if (node.type === 'impl_item') {
|
|
350
|
-
const typeNode = node.childForFieldName('type');
|
|
351
|
-
if (typeNode) {
|
|
352
|
-
const ident = typeNode.type === 'type_identifier'
|
|
353
|
-
? typeNode
|
|
354
|
-
: findChild(typeNode, 'type_identifier');
|
|
355
|
-
return ident?.text ?? null;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
359
|
-
const child = node.child(i);
|
|
360
|
-
if (child?.type === 'identifier' || child?.type === 'type_identifier') {
|
|
361
|
-
return child.text;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
return null;
|
|
365
|
-
}
|
|
366
|
-
function extractGoName(node) {
|
|
367
|
-
if (node.type === 'type_declaration') {
|
|
368
|
-
const spec = findChild(node, 'type_spec');
|
|
369
|
-
if (spec) {
|
|
370
|
-
const nameNode = spec.childForFieldName('name');
|
|
371
|
-
return nameNode?.text ?? null;
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
for (let i = 0; i < node.childCount; i++) {
|
|
375
|
-
const child = node.child(i);
|
|
376
|
-
if (child?.type === 'identifier' || child?.type === 'field_identifier') {
|
|
377
|
-
return child.text;
|
|
378
246
|
}
|
|
247
|
+
results.push({
|
|
248
|
+
name: nameNode.text,
|
|
249
|
+
line: child.startPosition.row + 1,
|
|
250
|
+
endLine: child.endPosition.row + 1,
|
|
251
|
+
type,
|
|
252
|
+
exported,
|
|
253
|
+
...(nodeIsExtern ? { extern: true } : {})
|
|
254
|
+
});
|
|
379
255
|
}
|
|
380
|
-
return
|
|
256
|
+
return results;
|
|
381
257
|
}
|
|
258
|
+
// ============================================================================
|
|
259
|
+
// Utility functions
|
|
260
|
+
// ============================================================================
|
|
382
261
|
/**
|
|
383
262
|
* Extract arrow function assigned to const/let
|
|
384
263
|
*/
|