mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-18 22:02:49 +08:00
235387ec42
`struct Foo { … } foo;`, `class Bar { … } bar;` and `static struct { … } SPT;`
outside any function or class body went to the variable extractor, which
skipped the declaration's children, so the type, its methods and its
enumerators were never indexed in either extraction engine.
Both engines now walk such a type before the variables: in C always, and in
C++ when the tree has no errors or the file is walked in brace scopes. This
converges with #2426's walk for erroring C++ files; a C++ file whose braces
don't balance is still left alone, since error recovery can run a class past
its own `}` there. The declaration's function-as-value scan skips the walked
type, which captured its own. An unnamed struct, union or enum takes the name
of the first variable its declaration declares (also inside function bodies,
where it was `<anonymous>`), as `typedef struct { … } Name;` already takes the
typedef name, and the comment above the declaration is the type's docstring.
cDeclaratorIdentifier moves to languages/c-cpp.ts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
158 lines
3.5 KiB
C++
158 lines
3.5 KiB
C++
/// Torture fixture for the C++ kernel walker (R7a) — namespaces (incl. C++17
|
|
/// nested + anonymous), out-of-line Cls::method defs, templates + template
|
|
/// bases, operator definitions, stack construction, local fn-ptrs, UE-macro
|
|
/// shapes THROUGH the hoisted preParse, using-aliases, access specifiers,
|
|
/// static-member value reads, and the cpp call shapes. Must parse ERROR-FREE
|
|
/// post-preParse or the kernel arm defers (spaced operator CALL SITES live in
|
|
/// torture-defer.cpp — they produce ERROR nodes by design).
|
|
#include <vector>
|
|
#include "widget_base.hpp"
|
|
|
|
namespace app {
|
|
|
|
/** Engine config (docstring). */
|
|
class Config {
|
|
public:
|
|
int retries;
|
|
void apply();
|
|
int helper_count() const { return 2; }
|
|
|
|
private:
|
|
int secret;
|
|
};
|
|
|
|
void Config::apply() { retries = helper_count(); }
|
|
|
|
namespace detail {
|
|
struct Counter {
|
|
int value;
|
|
Counter *next;
|
|
};
|
|
} // namespace detail
|
|
|
|
int detail_probe() { return 1; }
|
|
|
|
} // namespace app
|
|
|
|
namespace app::net {
|
|
class Session {
|
|
public:
|
|
void open();
|
|
virtual ~Session() {}
|
|
// #1727 — pure virtual must mint a method node (parity between wasm + kernel).
|
|
virtual int read(int key) = 0;
|
|
};
|
|
void Session::open() {}
|
|
} // namespace app::net
|
|
|
|
namespace {
|
|
int hidden_helper() { return 3; }
|
|
} // namespace
|
|
|
|
template <typename T>
|
|
class Base {
|
|
public:
|
|
T item;
|
|
};
|
|
|
|
template <typename T>
|
|
class Box : public Base<T> {
|
|
public:
|
|
T get() const { return value_; }
|
|
T unwrap();
|
|
|
|
private:
|
|
T value_;
|
|
};
|
|
|
|
template <typename T>
|
|
T Box<T>::unwrap() {
|
|
return value_;
|
|
}
|
|
|
|
class Derived : public Base<int>, private app::Config {
|
|
public:
|
|
Derived() : total_(0) {}
|
|
int total() const { return total_; }
|
|
|
|
private:
|
|
int total_;
|
|
};
|
|
|
|
struct Vec2 {
|
|
float x, y;
|
|
Vec2 operator+(const Vec2 &o) const { return {x + o.x, y + o.y}; }
|
|
explicit operator bool() const { return x != 0 || y != 0; }
|
|
Vec2 origin();
|
|
};
|
|
|
|
enum class Mode : unsigned char { Off, On };
|
|
enum Legacy { LEGACY_A, LEGACY_B };
|
|
typedef struct {
|
|
int id;
|
|
} packet_t;
|
|
using Handle = app::Config;
|
|
|
|
// UE-macro shapes — every one below is recovered by the hoisted preParse
|
|
// (export macro, reflection markup, inline specifier, API member prefix).
|
|
class MYMODULE_API Widget : public app::Config {
|
|
public:
|
|
UPROPERTY(EditAnywhere, Category = "State")
|
|
float Health;
|
|
FORCEINLINE float GetHealth() const { return Health; }
|
|
ENGINE_API virtual void Tick(float Delta);
|
|
};
|
|
|
|
void Widget::Tick(float Delta) { Health += Delta; }
|
|
|
|
Config GlobalConfig;
|
|
int build_number = 7;
|
|
|
|
// class/struct/union/enum definitions in a declaration's type — nodes beside
|
|
// the variables; an unnamed one takes its first variable's name
|
|
void on_open() {}
|
|
void on_close() {}
|
|
namespace decl_types {
|
|
/** The handler registry. */
|
|
struct Registry {
|
|
int size() const { return 2; }
|
|
void (*handlers[2])() = {&on_open, &on_close};
|
|
} registry;
|
|
class Bar { void g() {} } bar, *pbar;
|
|
static struct { int retries; } settings;
|
|
enum { kIdle, kBusy } state;
|
|
} // namespace decl_types
|
|
|
|
template <typename T>
|
|
T compute_seed(T v) {
|
|
return v + 1;
|
|
}
|
|
|
|
float drive_helper(float v) { return v; }
|
|
|
|
Widget *make_widget() { return new Widget(); }
|
|
|
|
float drive() {
|
|
Widget local;
|
|
app::Config cfg;
|
|
Vec2 a{1, 2};
|
|
Vec2 b(a);
|
|
Vec2 c2(1.5f, 2.5f);
|
|
float f = a.x + b.y + c2.x;
|
|
make_widget()->Tick(0.5f);
|
|
auto kernel = &compute_seed<float>;
|
|
if (f > 1) {
|
|
kernel = &drive_helper;
|
|
}
|
|
float r = kernel(f);
|
|
int flags = GlobalConfig.retries;
|
|
Mode m = Mode::Off;
|
|
int leg = LEGACY_A;
|
|
app::detail_probe();
|
|
compute_seed<int>(2);
|
|
auto mp = &app::Config::apply;
|
|
(void)mp;
|
|
(void)m;
|
|
return r + f + flags + leg;
|
|
}
|