GitNexus/gitnexus/test
glier 6a571570f2
Some checks are pending
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Gitleaks / gitleaks (push) Waiting to run
Publish / Classify release event (push) Waiting to run
Publish / RC guard (marker + release-PR skip) (push) Blocked by required conditions
Publish / ci (push) Blocked by required conditions
Publish / Publish to npm (push) Blocked by required conditions
Publish / Build & Push RC Docker images (push) Blocked by required conditions
Scorecard / Scorecard analysis (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-cli) (push) Waiting to run
Trivy Image Scan / Trivy (gitnexus-web) (push) Waiting to run
feat(group): Kotlin Spring HTTP consumer extraction + provider parity with Java (#2254)
* feat(group): Kotlin Spring HTTP consumer extraction + provider parity with Java

Brings the Kotlin group/contract HTTP extractor up to parity with Java for
inter-service contract detection, and unifies the language-agnostic consumer
logic so it is not duplicated.

Consumers (new for Kotlin):
- @FeignClient interface @(Get|...)Mapping methods are emitted as OpenFeign
  consumers (a remote call), not providers — previously mis-classified because
  tree-sitter-kotlin models an interface as a class_declaration.
- Spring 6 HTTP Interface @(Get|...)Exchange (with optional class-level
  @HttpExchange(url) prefix) — added for BOTH Java and Kotlin.
- Native OpenFeign @RequestLine, gated to interfaces (Feign proxies are
  interfaces only), mirroring java.ts's findEnclosingInterface check.

Providers (Kotlin parity with java.ts scanSpringProject):
- A @(Get|...)Mapping on a non-Feign interface is a route *contract*, not a
  served route; it is skipped in scan() so the implementing controller is the
  sole provider (Java drops these implicitly via interface_declaration).
- scanProject inherits interface routes onto the implementing class, gated on
  the class being a @RestController/@Controller (kotlinClassIsController handles
  both the attached `modifiers` shape and the detached leading-arg-form
  prefix_expression shape) so non-controller implementers don't emit phantom
  providers.

Shared module:
- New spring-consumer-shared.ts holds the language-agnostic primitives
  (REST_TEMPLATE_/WEB_CLIENT_/EXCHANGE verb maps, joinPath, parseRequestLine,
  framework + confidence constants); java.ts and kotlin.ts both import it.

Array-of-paths (both languages):
- Route/Feign/Exchange annotation paths are `String[]`; a multi-element array
  registers the route under EVERY element. The class/Feign/HttpExchange prefix
  maps now accumulate all elements (were last-write-wins) and emission
  cross-products prefixes × method paths, so `@RequestMapping(["/a","/b"])` +
  `@GetMapping(["/x","/y"])` yields all four contract IDs. Array form is matched
  via a predicate-free alternation over Kotlin `collection_literal` / Java
  `element_value_array_initializer`.

Tests: comprehensive Java + Kotlin cases incl. consumer-vs-provider
classification, @*Exchange, @RequestLine (interface-only + plain-interface),
interface-based controller inheritance, non-controller negative case, detached
@RestController, single- and multi-element array paths (method-level and
class-prefix cross-product). 109 http-route + group tests pass; tsc/eslint/
prettier clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(group): apply @RequestMapping prefix to Kotlin @RequestLine consumers (#2254 P2)

A @RequestLine method on an interface with a class-level @RequestMapping
prefix but no @FeignClient(path) dropped the prefix in Kotlin while Java
applied it (java.ts merges the fallback into feignPrefixByInterfaceId).
Mirror the feignPrefixByClassId ?? prefixByClassId ?? [''] chain already
used by the @GetMapping-in-Feign path. Adds Kotlin twins for the
@RequestMapping-prefix and @FeignClient(path)-wins cases.

* fix(group): accept named-arg Kotlin @RequestLine(value=...) (#2254 P2)

The positional pattern's '.' anchor only matched @RequestLine("VERB /x"),
silently dropping the named @RequestLine(value = "VERB /x") form that
java.ts accepts. Add a dedicated named pattern constrained to #eq? @key
"value" (Java parity: non-value keys stay dropped). Adds Kotlin twins
for the named-value and non-value-key cases.

* fix(group): resolve Kotlin FQN annotations/supertypes by trailing segment (#2254)

A fully-qualified @org…RestController / supertype : a.b.Api parses to a
user_type with one type_identifier per dotted segment; kotlinAnnotationName
and collectKotlinSupertypes took the FIRST ("org"/"a"), so FQN controllers
were not recognised and FQN supertypes never matched their interface. Take
the trailing segment. Adds FQN controller + FQN supertype inheritance twins.

* refactor(group): remove dead prefix_expression branch in kotlinClassIsController (#2254)

AST probe (bare and realistic package+constructor forms) confirms the
arg-form @RestController("bean") attaches under the class `modifiers` as an
annotation/constructor_invocation, caught by the modifiers loop — the
prefix_expression sibling branch was unreachable. Remove it and correct the
false grammar comments (source + the arg-form test). The existing arg-form
test stays green via the modifiers branch, confirming no behavior change.

* feat(group): support Kotlin arrayOf(...) annotation arrays (#2254 P3)

arrayOf("/a","/b") (the explicit String[] form) parses to a call_expression,
not a string_literal/collection_literal, so it was missed across all five
annotation-array families. Add dedicated arrayOf query patterns (positional +
named) per family via a shared arrayOfArg fragment — kept out of the existing
[(string_literal) (collection_literal …)] alternation to avoid the
tree-sitter 0.21.x predicate-bucket hazard. Verified one match per element
(multi-element accumulates) with buildPath/produces/empty anti-overreach.

* feat(group): detect WebClient long-form in Java for Kotlin parity (#2254 P3)

Java deliberately deferred webClient.method(HttpMethod.X).uri(...); the
Kotlin plugin proves a single structural query suffices (same field-access
shape as REST_TEMPLATE_EXCHANGE). Add WEB_CLIENT_LONG_FORM_PATTERNS + scan
loop so .java and .kt detect it identically. Move WEB_CLIENT_LONG_VERB_RE to
the shared module (single source for both). Flip the now-obsolete java :1741
negative test to positive (verbs + no-double-emit) and add a Java var-verb
anti-overreach twin.

* refactor(group): share pushPrefix between java.ts and kotlin.ts (#2254)

The de-duping prefix accumulator was duplicated as kotlin.ts pushKotlinPrefix
and a java.ts closure. Hoist a single export pushPrefix into
spring-consumer-shared.ts; both plugins import it. No behavior change.

* test(group): add Kotlin interface-inheritance boundary twins (#2254)

Twins for the Java inheritance-boundary cases that had no Kotlin counterpart:
shared-leading-segment combine, prefix-less method overlap, ambiguous
duplicate-interface-name suppression, plus a positive multi-interface
implementer. These pin Kotlin's scanProject behavior before U8 extracts the
shared inheritance algorithm.

* refactor(group): share the Spring interface-inheritance scanProject algorithm (#2254)

scanKotlinProject and scanSpringProject were ~80-line near-duplicates over
structurally identical type records. Extract scanSpringInheritanceProject +
SharedSpringType into spring-consumer-shared.ts; collapse KotlinTypeInfo and
SpringTypeInfo into the shared type; both plugins' scanProject become thin
collect-and-delegate wrappers. The ownerPrefix-carrying intermediate is owned
by the shared function. Behavior-preserving — Java and Kotlin inheritance
suites (incl. the new Kotlin boundary twins) byte-identical; tsc clean.

* test(group): close Kotlin↔Java consumer test-parity gaps + assert confidence (#2254)

Add Kotlin twins for Java-tested consumer scenarios with no Kotlin coverage:
@RequestLine query-strip, mixed @RequestLine+@GetMapping, malformed-value
rejection, and @FeignClient(path)-wins-when-@RequestMapping-first. Add the
Java dual-role twin (interface as consumer + implementing controller as
provider). Add two-sided provider confidence (0.8) assertions on the
canonical Java and Kotlin interface-inheritance tests.

* docs(group): document Java FQN route-annotation limitation + pin it (#2254)

Per KTD6, the Java FQN route-annotation gap is documentation-first: the gap is
route-string-only (FQN controllers are already recognised via hasAnnotation)
and FQN-written annotations are vanishingly rare. Document the asymmetry with
Kotlin in JAVA_ROUTE_ANNOTATION_PATTERNS and pin current behavior with an
anti-overreach test. The scoped_identifier query change is deferred to avoid
re-keying existing contracts via the predicate-bucket hazard.

* test(group): add Java↔Kotlin contract set-equality parity harness (#2254)

Independent per-side twins can both pass while the emitted contract SETS
differ. Add a table-driven harness over the parity-critical families
(@RequestLine prefix-fallback, named @RequestLine, @FeignClient(path)+@GetMapping,
@HttpExchange+@GetExchange, WebClient long-form, interface inheritance) that
runs matched .java/.kt fixtures through both plugins and asserts the full
projected contract set (role+contractId+framework+confidence) is equal across
languages AND equal to the expected set — the durable guard for the
byte-identical goal. Gated on kotlinConsumerAvailable.

* style(group): apply prettier formatting to #2254 changes

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-06-21 16:59:00 +01:00
..
fixtures fix(cpp-hooks): handle pack-base comments and missing hook overrides (#2247) 2026-06-18 21:55:46 +01:00
helpers feat(cfg): PDG/CFG visitors for all supported languages (#2195) (#2197) 2026-06-15 12:31:04 +01:00
integration fix(lbug): stop --pdg analyze double-free (skip LadybugDB close-destructor crash) + harden connection serialization (#2264) 2026-06-21 15:25:56 +01:00
unit feat(group): Kotlin Spring HTTP consumer extraction + provider parity with Java (#2254) 2026-06-21 16:59:00 +01:00
utils perf(hooks): cmdline-first Linux db-lock scan, drop the lsof fallback (#2180) (#2183) 2026-06-13 11:52:14 +01:00