@renseiai/agentfactory-code-intelligence 0.8.4
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/LICENSE +21 -0
- package/dist/src/__tests__/types.test.d.ts +2 -0
- package/dist/src/__tests__/types.test.d.ts.map +1 -0
- package/dist/src/__tests__/types.test.js +187 -0
- package/dist/src/index.d.ts +26 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +29 -0
- package/dist/src/indexing/__tests__/indexing.test.d.ts +2 -0
- package/dist/src/indexing/__tests__/indexing.test.d.ts.map +1 -0
- package/dist/src/indexing/__tests__/indexing.test.js +193 -0
- package/dist/src/indexing/change-detector.d.ts +16 -0
- package/dist/src/indexing/change-detector.d.ts.map +1 -0
- package/dist/src/indexing/change-detector.js +38 -0
- package/dist/src/indexing/git-hash-provider.d.ts +11 -0
- package/dist/src/indexing/git-hash-provider.d.ts.map +1 -0
- package/dist/src/indexing/git-hash-provider.js +25 -0
- package/dist/src/indexing/incremental-indexer.d.ts +38 -0
- package/dist/src/indexing/incremental-indexer.d.ts.map +1 -0
- package/dist/src/indexing/incremental-indexer.js +122 -0
- package/dist/src/indexing/merkle-tree.d.ts +33 -0
- package/dist/src/indexing/merkle-tree.d.ts.map +1 -0
- package/dist/src/indexing/merkle-tree.js +107 -0
- package/dist/src/memory/__tests__/dedup.test.d.ts +2 -0
- package/dist/src/memory/__tests__/dedup.test.d.ts.map +1 -0
- package/dist/src/memory/__tests__/dedup.test.js +173 -0
- package/dist/src/memory/dedup-pipeline.d.ts +24 -0
- package/dist/src/memory/dedup-pipeline.d.ts.map +1 -0
- package/dist/src/memory/dedup-pipeline.js +73 -0
- package/dist/src/memory/memory-store.d.ts +22 -0
- package/dist/src/memory/memory-store.d.ts.map +1 -0
- package/dist/src/memory/memory-store.js +32 -0
- package/dist/src/memory/simhash.d.ts +16 -0
- package/dist/src/memory/simhash.d.ts.map +1 -0
- package/dist/src/memory/simhash.js +67 -0
- package/dist/src/memory/xxhash.d.ts +3 -0
- package/dist/src/memory/xxhash.d.ts.map +1 -0
- package/dist/src/memory/xxhash.js +13 -0
- package/dist/src/parser/__tests__/multi-language.test.d.ts +2 -0
- package/dist/src/parser/__tests__/multi-language.test.d.ts.map +1 -0
- package/dist/src/parser/__tests__/multi-language.test.js +350 -0
- package/dist/src/parser/__tests__/symbol-extractor.test.d.ts +2 -0
- package/dist/src/parser/__tests__/symbol-extractor.test.d.ts.map +1 -0
- package/dist/src/parser/__tests__/symbol-extractor.test.js +188 -0
- package/dist/src/parser/go-extractor.d.ts +8 -0
- package/dist/src/parser/go-extractor.d.ts.map +1 -0
- package/dist/src/parser/go-extractor.js +127 -0
- package/dist/src/parser/python-extractor.d.ts +8 -0
- package/dist/src/parser/python-extractor.d.ts.map +1 -0
- package/dist/src/parser/python-extractor.js +92 -0
- package/dist/src/parser/rust-extractor.d.ts +8 -0
- package/dist/src/parser/rust-extractor.d.ts.map +1 -0
- package/dist/src/parser/rust-extractor.js +168 -0
- package/dist/src/parser/symbol-extractor.d.ts +14 -0
- package/dist/src/parser/symbol-extractor.d.ts.map +1 -0
- package/dist/src/parser/symbol-extractor.js +47 -0
- package/dist/src/parser/typescript-extractor.d.ts +13 -0
- package/dist/src/parser/typescript-extractor.d.ts.map +1 -0
- package/dist/src/parser/typescript-extractor.js +229 -0
- package/dist/src/plugin/__tests__/plugin.test.d.ts +2 -0
- package/dist/src/plugin/__tests__/plugin.test.d.ts.map +1 -0
- package/dist/src/plugin/__tests__/plugin.test.js +48 -0
- package/dist/src/plugin/code-intelligence-plugin.d.ts +15 -0
- package/dist/src/plugin/code-intelligence-plugin.d.ts.map +1 -0
- package/dist/src/plugin/code-intelligence-plugin.js +102 -0
- package/dist/src/repo-map/__tests__/repo-map.test.d.ts +2 -0
- package/dist/src/repo-map/__tests__/repo-map.test.d.ts.map +1 -0
- package/dist/src/repo-map/__tests__/repo-map.test.js +186 -0
- package/dist/src/repo-map/dependency-graph.d.ts +30 -0
- package/dist/src/repo-map/dependency-graph.d.ts.map +1 -0
- package/dist/src/repo-map/dependency-graph.js +105 -0
- package/dist/src/repo-map/pagerank.d.ts +20 -0
- package/dist/src/repo-map/pagerank.d.ts.map +1 -0
- package/dist/src/repo-map/pagerank.js +68 -0
- package/dist/src/repo-map/repo-map-generator.d.ts +20 -0
- package/dist/src/repo-map/repo-map-generator.d.ts.map +1 -0
- package/dist/src/repo-map/repo-map-generator.js +66 -0
- package/dist/src/search/__tests__/search.test.d.ts +2 -0
- package/dist/src/search/__tests__/search.test.d.ts.map +1 -0
- package/dist/src/search/__tests__/search.test.js +191 -0
- package/dist/src/search/bm25.d.ts +24 -0
- package/dist/src/search/bm25.d.ts.map +1 -0
- package/dist/src/search/bm25.js +44 -0
- package/dist/src/search/inverted-index.d.ts +31 -0
- package/dist/src/search/inverted-index.d.ts.map +1 -0
- package/dist/src/search/inverted-index.js +72 -0
- package/dist/src/search/search-engine.d.ts +22 -0
- package/dist/src/search/search-engine.d.ts.map +1 -0
- package/dist/src/search/search-engine.js +76 -0
- package/dist/src/search/tokenizer.d.ts +11 -0
- package/dist/src/search/tokenizer.d.ts.map +1 -0
- package/dist/src/search/tokenizer.js +48 -0
- package/dist/src/types.d.ts +242 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +96 -0
- package/package.json +74 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/** Regex-based Go symbol extractor. */
|
|
2
|
+
export class GoExtractor {
|
|
3
|
+
languages = ['go'];
|
|
4
|
+
extract(source, filePath) {
|
|
5
|
+
const lines = source.split('\n');
|
|
6
|
+
const symbols = [];
|
|
7
|
+
const imports = [];
|
|
8
|
+
const exports = [];
|
|
9
|
+
let currentComment;
|
|
10
|
+
for (let i = 0; i < lines.length; i++) {
|
|
11
|
+
const line = lines[i];
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
// Skip comments, but track for documentation
|
|
14
|
+
if (trimmed.startsWith('//')) {
|
|
15
|
+
currentComment = (currentComment ? currentComment + '\n' : '') + trimmed.slice(2).trim();
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
// Imports
|
|
19
|
+
const importMatch = trimmed.match(/^import\s+"([^"]+)"/);
|
|
20
|
+
if (importMatch) {
|
|
21
|
+
imports.push(importMatch[1]);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
// Multi-line import
|
|
25
|
+
if (trimmed === 'import (') {
|
|
26
|
+
for (let j = i + 1; j < lines.length; j++) {
|
|
27
|
+
const importLine = lines[j].trim();
|
|
28
|
+
if (importLine === ')')
|
|
29
|
+
break;
|
|
30
|
+
const pkg = importLine.match(/"([^"]+)"/);
|
|
31
|
+
if (pkg)
|
|
32
|
+
imports.push(pkg[1]);
|
|
33
|
+
}
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
// Function declarations (with optional receiver)
|
|
37
|
+
const funcMatch = trimmed.match(/^func\s+(?:\((\w+)\s+\*?(\w+)\)\s+)?(\w+)\s*\(/);
|
|
38
|
+
if (funcMatch) {
|
|
39
|
+
const receiverVar = funcMatch[1];
|
|
40
|
+
const receiverType = funcMatch[2];
|
|
41
|
+
const name = funcMatch[3];
|
|
42
|
+
const isExported = name[0] === name[0].toUpperCase() && name[0] !== name[0].toLowerCase();
|
|
43
|
+
symbols.push({
|
|
44
|
+
name,
|
|
45
|
+
kind: receiverType ? 'method' : 'function',
|
|
46
|
+
filePath, line: i,
|
|
47
|
+
exported: isExported,
|
|
48
|
+
signature: trimmed.split('{')[0].trim(),
|
|
49
|
+
documentation: currentComment,
|
|
50
|
+
language: 'go',
|
|
51
|
+
...(receiverType ? { parentName: receiverType } : {}),
|
|
52
|
+
});
|
|
53
|
+
if (isExported)
|
|
54
|
+
exports.push(name);
|
|
55
|
+
currentComment = undefined;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
// Struct declaration
|
|
59
|
+
const structMatch = trimmed.match(/^type\s+(\w+)\s+struct\b/);
|
|
60
|
+
if (structMatch) {
|
|
61
|
+
const name = structMatch[1];
|
|
62
|
+
const isExported = name[0] === name[0].toUpperCase();
|
|
63
|
+
symbols.push({
|
|
64
|
+
name, kind: 'struct', filePath, line: i,
|
|
65
|
+
exported: isExported,
|
|
66
|
+
documentation: currentComment,
|
|
67
|
+
language: 'go',
|
|
68
|
+
});
|
|
69
|
+
if (isExported)
|
|
70
|
+
exports.push(name);
|
|
71
|
+
currentComment = undefined;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
// Interface declaration
|
|
75
|
+
const ifaceMatch = trimmed.match(/^type\s+(\w+)\s+interface\b/);
|
|
76
|
+
if (ifaceMatch) {
|
|
77
|
+
const name = ifaceMatch[1];
|
|
78
|
+
const isExported = name[0] === name[0].toUpperCase();
|
|
79
|
+
symbols.push({
|
|
80
|
+
name, kind: 'interface', filePath, line: i,
|
|
81
|
+
exported: isExported,
|
|
82
|
+
documentation: currentComment,
|
|
83
|
+
language: 'go',
|
|
84
|
+
});
|
|
85
|
+
if (isExported)
|
|
86
|
+
exports.push(name);
|
|
87
|
+
currentComment = undefined;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// Type alias
|
|
91
|
+
const typeMatch = trimmed.match(/^type\s+(\w+)\s+(?!struct|interface)/);
|
|
92
|
+
if (typeMatch) {
|
|
93
|
+
const name = typeMatch[1];
|
|
94
|
+
const isExported = name[0] === name[0].toUpperCase();
|
|
95
|
+
symbols.push({
|
|
96
|
+
name, kind: 'type', filePath, line: i,
|
|
97
|
+
exported: isExported,
|
|
98
|
+
language: 'go',
|
|
99
|
+
});
|
|
100
|
+
if (isExported)
|
|
101
|
+
exports.push(name);
|
|
102
|
+
currentComment = undefined;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Variable/constant
|
|
106
|
+
const varMatch = trimmed.match(/^(?:var|const)\s+(\w+)/);
|
|
107
|
+
if (varMatch) {
|
|
108
|
+
const name = varMatch[1];
|
|
109
|
+
const isExported = name[0] === name[0].toUpperCase();
|
|
110
|
+
symbols.push({
|
|
111
|
+
name, kind: 'variable', filePath, line: i,
|
|
112
|
+
exported: isExported,
|
|
113
|
+
language: 'go',
|
|
114
|
+
});
|
|
115
|
+
if (isExported)
|
|
116
|
+
exports.push(name);
|
|
117
|
+
currentComment = undefined;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Clear comment if line is not empty and not a comment
|
|
121
|
+
if (trimmed.length > 0) {
|
|
122
|
+
currentComment = undefined;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { filePath, language: 'go', symbols, imports, exports };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FileAST } from '../types.js';
|
|
2
|
+
import type { LanguageExtractor } from './symbol-extractor.js';
|
|
3
|
+
/** Regex-based Python symbol extractor. */
|
|
4
|
+
export declare class PythonExtractor implements LanguageExtractor {
|
|
5
|
+
languages: string[];
|
|
6
|
+
extract(source: string, filePath: string): FileAST;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=python-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python-extractor.d.ts","sourceRoot":"","sources":["../../../src/parser/python-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,OAAO,EAAc,MAAM,aAAa,CAAA;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,2CAA2C;AAC3C,qBAAa,eAAgB,YAAW,iBAAiB;IACvD,SAAS,WAAa;IAEtB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;CA+FnD"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/** Regex-based Python symbol extractor. */
|
|
2
|
+
export class PythonExtractor {
|
|
3
|
+
languages = ['python'];
|
|
4
|
+
extract(source, filePath) {
|
|
5
|
+
const lines = source.split('\n');
|
|
6
|
+
const symbols = [];
|
|
7
|
+
const imports = [];
|
|
8
|
+
const exports = [];
|
|
9
|
+
let currentDocstring;
|
|
10
|
+
for (let i = 0; i < lines.length; i++) {
|
|
11
|
+
const line = lines[i];
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
// Skip comments
|
|
14
|
+
if (trimmed.startsWith('#'))
|
|
15
|
+
continue;
|
|
16
|
+
// Docstrings (single-line)
|
|
17
|
+
if (trimmed.startsWith('"""') || trimmed.startsWith("'''")) {
|
|
18
|
+
if (trimmed.slice(3).includes(trimmed.slice(0, 3))) {
|
|
19
|
+
currentDocstring = trimmed.slice(3, trimmed.lastIndexOf(trimmed.slice(0, 3)));
|
|
20
|
+
}
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
// Imports
|
|
24
|
+
const importMatch = trimmed.match(/^(?:from\s+(\S+)\s+)?import\s+(.+)/);
|
|
25
|
+
if (importMatch) {
|
|
26
|
+
const module = importMatch[1] ?? importMatch[2].split(',')[0].trim().split(/\s+as\s+/)[0];
|
|
27
|
+
imports.push(module);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
// Decorators
|
|
31
|
+
const decoratorMatch = trimmed.match(/^@(\w+)/);
|
|
32
|
+
if (decoratorMatch) {
|
|
33
|
+
symbols.push({
|
|
34
|
+
name: decoratorMatch[1], kind: 'decorator', filePath, line: i,
|
|
35
|
+
exported: false, language: 'python',
|
|
36
|
+
});
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
// Function definitions
|
|
40
|
+
const funcMatch = trimmed.match(/^(?:async\s+)?def\s+(\w+)\s*\(/);
|
|
41
|
+
if (funcMatch) {
|
|
42
|
+
const name = funcMatch[1];
|
|
43
|
+
const indent = line.length - line.trimStart().length;
|
|
44
|
+
const isMethod = indent > 0;
|
|
45
|
+
const exported = !name.startsWith('_');
|
|
46
|
+
symbols.push({
|
|
47
|
+
name,
|
|
48
|
+
kind: isMethod ? 'method' : 'function',
|
|
49
|
+
filePath, line: i,
|
|
50
|
+
exported,
|
|
51
|
+
signature: trimmed.split(':')[0],
|
|
52
|
+
documentation: currentDocstring,
|
|
53
|
+
language: 'python',
|
|
54
|
+
});
|
|
55
|
+
if (exported && !isMethod)
|
|
56
|
+
exports.push(name);
|
|
57
|
+
currentDocstring = undefined;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// Class definitions
|
|
61
|
+
const classMatch = trimmed.match(/^class\s+(\w+)/);
|
|
62
|
+
if (classMatch) {
|
|
63
|
+
const name = classMatch[1];
|
|
64
|
+
const exported = !name.startsWith('_');
|
|
65
|
+
symbols.push({
|
|
66
|
+
name, kind: 'class', filePath, line: i,
|
|
67
|
+
exported,
|
|
68
|
+
signature: trimmed.split(':')[0],
|
|
69
|
+
documentation: currentDocstring,
|
|
70
|
+
language: 'python',
|
|
71
|
+
});
|
|
72
|
+
if (exported)
|
|
73
|
+
exports.push(name);
|
|
74
|
+
currentDocstring = undefined;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
// Module-level variable assignment
|
|
78
|
+
const varMatch = trimmed.match(/^(\w+)\s*(?::\s*\w[^=]*)?\s*=/);
|
|
79
|
+
if (varMatch && line.length - line.trimStart().length === 0) {
|
|
80
|
+
const name = varMatch[1];
|
|
81
|
+
const exported = !name.startsWith('_') && name === name.toUpperCase() || !name.startsWith('_');
|
|
82
|
+
symbols.push({
|
|
83
|
+
name, kind: 'variable', filePath, line: i,
|
|
84
|
+
exported: !name.startsWith('_'),
|
|
85
|
+
language: 'python',
|
|
86
|
+
});
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { filePath, language: 'python', symbols, imports, exports };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FileAST } from '../types.js';
|
|
2
|
+
import type { LanguageExtractor } from './symbol-extractor.js';
|
|
3
|
+
/** Regex-based Rust symbol extractor. */
|
|
4
|
+
export declare class RustExtractor implements LanguageExtractor {
|
|
5
|
+
languages: string[];
|
|
6
|
+
extract(source: string, filePath: string): FileAST;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=rust-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rust-extractor.d.ts","sourceRoot":"","sources":["../../../src/parser/rust-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,OAAO,EAAc,MAAM,aAAa,CAAA;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,yCAAyC;AACzC,qBAAa,aAAc,YAAW,iBAAiB;IACrD,SAAS,WAAW;IAEpB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;CA4KnD"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/** Regex-based Rust symbol extractor. */
|
|
2
|
+
export class RustExtractor {
|
|
3
|
+
languages = ['rust'];
|
|
4
|
+
extract(source, filePath) {
|
|
5
|
+
const lines = source.split('\n');
|
|
6
|
+
const symbols = [];
|
|
7
|
+
const imports = [];
|
|
8
|
+
const exports = [];
|
|
9
|
+
let currentDoc;
|
|
10
|
+
for (let i = 0; i < lines.length; i++) {
|
|
11
|
+
const line = lines[i];
|
|
12
|
+
const trimmed = line.trim();
|
|
13
|
+
// Doc comments
|
|
14
|
+
if (trimmed.startsWith('///')) {
|
|
15
|
+
currentDoc = (currentDoc ? currentDoc + '\n' : '') + trimmed.slice(3).trim();
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
// Regular comments
|
|
19
|
+
if (trimmed.startsWith('//'))
|
|
20
|
+
continue;
|
|
21
|
+
// Use statements (imports)
|
|
22
|
+
const useMatch = trimmed.match(/^(?:pub\s+)?use\s+(.+);/);
|
|
23
|
+
if (useMatch) {
|
|
24
|
+
imports.push(useMatch[1]);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const isPublic = trimmed.startsWith('pub ');
|
|
28
|
+
const effective = isPublic ? trimmed.replace(/^pub\s+(?:\(crate\)\s+)?/, '') : trimmed;
|
|
29
|
+
// Function declarations
|
|
30
|
+
const fnMatch = effective.match(/^(?:async\s+)?(?:unsafe\s+)?fn\s+(\w+)/);
|
|
31
|
+
if (fnMatch) {
|
|
32
|
+
const name = fnMatch[1];
|
|
33
|
+
symbols.push({
|
|
34
|
+
name, kind: 'function', filePath, line: i,
|
|
35
|
+
exported: isPublic,
|
|
36
|
+
signature: effective.split('{')[0].trim(),
|
|
37
|
+
documentation: currentDoc,
|
|
38
|
+
language: 'rust',
|
|
39
|
+
});
|
|
40
|
+
if (isPublic)
|
|
41
|
+
exports.push(name);
|
|
42
|
+
currentDoc = undefined;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
// Struct declarations
|
|
46
|
+
const structMatch = effective.match(/^struct\s+(\w+)/);
|
|
47
|
+
if (structMatch) {
|
|
48
|
+
const name = structMatch[1];
|
|
49
|
+
symbols.push({
|
|
50
|
+
name, kind: 'struct', filePath, line: i,
|
|
51
|
+
exported: isPublic,
|
|
52
|
+
documentation: currentDoc,
|
|
53
|
+
language: 'rust',
|
|
54
|
+
});
|
|
55
|
+
if (isPublic)
|
|
56
|
+
exports.push(name);
|
|
57
|
+
currentDoc = undefined;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// Enum declarations
|
|
61
|
+
const enumMatch = effective.match(/^enum\s+(\w+)/);
|
|
62
|
+
if (enumMatch) {
|
|
63
|
+
const name = enumMatch[1];
|
|
64
|
+
symbols.push({
|
|
65
|
+
name, kind: 'enum', filePath, line: i,
|
|
66
|
+
exported: isPublic,
|
|
67
|
+
documentation: currentDoc,
|
|
68
|
+
language: 'rust',
|
|
69
|
+
});
|
|
70
|
+
if (isPublic)
|
|
71
|
+
exports.push(name);
|
|
72
|
+
currentDoc = undefined;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
// Trait declarations
|
|
76
|
+
const traitMatch = effective.match(/^trait\s+(\w+)/);
|
|
77
|
+
if (traitMatch) {
|
|
78
|
+
const name = traitMatch[1];
|
|
79
|
+
symbols.push({
|
|
80
|
+
name, kind: 'trait', filePath, line: i,
|
|
81
|
+
exported: isPublic,
|
|
82
|
+
documentation: currentDoc,
|
|
83
|
+
language: 'rust',
|
|
84
|
+
});
|
|
85
|
+
if (isPublic)
|
|
86
|
+
exports.push(name);
|
|
87
|
+
currentDoc = undefined;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
// Impl blocks
|
|
91
|
+
const implMatch = effective.match(/^impl(?:<[^>]+>)?\s+(?:(\w+)\s+for\s+)?(\w+)/);
|
|
92
|
+
if (implMatch) {
|
|
93
|
+
const traitName = implMatch[1];
|
|
94
|
+
const typeName = implMatch[2];
|
|
95
|
+
const name = traitName ? `${traitName} for ${typeName}` : typeName;
|
|
96
|
+
symbols.push({
|
|
97
|
+
name, kind: 'impl', filePath, line: i,
|
|
98
|
+
exported: false,
|
|
99
|
+
documentation: currentDoc,
|
|
100
|
+
language: 'rust',
|
|
101
|
+
});
|
|
102
|
+
currentDoc = undefined;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
// Macro definitions
|
|
106
|
+
const macroMatch = effective.match(/^macro_rules!\s+(\w+)/);
|
|
107
|
+
if (macroMatch) {
|
|
108
|
+
const name = macroMatch[1];
|
|
109
|
+
symbols.push({
|
|
110
|
+
name, kind: 'macro', filePath, line: i,
|
|
111
|
+
exported: isPublic,
|
|
112
|
+
documentation: currentDoc,
|
|
113
|
+
language: 'rust',
|
|
114
|
+
});
|
|
115
|
+
if (isPublic)
|
|
116
|
+
exports.push(name);
|
|
117
|
+
currentDoc = undefined;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Const/static
|
|
121
|
+
const constMatch = effective.match(/^(?:const|static)\s+(\w+)/);
|
|
122
|
+
if (constMatch) {
|
|
123
|
+
const name = constMatch[1];
|
|
124
|
+
symbols.push({
|
|
125
|
+
name, kind: 'variable', filePath, line: i,
|
|
126
|
+
exported: isPublic,
|
|
127
|
+
language: 'rust',
|
|
128
|
+
});
|
|
129
|
+
if (isPublic)
|
|
130
|
+
exports.push(name);
|
|
131
|
+
currentDoc = undefined;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// Type alias
|
|
135
|
+
const typeMatch = effective.match(/^type\s+(\w+)/);
|
|
136
|
+
if (typeMatch) {
|
|
137
|
+
const name = typeMatch[1];
|
|
138
|
+
symbols.push({
|
|
139
|
+
name, kind: 'type', filePath, line: i,
|
|
140
|
+
exported: isPublic,
|
|
141
|
+
language: 'rust',
|
|
142
|
+
});
|
|
143
|
+
if (isPublic)
|
|
144
|
+
exports.push(name);
|
|
145
|
+
currentDoc = undefined;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
// Module declarations
|
|
149
|
+
const modMatch = effective.match(/^mod\s+(\w+)/);
|
|
150
|
+
if (modMatch) {
|
|
151
|
+
const name = modMatch[1];
|
|
152
|
+
symbols.push({
|
|
153
|
+
name, kind: 'module', filePath, line: i,
|
|
154
|
+
exported: isPublic,
|
|
155
|
+
language: 'rust',
|
|
156
|
+
});
|
|
157
|
+
if (isPublic)
|
|
158
|
+
exports.push(name);
|
|
159
|
+
currentDoc = undefined;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (trimmed.length > 0 && !trimmed.startsWith('*')) {
|
|
163
|
+
currentDoc = undefined;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return { filePath, language: 'rust', symbols, imports, exports };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { FileAST } from '../types.js';
|
|
2
|
+
export interface LanguageExtractor {
|
|
3
|
+
languages: string[];
|
|
4
|
+
extract(source: string, filePath: string): FileAST;
|
|
5
|
+
}
|
|
6
|
+
export declare class SymbolExtractor {
|
|
7
|
+
private extractors;
|
|
8
|
+
constructor();
|
|
9
|
+
registerExtractor(extractor: LanguageExtractor): void;
|
|
10
|
+
extractFromSource(source: string, filePath: string): FileAST;
|
|
11
|
+
detectLanguage(filePath: string): string;
|
|
12
|
+
supportsLanguage(language: string): boolean;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=symbol-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbol-extractor.d.ts","sourceRoot":"","sources":["../../../src/parser/symbol-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,OAAO,EAAc,MAAM,aAAa,CAAA;AAGlE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;CACnD;AAcD,qBAAa,eAAe;IAC1B,OAAO,CAAC,UAAU,CAA4C;;IAS9D,iBAAiB,CAAC,SAAS,EAAE,iBAAiB,GAAG,IAAI;IAMrD,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAe5D,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAG5C"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { TypeScriptExtractor } from './typescript-extractor.js';
|
|
2
|
+
const EXTENSION_MAP = {
|
|
3
|
+
'.ts': 'typescript',
|
|
4
|
+
'.tsx': 'typescript',
|
|
5
|
+
'.js': 'javascript',
|
|
6
|
+
'.jsx': 'javascript',
|
|
7
|
+
'.mjs': 'javascript',
|
|
8
|
+
'.cjs': 'javascript',
|
|
9
|
+
'.py': 'python',
|
|
10
|
+
'.go': 'go',
|
|
11
|
+
'.rs': 'rust',
|
|
12
|
+
};
|
|
13
|
+
export class SymbolExtractor {
|
|
14
|
+
extractors = new Map();
|
|
15
|
+
constructor() {
|
|
16
|
+
const tsExtractor = new TypeScriptExtractor();
|
|
17
|
+
for (const lang of tsExtractor.languages) {
|
|
18
|
+
this.extractors.set(lang, tsExtractor);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
registerExtractor(extractor) {
|
|
22
|
+
for (const lang of extractor.languages) {
|
|
23
|
+
this.extractors.set(lang, extractor);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
extractFromSource(source, filePath) {
|
|
27
|
+
const language = this.detectLanguage(filePath);
|
|
28
|
+
const extractor = this.extractors.get(language);
|
|
29
|
+
if (!extractor) {
|
|
30
|
+
return {
|
|
31
|
+
filePath,
|
|
32
|
+
language,
|
|
33
|
+
symbols: [],
|
|
34
|
+
imports: [],
|
|
35
|
+
exports: [],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return extractor.extract(source, filePath);
|
|
39
|
+
}
|
|
40
|
+
detectLanguage(filePath) {
|
|
41
|
+
const ext = filePath.slice(filePath.lastIndexOf('.'));
|
|
42
|
+
return EXTENSION_MAP[ext] ?? 'unknown';
|
|
43
|
+
}
|
|
44
|
+
supportsLanguage(language) {
|
|
45
|
+
return this.extractors.has(language);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FileAST } from '../types.js';
|
|
2
|
+
import type { LanguageExtractor } from './symbol-extractor.js';
|
|
3
|
+
/** Regex-based TypeScript/JavaScript symbol extractor (no native deps). */
|
|
4
|
+
export declare class TypeScriptExtractor implements LanguageExtractor {
|
|
5
|
+
languages: string[];
|
|
6
|
+
extract(source: string, filePath: string): FileAST;
|
|
7
|
+
private extractClassMembers;
|
|
8
|
+
private makeSymbol;
|
|
9
|
+
private extractSignature;
|
|
10
|
+
private findBlockEnd;
|
|
11
|
+
private lineOffset;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=typescript-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescript-extractor.d.ts","sourceRoot":"","sources":["../../../src/parser/typescript-extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,OAAO,EAAc,MAAM,aAAa,CAAA;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,2EAA2E;AAC3E,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,SAAS,WAA+B;IAExC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IA4KlD,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,UAAU;CAOnB"}
|