fix(explore): surface camel-infix field definers on service-layer codebases (#1196)#1233
Open
umi008 wants to merge 1 commit into
Open
fix(explore): surface camel-infix field definers on service-layer codebases (#1196)#1233umi008 wants to merge 1 commit into
umi008 wants to merge 1 commit into
Conversation
…ebases (colbymchenry#1196) Multi-word field-name queries (e.g. `profileInfo isTrialEligible quotaInfo billingMethod`) used to return 134 unrelated symbols and bury the defining controller and service files under a dense neighbor. Three compounding retrieval bugs were dead on JS/TS/Ruby/Python service-layer codebases (where the camel-infix definer is a method, not a class): 1. context builder 5b (CamelCase-boundary LIKE) used `name.indexOf(titleCased)` after `titleCased.toLowerCase()`, so a multi-hump token ("Profileinfo") could never indexOf into "getProfileInfoV2". The SQL layer matched case-insensitively; the JS boundary check silently re-tightened that and dropped the row. Now case-insensitive, with a guard that the boundary char itself is uppercase so we still require a real hump. 2. context builder 5b AND 5c restricted the LIKE batch to declaration kinds (class/interface/struct/trait/protocol/enum/type_alias), so on a method-centric codebase they contributed nothing. Both now issue a separate LIKE batch for callable kinds (function/method/ component) and merge before scoring, with a per-batch 200-row cap so a hot single-word term can't crowd classes out. 3. explore's named-symbol seeding was exact-name only. A field-name token (profileInfo) has no node of its own, so it contributed zero seeds: no +50 file score, no entryFiles protection, no named-file sort. Added findCamelInfixCallables: a LIKE-based fallback that accepts prefix or camel-hump boundary matches on method/function/ component kinds, case-insensitive. Fires only when the exact lookup yields no callable (cands.length === 0), so well-named queries are unaffected. Exposed CodeGraph.findNodesByNameSubstring publicly so this can be reached through the public API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Multi-word field-name queries (e.g.
profileInfo isTrialEligible quotaInfo billingMethod) used to return 134 unrelated symbols andbury the defining controller and service files under a dense neighbor.
Three compounding retrieval bugs were dead on JS/TS/Ruby/Python
service-layer codebases, where the camel-infix definer of a business
field is a method, not a class.
Root causes
context builder 5b (CamelCase-boundary LIKE) used
name.indexOf(titleCased)aftertitleCased.toLowerCase(), soa multi-hump token ("Profileinfo") could never
indexOfinto"getProfileInfoV2". The SQL layer matched case-insensitively; the
JS boundary check silently re-tightened that and dropped the row.
context builder 5b AND 5c restricted the LIKE batch to declaration
kinds (class/interface/struct/trait/protocol/enum/type_alias), so on
a method-centric codebase they contributed nothing. Single-word
tokens like "search" → "Search" were unaffected because they
don't go through the LIKE path the same way; this is why the bug
wasn't caught during tuning.
explore's named-symbol seeding was exact-name only. A field-name
token (
profileInfo) has no node of its own, so it contributedzero seeds: no
+50file score, noentryFilesprotection, nonamed-file sort. The only surviving entry points were weak FTS
sub-token hits (camelCase split gives
quota,payment, …) anda depth-3 BFS from those dragged in a huge neighbor whose body
filled the render budget.
FTS can't cover this case by design: camelCase identifiers are single
FTS tokens, so
"profileinfo"*never matches an interior hump —that's what 5b/5c were built for, and they were disabled by (1)+(2).
Fix
boundary char itself is uppercase (so we still require a real hump).
(
function/method/component), merged before the boundaryfilter. Per-batch 200-row cap so a hot single-word term can't crowd
classes out of the length-ordered batch.
findCamelInfixCallables(cg, token)— a LIKE-based fallback thataccepts prefix or camel-hump boundary matches on method/function/
component kinds, case-insensitive. Fires only when the exact
lookup yields no callable, so well-named queries are unaffected.
Exposed
CodeGraph.findNodesByNameSubstringpublicly so this canbe reached through the public API.
Validation
__tests__/context-multi-word-fields.test.tsbuilds a mini service-layer JS repo (controller/profileController.js
with
getProfileInfo/getProfileInfoV2, service/billing.js with_getCustomerBillingMethods) and asserts:getProfileInfoV2from aprofileInfotoken_getCustomerBillingMethodsfor a
billingMethodtokenmethods in the same call
profileinfomatchesgetProfileInfoByName(true hump) but NOTreprofileinfoBogus(mid-word lowercase run)
context-ranking.test.ts(4),context.test.ts(17),explore-result-count.test.ts,explore-output-budget.test.ts,adaptive-explore-sizing.test.ts,explore-corroboration-ranking.test.ts,explore-blast-radius.test.ts— 63 tests — all still pass.Reproduction
Before: 134 symbols across 26 files; defining files
controller/profileController.jsandservice/billing.jsabsent.After: those two files rank at the top.
Closes #1196