fix(extraction): detect export-macro-annotated class in .h language check (#1159)#1207
Merged
Merged
Conversation
…heck (#1133) A `.h` file defaults to C and is reclassified as C++ only when `looksLikeCpp` finds a C++-specific construct. Its class branch (`\bclass\s+\w+\s*[:{]`) couldn't see through an export/visibility macro: in `class ENGINE_API UFoo : public UObject` the macro sits between `class` and the type name, so `\w+` consumed the macro and the following `[:{]` guard failed. A lean Unreal-Engine header carrying only that macro-class plus `GENERATED_BODY()` — with no `public:` / `virtual` / `namespace` / `template` to fall back on — was therefore parsed as C. The C extractor has `classTypes: []` and no export-macro pre-parse, so the class definition and its inheritance edge silently vanished, undoing the macro-class recovery from #1061. Add a detection branch for a macro-annotated `class`/`struct` declaration, mirroring the shape `blankCppExportMacros` already recovers before parsing. The two-token `<keyword> <MACRO> <Name>` before a `[:{]` never occurs in valid C, so genuine C headers stay classified as C (covered by a new regression guard). Thanks @luoyxy for the report and root-cause analysis.
3 tasks
pull Bot
pushed a commit
to TheTechOddBug/codegraph
that referenced
this pull request
Jul 7, 2026
…heck (colbymchenry#1159) (colbymchenry#1207) Carries colbymchenry#1133 forward onto current main (rebased for conflicts). A lean Unreal-Engine-style `.h` whose only C++ signal is `class ENGINE_API Foo : public Bar` (no public:/virtual/namespace/template) was misdetected as C and its class + inheritance edge silently dropped; looksLikeCpp now recognizes the export-macro-annotated class/struct shape, matching what blankCppExportMacros already recovers. Fixes colbymchenry#1159. Co-Authored-By: robertyluo <robertyluo@tencent.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Carries @luoyxy's #1133 forward onto current
main(rebased to resolve conflicts with the UE work — #1158 and the #1206 dense-header guard — that landed after #1133 was opened; the fix itself ingrammars.tswas unchanged and auto-merged).Fixes #1159.
The bug
A
.hfile defaults to C and is only reclassified as C++ whenlooksLikeCppfinds a C++-specific construct. That check couldn't see through an export/visibility macro: inclass ENGINE_API UFoo : public UObjectthe macro sits betweenclassand the type name, so the macro-blind\bclass\s+\w+\s*[:{]branch failed to match. A lean Unreal-Engine header carrying only that macro-annotated class plusGENERATED_BODY()— nopublic:/virtual/namespace/templateto fall back on — was therefore parsed as C. The C extractor hasclassTypes: []and no export-macro pre-parse, so the class definition and its inheritance edge silently vanished, quietly undoing the macro-class recovery from #1061.Note: the issue's literal minimal repro has a
public:inside the body, which already trips the existing heuristic → detectscpp. The true failing shape is the lean header (no other C++ signal), which this PR targets.The fix
One alternation branch added to
looksLikeCpp, mirroring the exact shapeblankCppExportMacrosalready recovers:The macro shape
[A-Z][A-Z0-9_]+is identical toblankCppExportMacros(c-cpp.ts) — so the exact set of headers this routes tocppis precisely the set the C++ path then recovers (no "routes to cpp but still collapses" gap). The two-token<keyword> <MACRO> <Name>before a[:{]never occurs in valid C, so genuine C headers are unaffected.Verified (on current
main).h)class ENGINE_API UFoo : public UObject+GENERATED_BODY(), nopublic:c❌cpp✓struct ENGINE_API FBar : public FBase {};c❌cpp✓class MYMODULE_API FFoo{(brace next line, no base)c❌cpp✓struct Point {…},struct FOO bar;,struct FOO getFoo(){,enum COLOR{…},struct FOO x = {5},typedef struct FOO T;)cc✓ (unchanged)Test plan
__tests__/extraction.test.ts(macro class, macro struct w/ inheritance, brace-next-line, plus a genuine-C guard)npx vitest run __tests__/extraction.test.ts— 579 passednpx tsc --noEmitclean🤖 Generated with Claude Code