@saluzi/codegraph 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/codegraph.d.ts +25 -0
- package/dist/bin/node-version-check.d.ts +37 -0
- package/dist/bin/uninstall.d.ts +14 -0
- package/dist/context/formatter.d.ts +33 -0
- package/dist/context/formatter.js +244 -0
- package/dist/context/index.d.ts +117 -0
- package/dist/context/index.js +1050 -0
- package/dist/db/index.d.ts +101 -0
- package/dist/db/index.js +250 -0
- package/dist/db/migrations.d.ts +47 -0
- package/dist/db/migrations.js +131 -0
- package/dist/db/queries.d.ts +291 -0
- package/dist/db/queries.js +1349 -0
- package/dist/db/schema.sql +151 -0
- package/dist/db/sqlite-adapter.d.ts +49 -0
- package/dist/db/sqlite-adapter.js +141 -0
- package/dist/directory.d.ts +62 -0
- package/dist/directory.js +264 -0
- package/dist/errors.d.ts +149 -0
- package/dist/errors.js +219 -0
- package/dist/extraction/dfm-extractor.d.ts +31 -0
- package/dist/extraction/dfm-extractor.js +151 -0
- package/dist/extraction/grammars.d.ts +94 -0
- package/dist/extraction/grammars.js +357 -0
- package/dist/extraction/index.d.ts +148 -0
- package/dist/extraction/index.js +1286 -0
- package/dist/extraction/languages/c-cpp.d.ts +4 -0
- package/dist/extraction/languages/c-cpp.js +126 -0
- package/dist/extraction/languages/csharp.d.ts +3 -0
- package/dist/extraction/languages/csharp.js +72 -0
- package/dist/extraction/languages/dart.d.ts +3 -0
- package/dist/extraction/languages/dart.js +192 -0
- package/dist/extraction/languages/go.d.ts +3 -0
- package/dist/extraction/languages/go.js +58 -0
- package/dist/extraction/languages/index.d.ts +10 -0
- package/dist/extraction/languages/index.js +49 -0
- package/dist/extraction/languages/java.d.ts +3 -0
- package/dist/extraction/languages/java.js +64 -0
- package/dist/extraction/languages/javascript.d.ts +3 -0
- package/dist/extraction/languages/javascript.js +90 -0
- package/dist/extraction/languages/kotlin.d.ts +3 -0
- package/dist/extraction/languages/kotlin.js +253 -0
- package/dist/extraction/languages/lua.d.ts +3 -0
- package/dist/extraction/languages/lua.js +150 -0
- package/dist/extraction/languages/luau.d.ts +3 -0
- package/dist/extraction/languages/luau.js +37 -0
- package/dist/extraction/languages/pascal.d.ts +3 -0
- package/dist/extraction/languages/pascal.js +66 -0
- package/dist/extraction/languages/php.d.ts +3 -0
- package/dist/extraction/languages/php.js +107 -0
- package/dist/extraction/languages/python.d.ts +3 -0
- package/dist/extraction/languages/python.js +56 -0
- package/dist/extraction/languages/ruby.d.ts +3 -0
- package/dist/extraction/languages/ruby.js +114 -0
- package/dist/extraction/languages/rust.d.ts +3 -0
- package/dist/extraction/languages/rust.js +109 -0
- package/dist/extraction/languages/scala.d.ts +3 -0
- package/dist/extraction/languages/scala.js +139 -0
- package/dist/extraction/languages/swift.d.ts +3 -0
- package/dist/extraction/languages/swift.js +91 -0
- package/dist/extraction/languages/typescript.d.ts +3 -0
- package/dist/extraction/languages/typescript.js +129 -0
- package/dist/extraction/liquid-extractor.d.ts +52 -0
- package/dist/extraction/liquid-extractor.js +313 -0
- package/dist/extraction/parse-worker.d.ts +8 -0
- package/dist/extraction/parse-worker.js +94 -0
- package/dist/extraction/svelte-extractor.d.ts +56 -0
- package/dist/extraction/svelte-extractor.js +272 -0
- package/dist/extraction/tree-sitter-helpers.d.ts +39 -0
- package/dist/extraction/tree-sitter-helpers.js +103 -0
- package/dist/extraction/tree-sitter-types.d.ts +191 -0
- package/dist/extraction/tree-sitter-types.js +10 -0
- package/dist/extraction/tree-sitter.d.ts +238 -0
- package/dist/extraction/tree-sitter.js +2430 -0
- package/dist/extraction/vue-extractor.d.ts +36 -0
- package/dist/extraction/vue-extractor.js +163 -0
- package/dist/extraction/wasm/tree-sitter-c.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cpp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-dart.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-kotlin.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-luau.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-php.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ruby.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-swift.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +46 -0
- package/dist/extraction/wasm-runtime-flags.js +105 -0
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.js +13 -0
- package/dist/graph/queries.d.ts +109 -0
- package/dist/graph/queries.js +366 -0
- package/dist/graph/traversal.d.ts +137 -0
- package/dist/graph/traversal.js +528 -0
- package/dist/index.d.ts +509 -0
- package/dist/index.js +800 -0
- package/dist/installer/claude-md-template.d.ts +19 -0
- package/dist/installer/config-writer.d.ts +29 -0
- package/dist/installer/index.d.ts +140 -0
- package/dist/installer/instructions-template.d.ts +30 -0
- package/dist/installer/targets/claude.d.ts +55 -0
- package/dist/installer/targets/codex.d.ts +18 -0
- package/dist/installer/targets/cursor.d.ts +35 -0
- package/dist/installer/targets/hermes.d.ts +18 -0
- package/dist/installer/targets/opencode.d.ts +30 -0
- package/dist/installer/targets/registry.d.ts +38 -0
- package/dist/installer/targets/shared.d.ts +92 -0
- package/dist/installer/targets/toml.d.ts +64 -0
- package/dist/installer/targets/types.d.ts +122 -0
- package/dist/mcp/index.d.ts +98 -0
- package/dist/mcp/server-instructions.d.ts +20 -0
- package/dist/mcp/tools.d.ts +269 -0
- package/dist/mcp/transport.d.ts +117 -0
- package/dist/resolution/frameworks/cargo-workspace.d.ts +20 -0
- package/dist/resolution/frameworks/cargo-workspace.js +225 -0
- package/dist/resolution/frameworks/csharp.d.ts +8 -0
- package/dist/resolution/frameworks/csharp.js +213 -0
- package/dist/resolution/frameworks/drupal.d.ts +51 -0
- package/dist/resolution/frameworks/drupal.js +335 -0
- package/dist/resolution/frameworks/express.d.ts +8 -0
- package/dist/resolution/frameworks/express.js +225 -0
- package/dist/resolution/frameworks/go.d.ts +8 -0
- package/dist/resolution/frameworks/go.js +158 -0
- package/dist/resolution/frameworks/index.d.ts +52 -0
- package/dist/resolution/frameworks/index.js +137 -0
- package/dist/resolution/frameworks/java.d.ts +8 -0
- package/dist/resolution/frameworks/java.js +177 -0
- package/dist/resolution/frameworks/laravel.d.ts +13 -0
- package/dist/resolution/frameworks/laravel.js +248 -0
- package/dist/resolution/frameworks/nestjs.d.ts +26 -0
- package/dist/resolution/frameworks/nestjs.js +374 -0
- package/dist/resolution/frameworks/python.d.ts +10 -0
- package/dist/resolution/frameworks/python.js +278 -0
- package/dist/resolution/frameworks/react.d.ts +8 -0
- package/dist/resolution/frameworks/react.js +272 -0
- package/dist/resolution/frameworks/ruby.d.ts +8 -0
- package/dist/resolution/frameworks/ruby.js +198 -0
- package/dist/resolution/frameworks/rust.d.ts +8 -0
- package/dist/resolution/frameworks/rust.js +207 -0
- package/dist/resolution/frameworks/svelte.d.ts +9 -0
- package/dist/resolution/frameworks/svelte.js +249 -0
- package/dist/resolution/frameworks/swift.d.ts +10 -0
- package/dist/resolution/frameworks/swift.js +376 -0
- package/dist/resolution/frameworks/vue.d.ts +9 -0
- package/dist/resolution/frameworks/vue.js +306 -0
- package/dist/resolution/import-resolver.d.ts +61 -0
- package/dist/resolution/import-resolver.js +663 -0
- package/dist/resolution/index.d.ts +118 -0
- package/dist/resolution/index.js +744 -0
- package/dist/resolution/lru-cache.d.ts +24 -0
- package/dist/resolution/lru-cache.js +62 -0
- package/dist/resolution/name-matcher.d.ts +50 -0
- package/dist/resolution/name-matcher.js +384 -0
- package/dist/resolution/path-aliases.d.ts +72 -0
- package/dist/resolution/path-aliases.js +238 -0
- package/dist/resolution/strip-comments.d.ts +40 -0
- package/dist/resolution/strip-comments.js +441 -0
- package/dist/resolution/types.d.ts +181 -0
- package/dist/resolution/types.js +8 -0
- package/dist/search/query-parser.d.ts +61 -0
- package/dist/search/query-parser.js +177 -0
- package/dist/search/query-utils.d.ts +59 -0
- package/dist/search/query-utils.js +383 -0
- package/dist/sync/git-hooks.d.ts +54 -0
- package/dist/sync/git-hooks.js +223 -0
- package/dist/sync/index.d.ts +25 -0
- package/dist/sync/index.js +28 -0
- package/dist/sync/watch-policy.d.ts +51 -0
- package/dist/sync/watch-policy.js +124 -0
- package/dist/sync/watcher.d.ts +83 -0
- package/dist/sync/watcher.js +192 -0
- package/dist/types.d.ts +433 -0
- package/dist/types.js +75 -0
- package/dist/ui/glyphs.d.ts +42 -0
- package/dist/ui/shimmer-progress.d.ts +11 -0
- package/dist/ui/shimmer-worker.d.ts +2 -0
- package/dist/ui/types.d.ts +20 -0
- package/dist/utils.d.ts +231 -0
- package/dist/utils.js +549 -0
- package/package.json +24 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.javascriptExtractor = void 0;
|
|
4
|
+
const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
|
|
5
|
+
exports.javascriptExtractor = {
|
|
6
|
+
functionTypes: ['function_declaration', 'arrow_function', 'function_expression'],
|
|
7
|
+
classTypes: ['class_declaration'],
|
|
8
|
+
methodTypes: ['method_definition', 'field_definition'],
|
|
9
|
+
interfaceTypes: [],
|
|
10
|
+
structTypes: [],
|
|
11
|
+
enumTypes: [],
|
|
12
|
+
typeAliasTypes: [],
|
|
13
|
+
importTypes: ['import_statement'],
|
|
14
|
+
callTypes: ['call_expression'],
|
|
15
|
+
variableTypes: ['lexical_declaration', 'variable_declaration'],
|
|
16
|
+
nameField: 'name',
|
|
17
|
+
bodyField: 'body',
|
|
18
|
+
resolveBody: (node, bodyField) => {
|
|
19
|
+
// field_definition (arrow function class fields) nest the body inside
|
|
20
|
+
// an arrow_function or function_expression child:
|
|
21
|
+
// field_definition → arrow_function → body (statement_block)
|
|
22
|
+
// Also handles wrapper patterns like: field = throttle((e) => { ... })
|
|
23
|
+
// field_definition → call_expression → arguments → arrow_function → body
|
|
24
|
+
if (node.type === 'field_definition') {
|
|
25
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
26
|
+
const child = node.namedChild(i);
|
|
27
|
+
if (!child)
|
|
28
|
+
continue;
|
|
29
|
+
if (child.type === 'arrow_function' || child.type === 'function_expression') {
|
|
30
|
+
return (0, tree_sitter_helpers_1.getChildByField)(child, bodyField);
|
|
31
|
+
}
|
|
32
|
+
if (child.type === 'call_expression') {
|
|
33
|
+
const args = (0, tree_sitter_helpers_1.getChildByField)(child, 'arguments');
|
|
34
|
+
if (args) {
|
|
35
|
+
for (let j = 0; j < args.namedChildCount; j++) {
|
|
36
|
+
const arg = args.namedChild(j);
|
|
37
|
+
if (arg && (arg.type === 'arrow_function' || arg.type === 'function_expression')) {
|
|
38
|
+
return (0, tree_sitter_helpers_1.getChildByField)(arg, bodyField);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
},
|
|
47
|
+
paramsField: 'parameters',
|
|
48
|
+
getSignature: (node, source) => {
|
|
49
|
+
const params = (0, tree_sitter_helpers_1.getChildByField)(node, 'parameters');
|
|
50
|
+
return params ? (0, tree_sitter_helpers_1.getNodeText)(params, source) : undefined;
|
|
51
|
+
},
|
|
52
|
+
isExported: (node, _source) => {
|
|
53
|
+
let current = node.parent;
|
|
54
|
+
while (current) {
|
|
55
|
+
if (current.type === 'export_statement')
|
|
56
|
+
return true;
|
|
57
|
+
current = current.parent;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
},
|
|
61
|
+
isAsync: (node) => {
|
|
62
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
63
|
+
const child = node.child(i);
|
|
64
|
+
if (child?.type === 'async')
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
},
|
|
69
|
+
isConst: (node) => {
|
|
70
|
+
if (node.type === 'lexical_declaration') {
|
|
71
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
72
|
+
const child = node.child(i);
|
|
73
|
+
if (child?.type === 'const')
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return false;
|
|
78
|
+
},
|
|
79
|
+
extractImport: (node, source) => {
|
|
80
|
+
const sourceField = node.childForFieldName('source');
|
|
81
|
+
if (sourceField) {
|
|
82
|
+
const moduleName = source.substring(sourceField.startIndex, sourceField.endIndex).replace(/['"]/g, '');
|
|
83
|
+
if (moduleName) {
|
|
84
|
+
return { moduleName, signature: source.substring(node.startIndex, node.endIndex).trim() };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
//# sourceMappingURL=javascript.js.map
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.kotlinExtractor = void 0;
|
|
4
|
+
const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
|
|
5
|
+
/** Check if a node matches the `fun interface` misparse pattern */
|
|
6
|
+
function isFunInterfaceNode(node) {
|
|
7
|
+
let hasFun = false;
|
|
8
|
+
let hasInterfaceType = false;
|
|
9
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
10
|
+
const child = node.child(i);
|
|
11
|
+
if (!child)
|
|
12
|
+
continue;
|
|
13
|
+
if (child.type === 'fun' && !child.isNamed)
|
|
14
|
+
hasFun = true;
|
|
15
|
+
if (child.type === 'user_type') {
|
|
16
|
+
const typeId = child.namedChildren.find((c) => c.type === 'type_identifier');
|
|
17
|
+
if (typeId && typeId.text === 'interface')
|
|
18
|
+
hasInterfaceType = true;
|
|
19
|
+
}
|
|
20
|
+
// Pattern 2b: user_type("interface") is inside an ERROR child
|
|
21
|
+
if (child.type === 'ERROR') {
|
|
22
|
+
for (let j = 0; j < child.childCount; j++) {
|
|
23
|
+
const gc = child.child(j);
|
|
24
|
+
if (gc && gc.type === 'user_type') {
|
|
25
|
+
const typeId = gc.namedChildren.find((c) => c.type === 'type_identifier');
|
|
26
|
+
if (typeId && typeId.text === 'interface')
|
|
27
|
+
hasInterfaceType = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return hasFun && hasInterfaceType;
|
|
33
|
+
}
|
|
34
|
+
exports.kotlinExtractor = {
|
|
35
|
+
functionTypes: ['function_declaration'],
|
|
36
|
+
classTypes: ['class_declaration'],
|
|
37
|
+
methodTypes: ['function_declaration'], // Methods are functions inside classes
|
|
38
|
+
interfaceTypes: [], // Handled via classifyClassNode
|
|
39
|
+
structTypes: [], // Kotlin uses data classes
|
|
40
|
+
enumTypes: [], // Handled via classifyClassNode
|
|
41
|
+
enumMemberTypes: ['enum_entry'],
|
|
42
|
+
typeAliasTypes: ['type_alias'],
|
|
43
|
+
importTypes: ['import_header'],
|
|
44
|
+
callTypes: ['call_expression'],
|
|
45
|
+
variableTypes: ['property_declaration'],
|
|
46
|
+
fieldTypes: ['property_declaration'],
|
|
47
|
+
extraClassNodeTypes: ['object_declaration'],
|
|
48
|
+
nameField: 'simple_identifier',
|
|
49
|
+
bodyField: 'function_body',
|
|
50
|
+
visitNode: (node, ctx) => {
|
|
51
|
+
// Handle Kotlin `fun interface` declarations.
|
|
52
|
+
// Tree-sitter-kotlin doesn't support `fun interface` syntax (Kotlin 1.4+).
|
|
53
|
+
// It produces two different misparse patterns:
|
|
54
|
+
// Pattern 1 (simple): ERROR node + sibling lambda_literal for body
|
|
55
|
+
// Pattern 2 (complex): function_declaration misparse with ERROR child
|
|
56
|
+
// Skip lambda_literal bodies that were already consumed by a fun interface ERROR node
|
|
57
|
+
if (node.type === 'lambda_literal') {
|
|
58
|
+
const prev = node.previousSibling;
|
|
59
|
+
if (prev && prev.type === 'ERROR' && isFunInterfaceNode(prev))
|
|
60
|
+
return true;
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
if (node.type !== 'ERROR' && node.type !== 'function_declaration')
|
|
64
|
+
return false;
|
|
65
|
+
// Skip ERROR nodes that are class bodies (start with `{`). These contain parent
|
|
66
|
+
// methods + trailing `fun interface` tokens. The methods are extracted via
|
|
67
|
+
// resolveBody; handling the ERROR here would consume the whole body.
|
|
68
|
+
if (node.type === 'ERROR') {
|
|
69
|
+
const firstChild = node.child(0);
|
|
70
|
+
if (firstChild && firstChild.type === '{')
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
if (!isFunInterfaceNode(node))
|
|
74
|
+
return false;
|
|
75
|
+
// Extract the interface name.
|
|
76
|
+
// For function_declaration misparses (patterns 2a/2b), the real name is inside
|
|
77
|
+
// an ERROR child — direct simple_identifier children are the misparsed method name.
|
|
78
|
+
let nameText = null;
|
|
79
|
+
if (node.type === 'function_declaration') {
|
|
80
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
81
|
+
const child = node.child(i);
|
|
82
|
+
if (child && child.type === 'ERROR') {
|
|
83
|
+
for (let j = 0; j < child.childCount; j++) {
|
|
84
|
+
const gc = child.child(j);
|
|
85
|
+
if (gc && gc.type === 'simple_identifier') {
|
|
86
|
+
nameText = gc.text;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (nameText)
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Fallback: direct simple_identifier child (Pattern 1: ERROR node at top level)
|
|
96
|
+
if (!nameText) {
|
|
97
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
98
|
+
const child = node.child(i);
|
|
99
|
+
if (child && child.type === 'simple_identifier') {
|
|
100
|
+
nameText = child.text;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!nameText)
|
|
106
|
+
return false;
|
|
107
|
+
// Create the interface node
|
|
108
|
+
const ifaceNode = ctx.createNode('interface', nameText, node);
|
|
109
|
+
if (!ifaceNode)
|
|
110
|
+
return false;
|
|
111
|
+
ctx.pushScope(ifaceNode.id);
|
|
112
|
+
if (node.type === 'ERROR') {
|
|
113
|
+
// Pattern 1: body is in the next sibling lambda_literal
|
|
114
|
+
const nextSibling = node.nextSibling;
|
|
115
|
+
if (nextSibling && nextSibling.type === 'lambda_literal') {
|
|
116
|
+
for (let i = 0; i < nextSibling.namedChildCount; i++) {
|
|
117
|
+
const child = nextSibling.namedChild(i);
|
|
118
|
+
if (child && child.type === 'statements') {
|
|
119
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
120
|
+
const stmt = child.namedChild(j);
|
|
121
|
+
if (stmt)
|
|
122
|
+
ctx.visitNode(stmt);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Pattern 2 (function_declaration): nested classes are siblings at source_file level,
|
|
129
|
+
// already visited by the normal traversal. The single abstract method is misparsed
|
|
130
|
+
// and cannot be reliably recovered, but the interface node itself is the key value.
|
|
131
|
+
ctx.popScope();
|
|
132
|
+
return true;
|
|
133
|
+
},
|
|
134
|
+
paramsField: 'function_value_parameters',
|
|
135
|
+
returnField: 'type',
|
|
136
|
+
resolveBody: (node, _bodyField) => {
|
|
137
|
+
// Kotlin's tree-sitter grammar doesn't use field names, so getChildByField fails.
|
|
138
|
+
// Find body by type: function_body for functions/methods, class_body for classes,
|
|
139
|
+
// enum_class_body for enums.
|
|
140
|
+
//
|
|
141
|
+
// Special case: when a class/interface contains a nested `fun interface`, tree-sitter
|
|
142
|
+
// misparsed the parent's body as an ERROR node (starting with `{`) and creates
|
|
143
|
+
// a class_body sibling for the nested interface's body. Prefer the ERROR body
|
|
144
|
+
// so the parent's methods are extracted.
|
|
145
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
146
|
+
const child = node.namedChild(i);
|
|
147
|
+
if (child && child.type === 'ERROR') {
|
|
148
|
+
const firstChild = child.child(0);
|
|
149
|
+
if (firstChild && firstChild.type === '{') {
|
|
150
|
+
return child;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (child && (child.type === 'function_body' || child.type === 'class_body' || child.type === 'enum_class_body')) {
|
|
154
|
+
return child;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
},
|
|
159
|
+
classifyClassNode: (node) => {
|
|
160
|
+
// Kotlin reuses class_declaration for classes, interfaces, and enums.
|
|
161
|
+
// Detect by checking for keyword children:
|
|
162
|
+
// interface Foo { } → has 'interface' keyword child
|
|
163
|
+
// enum class Level { } → has 'enum' keyword child
|
|
164
|
+
// class / data class / abstract class → default 'class'
|
|
165
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
166
|
+
const child = node.child(i);
|
|
167
|
+
if (!child)
|
|
168
|
+
continue;
|
|
169
|
+
if (child.type === 'interface')
|
|
170
|
+
return 'interface';
|
|
171
|
+
if (child.type === 'enum')
|
|
172
|
+
return 'enum';
|
|
173
|
+
}
|
|
174
|
+
return 'class';
|
|
175
|
+
},
|
|
176
|
+
getReceiverType: (node, source) => {
|
|
177
|
+
// Kotlin extension functions: fun Type.method() { }
|
|
178
|
+
// AST: function_declaration > user_type, ".", simple_identifier
|
|
179
|
+
// The user_type before the dot is the receiver type.
|
|
180
|
+
let foundUserType = null;
|
|
181
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
182
|
+
const child = node.child(i);
|
|
183
|
+
if (!child)
|
|
184
|
+
continue;
|
|
185
|
+
if (child.type === 'user_type') {
|
|
186
|
+
foundUserType = child;
|
|
187
|
+
}
|
|
188
|
+
else if (child.type === '.' && foundUserType) {
|
|
189
|
+
// The user_type before the dot is the receiver type
|
|
190
|
+
const typeId = foundUserType.namedChildren.find((c) => c.type === 'type_identifier');
|
|
191
|
+
return typeId ? (0, tree_sitter_helpers_1.getNodeText)(typeId, source) : (0, tree_sitter_helpers_1.getNodeText)(foundUserType, source);
|
|
192
|
+
}
|
|
193
|
+
else if (child.type === 'simple_identifier' || child.type === 'function_value_parameters') {
|
|
194
|
+
// Past the function name — no receiver
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return undefined;
|
|
199
|
+
},
|
|
200
|
+
getSignature: (node, source) => {
|
|
201
|
+
// Kotlin function signature: fun name(params): ReturnType
|
|
202
|
+
const params = (0, tree_sitter_helpers_1.getChildByField)(node, 'function_value_parameters');
|
|
203
|
+
const returnType = (0, tree_sitter_helpers_1.getChildByField)(node, 'type');
|
|
204
|
+
if (!params)
|
|
205
|
+
return undefined;
|
|
206
|
+
let sig = (0, tree_sitter_helpers_1.getNodeText)(params, source);
|
|
207
|
+
if (returnType) {
|
|
208
|
+
sig += ': ' + (0, tree_sitter_helpers_1.getNodeText)(returnType, source);
|
|
209
|
+
}
|
|
210
|
+
return sig;
|
|
211
|
+
},
|
|
212
|
+
getVisibility: (node) => {
|
|
213
|
+
// Check for visibility modifiers in Kotlin
|
|
214
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
215
|
+
const child = node.child(i);
|
|
216
|
+
if (child?.type === 'modifiers') {
|
|
217
|
+
const text = child.text;
|
|
218
|
+
if (text.includes('public'))
|
|
219
|
+
return 'public';
|
|
220
|
+
if (text.includes('private'))
|
|
221
|
+
return 'private';
|
|
222
|
+
if (text.includes('protected'))
|
|
223
|
+
return 'protected';
|
|
224
|
+
if (text.includes('internal'))
|
|
225
|
+
return 'internal';
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return 'public'; // Kotlin defaults to public
|
|
229
|
+
},
|
|
230
|
+
isStatic: (_node) => {
|
|
231
|
+
// Kotlin doesn't have static, uses companion objects
|
|
232
|
+
return false;
|
|
233
|
+
},
|
|
234
|
+
isAsync: (node) => {
|
|
235
|
+
// Kotlin uses suspend keyword for coroutines
|
|
236
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
237
|
+
const child = node.child(i);
|
|
238
|
+
if (child?.type === 'modifiers' && child.text.includes('suspend')) {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
},
|
|
244
|
+
extractImport: (node, source) => {
|
|
245
|
+
const importText = source.substring(node.startIndex, node.endIndex).trim();
|
|
246
|
+
const identifier = node.namedChildren.find((c) => c.type === 'identifier');
|
|
247
|
+
if (identifier) {
|
|
248
|
+
return { moduleName: source.substring(identifier.startIndex, identifier.endIndex), signature: importText };
|
|
249
|
+
}
|
|
250
|
+
return null;
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=kotlin.js.map
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.luaExtractor = void 0;
|
|
4
|
+
const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
|
|
5
|
+
// Node names follow the vendored ABI-15 grammar (@tree-sitter-grammars/
|
|
6
|
+
// tree-sitter-lua), NOT the older tree-sitter-wasms build — see grammars.ts.
|
|
7
|
+
/** First descendant of a given type (breadth-first), or null. */
|
|
8
|
+
function findDescendant(node, type) {
|
|
9
|
+
const queue = [...node.namedChildren];
|
|
10
|
+
while (queue.length) {
|
|
11
|
+
const n = queue.shift();
|
|
12
|
+
if (n.type === type)
|
|
13
|
+
return n;
|
|
14
|
+
queue.push(...n.namedChildren);
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* If `callNode` is a `require(...)` call, return the module name; otherwise null.
|
|
20
|
+
* Lua/Luau have no import statement — modules are loaded by calling the global
|
|
21
|
+
* `require`. Handles both:
|
|
22
|
+
* - string requires: `require("net.http")` / `require "net.http"` → "net.http"
|
|
23
|
+
* - Roblox/Luau path requires: `require(script.Parent.Signal)` → "Signal"
|
|
24
|
+
* (the dominant idiom in Roblox code, where the argument is an instance path
|
|
25
|
+
* rather than a string — use the trailing field as the module name).
|
|
26
|
+
*/
|
|
27
|
+
function requireModule(callNode, source) {
|
|
28
|
+
// function_call > name: <callee>, arguments: arguments
|
|
29
|
+
const name = (0, tree_sitter_helpers_1.getChildByField)(callNode, 'name');
|
|
30
|
+
// A dotted/colon callee (e.g. `socket.connect`) is dot/method_index_expression,
|
|
31
|
+
// never a bare `require`.
|
|
32
|
+
if (!name || name.type !== 'identifier')
|
|
33
|
+
return null;
|
|
34
|
+
if ((0, tree_sitter_helpers_1.getNodeText)(name, source) !== 'require')
|
|
35
|
+
return null;
|
|
36
|
+
const args = (0, tree_sitter_helpers_1.getChildByField)(callNode, 'arguments');
|
|
37
|
+
if (!args)
|
|
38
|
+
return null;
|
|
39
|
+
// String require — `string > content: string_content` gives the bare name.
|
|
40
|
+
const content = findDescendant(args, 'string_content');
|
|
41
|
+
if (content)
|
|
42
|
+
return (0, tree_sitter_helpers_1.getNodeText)(content, source).trim() || null;
|
|
43
|
+
const str = findDescendant(args, 'string');
|
|
44
|
+
if (str) {
|
|
45
|
+
const mod = (0, tree_sitter_helpers_1.getNodeText)(str, source)
|
|
46
|
+
.trim()
|
|
47
|
+
.replace(/^\[\[/, '')
|
|
48
|
+
.replace(/\]\]$/, '')
|
|
49
|
+
.replace(/^["']/, '')
|
|
50
|
+
.replace(/["']$/, '');
|
|
51
|
+
if (mod)
|
|
52
|
+
return mod;
|
|
53
|
+
}
|
|
54
|
+
// Roblox/Luau instance-path require: `require(script.Parent.Signal)` → "Signal".
|
|
55
|
+
const idx = findDescendant(args, 'dot_index_expression') ?? findDescendant(args, 'method_index_expression');
|
|
56
|
+
if (idx) {
|
|
57
|
+
const field = (0, tree_sitter_helpers_1.getChildByField)(idx, 'field') ?? (0, tree_sitter_helpers_1.getChildByField)(idx, 'method');
|
|
58
|
+
if (field)
|
|
59
|
+
return (0, tree_sitter_helpers_1.getNodeText)(field, source).trim() || null;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
exports.luaExtractor = {
|
|
64
|
+
// function_declaration covers global (`function f`), table (`function t.f`),
|
|
65
|
+
// method (`function t:m`), and local (`local function f`) forms — the form is
|
|
66
|
+
// distinguished by the `name:` child (identifier / dot_index_expression /
|
|
67
|
+
// method_index_expression) and a `local` token, not by separate node types.
|
|
68
|
+
// Anonymous `function() ... end` (function_definition) has no name and is
|
|
69
|
+
// captured via its enclosing variable instead.
|
|
70
|
+
functionTypes: ['function_declaration'],
|
|
71
|
+
classTypes: [], // Lua has no classes/structs/interfaces/enums — tables are used for everything
|
|
72
|
+
methodTypes: [],
|
|
73
|
+
interfaceTypes: [],
|
|
74
|
+
structTypes: [],
|
|
75
|
+
enumTypes: [],
|
|
76
|
+
typeAliasTypes: [],
|
|
77
|
+
importTypes: [], // `require` is a function_call — handled in visitNode below
|
|
78
|
+
callTypes: ['function_call'],
|
|
79
|
+
variableTypes: ['variable_declaration'], // see the `lua` branch in extractVariable
|
|
80
|
+
nameField: 'name',
|
|
81
|
+
bodyField: 'body',
|
|
82
|
+
paramsField: 'parameters',
|
|
83
|
+
getSignature: (node, source) => {
|
|
84
|
+
const params = (0, tree_sitter_helpers_1.getChildByField)(node, 'parameters');
|
|
85
|
+
return params ? (0, tree_sitter_helpers_1.getNodeText)(params, source) : undefined;
|
|
86
|
+
},
|
|
87
|
+
// `function t.f()` / `function t:m()` are methods on table `t`: return the
|
|
88
|
+
// table as the receiver so they extract as methods with a `t::f` qualified
|
|
89
|
+
// name. Plain `function f()` / `local function f()` have no receiver and stay
|
|
90
|
+
// functions. (For `a.b.c`, the receiver is the nested `a.b`.)
|
|
91
|
+
getReceiverType: (node, source) => {
|
|
92
|
+
const name = (0, tree_sitter_helpers_1.getChildByField)(node, 'name');
|
|
93
|
+
if (name && (name.type === 'dot_index_expression' || name.type === 'method_index_expression')) {
|
|
94
|
+
const table = (0, tree_sitter_helpers_1.getChildByField)(name, 'table');
|
|
95
|
+
if (table)
|
|
96
|
+
return (0, tree_sitter_helpers_1.getNodeText)(table, source);
|
|
97
|
+
}
|
|
98
|
+
return undefined;
|
|
99
|
+
},
|
|
100
|
+
// Emit import nodes for `require(...)`. The local-declaration form is handled
|
|
101
|
+
// explicitly because the variable branch skips the initializer subtree; bare
|
|
102
|
+
// and global `require` calls are caught when the walker reaches the
|
|
103
|
+
// function_call node.
|
|
104
|
+
visitNode: (node, ctx) => {
|
|
105
|
+
const source = ctx.source;
|
|
106
|
+
const emit = (callNode) => {
|
|
107
|
+
const mod = requireModule(callNode, source);
|
|
108
|
+
if (!mod)
|
|
109
|
+
return;
|
|
110
|
+
const imp = ctx.createNode('import', mod, callNode, {
|
|
111
|
+
signature: (0, tree_sitter_helpers_1.getNodeText)(callNode, source).trim().slice(0, 100),
|
|
112
|
+
});
|
|
113
|
+
if (imp && ctx.nodeStack.length > 0) {
|
|
114
|
+
const parentId = ctx.nodeStack[ctx.nodeStack.length - 1];
|
|
115
|
+
if (parentId) {
|
|
116
|
+
ctx.addUnresolvedReference({
|
|
117
|
+
fromNodeId: parentId,
|
|
118
|
+
referenceName: mod,
|
|
119
|
+
referenceKind: 'imports',
|
|
120
|
+
line: callNode.startPosition.row + 1,
|
|
121
|
+
column: callNode.startPosition.column,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
// Bare / global `require("x")` — claim it so it isn't double-counted as a call.
|
|
127
|
+
if (node.type === 'function_call') {
|
|
128
|
+
if (requireModule(node, source)) {
|
|
129
|
+
emit(node);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
// `local x = require("x")` — variable_declaration wraps an assignment_statement
|
|
135
|
+
// whose initializer subtree the variable branch will skip, so dig it out here.
|
|
136
|
+
if (node.type === 'variable_declaration') {
|
|
137
|
+
const assign = node.namedChildren.find((c) => c.type === 'assignment_statement');
|
|
138
|
+
const exprList = assign?.namedChildren.find((c) => c.type === 'expression_list');
|
|
139
|
+
if (exprList) {
|
|
140
|
+
for (const val of exprList.namedChildren) {
|
|
141
|
+
if (val.type === 'function_call')
|
|
142
|
+
emit(val);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
//# sourceMappingURL=lua.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.luauExtractor = void 0;
|
|
4
|
+
const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
|
|
5
|
+
const lua_1 = require("./lua");
|
|
6
|
+
// Luau (https://luau.org) is a gradually-typed superset of Lua. The
|
|
7
|
+
// tree-sitter-luau grammar reuses the same node names as the vendored Lua
|
|
8
|
+
// grammar (function_declaration, variable_declaration, function_call,
|
|
9
|
+
// dot/method_index_expression, …), so the Luau extractor extends the Lua one
|
|
10
|
+
// and adds the type-system pieces Luau introduces:
|
|
11
|
+
// - `type X = ...` / `export type X = ...` → type_definition (type_alias)
|
|
12
|
+
// - typed parameters and return types → richer signatures
|
|
13
|
+
//
|
|
14
|
+
// require detection, receiver-splitting (t.f / t:m → methods), and local
|
|
15
|
+
// variable extraction are inherited unchanged from luaExtractor. The shared
|
|
16
|
+
// `extractVariable` core branch is gated on `lua` || `luau`.
|
|
17
|
+
exports.luauExtractor = {
|
|
18
|
+
...lua_1.luaExtractor,
|
|
19
|
+
// `type X = ...` and `export type X = ...`
|
|
20
|
+
typeAliasTypes: ['type_definition'],
|
|
21
|
+
// Only Luau `export type` is exported; the keyword leads the node.
|
|
22
|
+
isExported: (node, source) => source.slice(node.startIndex, node.startIndex + 7) === 'export ',
|
|
23
|
+
// Params + Luau return type (the named child after `parameters`, before the body).
|
|
24
|
+
getSignature: (node, source) => {
|
|
25
|
+
const params = (0, tree_sitter_helpers_1.getChildByField)(node, 'parameters');
|
|
26
|
+
if (!params)
|
|
27
|
+
return undefined;
|
|
28
|
+
let sig = (0, tree_sitter_helpers_1.getNodeText)(params, source);
|
|
29
|
+
const kids = node.namedChildren;
|
|
30
|
+
const idx = kids.findIndex((c) => c.startIndex === params.startIndex);
|
|
31
|
+
const ret = idx >= 0 ? kids[idx + 1] : null;
|
|
32
|
+
if (ret && ret.type !== 'block')
|
|
33
|
+
sig += `: ${(0, tree_sitter_helpers_1.getNodeText)(ret, source)}`;
|
|
34
|
+
return sig;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=luau.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pascalExtractor = void 0;
|
|
4
|
+
const tree_sitter_helpers_1 = require("../tree-sitter-helpers");
|
|
5
|
+
exports.pascalExtractor = {
|
|
6
|
+
functionTypes: ['declProc'],
|
|
7
|
+
classTypes: ['declClass'],
|
|
8
|
+
methodTypes: ['declProc'],
|
|
9
|
+
interfaceTypes: ['declIntf'],
|
|
10
|
+
structTypes: [],
|
|
11
|
+
enumTypes: ['declEnum'],
|
|
12
|
+
typeAliasTypes: ['declType'],
|
|
13
|
+
importTypes: ['declUses'],
|
|
14
|
+
callTypes: ['exprCall'],
|
|
15
|
+
variableTypes: ['declField', 'declConst'],
|
|
16
|
+
nameField: 'name',
|
|
17
|
+
bodyField: 'body',
|
|
18
|
+
paramsField: 'args',
|
|
19
|
+
returnField: 'type',
|
|
20
|
+
getSignature: (node, source) => {
|
|
21
|
+
const args = (0, tree_sitter_helpers_1.getChildByField)(node, 'args');
|
|
22
|
+
const returnType = node.namedChildren.find((c) => c.type === 'typeref');
|
|
23
|
+
if (!args && !returnType)
|
|
24
|
+
return undefined;
|
|
25
|
+
let sig = '';
|
|
26
|
+
if (args)
|
|
27
|
+
sig = (0, tree_sitter_helpers_1.getNodeText)(args, source);
|
|
28
|
+
if (returnType) {
|
|
29
|
+
sig += ': ' + (0, tree_sitter_helpers_1.getNodeText)(returnType, source);
|
|
30
|
+
}
|
|
31
|
+
return sig || undefined;
|
|
32
|
+
},
|
|
33
|
+
getVisibility: (node) => {
|
|
34
|
+
let current = node.parent;
|
|
35
|
+
while (current) {
|
|
36
|
+
if (current.type === 'declSection') {
|
|
37
|
+
for (let i = 0; i < current.childCount; i++) {
|
|
38
|
+
const child = current.child(i);
|
|
39
|
+
if (child?.type === 'kPublic' || child?.type === 'kPublished')
|
|
40
|
+
return 'public';
|
|
41
|
+
if (child?.type === 'kPrivate')
|
|
42
|
+
return 'private';
|
|
43
|
+
if (child?.type === 'kProtected')
|
|
44
|
+
return 'protected';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
current = current.parent;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
},
|
|
51
|
+
isExported: (_node, _source) => {
|
|
52
|
+
// In Pascal, symbols declared in the interface section are exported
|
|
53
|
+
return false;
|
|
54
|
+
},
|
|
55
|
+
isStatic: (node) => {
|
|
56
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
57
|
+
if (node.child(i)?.type === 'kClass')
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
},
|
|
62
|
+
isConst: (node) => {
|
|
63
|
+
return node.type === 'declConst';
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=pascal.js.map
|