test(code-graph): add Kotlin fixture for suspend functions and coroutine patterns
## Problem `suspend` functions are fundamental to Kotlin coroutines — the standard concurrency model in all modern Kotlin code (Android, Ktor, Spring with coroutines, Arrow). A `suspend` function can only be called from another coroutine or a suspending context: ```kotlin suspend fun fetchUser(id: String): User { return userRepository.findById(id) } suspend fun loadDashboard(): Dashboard { val user = fetchUser("alice") // ← suspends, resumes when done val data = fetchData(user.id) // ← chained suspension return Dashboard(user, data) } ``` The `suspend` modifier is transparent to tree-sitter: a `suspend` function is still a `function_declaration` in the Kotlin grammar, so it should be extracted correctly. However, there is no test fixture confirming this behavior. Without a fixture: - A regression in `suspend` function extraction would silently pass CI - Contributors adding coroutine-specific features (e.g., `CoroutineScope` extension detection) have no baseline test to build on - The `launch {}` and `async {}` block patterns (coroutine builders that create anonymous lambdas) are not documented for their non-extraction behavior ## Proposed solution Add `crates/integration-tests-codegraph/fixtures/kotlin/coroutines.yaml`: 1. **Confirm** that `suspend` functions are extracted as `Function` definitions 2. **Confirm** that `launch {}` blocks do NOT create spurious anonymous definitions (they're inline lambdas) 3. **Confirm** that a `suspend fun` on an interface is extracted as a `Method` ```yaml name: "Kotlin: suspend functions and coroutine patterns" fixtures: - path: com/example/repo.kt content: | package com.example import kotlinx.coroutines.* interface UserRepository { suspend fun findById(id: String): String } class UserService(private val repo: UserRepository) { suspend fun fetchUser(id: String): String { return repo.findById(id) } fun startLoading(id: String) { CoroutineScope(Dispatchers.IO).launch { val user = fetchUser(id) println(user) } } } tests: - name: "suspend fun extracted as Function" query: | MATCH (d:Definition) WHERE d.name = 'fetchUser' AND d.definition_type = 'Method' RETURN d.name AS name, d.fqn AS fqn assert: - { row: { name: "fetchUser" } } - name: "suspend interface method extracted" query: | MATCH (d:Definition) WHERE d.name = 'findById' AND d.definition_type = 'Method' RETURN d.name AS name assert: - { row: { name: "findById" } } ``` If the `suspend` modifier causes any unexpected parse behavior, document it and open a follow-up issue. ## Affected files - `crates/integration-tests-codegraph/fixtures/kotlin/coroutines.yaml` (new file) ## Validation ```bash mise run test:integration:codegraph # All tests pass, including "Kotlin: suspend functions and coroutine patterns" ``` ## Hackathon notes - **Difficulty:** L1 - **Estimated effort:** 2–4h - **No server needed:** Yes - **Prerequisites:** `mise install`; Rust toolchain (stable); basic Kotlin knowledge; no Rust changes likely needed (this is expected to be a fixture-only contribution)
issue