Skip to content

fix(extraction): detect export-macro-annotated class in .h language check#1133

Open
luoyxy wants to merge 1 commit into
colbymchenry:mainfrom
luoyxy:fix/cpp-export-macro-header-language-detection
Open

fix(extraction): detect export-macro-annotated class in .h language check#1133
luoyxy wants to merge 1 commit into
colbymchenry:mainfrom
luoyxy:fix/cpp-export-macro-header-language-detection

Conversation

@luoyxy

@luoyxy luoyxy commented Jul 2, 2026

Copy link
Copy Markdown

Summary

A .h file defaults to C and is only reclassified as C++ when looksLikeCpp finds a C++-specific construct. Its class branch (\bclass\s+\w+\s*[:{]) could not 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 trailing [:{] guard failed to match.

A lean Unreal-Engine header carrying only that macro-annotated 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 from the graph, quietly undoing the macro-class recovery from #1061.

This is a language-detection gap, distinct from #1061 (which correctly blanks the macro after the file is already routed as C++) — the file never reached the C++ path in the first place.

Fix

Add a detection branch to looksLikeCpp for a macro-annotated class/struct declaration, mirroring the exact shape blankCppExportMacros already recovers before parsing:

\b(?:class|struct)\s+[A-Z][A-Z0-9_]+\s+\w+\s*(?:final\s*)?[:{]

The two-token <keyword> <MACRO> <Name> before a [:{] never occurs in valid C, so genuine C headers are unaffected.

Repro (verified)

Header Before After
class ENGINE_API UFoo : public UObject (no other C++ signal) detected c, 0 class nodes detected cpp, 1 class node
Same header with public: present cpp (already worked) cpp

Test plan

  • New regression test in __tests__/extraction.test.ts (macro-class header detects as cpp; macro-struct with inheritance; plain C header still detects as c)
  • npm run build succeeds
  • No new failures vs. baseline in extraction.test.ts

Thanks for CodeGraph! Follow-up to #1061.

Made with Cursor


Fixes #1159.

luoyxy pushed a commit to luoyxy/codegraph that referenced this pull request Jul 2, 2026
…heck (colbymchenry#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 colbymchenry#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.
@luoyxy luoyxy force-pushed the fix/cpp-export-macro-header-language-detection branch from a5f5f50 to 2d7afb0 Compare July 2, 2026 18:00
…heck (colbymchenry#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 colbymchenry#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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UE-style single-line export-macro class headers (class ENGINE_API Foo : public Bar) are misdetected as C and their class definitions are dropped

1 participant