diff --git a/esbuild.js b/esbuild.js index 8b203076e4..7907dd1c39 100644 --- a/esbuild.js +++ b/esbuild.js @@ -52,6 +52,7 @@ const copyWasmFiles = { "java", "php", "swift", + "kotlin", ] languages.forEach((lang) => { diff --git a/src/services/tree-sitter/__tests__/index.test.ts b/src/services/tree-sitter/__tests__/index.test.ts index 4a5782dcb1..8372e7e580 100644 --- a/src/services/tree-sitter/__tests__/index.test.ts +++ b/src/services/tree-sitter/__tests__/index.test.ts @@ -169,6 +169,8 @@ describe("Tree-sitter Service", () => { "/test/path/main.rs", "/test/path/program.cpp", "/test/path/code.go", + "/test/path/app.kt", + "/test/path/script.kts", ] ;(listFiles as jest.Mock).mockResolvedValue([mockFiles, new Set()]) @@ -197,6 +199,8 @@ describe("Tree-sitter Service", () => { rs: { parser: mockParser, query: mockQuery }, cpp: { parser: mockParser, query: mockQuery }, go: { parser: mockParser, query: mockQuery }, + kt: { parser: mockParser, query: mockQuery }, + kts: { parser: mockParser, query: mockQuery }, }) ;(fs.readFile as jest.Mock).mockResolvedValue("function test() {}") @@ -207,6 +211,8 @@ describe("Tree-sitter Service", () => { expect(result).toContain("main.rs") expect(result).toContain("program.cpp") expect(result).toContain("code.go") + expect(result).toContain("app.kt") + expect(result).toContain("script.kts") }) it("should normalize paths in output", async () => { diff --git a/src/services/tree-sitter/__tests__/languageParser.test.ts b/src/services/tree-sitter/__tests__/languageParser.test.ts index 1b92d81b6b..54271e30e8 100644 --- a/src/services/tree-sitter/__tests__/languageParser.test.ts +++ b/src/services/tree-sitter/__tests__/languageParser.test.ts @@ -92,6 +92,17 @@ describe("Language Parser", () => { expect(parsers.hpp).toBeDefined() }) + it("should handle Kotlin files correctly", async () => { + const files = ["test.kt", "test.kts"] + const parsers = await loadRequiredLanguageParsers(files) + + expect(ParserMock.Language.load).toHaveBeenCalledWith(expect.stringContaining("tree-sitter-kotlin.wasm")) + expect(parsers.kt).toBeDefined() + expect(parsers.kts).toBeDefined() + expect(parsers.kt.query).toBeDefined() + expect(parsers.kts.query).toBeDefined() + }) + it("should throw error for unsupported file extensions", async () => { const files = ["test.unsupported"] diff --git a/src/services/tree-sitter/index.ts b/src/services/tree-sitter/index.ts index bfdfa6c52c..9aaa672ce2 100644 --- a/src/services/tree-sitter/index.ts +++ b/src/services/tree-sitter/index.ts @@ -80,6 +80,9 @@ function separateFiles(allFiles: string[]): { filesToParse: string[]; remainingF "java", "php", "swift", + // Kotlin + "kt", + "kts", ].map((e) => `.${e}`) const filesToParse = allFiles.filter((file) => extensions.includes(path.extname(file))).slice(0, 50) // 50 files max const remainingFiles = allFiles.filter((file) => !filesToParse.includes(file)) diff --git a/src/services/tree-sitter/languageParser.ts b/src/services/tree-sitter/languageParser.ts index 2d791b39a8..f256b0b62a 100644 --- a/src/services/tree-sitter/languageParser.ts +++ b/src/services/tree-sitter/languageParser.ts @@ -13,6 +13,7 @@ import { javaQuery, phpQuery, swiftQuery, + kotlinQuery, } from "./queries" export interface LanguageParser { @@ -120,6 +121,11 @@ export async function loadRequiredLanguageParsers(filesToParse: string[]): Promi language = await loadLanguage("swift") query = language.query(swiftQuery) break + case "kt": + case "kts": + language = await loadLanguage("kotlin") + query = language.query(kotlinQuery) + break default: throw new Error(`Unsupported language: ${ext}`) } diff --git a/src/services/tree-sitter/queries/index.ts b/src/services/tree-sitter/queries/index.ts index 889210a8e5..818eacca01 100644 --- a/src/services/tree-sitter/queries/index.ts +++ b/src/services/tree-sitter/queries/index.ts @@ -10,3 +10,4 @@ export { default as cQuery } from "./c" export { default as csharpQuery } from "./c-sharp" export { default as goQuery } from "./go" export { default as swiftQuery } from "./swift" +export { default as kotlinQuery } from "./kotlin" diff --git a/src/services/tree-sitter/queries/kotlin.ts b/src/services/tree-sitter/queries/kotlin.ts new file mode 100644 index 0000000000..61eb112448 --- /dev/null +++ b/src/services/tree-sitter/queries/kotlin.ts @@ -0,0 +1,28 @@ +/* +- class declarations (including interfaces) +- function declarations +- object declarations +- property declarations +- type alias declarations +*/ +export default ` +(class_declaration + (type_identifier) @name.definition.class +) @definition.class + +(function_declaration + (simple_identifier) @name.definition.function +) @definition.function + +(object_declaration + (type_identifier) @name.definition.object +) @definition.object + +(property_declaration + (simple_identifier) @name.definition.property +) @definition.property + +(type_alias + (type_identifier) @name.definition.type +) @definition.type +`