Why this is needed:
- The extractor compatibility fixes now preserve the information these Kotlin1-era
tests were protecting, even when compiled with Kotlin 2.4 and
`-language-version 2.0`.
- Keeping mixed legacy language-version wiring in individual tests is no longer
necessary and obscures the intended steady-state execution mode.
What this changes:
- Update all affected Kotlin1 compatibility integration tests to run with
`-language-version 2.0` directly.
- Keep the expected extraction signal aligned for extractor information output.
- Remove the obsolete CODEOWNERS entry for the retired `java/ql/test-kotlin1/`
path.
This consolidates the language-version transition into a single test rollup
commit, as requested.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Why this is needed:
- Under K2, binary Java symbols are represented differently from K1:
JavaSourceElement metadata is often absent and sources are exposed through
VirtualFileBasedSourceElement.
- Without recovery logic, callable matching can miss declared Java methods,
callable labels can drift (primitive vs boxed reference types), and external
Java declaration stubs can gain wildcard noise when Java signatures are not
available.
- These differences produced Kotlin 2.0 parity drift in tests that rely on
stable Java/Kotlin cross-extractor callable identity.
What this changes:
- Add K2-aware Java binary inspection helpers (ASM-based fallback) to detect
declared methods and parameter/return reference-vs-primitive shape when
JavaSourceElement metadata is unavailable.
- Recover Java callables more reliably in KotlinUsesExtractor, including a
binary-class fallback path.
- Normalise callable labels and call result typing to boxed Java classes when
K2 enhanced reference types appear as Kotlin primitives.
- Accept K2's `Any` form for Object.equals(Object) and keep binary declaration
checks stable.
- Suppress default wildcard insertion for external Java declaration stubs when
no Java callable metadata is available, preventing synthetic wildcard drift.
This commit restores Java interop parity for Kotlin 2.0 extraction paths.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Why this is needed:
- With Kotlin 2.0 analysis, some local-variable locations resolve to a wider
declaration span than before.
- The previous extractor logic used provider-based ranges that can cover type,
annotations, and modifiers, which shifts expected variable location facts.
- This caused parity drift in tests that expect the location to point at the
variable name token itself.
What this changes:
- Cache current source text per file during extraction.
- Derive variable-name offsets by scanning the declaration slice and locating
the declared identifier token.
- Emit local-variable declaration/expr locations from that identifier span,
with fallback to the previous provider when source offsets are unavailable.
This restores stable name-anchored variable locations under Kotlin 2.0.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Why this is needed:
- Under K2, top-level declarations from external binaries are attached directly
to IrExternalPackageFragment rather than to an IrClass file-class parent.
- That bypassed the normal class-source location path, so some external file-class
entities ended up without stable binary file locations.
- Missing/unstable locations caused drift in tests that depend on external file
class member resolution and location facts.
What this changes:
- Resolve binary paths from IrMemberWithContainerSource (JvmPackagePartSource)
via a dedicated getContainerSourceBinaryPath helper.
- In KotlinUsesExtractor, when extracting top-level external declarations,
attach file-class location from container-source binary path when available.
- Track external file classes whose locations were emitted to avoid duplicate
hasLocation facts.
This targets the K2 external file-class location gap (for example file_classes and
external-property-overloads parity).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The trait had a single implementor (`AstCursor`), three type parameters
of which one (`T`) was never used in any method signature, and one
external consumer that needed `use yeast::Cursor;` in scope just to
call methods on the cursor. The abstraction was overhead without a
second implementor to justify it.
Move the six trait methods to an inherent `impl AstCursor` block;
delete `shared/yeast/src/cursor.rs`, the `pub mod cursor;` and
`pub use cursor::Cursor;` lines in `lib.rs`, and the `use yeast::Cursor;`
in `tree-sitter-extractor`'s `traverse_yeast`.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The `{expr}.map(p -> tpl)` and `{expr}.reduce_left(first -> init, acc,
elem -> fold)` post-fix chains on `{expr}` placeholders had no
remaining users in the codebase: `.map` was never used, and the
4 `.reduce_left` sites in `swift.rs` were rewritten to plain
`Iterator::reduce` via an `and_chain` helper in an earlier commit.
Removes the entire `parse_chain_suffix` function (~90 lines) and the
`has_chain` detection / dispatch branches at the two call sites
(field-position in `parse_direct_node_inner` and body-position in
`parse_direct_list`). The remaining `{expr}` path is the
trait-dispatched one introduced by the splice-syntax cleanup, which
handles single ids and iterables uniformly via `IntoFieldIds`.
Also strips the chain syntax from the `tree!` macro doc comment.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The empty error string passed to `expect_ident` was dead code (the
preceding lookahead has already confirmed the token is an ident),
but it would have been a confusing message if it ever fired. Replace
with an explicit "unreachable" string that makes the intent
clearer to readers.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both accessors returned the same private `kind_name: &'static str`
field; `kind_name()` is widely used (mainly by dump.rs and schema
diagnostics) and `kind()` had only 2 internal callers in lib.rs and
a handful in tests. Pick the more descriptive name and update the
callers.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`BuildCtx::prepend_field` and the underlying `Ast::prepend_field_child`
existed to support the create-then-mutate pattern in swift.rs (build
an output node, then prepend modifiers to its `modifier:` field). The
SwiftContext-based refactor on the previous branches eliminated all
such call sites: every emitted declaration now carries its modifiers
from birth, so the in-place prepend operation has no users.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`translate_opt` was a convenience for the manual_rule! body code,
collapsing `Option<I>` to `Option<Id>` via `translate`. Since the
`@@` raw-capture migration replaced manual_rule! with rule!, no
callers remain — the auto-translate prefix handles `Option<Id>`
captures directly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`Captures::map_captures`, `Captures::map_captures_to`, and
`Captures::try_map_all_captures` had no callers. The last one was
subsumed by `try_map_captures_except` (which takes a skip list and
degenerates to the old behaviour when the list is empty).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In the initial implementation of yeast, the splice syntax was needed do
distinguish between splicing multiple nodes or just a single node.
However, this was always an ugly "wart" in the syntax, since the user
shouldn't have to worry about these things.
To fix this, we add an `IntoFieldIds` trait that dispatches on the
value's type: `Id` pushes a single id, and a blanket impl for
`IntoIterator<Item: Into<Id>>` handles `Vec<Id>`, `Option<Id>`, and
arbitrary iterator chains.
With this, we no longer need to use the special splice syntax, and hence
we can get rid of it.
Previously, the `Id` type was a bare usize alias. The `NodeRef` newtype
existed solely to carry the AST-aware `YeastDisplay` /
`YeastSourceRange` impls (so that `#{captured_node}` rendered source
text rather than the numeric id) without colliding with the impls for
raw integer types.
This commit promotes `Id` itself to a (transparent) newtype struct and
moves the AST-aware trait impls directly onto it. With `Id` and `usize`
now being different types, the integer-display impl (for `usize`) and
the source-text impl (for `Id`) coexist without conflict, and `NodeRef`
becomes redundant (and so we remove it).
- unified/swift: Mark `binding_kind` as a raw `@@` capture in the
property_declaration rule. It is only used to read its source text
(`ctx.ast.source_text`), never as a translated node. With `@` the
auto-translate prefix would route the unnamed `let`/`var` token
through the catch-all `_ @node => {node}` fallback for a no-op
roundtrip; `@@` makes the intent explicit and removes that reliance.
- shared/yeast/tests: Reword a stale comment in test_raw_capture_marker.
The text claimed a "second assertion" exists in this test, but the
explicit-translation check actually lives in the companion
test_raw_capture_marker_explicit_translate.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
With `@@name` available, there's no longer a need to use `manual_rule!`.
Every place where it is used, we can instead just mark the relevant raw
captures as such. This results in quite a lot of cleanup! (Also, to me
at least, it makes these rules a lot easier to reason about.)
A first iteration of this approach resulted in a lot of
`.map(Into::into)` being needed, because `SwiftContext` stores `Id`s,
but captures produce `NodeRef`s. To avoid this, I swapped it around so
that the context stores `NodeRef`s. This does require adding `.into()`
in a few places, but it makes the rest of the code a lot more ergonomic.
The `@@name` capture marker in `rule!` queries skips the
auto-translate prefix for that specific capture, letting the body see
the original capture (and thus delay its translation using
`ctx.translate` until it becomes convenient).
Regular `@name` captures continue to be auto-translated as before.
Specifically these are translated _eagerly_, before the main body of the
rewrite rule is run.
I settled on `@@` as the syntax because it did not add new symbols that
the user has to keep track of (it's still a kind of capture), but it's
still visually distinct enough that the user should be able to tell that
there's something special going on. In principle one could accidentally
write one form of capture where the other was intended, but in practice
this would result in code that did not compile (because the types would
not match).