Exported generators were invisible to the code graph - #45
Merged
Conversation
`export function*` and `export async function*` produced no `function` symbol,
so 40 declarations across 17 files were absent from find_references,
analyze_impact and PKI retrieval. They are the streaming core — parseSse,
streamOpenAiSse, translateAnthropicStream, pullModelStream, parseThinkTags,
scanCode — so asking who calls any of them returned nothing, and an empty
result is indistinguishable from a symbol with no callers.
Both analyzers missed them, for unrelated reasons, which is why neither covered
for the other:
- tree-sitter parses `function*` as `generator_function_declaration`, its own
node type rather than a modifier on `function_declaration`, and only the
latter was mapped. Added for javascript/typescript/tsx/vue; deliberately NOT
for kotlin/swift, which have no such syntax and where the entry would be
inert and misleading.
- the regex fallback gated on `line.includes('function ')`, which is false for
`function*` — the star sits exactly where the space would be. Replaced with
an alternation requiring a name to be separated by whitespace or by the star,
so `functionfoo` still cannot match and `function(` still yields nothing.
GRAPH_VERSION 4 → 5. Same reasoning as the v4 bump for variable symbols: none
of the 17 files changed, and reconciliation is by content hash, so without it
an existing cache would serve a generator-free graph forever.
Found by auditing the four src files that still had zero symbols after the
truncation fix. Three were benign — two re-export barrels and a type-only
index — and the fourth was this. Mutation-checked: removing either analyzer's
fix fails three tests.
Class methods (`*iter()`) were already correct via method_definition.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
✅ All checks passed
Posted by SideCarAI-Bot |
This was referenced Aug 3, 2026
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.
export function*andexport async function*produced nofunctionsymbol.40 declarations across 17 files, absent from
find_references,analyze_impactand PKI retrieval.They are not incidental code — they are the streaming core:
Asking who calls any of them returned nothing, and an empty result is
indistinguishable from a symbol with no callers — the same property that let
221 exported constants stay invisible for the life of that feature.
Both analyzers missed it, for unrelated reasons
Which is why neither covered for the other:
function*parses asgenerator_function_declaration— its own node type, not a modifier onfunction_declaration. Only the latter was mapped.line.includes('function '), which is false forfunction*— the star sits exactly where the space would be.The tree-sitter mapping was added for javascript/typescript/tsx/vue and
deliberately not for kotlin/swift, which have no generator syntax and where
the entry would be inert and misleading. My first pass added it to all six by a
too-loose anchor; caught before commit.
The regex replacement requires a name to be separated by whitespace or by
the star, so
functionfoostill cannot match andfunction(still yieldsnothing — both pinned by tests.
Cache invalidation
GRAPH_VERSION4 → 5. Same reasoning as the v4 bump for variable symbols: noneof the 17 files changed, and reconciliation is by content hash, so without the
bump an existing cache would serve a generator-free graph forever.
How it was found
By auditing the four
srcfiles that still had zero symbols after thetruncation fix (#40) landed. Three were benign — two re-export barrels
(
export * from,export { X } from) and a type-only index — and legitimatelyown no symbols. The fourth was this.
Worth noting the truncation fix is what made this visible: while ~35 files were
being dropped per index run at random, a file with no symbols was unremarkable.
Verified
Against the real parser, not by reading the grammar:
And on real files:
translateAnthropicStream,parseThinkTags,scanCode,pullModelStreamall now extract.Mutation-checked: removing either analyzer's fix fails three tests.
npm run check: 8619 passed, 2 skipped, 464 files.🤖 Generated with Claude Code