@getmikk/core 1.7.1 → 1.8.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/README.md +82 -412
- package/package.json +3 -1
- package/src/contract/contract-reader.ts +2 -2
- package/src/contract/lock-compiler.ts +15 -14
- package/src/contract/lock-reader.ts +14 -14
- package/src/contract/schema.ts +3 -3
- package/src/index.ts +1 -0
- package/src/parser/base-parser.ts +1 -1
- package/src/parser/boundary-checker.ts +74 -212
- package/src/parser/go/go-extractor.ts +10 -10
- package/src/parser/go/go-parser.ts +2 -2
- package/src/parser/index.ts +45 -31
- package/src/parser/javascript/js-extractor.ts +9 -9
- package/src/parser/javascript/js-parser.ts +2 -2
- package/src/parser/tree-sitter/parser.ts +228 -0
- package/src/parser/tree-sitter/queries.ts +181 -0
- package/src/parser/types.ts +1 -1
- package/src/parser/typescript/ts-extractor.ts +15 -15
- package/src/parser/typescript/ts-parser.ts +1 -1
- package/src/parser/typescript/ts-resolver.ts +2 -2
- package/src/search/bm25.ts +206 -0
- package/src/search/index.ts +3 -0
- package/src/utils/fs.ts +31 -31
- package/src/utils/minimatch.ts +23 -14
- package/test-output.txt +0 -0
- package/tests/go-parser.test.ts +10 -10
- package/tests/js-parser.test.ts +34 -19
- package/tests/parser.test.ts +5 -5
- package/tests/tree-sitter-parser.test.ts +168 -0
- package/tests/ts-parser.test.ts +49 -1
- package/out.log +0 -0
package/src/parser/index.ts
CHANGED
|
@@ -18,6 +18,8 @@ export { JavaScriptParser } from './javascript/js-parser.js'
|
|
|
18
18
|
export { JavaScriptExtractor } from './javascript/js-extractor.js'
|
|
19
19
|
export { JavaScriptResolver } from './javascript/js-resolver.js'
|
|
20
20
|
export { BoundaryChecker } from './boundary-checker.js'
|
|
21
|
+
export { TreeSitterParser } from './tree-sitter/parser.js'
|
|
22
|
+
import { TreeSitterParser } from './tree-sitter/parser.js'
|
|
21
23
|
|
|
22
24
|
/** Get the appropriate parser for a file based on its extension */
|
|
23
25
|
export function getParser(filePath: string): BaseParser {
|
|
@@ -32,7 +34,19 @@ export function getParser(filePath: string): BaseParser {
|
|
|
32
34
|
case '.jsx':
|
|
33
35
|
return new JavaScriptParser()
|
|
34
36
|
case '.go':
|
|
35
|
-
return new GoParser()
|
|
37
|
+
return new GoParser() // Mikk's custom Regex Go parser
|
|
38
|
+
case '.py':
|
|
39
|
+
case '.java':
|
|
40
|
+
case '.c':
|
|
41
|
+
case '.h':
|
|
42
|
+
case '.cpp':
|
|
43
|
+
case '.cc':
|
|
44
|
+
case '.hpp':
|
|
45
|
+
case '.cs':
|
|
46
|
+
case '.rs':
|
|
47
|
+
case '.php':
|
|
48
|
+
case '.rb':
|
|
49
|
+
return new TreeSitterParser()
|
|
36
50
|
default:
|
|
37
51
|
throw new UnsupportedLanguageError(ext)
|
|
38
52
|
}
|
|
@@ -44,43 +58,43 @@ export async function parseFiles(
|
|
|
44
58
|
projectRoot: string,
|
|
45
59
|
readFile: (fp: string) => Promise<string>
|
|
46
60
|
): Promise<ParsedFile[]> {
|
|
61
|
+
const parsersMap = new Map<BaseParser, ParsedFile[]>()
|
|
62
|
+
// Re-use parser instances so they can share cache/bindings
|
|
47
63
|
const tsParser = new TypeScriptParser()
|
|
48
64
|
const jsParser = new JavaScriptParser()
|
|
49
65
|
const goParser = new GoParser()
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const
|
|
66
|
+
const treeSitterParser = new TreeSitterParser()
|
|
67
|
+
|
|
68
|
+
const getCachedParser = (ext: string): BaseParser | null => {
|
|
69
|
+
switch (ext) {
|
|
70
|
+
case '.ts': case '.tsx': return tsParser
|
|
71
|
+
case '.js': case '.mjs': case '.cjs': case '.jsx': return jsParser
|
|
72
|
+
case '.go': return goParser
|
|
73
|
+
case '.py': case '.java': case '.c': case '.h': case '.cpp': case '.cc': case '.hpp': case '.cs': case '.rs': case '.php': case '.rb': return treeSitterParser
|
|
74
|
+
default: return null
|
|
75
|
+
}
|
|
76
|
+
}
|
|
53
77
|
|
|
54
78
|
for (const fp of filePaths) {
|
|
55
|
-
const ext = path.extname(fp)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
} catch {
|
|
68
|
-
// Skip unreadable files
|
|
69
|
-
}
|
|
70
|
-
} else if (ext === '.go') {
|
|
71
|
-
try {
|
|
72
|
-
const content = await readFile(path.join(projectRoot, fp))
|
|
73
|
-
goFiles.push(goParser.parse(fp, content))
|
|
74
|
-
} catch {
|
|
75
|
-
// Skip unreadable files
|
|
76
|
-
}
|
|
79
|
+
const ext = path.extname(fp).toLowerCase()
|
|
80
|
+
const parser = getCachedParser(ext)
|
|
81
|
+
if (!parser) continue
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const content = await readFile(path.join(projectRoot, fp))
|
|
85
|
+
const parsed = await parser.parse(fp, content)
|
|
86
|
+
|
|
87
|
+
if (!parsersMap.has(parser)) parsersMap.set(parser, [])
|
|
88
|
+
parsersMap.get(parser)!.push(parsed)
|
|
89
|
+
} catch {
|
|
90
|
+
// Skip unreadable files (permissions, binary, etc.) — don't abort the whole parse
|
|
77
91
|
}
|
|
78
92
|
}
|
|
79
93
|
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
const allResolvedFiles: ParsedFile[] = []
|
|
95
|
+
for (const [parser, files] of parsersMap.entries()) {
|
|
96
|
+
allResolvedFiles.push(...parser.resolveImports(files, projectRoot))
|
|
97
|
+
}
|
|
84
98
|
|
|
85
|
-
return
|
|
99
|
+
return allResolvedFiles
|
|
86
100
|
}
|
|
@@ -4,7 +4,7 @@ import { hashContent } from '../../hash/file-hasher.js'
|
|
|
4
4
|
import type { ParsedFunction, ParsedImport, ParsedExport } from '../types.js'
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* JavaScriptExtractor
|
|
7
|
+
* JavaScriptExtractor -- extends TypeScriptExtractor to add CommonJS support on top of
|
|
8
8
|
* the TypeScript Compiler API's native JS/JSX parsing.
|
|
9
9
|
*
|
|
10
10
|
* Extra patterns handled:
|
|
@@ -17,7 +17,7 @@ import type { ParsedFunction, ParsedImport, ParsedExport } from '../types.js'
|
|
|
17
17
|
*/
|
|
18
18
|
export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
19
19
|
|
|
20
|
-
//
|
|
20
|
+
// --- Public overrides ------------------------------------------------------
|
|
21
21
|
|
|
22
22
|
/** ESM functions + module.exports-assigned functions */
|
|
23
23
|
override extractFunctions(): ParsedFunction[] {
|
|
@@ -49,7 +49,7 @@ export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
|
49
49
|
return esm
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
//
|
|
52
|
+
// --- CommonJS: require() ---------------------------------------------------
|
|
53
53
|
|
|
54
54
|
private extractRequireImports(): ParsedImport[] {
|
|
55
55
|
const imports: ParsedImport[] = []
|
|
@@ -102,7 +102,7 @@ export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
|
102
102
|
return []
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
//
|
|
105
|
+
// --- CommonJS: module.exports / exports.x exports -------------------------
|
|
106
106
|
|
|
107
107
|
private extractCommonJsExports(): ParsedExport[] {
|
|
108
108
|
const result: ParsedExport[] = []
|
|
@@ -117,7 +117,7 @@ export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
|
117
117
|
const lhs = node.expression.left
|
|
118
118
|
const rhs = node.expression.right
|
|
119
119
|
|
|
120
|
-
//
|
|
120
|
+
// --- module.exports = ... ------------------------------------
|
|
121
121
|
if (isModuleExports(lhs)) {
|
|
122
122
|
if (ts.isObjectLiteralExpression(rhs)) {
|
|
123
123
|
// module.exports = { foo, bar }
|
|
@@ -142,14 +142,14 @@ export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
//
|
|
145
|
+
// --- exports.foo = ... ---------------------------------------
|
|
146
146
|
if (isExportsDotProp(lhs)) {
|
|
147
147
|
const prop = lhs as ts.PropertyAccessExpression
|
|
148
148
|
const isFunc = ts.isFunctionExpression(rhs) || ts.isArrowFunction(rhs)
|
|
149
149
|
result.push({ name: prop.name.text, type: isFunc ? 'function' : 'const', file: fp })
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
//
|
|
152
|
+
// --- module.exports.foo = ... --------------------------------
|
|
153
153
|
if (isModuleExportsDotProp(lhs)) {
|
|
154
154
|
const prop = lhs as ts.PropertyAccessExpression
|
|
155
155
|
const isFunc = ts.isFunctionExpression(rhs) || ts.isArrowFunction(rhs)
|
|
@@ -163,7 +163,7 @@ export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
|
163
163
|
return result
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
//
|
|
166
|
+
// --- CommonJS: module.exports / exports.x function bodies -----------------
|
|
167
167
|
|
|
168
168
|
/**
|
|
169
169
|
* Detect functions directly assigned via module.exports or exports.x:
|
|
@@ -232,7 +232,7 @@ export class JavaScriptExtractor extends TypeScriptExtractor {
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
//
|
|
235
|
+
// --- Helpers -----------------------------------------------------------------
|
|
236
236
|
|
|
237
237
|
/** node is `module.exports` */
|
|
238
238
|
function isModuleExports(node: ts.Node): boolean {
|
|
@@ -7,14 +7,14 @@ import { hashContent } from '../../hash/file-hasher.js'
|
|
|
7
7
|
import type { ParsedFile } from '../types.js'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* JavaScriptParser
|
|
10
|
+
* JavaScriptParser -- implements BaseParser for .js / .mjs / .cjs / .jsx files.
|
|
11
11
|
*
|
|
12
12
|
* Uses the TypeScript Compiler API (ScriptKind.JS / ScriptKind.JSX) which correctly
|
|
13
13
|
* parses JavaScript without type annotations. JavaScriptExtractor extends
|
|
14
14
|
* TypeScriptExtractor and adds CommonJS require() / module.exports support.
|
|
15
15
|
*/
|
|
16
16
|
export class JavaScriptParser extends BaseParser {
|
|
17
|
-
parse(filePath: string, content: string): ParsedFile {
|
|
17
|
+
async parse(filePath: string, content: string): Promise<ParsedFile> {
|
|
18
18
|
const extractor = new JavaScriptExtractor(filePath, content)
|
|
19
19
|
|
|
20
20
|
const functions = extractor.extractFunctions()
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import * as path from 'node:path'
|
|
2
|
+
import { createRequire } from 'node:module'
|
|
3
|
+
import { hashContent } from '../../hash/file-hasher.js'
|
|
4
|
+
import { BaseParser } from '../base-parser.js'
|
|
5
|
+
import type { ParsedFile, ParsedFunction, ParsedClass, ParsedParam, ParsedImport, ParsedExport, ParsedRoute } from '../types.js'
|
|
6
|
+
import * as Queries from './queries.js'
|
|
7
|
+
|
|
8
|
+
// Safely require web-tree-sitter via CJS
|
|
9
|
+
const getRequire = () => {
|
|
10
|
+
if (typeof require !== 'undefined') return require;
|
|
11
|
+
return createRequire(import.meta.url);
|
|
12
|
+
};
|
|
13
|
+
const _require = getRequire();
|
|
14
|
+
const ParserModule = _require('web-tree-sitter')
|
|
15
|
+
const Parser = ParserModule.Parser || ParserModule
|
|
16
|
+
|
|
17
|
+
export class TreeSitterParser extends BaseParser {
|
|
18
|
+
private parser: any = null
|
|
19
|
+
private languages = new Map<string, any>()
|
|
20
|
+
|
|
21
|
+
getSupportedExtensions(): string[] {
|
|
22
|
+
return ['.py', '.java', '.c', '.cpp', '.cc', '.h', '.hpp', '.cs', '.go', '.rs', '.php', '.rb']
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private async init() {
|
|
26
|
+
if (!this.parser) {
|
|
27
|
+
await Parser.init()
|
|
28
|
+
this.parser = new Parser()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async parse(filePath: string, content: string): Promise<ParsedFile> {
|
|
33
|
+
await this.init()
|
|
34
|
+
const ext = path.extname(filePath).toLowerCase()
|
|
35
|
+
const config = await this.getLanguageConfig(ext)
|
|
36
|
+
|
|
37
|
+
if (!config || !config.lang) {
|
|
38
|
+
// Fallback to empty if language not supported or grammar failed to load
|
|
39
|
+
return this.buildEmptyFile(filePath, content, ext)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
this.parser!.setLanguage(config.lang)
|
|
43
|
+
const tree = this.parser!.parse(content)
|
|
44
|
+
const query = config.lang.query(config.query)
|
|
45
|
+
const matches = query.matches(tree.rootNode)
|
|
46
|
+
|
|
47
|
+
const functions: ParsedFunction[] = []
|
|
48
|
+
const classesMap = new Map<string, ParsedClass>()
|
|
49
|
+
const imports: ParsedImport[] = []
|
|
50
|
+
const calls = new Set<string>()
|
|
51
|
+
|
|
52
|
+
for (const match of matches) {
|
|
53
|
+
const captures: Record<string, any> = {}
|
|
54
|
+
for (const c of match.captures) {
|
|
55
|
+
captures[c.name] = c.node
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Calls
|
|
59
|
+
if (captures['call.name']) {
|
|
60
|
+
calls.add(captures['call.name'].text)
|
|
61
|
+
continue
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Imports
|
|
65
|
+
if (captures['import.source']) {
|
|
66
|
+
const src = captures['import.source'].text.replace(/['"]/g, '')
|
|
67
|
+
imports.push({
|
|
68
|
+
source: src,
|
|
69
|
+
resolvedPath: '',
|
|
70
|
+
names: [],
|
|
71
|
+
isDefault: false,
|
|
72
|
+
isDynamic: false
|
|
73
|
+
})
|
|
74
|
+
continue
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Functions / Methods
|
|
78
|
+
if (captures['definition.function'] || captures['definition.method']) {
|
|
79
|
+
const nameNode = captures['name']
|
|
80
|
+
const defNode = captures['definition.function'] || captures['definition.method']
|
|
81
|
+
|
|
82
|
+
if (nameNode && defNode) {
|
|
83
|
+
const fnName = nameNode.text
|
|
84
|
+
functions.push({
|
|
85
|
+
id: `fn:${filePath}:${fnName}`,
|
|
86
|
+
name: fnName,
|
|
87
|
+
file: filePath,
|
|
88
|
+
startLine: defNode.startPosition.row + 1,
|
|
89
|
+
endLine: defNode.endPosition.row + 1,
|
|
90
|
+
params: [],
|
|
91
|
+
returnType: 'any',
|
|
92
|
+
isExported: true, // simplified for universal parser
|
|
93
|
+
isAsync: false,
|
|
94
|
+
calls: [], // We aggregate at file level currently
|
|
95
|
+
hash: hashContent(defNode.text),
|
|
96
|
+
purpose: '',
|
|
97
|
+
edgeCasesHandled: [],
|
|
98
|
+
errorHandling: [],
|
|
99
|
+
detailedLines: [],
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Classes / Structs / Interfaces
|
|
105
|
+
if (captures['definition.class'] || captures['definition.struct'] || captures['definition.interface']) {
|
|
106
|
+
const nameNode = captures['name']
|
|
107
|
+
const defNode = captures['definition.class'] || captures['definition.struct'] || captures['definition.interface']
|
|
108
|
+
|
|
109
|
+
if (nameNode && defNode) {
|
|
110
|
+
const clsName = nameNode.text
|
|
111
|
+
if (!classesMap.has(clsName)) {
|
|
112
|
+
classesMap.set(clsName, {
|
|
113
|
+
id: `cls:${filePath}:${clsName}`,
|
|
114
|
+
name: clsName,
|
|
115
|
+
file: filePath,
|
|
116
|
+
startLine: defNode.startPosition.row + 1,
|
|
117
|
+
endLine: defNode.endPosition.row + 1,
|
|
118
|
+
methods: [],
|
|
119
|
+
isExported: true,
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Attach global calls to the first function as a heuristic, or store in a dummy
|
|
127
|
+
if (functions.length > 0) {
|
|
128
|
+
functions[0].calls = Array.from(calls)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let finalLang: ParsedFile['language'] = 'go'
|
|
132
|
+
switch (ext) {
|
|
133
|
+
case '.py': finalLang = 'python'; break
|
|
134
|
+
case '.java': finalLang = 'java'; break
|
|
135
|
+
case '.c': case '.h': finalLang = 'c'; break
|
|
136
|
+
case '.cpp': case '.cc': case '.hpp': finalLang = 'cpp'; break
|
|
137
|
+
case '.cs': finalLang = 'csharp'; break
|
|
138
|
+
case '.go': finalLang = 'go'; break
|
|
139
|
+
case '.rs': finalLang = 'rust'; break
|
|
140
|
+
case '.php': finalLang = 'php'; break
|
|
141
|
+
case '.rb': finalLang = 'ruby'; break
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
path: filePath,
|
|
146
|
+
language: finalLang,
|
|
147
|
+
functions,
|
|
148
|
+
classes: Array.from(classesMap.values()),
|
|
149
|
+
generics: [],
|
|
150
|
+
imports,
|
|
151
|
+
exports: functions.map(f => ({ name: f.name, type: 'function', file: filePath })),
|
|
152
|
+
routes: [],
|
|
153
|
+
hash: hashContent(content),
|
|
154
|
+
parsedAt: Date.now()
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
resolveImports(files: ParsedFile[], projectRoot: string): ParsedFile[] {
|
|
159
|
+
// Universal resolver: just link absolute paths if they exist locally
|
|
160
|
+
// Basic heuristic for all 11 languages
|
|
161
|
+
return files
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private buildEmptyFile(filePath: string, content: string, ext: string): ParsedFile {
|
|
165
|
+
let finalLang: ParsedFile['language'] = 'unknown'
|
|
166
|
+
switch (ext) {
|
|
167
|
+
case '.py': finalLang = 'python'; break
|
|
168
|
+
case '.java': finalLang = 'java'; break
|
|
169
|
+
case '.c': case '.h': finalLang = 'c'; break
|
|
170
|
+
case '.cpp': case '.cc': case '.hpp': finalLang = 'cpp'; break
|
|
171
|
+
case '.cs': finalLang = 'csharp'; break
|
|
172
|
+
case '.go': finalLang = 'go'; break
|
|
173
|
+
case '.rs': finalLang = 'rust'; break
|
|
174
|
+
case '.php': finalLang = 'php'; break
|
|
175
|
+
case '.rb': finalLang = 'ruby'; break
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
path: filePath,
|
|
179
|
+
language: finalLang,
|
|
180
|
+
functions: [], classes: [], generics: [], imports: [], exports: [], routes: [],
|
|
181
|
+
hash: hashContent(content),
|
|
182
|
+
parsedAt: Date.now()
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
private async loadLang(name: string): Promise<any> {
|
|
187
|
+
if (this.languages.has(name)) return this.languages.get(name)
|
|
188
|
+
try {
|
|
189
|
+
// Get module root path to locate wasms
|
|
190
|
+
const tcPath = _require.resolve('tree-sitter-wasms/package.json')
|
|
191
|
+
const wasmPath = path.join(path.dirname(tcPath), 'out', `tree-sitter-${name}.wasm`)
|
|
192
|
+
const lang = await Parser.Language.load(wasmPath)
|
|
193
|
+
this.languages.set(name, lang)
|
|
194
|
+
return lang
|
|
195
|
+
} catch (err) {
|
|
196
|
+
console.warn(`Failed to load Tree-sitter WASM for ${name}:`, err)
|
|
197
|
+
return null
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
private async getLanguageConfig(ext: string) {
|
|
202
|
+
switch (ext) {
|
|
203
|
+
case '.py':
|
|
204
|
+
return { lang: await this.loadLang('python'), query: Queries.PYTHON_QUERIES }
|
|
205
|
+
case '.java':
|
|
206
|
+
return { lang: await this.loadLang('java'), query: Queries.JAVA_QUERIES }
|
|
207
|
+
case '.c':
|
|
208
|
+
case '.h':
|
|
209
|
+
return { lang: await this.loadLang('c'), query: Queries.C_QUERIES }
|
|
210
|
+
case '.cpp':
|
|
211
|
+
case '.cc':
|
|
212
|
+
case '.hpp':
|
|
213
|
+
return { lang: await this.loadLang('cpp'), query: Queries.CPP_QUERIES }
|
|
214
|
+
case '.cs':
|
|
215
|
+
return { lang: await this.loadLang('c-sharp'), query: Queries.CSHARP_QUERIES }
|
|
216
|
+
case '.go':
|
|
217
|
+
return { lang: await this.loadLang('go'), query: Queries.GO_QUERIES }
|
|
218
|
+
case '.rs':
|
|
219
|
+
return { lang: await this.loadLang('rust'), query: Queries.RUST_QUERIES }
|
|
220
|
+
case '.php':
|
|
221
|
+
return { lang: await this.loadLang('php'), query: Queries.PHP_QUERIES }
|
|
222
|
+
case '.rb':
|
|
223
|
+
return { lang: await this.loadLang('ruby'), query: Queries.RUBY_QUERIES }
|
|
224
|
+
default:
|
|
225
|
+
return null
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree-sitter queries for extracting code definitions across 13 languages.
|
|
3
|
+
* Ported from GitNexus.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: Some grammars (like Python and Ruby) use slightly different AST node
|
|
6
|
+
* types for equivalent structures. These queries are written against
|
|
7
|
+
* the standard tree-sitter grammars.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const TYPESCRIPT_QUERIES = `
|
|
11
|
+
(class_declaration name: (type_identifier) @name) @definition.class
|
|
12
|
+
(interface_declaration name: (type_identifier) @name) @definition.interface
|
|
13
|
+
(function_declaration name: (identifier) @name) @definition.function
|
|
14
|
+
(method_definition name: (property_identifier) @name) @definition.method
|
|
15
|
+
(lexical_declaration (variable_declarator name: (identifier) @name value: (arrow_function))) @definition.function
|
|
16
|
+
(lexical_declaration (variable_declarator name: (identifier) @name value: (function_expression))) @definition.function
|
|
17
|
+
(export_statement declaration: (lexical_declaration (variable_declarator name: (identifier) @name value: (arrow_function)))) @definition.function
|
|
18
|
+
(export_statement declaration: (lexical_declaration (variable_declarator name: (identifier) @name value: (function_expression)))) @definition.function
|
|
19
|
+
(import_statement source: (string) @import.source) @import
|
|
20
|
+
(export_statement source: (string) @import.source) @import
|
|
21
|
+
(call_expression function: (identifier) @call.name) @call
|
|
22
|
+
(call_expression function: (member_expression property: (property_identifier) @call.name)) @call
|
|
23
|
+
(new_expression constructor: (identifier) @call.name) @call
|
|
24
|
+
(public_field_definition name: (property_identifier) @name) @definition.property
|
|
25
|
+
(public_field_definition name: (private_property_identifier) @name) @definition.property
|
|
26
|
+
(required_parameter (accessibility_modifier) pattern: (identifier) @name) @definition.property
|
|
27
|
+
(class_declaration name: (type_identifier) @heritage.class (class_heritage (extends_clause value: (identifier) @heritage.extends))) @heritage
|
|
28
|
+
(class_declaration name: (type_identifier) @heritage.class (class_heritage (implements_clause (type_identifier) @heritage.implements))) @heritage.impl
|
|
29
|
+
`;
|
|
30
|
+
|
|
31
|
+
export const JAVASCRIPT_QUERIES = `
|
|
32
|
+
(class_declaration name: (identifier) @name) @definition.class
|
|
33
|
+
(function_declaration name: (identifier) @name) @definition.function
|
|
34
|
+
(method_definition name: (property_identifier) @name) @definition.method
|
|
35
|
+
(lexical_declaration (variable_declarator name: (identifier) @name value: (arrow_function))) @definition.function
|
|
36
|
+
(lexical_declaration (variable_declarator name: (identifier) @name value: (function_expression))) @definition.function
|
|
37
|
+
(export_statement declaration: (lexical_declaration (variable_declarator name: (identifier) @name value: (arrow_function)))) @definition.function
|
|
38
|
+
(export_statement declaration: (lexical_declaration (variable_declarator name: (identifier) @name value: (function_expression)))) @definition.function
|
|
39
|
+
(import_statement source: (string) @import.source) @import
|
|
40
|
+
(export_statement source: (string) @import.source) @import
|
|
41
|
+
(call_expression function: (identifier) @call.name) @call
|
|
42
|
+
(call_expression function: (member_expression property: (property_identifier) @call.name)) @call
|
|
43
|
+
(new_expression constructor: (identifier) @call.name) @call
|
|
44
|
+
(field_definition property: (property_identifier) @name) @definition.property
|
|
45
|
+
(class_declaration name: (identifier) @heritage.class (class_heritage (identifier) @heritage.extends)) @heritage
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
export const PYTHON_QUERIES = `
|
|
49
|
+
(class_definition name: (identifier) @name) @definition.class
|
|
50
|
+
(function_definition name: (identifier) @name) @definition.function
|
|
51
|
+
(import_statement name: (dotted_name) @import.source) @import
|
|
52
|
+
(import_from_statement module_name: (dotted_name) @import.source) @import
|
|
53
|
+
(import_from_statement module_name: (relative_import) @import.source) @import
|
|
54
|
+
(call function: (identifier) @call.name) @call
|
|
55
|
+
(call function: (attribute attribute: (identifier) @call.name)) @call
|
|
56
|
+
(expression_statement (assignment left: (identifier) @name type: (type))) @definition.property
|
|
57
|
+
(class_definition name: (identifier) @heritage.class superclasses: (argument_list (identifier) @heritage.extends)) @heritage
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
export const JAVA_QUERIES = `
|
|
61
|
+
(class_declaration name: (identifier) @name) @definition.class
|
|
62
|
+
(interface_declaration name: (identifier) @name) @definition.interface
|
|
63
|
+
(enum_declaration name: (identifier) @name) @definition.enum
|
|
64
|
+
(method_declaration name: (identifier) @name) @definition.method
|
|
65
|
+
(constructor_declaration name: (identifier) @name) @definition.constructor
|
|
66
|
+
(field_declaration declarator: (variable_declarator name: (identifier) @name)) @definition.property
|
|
67
|
+
(import_declaration (_) @import.source) @import
|
|
68
|
+
(method_invocation name: (identifier) @call.name) @call
|
|
69
|
+
(method_invocation object: (_) name: (identifier) @call.name) @call
|
|
70
|
+
(object_creation_expression type: (type_identifier) @call.name) @call
|
|
71
|
+
(class_declaration name: (identifier) @heritage.class (superclass (type_identifier) @heritage.extends)) @heritage
|
|
72
|
+
(class_declaration name: (identifier) @heritage.class (super_interfaces (type_list (type_identifier) @heritage.implements))) @heritage.impl
|
|
73
|
+
`;
|
|
74
|
+
|
|
75
|
+
export const C_QUERIES = `
|
|
76
|
+
(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
|
|
77
|
+
(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function
|
|
78
|
+
(function_definition declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function
|
|
79
|
+
(declaration declarator: (pointer_declarator declarator: (function_declarator declarator: (identifier) @name))) @definition.function
|
|
80
|
+
(struct_specifier name: (type_identifier) @name) @definition.struct
|
|
81
|
+
(union_specifier name: (type_identifier) @name) @definition.union
|
|
82
|
+
(enum_specifier name: (type_identifier) @name) @definition.enum
|
|
83
|
+
(type_definition declarator: (type_identifier) @name) @definition.typedef
|
|
84
|
+
(preproc_function_def name: (identifier) @name) @definition.macro
|
|
85
|
+
(preproc_def name: (identifier) @name) @definition.macro
|
|
86
|
+
(preproc_include path: (_) @import.source) @import
|
|
87
|
+
(call_expression function: (identifier) @call.name) @call
|
|
88
|
+
(call_expression function: (field_expression field: (field_identifier) @call.name)) @call
|
|
89
|
+
`;
|
|
90
|
+
|
|
91
|
+
export const GO_QUERIES = `
|
|
92
|
+
(function_declaration name: (identifier) @name) @definition.function
|
|
93
|
+
(method_declaration name: (field_identifier) @name) @definition.method
|
|
94
|
+
(type_declaration (type_spec name: (type_identifier) @name type: (struct_type))) @definition.struct
|
|
95
|
+
(type_declaration (type_spec name: (type_identifier) @name type: (interface_type))) @definition.interface
|
|
96
|
+
(import_declaration (import_spec path: (interpreted_string_literal) @import.source)) @import
|
|
97
|
+
(import_declaration (import_spec_list (import_spec path: (interpreted_string_literal) @import.source))) @import
|
|
98
|
+
(field_declaration_list (field_declaration name: (field_identifier) @name)) @definition.property
|
|
99
|
+
(call_expression function: (identifier) @call.name) @call
|
|
100
|
+
(call_expression function: (selector_expression field: (field_identifier) @call.name)) @call
|
|
101
|
+
(composite_literal type: (type_identifier) @call.name) @call
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
export const CPP_QUERIES = `
|
|
105
|
+
(class_specifier name: (type_identifier) @name) @definition.class
|
|
106
|
+
(struct_specifier name: (type_identifier) @name) @definition.struct
|
|
107
|
+
(namespace_definition name: (namespace_identifier) @name) @definition.namespace
|
|
108
|
+
(enum_specifier name: (type_identifier) @name) @definition.enum
|
|
109
|
+
(type_definition declarator: (type_identifier) @name) @definition.typedef
|
|
110
|
+
(union_specifier name: (type_identifier) @name) @definition.union
|
|
111
|
+
(function_definition declarator: (function_declarator declarator: (identifier) @name)) @definition.function
|
|
112
|
+
(function_definition declarator: (function_declarator declarator: (qualified_identifier name: (identifier) @name))) @definition.method
|
|
113
|
+
(declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.function
|
|
114
|
+
(field_declaration declarator: (field_identifier) @name) @definition.property
|
|
115
|
+
(field_declaration declarator: (function_declarator declarator: (identifier) @name)) @definition.method
|
|
116
|
+
(preproc_include path: (_) @import.source) @import
|
|
117
|
+
(call_expression function: (identifier) @call.name) @call
|
|
118
|
+
(call_expression function: (field_expression field: (field_identifier) @call.name)) @call
|
|
119
|
+
(call_expression function: (qualified_identifier name: (identifier) @call.name)) @call
|
|
120
|
+
(new_expression type: (type_identifier) @call.name) @call
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
export const CSHARP_QUERIES = `
|
|
124
|
+
(class_declaration name: (identifier) @name) @definition.class
|
|
125
|
+
(interface_declaration name: (identifier) @name) @definition.interface
|
|
126
|
+
(struct_declaration name: (identifier) @name) @definition.struct
|
|
127
|
+
(enum_declaration name: (identifier) @name) @definition.enum
|
|
128
|
+
(record_declaration name: (identifier) @name) @definition.record
|
|
129
|
+
(namespace_declaration name: (identifier) @name) @definition.namespace
|
|
130
|
+
(namespace_declaration name: (qualified_name) @name) @definition.namespace
|
|
131
|
+
(file_scoped_namespace_declaration name: (identifier) @name) @definition.namespace
|
|
132
|
+
(method_declaration name: (identifier) @name) @definition.method
|
|
133
|
+
(local_function_statement name: (identifier) @name) @definition.function
|
|
134
|
+
(constructor_declaration name: (identifier) @name) @definition.constructor
|
|
135
|
+
(property_declaration name: (identifier) @name) @definition.property
|
|
136
|
+
(using_directive (qualified_name) @import.source) @import
|
|
137
|
+
(using_directive (identifier) @import.source) @import
|
|
138
|
+
(invocation_expression function: (identifier) @call.name) @call
|
|
139
|
+
(invocation_expression function: (member_access_expression name: (identifier) @call.name)) @call
|
|
140
|
+
(object_creation_expression type: (identifier) @call.name) @call
|
|
141
|
+
`;
|
|
142
|
+
|
|
143
|
+
export const RUST_QUERIES = `
|
|
144
|
+
(function_item name: (identifier) @name) @definition.function
|
|
145
|
+
(struct_item name: (type_identifier) @name) @definition.struct
|
|
146
|
+
(enum_item name: (type_identifier) @name) @definition.enum
|
|
147
|
+
(trait_item name: (type_identifier) @name) @definition.trait
|
|
148
|
+
(impl_item type: (type_identifier) @name !trait) @definition.impl
|
|
149
|
+
(mod_item name: (identifier) @name) @definition.module
|
|
150
|
+
(type_item name: (type_identifier) @name) @definition.type
|
|
151
|
+
(use_declaration argument: (_) @import.source) @import
|
|
152
|
+
(call_expression function: (identifier) @call.name) @call
|
|
153
|
+
(call_expression function: (field_expression field: (field_identifier) @call.name)) @call
|
|
154
|
+
(call_expression function: (scoped_identifier name: (identifier) @call.name)) @call
|
|
155
|
+
(struct_expression name: (type_identifier) @call.name) @call
|
|
156
|
+
(field_declaration_list (field_declaration name: (field_identifier) @name)) @definition.property
|
|
157
|
+
`;
|
|
158
|
+
|
|
159
|
+
export const PHP_QUERIES = `
|
|
160
|
+
(namespace_definition name: (namespace_name) @name) @definition.namespace
|
|
161
|
+
(class_declaration name: (name) @name) @definition.class
|
|
162
|
+
(interface_declaration name: (name) @name) @definition.interface
|
|
163
|
+
(trait_declaration name: (name) @name) @definition.trait
|
|
164
|
+
(enum_declaration name: (name) @name) @definition.enum
|
|
165
|
+
(function_definition name: (name) @name) @definition.function
|
|
166
|
+
(method_declaration name: (name) @name) @definition.method
|
|
167
|
+
(property_declaration (property_element (variable_name (name) @name))) @definition.property
|
|
168
|
+
(namespace_use_declaration (namespace_use_clause (qualified_name) @import.source)) @import
|
|
169
|
+
(function_call_expression function: (name) @call.name) @call
|
|
170
|
+
(member_call_expression name: (name) @call.name) @call
|
|
171
|
+
(nullsafe_member_call_expression name: (name) @call.name) @call
|
|
172
|
+
(object_creation_expression (name) @call.name) @call
|
|
173
|
+
`;
|
|
174
|
+
|
|
175
|
+
export const RUBY_QUERIES = `
|
|
176
|
+
(module name: (constant) @name) @definition.module
|
|
177
|
+
(class name: (constant) @name) @definition.class
|
|
178
|
+
(method name: (identifier) @name) @definition.method
|
|
179
|
+
(singleton_method name: (identifier) @name) @definition.method
|
|
180
|
+
(call method: (identifier) @call.name) @call
|
|
181
|
+
`;
|
package/src/parser/types.ts
CHANGED
|
@@ -89,7 +89,7 @@ export interface ParsedGeneric {
|
|
|
89
89
|
/** Everything extracted from a single file */
|
|
90
90
|
export interface ParsedFile {
|
|
91
91
|
path: string // "src/auth/verify.ts"
|
|
92
|
-
language: 'typescript' | 'javascript' | '
|
|
92
|
+
language: 'python' | 'go' | 'typescript' | 'javascript' | 'java' | 'c' | 'cpp' | 'csharp' | 'rust' | 'php' | 'ruby' | 'unknown'
|
|
93
93
|
functions: ParsedFunction[]
|
|
94
94
|
classes: ParsedClass[]
|
|
95
95
|
generics: ParsedGeneric[]
|