From 40b6fa82630a9b7e1c62bc1370b3943241a505ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 May 2026 13:49:59 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20address=20review=20findings=201-4=20?= =?UTF-8?q?=E2=80=94=20varargs=20arity,=20static=20import=20resolution,=20?= =?UTF-8?q?importOwningScope,=20stripGeneric?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/22308da3-59c9-47e6-8e52-738305b1b80a Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> --- .../languages/java/arity-metadata.ts | 10 +++++-- .../ingestion/languages/java/interpret.ts | 26 ++++++++++++++++--- .../ingestion/languages/java/simple-hooks.ts | 7 +++-- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gitnexus/src/core/ingestion/languages/java/arity-metadata.ts b/gitnexus/src/core/ingestion/languages/java/arity-metadata.ts index 38d4f6c80..47cccbff9 100644 --- a/gitnexus/src/core/ingestion/languages/java/arity-metadata.ts +++ b/gitnexus/src/core/ingestion/languages/java/arity-metadata.ts @@ -31,9 +31,15 @@ export function computeJavaArityMetadata(fnNode: SyntaxNode): JavaArityMetadata if (hasVariadic) types.push('varargs'); const total = params.length; + // For varargs methods, `parameterCount` (max) is unknown — any number of + // trailing arguments is valid. But the fixed-prefix parameters (everything + // before the variadic `...` param) are still required, so we preserve that + // count in `requiredParameterCount` so `javaArityCompatibility` can reject + // calls that undersupply the fixed prefix (e.g. `f(int x, String... args)` + // called with 0 args). + const fixedCount = params.filter((p) => !p.isVariadic).length; const parameterCount = hasVariadic ? undefined : total; - // Java has no optional parameters (no default values), so required = total - const requiredParameterCount = hasVariadic ? undefined : total; + const requiredParameterCount = hasVariadic ? fixedCount : total; return { parameterCount, diff --git a/gitnexus/src/core/ingestion/languages/java/interpret.ts b/gitnexus/src/core/ingestion/languages/java/interpret.ts index 9f45f3b4c..107b879cd 100644 --- a/gitnexus/src/core/ingestion/languages/java/interpret.ts +++ b/gitnexus/src/core/ingestion/languages/java/interpret.ts @@ -40,15 +40,25 @@ export function interpretJavaImport(captures: CaptureMatch): ParsedImport | null } case 'static': { // `import static com.example.Utils.format;` + // The source contains the full path including the member name + // (e.g. `com.example.Utils.format`). For file resolution we need + // the class path (`com.example.Utils`), so strip the final member + // segment. The local binding name is the member itself. + const fullSource = sourceCap.text; + const lastDot = fullSource.lastIndexOf('.'); + const classPath = lastDot >= 0 ? fullSource.slice(0, lastDot) : fullSource; return { kind: 'named', - localName: nameCap?.text ?? sourceCap.text.split('.').pop() ?? sourceCap.text, - importedName: sourceCap.text, - targetRaw: sourceCap.text, + localName: nameCap?.text ?? (lastDot >= 0 ? fullSource.slice(lastDot + 1) : fullSource), + importedName: fullSource, + targetRaw: classPath, }; } case 'static-wildcard': { // `import static com.example.Utils.*;` + // The source is the class path (e.g. `com.example.Utils`). + // Resolution should target the class file, not a wildcard directory + // scan — `Utils.java` is the file that contains the static members. return { kind: 'wildcard', targetRaw: sourceCap.text + '.*', @@ -87,10 +97,18 @@ export function interpretJavaTypeBinding(captures: CaptureMatch): ParsedTypeBind * `ArrayList`, `Optional` — to its element type. */ function stripGeneric(text: string): string { + // Single-type-argument containers — extract the element type. const single = text.match( - /^(?:[A-Za-z_][A-Za-z0-9_.]*\.)?(?:List|ArrayList|LinkedList|Set|HashSet|TreeSet|Collection|Iterable|Iterator|Optional|Stream|CompletableFuture|Future|Queue|Deque|ArrayDeque|Vector|Stack)<([^,<>]+)>$/, + /^(?:[A-Za-z_][A-Za-z0-9_.]*\.)?(?:List|ArrayList|LinkedList|Set|HashSet|TreeSet|SortedSet|LinkedHashSet|Collection|Iterable|Iterator|Optional|Stream|CompletableFuture|Future|Queue|Deque|ArrayDeque|PriorityQueue|Vector|Stack|Supplier|Consumer|Predicate|Function)<([^,<>]+)>$/, ); if (single !== null) return single[1].trim(); + + // Two-type-argument map/container types — extract the value type (second arg). + const twoArg = text.match( + /^(?:[A-Za-z_][A-Za-z0-9_.]*\.)?(?:Map|HashMap|TreeMap|LinkedHashMap|ConcurrentHashMap|ConcurrentMap|SortedMap|NavigableMap|Hashtable|EnumMap|WeakHashMap|IdentityHashMap|BiFunction|BiConsumer|BiPredicate|Pair|Entry)<[^,<>]+,\s*([^,<>]+)>$/, + ); + if (twoArg !== null) return twoArg[1].trim(); + return text; } diff --git a/gitnexus/src/core/ingestion/languages/java/simple-hooks.ts b/gitnexus/src/core/ingestion/languages/java/simple-hooks.ts index 25da32369..e69f768a6 100644 --- a/gitnexus/src/core/ingestion/languages/java/simple-hooks.ts +++ b/gitnexus/src/core/ingestion/languages/java/simple-hooks.ts @@ -35,14 +35,13 @@ export function javaBindingScopeFor( // ─── importOwningScope ──────────────────────────────────────────────────── -/** Java imports are always at file level. Defensively handle nested - * scopes by attaching to the innermost if it's Class or Function. */ +/** Java imports are always at compilation-unit (Module) level (JLS §7.5). + * Return `null` unconditionally so the default Module scope is used. */ export function javaImportOwningScope( _imp: ParsedImport, - innermost: Scope, + _innermost: Scope, _tree: ScopeTree, ): ScopeId | null { - if (innermost.kind === 'Class' || innermost.kind === 'Function') return innermost.id; return null; }