651 lines
23 KiB
C
651 lines
23 KiB
C
#ifndef CBM_H
|
|
#define CBM_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "arena.h"
|
|
#include "tree_sitter/api.h"
|
|
|
|
// Language enum mirrors lang.Language in Go.
|
|
// Order must match lang_specs.c tables.
|
|
typedef enum {
|
|
CBM_LANG_GO = 0,
|
|
CBM_LANG_PYTHON,
|
|
CBM_LANG_JAVASCRIPT,
|
|
CBM_LANG_TYPESCRIPT,
|
|
CBM_LANG_TSX,
|
|
CBM_LANG_RUST,
|
|
CBM_LANG_JAVA,
|
|
CBM_LANG_CPP,
|
|
CBM_LANG_CSHARP,
|
|
CBM_LANG_PHP,
|
|
CBM_LANG_LUA,
|
|
CBM_LANG_SCALA,
|
|
CBM_LANG_KOTLIN,
|
|
CBM_LANG_RUBY,
|
|
CBM_LANG_C,
|
|
CBM_LANG_BASH,
|
|
CBM_LANG_ZIG,
|
|
CBM_LANG_ELIXIR,
|
|
CBM_LANG_HASKELL,
|
|
CBM_LANG_OCAML,
|
|
CBM_LANG_OBJC,
|
|
CBM_LANG_SWIFT,
|
|
CBM_LANG_DART,
|
|
CBM_LANG_PERL,
|
|
CBM_LANG_GROOVY,
|
|
CBM_LANG_ERLANG,
|
|
CBM_LANG_R,
|
|
CBM_LANG_HTML,
|
|
CBM_LANG_CSS,
|
|
CBM_LANG_SCSS,
|
|
CBM_LANG_YAML,
|
|
CBM_LANG_TOML,
|
|
CBM_LANG_HCL,
|
|
CBM_LANG_SQL,
|
|
CBM_LANG_DOCKERFILE,
|
|
// New languages (v0.5 expansion)
|
|
CBM_LANG_CLOJURE,
|
|
CBM_LANG_FSHARP,
|
|
CBM_LANG_JULIA,
|
|
CBM_LANG_VIMSCRIPT,
|
|
CBM_LANG_NIX,
|
|
CBM_LANG_COMMONLISP,
|
|
CBM_LANG_ELM,
|
|
CBM_LANG_FORTRAN,
|
|
CBM_LANG_CUDA,
|
|
CBM_LANG_COBOL,
|
|
CBM_LANG_VERILOG,
|
|
CBM_LANG_EMACSLISP,
|
|
CBM_LANG_JSON,
|
|
CBM_LANG_XML,
|
|
CBM_LANG_MARKDOWN,
|
|
CBM_LANG_MAKEFILE,
|
|
CBM_LANG_CMAKE,
|
|
CBM_LANG_PROTOBUF,
|
|
CBM_LANG_GRAPHQL,
|
|
CBM_LANG_VUE,
|
|
CBM_LANG_SVELTE,
|
|
CBM_LANG_MESON,
|
|
CBM_LANG_GLSL,
|
|
CBM_LANG_INI,
|
|
// Scientific/math languages
|
|
CBM_LANG_MATLAB,
|
|
CBM_LANG_LEAN,
|
|
CBM_LANG_FORM,
|
|
CBM_LANG_MAGMA,
|
|
CBM_LANG_WOLFRAM,
|
|
CBM_LANG_SOLIDITY,
|
|
CBM_LANG_TYPST,
|
|
CBM_LANG_GDSCRIPT,
|
|
CBM_LANG_GLEAM,
|
|
CBM_LANG_POWERSHELL,
|
|
CBM_LANG_PASCAL,
|
|
CBM_LANG_DLANG,
|
|
CBM_LANG_NIM,
|
|
CBM_LANG_SCHEME,
|
|
CBM_LANG_FENNEL,
|
|
CBM_LANG_FISH,
|
|
CBM_LANG_AWK,
|
|
CBM_LANG_ZSH,
|
|
CBM_LANG_TCL,
|
|
CBM_LANG_ADA,
|
|
CBM_LANG_AGDA,
|
|
CBM_LANG_RACKET,
|
|
CBM_LANG_ODIN,
|
|
CBM_LANG_RESCRIPT,
|
|
CBM_LANG_PURESCRIPT,
|
|
CBM_LANG_NICKEL,
|
|
CBM_LANG_CRYSTAL,
|
|
CBM_LANG_TEAL,
|
|
CBM_LANG_HARE,
|
|
CBM_LANG_PONY,
|
|
CBM_LANG_LUAU,
|
|
CBM_LANG_JANET,
|
|
CBM_LANG_SWAY,
|
|
CBM_LANG_NASM,
|
|
CBM_LANG_ASSEMBLY,
|
|
CBM_LANG_ASTRO,
|
|
CBM_LANG_BLADE,
|
|
CBM_LANG_JUST,
|
|
CBM_LANG_GOTEMPLATE,
|
|
CBM_LANG_TEMPL,
|
|
CBM_LANG_LIQUID,
|
|
CBM_LANG_JINJA2,
|
|
CBM_LANG_PRISMA,
|
|
CBM_LANG_HYPRLANG,
|
|
CBM_LANG_DOTENV,
|
|
CBM_LANG_DIFF,
|
|
CBM_LANG_WGSL,
|
|
CBM_LANG_KDL,
|
|
CBM_LANG_JSON5,
|
|
CBM_LANG_JSONNET,
|
|
CBM_LANG_RON,
|
|
CBM_LANG_THRIFT,
|
|
CBM_LANG_CAPNP,
|
|
CBM_LANG_PROPERTIES,
|
|
CBM_LANG_SSHCONFIG,
|
|
CBM_LANG_BIBTEX,
|
|
CBM_LANG_STARLARK,
|
|
CBM_LANG_BICEP,
|
|
CBM_LANG_CSV,
|
|
CBM_LANG_REQUIREMENTS,
|
|
CBM_LANG_HLSL,
|
|
CBM_LANG_VHDL,
|
|
CBM_LANG_SYSTEMVERILOG,
|
|
CBM_LANG_DEVICETREE,
|
|
CBM_LANG_LINKERSCRIPT,
|
|
CBM_LANG_GN,
|
|
CBM_LANG_KCONFIG,
|
|
CBM_LANG_BITBAKE,
|
|
CBM_LANG_SMALI,
|
|
CBM_LANG_TABLEGEN,
|
|
CBM_LANG_ISPC,
|
|
CBM_LANG_CAIRO,
|
|
CBM_LANG_MOVE,
|
|
CBM_LANG_SQUIRREL,
|
|
CBM_LANG_FUNC,
|
|
CBM_LANG_REGEX,
|
|
CBM_LANG_JSDOC,
|
|
CBM_LANG_RST,
|
|
CBM_LANG_BEANCOUNT,
|
|
CBM_LANG_MERMAID,
|
|
CBM_LANG_PUPPET,
|
|
CBM_LANG_PO,
|
|
CBM_LANG_GITATTRIBUTES,
|
|
CBM_LANG_GITIGNORE,
|
|
CBM_LANG_SLANG,
|
|
CBM_LANG_LLVM_IR,
|
|
CBM_LANG_SMITHY,
|
|
CBM_LANG_WIT,
|
|
CBM_LANG_TLAPLUS,
|
|
CBM_LANG_PKL,
|
|
CBM_LANG_GOMOD,
|
|
CBM_LANG_APEX,
|
|
CBM_LANG_SOQL,
|
|
CBM_LANG_SOSL,
|
|
CBM_LANG_KUSTOMIZE, // kustomization.yaml — Kubernetes overlay tool
|
|
CBM_LANG_K8S, // Generic Kubernetes manifest (apiVersion: detected)
|
|
CBM_LANG_PINE, // Pine Script (TradingView indicator / strategy language)
|
|
CBM_LANG_QML, // Qt QML (Qt Modeling Language — declarative UI + embedded JS)
|
|
CBM_LANG_CFSCRIPT, // CFML script dialect (.cfc components — Lucee/ColdFusion)
|
|
CBM_LANG_CFML, // CFML tag dialect (.cfm templates — Lucee/ColdFusion)
|
|
CBM_LANG_MOJO, // Mojo
|
|
CBM_LANG_COUNT
|
|
} CBMLanguage;
|
|
|
|
// --- Extraction result structs ---
|
|
|
|
typedef struct {
|
|
const char *name; // short name
|
|
const char *qualified_name; // project.path.name
|
|
const char *label; // "Function", "Method", "Class", "Variable", "Module"
|
|
const char *file_path; // relative path
|
|
uint32_t start_line;
|
|
uint32_t end_line;
|
|
const char *signature; // parameter text (NULL if none)
|
|
const char *return_type; // return type text (NULL if none)
|
|
const char *receiver; // Go method receiver (NULL if none)
|
|
const char *docstring; // leading doc comment (NULL if none)
|
|
const char *parent_class; // enclosing class QN for methods (NULL if none)
|
|
const char **decorators; // NULL-terminated array (NULL if none)
|
|
const char **base_classes; // NULL-terminated array (NULL if none)
|
|
const char **param_names; // NULL-terminated array (NULL if none)
|
|
const char **param_types; // NULL-terminated array (NULL if none)
|
|
const char **return_types; // NULL-terminated array (NULL if none)
|
|
const char *route_path; // HTTP route path from decorator (e.g., "/api/users") or NULL
|
|
const char *route_method; // HTTP method from decorator (e.g., "POST") or NULL
|
|
int complexity; // cyclomatic complexity
|
|
int cognitive; // cognitive complexity (nesting-weighted)
|
|
int loop_count; // number of loop constructs in the body
|
|
int loop_depth; // max nested-loop depth (bottleneck proxy)
|
|
bool is_recursive; // body contains a direct self-call (seed for "recursive")
|
|
int param_count; // number of parameters (large = complexity smell)
|
|
int max_access_depth; // deepest chained member/subscript access (a.b.c.d)
|
|
int linear_scan_in_loop; // count of linear-scan calls (find/contains/indexOf) inside loops
|
|
int alloc_in_loop; // count of allocation/append calls inside loops
|
|
bool recursion_in_loop; // a self-call occurs inside a loop body
|
|
bool unguarded_recursion; // recursive with no self-call guarded by a conditional
|
|
int lines; // body line count
|
|
uint32_t *fingerprint; // MinHash fingerprint (arena-allocated, K values) or NULL
|
|
int fingerprint_k; // number of hash values (CBM_MINHASH_K or 0)
|
|
bool is_exported;
|
|
bool is_abstract;
|
|
bool is_test;
|
|
bool is_entry_point;
|
|
const char *structural_profile; // AST structural profile (arena-allocated) or NULL
|
|
const char *body_tokens; // space-separated raw identifier tokens from body (arena) or NULL
|
|
} CBMDefinition;
|
|
|
|
/* Argument captured from a call expression */
|
|
typedef struct {
|
|
const char *expr; // raw expression text ("payload.info", "MY_URL", "'hello'")
|
|
const char *value; // resolved string value or NULL (constant propagation)
|
|
const char *keyword; // keyword name if keyword arg ("url", "topic_id"), NULL if positional
|
|
int index; // positional index (0-based)
|
|
} CBMCallArg;
|
|
|
|
#define CBM_MAX_CALL_ARGS 8
|
|
|
|
typedef struct {
|
|
const char *callee_name; // raw callee text ("pkg.Func", "foo")
|
|
const char *enclosing_func_qn; // QN of enclosing function (or module QN)
|
|
const char *first_string_arg; // first string literal argument (URL, topic, key) or NULL
|
|
const char *second_arg_name; // second argument identifier (handler ref) or NULL
|
|
CBMCallArg args[CBM_MAX_CALL_ARGS]; // first N arguments with expressions
|
|
int arg_count; // number of captured arguments
|
|
int loop_depth; // enclosing loop nesting at the call site
|
|
int branch_depth; // enclosing branch nesting at the call site
|
|
int start_line; // 1-based source line of the call (for def range-match)
|
|
bool is_method; // method/member call with a non-self receiver. Perl:
|
|
// arrow/method call ($obj->m). TS/JS/TSX: member call
|
|
// x.foo() whose receiver is not this/super. Default false.
|
|
} CBMCall;
|
|
|
|
typedef struct {
|
|
const char *local_name; // local alias or name
|
|
const char *module_path; // resolved module path / QN
|
|
} CBMImport;
|
|
|
|
typedef struct {
|
|
const char *ref_name; // referenced identifier
|
|
const char *enclosing_func_qn; // QN of enclosing function (or module QN)
|
|
} CBMUsage;
|
|
|
|
typedef struct {
|
|
const char *exception_name; // exception class/type name
|
|
const char *enclosing_func_qn; // QN of enclosing function
|
|
} CBMThrow;
|
|
|
|
typedef struct {
|
|
const char *var_name; // variable name
|
|
const char *enclosing_func_qn; // QN of enclosing function
|
|
bool is_write; // true = write, false = read
|
|
} CBMReadWrite;
|
|
|
|
typedef struct {
|
|
const char *type_name; // referenced type/class name
|
|
const char *enclosing_func_qn; // QN of enclosing function
|
|
} CBMTypeRef;
|
|
|
|
typedef struct {
|
|
const char *env_key; // environment variable key
|
|
const char *enclosing_func_qn; // QN of enclosing function
|
|
} CBMEnvAccess;
|
|
|
|
typedef struct {
|
|
const char *var_name; // variable being assigned
|
|
const char *type_name; // class/type name of RHS constructor
|
|
const char *enclosing_func_qn; // QN of enclosing function
|
|
} CBMTypeAssign;
|
|
|
|
// String reference: URL, config key, or async target found in source.
|
|
// Extracted from string literals during AST walk.
|
|
typedef enum {
|
|
CBM_STRREF_URL = 0, // REST path or full URL
|
|
CBM_STRREF_CONFIG = 1, // config file path or env var key
|
|
} CBMStringRefKind;
|
|
|
|
typedef struct {
|
|
const char *value; // the string literal content
|
|
const char *enclosing_func_qn; // QN of enclosing function
|
|
const char *key_path; // dotted key path from YAML/JSON nesting (NULL if flat)
|
|
CBMStringRefKind kind; // URL, CONFIG
|
|
} CBMStringRef;
|
|
|
|
/* Infrastructure binding: topic/queue → endpoint URL.
|
|
* Extracted from YAML/HCL/JSON subscription/scheduler configs.
|
|
* Used by pass_route_nodes to connect async Route nodes to handler services. */
|
|
typedef struct {
|
|
const char *source_name; // topic, queue, or schedule name
|
|
const char *target_url; // push_endpoint, uri, or http_target URL
|
|
const char *broker; // "pubsub", "cloud_tasks", "cloud_scheduler", "sqs", "kafka"
|
|
} CBMInfraBinding;
|
|
|
|
/* Pub/sub channel participation. One record per emit() or on()/addListener()
|
|
* call detected in source — the receiver (e.g. Socket.IO client, EventEmitter
|
|
* instance) is intentionally NOT identified; matching is by channel_name
|
|
* across files, which captures the common pattern of one logical bus per
|
|
* service. Transport disambiguates Socket.IO vs EventEmitter vs future
|
|
* detectors (Kafka, Cloud Pub/Sub, etc.). */
|
|
typedef enum {
|
|
CBM_CHANNEL_EMIT = 0,
|
|
CBM_CHANNEL_LISTEN = 1,
|
|
} CBMChannelDirection;
|
|
|
|
typedef struct {
|
|
const char *channel_name; // literal channel name (e.g. "user.created")
|
|
const char *transport; // "socketio", "event_emitter", ...
|
|
const char *enclosing_func_qn; // QN of the function containing the emit/on call
|
|
CBMChannelDirection direction;
|
|
} CBMChannel;
|
|
|
|
// Rust: impl Trait for Struct
|
|
typedef struct {
|
|
const char *trait_name; // trait name (raw text)
|
|
const char *struct_name; // struct/type name (raw text)
|
|
} CBMImplTrait;
|
|
|
|
// LSP-resolved call: high-confidence type-aware call resolution
|
|
typedef struct {
|
|
const char *caller_qn; // enclosing function QN
|
|
const char *callee_qn; // resolved target QN (fully qualified)
|
|
const char *strategy; // "lsp_type_dispatch", "lsp_direct", etc.
|
|
float confidence; // 0.90-0.95
|
|
const char *reason; // diagnostic label for unresolved calls (NULL if resolved)
|
|
} CBMResolvedCall;
|
|
|
|
typedef struct {
|
|
CBMResolvedCall *items;
|
|
int count;
|
|
int cap;
|
|
} CBMResolvedCallArray;
|
|
|
|
// Growable arrays used during extraction.
|
|
typedef struct {
|
|
CBMDefinition *items;
|
|
int count;
|
|
int cap;
|
|
} CBMDefArray;
|
|
|
|
typedef struct {
|
|
CBMCall *items;
|
|
int count;
|
|
int cap;
|
|
} CBMCallArray;
|
|
|
|
typedef struct {
|
|
CBMImport *items;
|
|
int count;
|
|
int cap;
|
|
} CBMImportArray;
|
|
|
|
typedef struct {
|
|
CBMUsage *items;
|
|
int count;
|
|
int cap;
|
|
} CBMUsageArray;
|
|
|
|
typedef struct {
|
|
CBMThrow *items;
|
|
int count;
|
|
int cap;
|
|
} CBMThrowArray;
|
|
|
|
typedef struct {
|
|
CBMReadWrite *items;
|
|
int count;
|
|
int cap;
|
|
} CBMRWArray;
|
|
|
|
typedef struct {
|
|
CBMTypeRef *items;
|
|
int count;
|
|
int cap;
|
|
} CBMTypeRefArray;
|
|
|
|
typedef struct {
|
|
CBMEnvAccess *items;
|
|
int count;
|
|
int cap;
|
|
} CBMEnvAccessArray;
|
|
|
|
typedef struct {
|
|
CBMTypeAssign *items;
|
|
int count;
|
|
int cap;
|
|
} CBMTypeAssignArray;
|
|
|
|
typedef struct {
|
|
CBMStringRef *items;
|
|
int count;
|
|
int cap;
|
|
} CBMStringRefArray;
|
|
|
|
typedef struct {
|
|
CBMInfraBinding *items;
|
|
int count;
|
|
int cap;
|
|
} CBMInfraBindingArray;
|
|
|
|
typedef struct {
|
|
CBMImplTrait *items;
|
|
int count;
|
|
int cap;
|
|
} CBMImplTraitArray;
|
|
|
|
typedef struct {
|
|
CBMChannel *items;
|
|
int count;
|
|
int cap;
|
|
} CBMChannelArray;
|
|
|
|
// Full extraction result for one file.
|
|
typedef struct {
|
|
CBMArena arena; // owns all string memory
|
|
|
|
CBMDefArray defs;
|
|
CBMCallArray calls;
|
|
CBMImportArray imports;
|
|
CBMUsageArray usages;
|
|
CBMThrowArray throws;
|
|
CBMRWArray rw;
|
|
CBMTypeRefArray type_refs;
|
|
CBMEnvAccessArray env_accesses;
|
|
CBMTypeAssignArray type_assigns;
|
|
CBMImplTraitArray impl_traits; // Rust: impl Trait for Struct pairs
|
|
CBMResolvedCallArray resolved_calls; // LSP-resolved calls (high confidence)
|
|
CBMStringRefArray string_refs; // URL/config string literals from AST
|
|
CBMInfraBindingArray infra_bindings; // topic→URL pairs from IaC configs
|
|
CBMChannelArray channels; // Socket.IO / EventEmitter pub/sub participation
|
|
|
|
const char *module_qn; // module qualified name
|
|
const char *namespace_name; // declared namespace/package (Java/Kotlin/C#/PHP), NULL if none
|
|
const char **exports; // NULL-terminated (NULL if none)
|
|
const char **constants; // NULL-terminated (NULL if none)
|
|
const char **global_vars; // NULL-terminated (NULL if none)
|
|
const char **macros; // NULL-terminated, C/C++ only (NULL if none)
|
|
|
|
bool has_error;
|
|
const char *error_msg;
|
|
/* Best-effort parse-coverage signal (experimental). parse_incomplete is true
|
|
* when the parse tree contains tree-sitter ERROR/MISSING nodes — constructs
|
|
* in those regions are silently absent from the graph. error_ranges is a
|
|
* compact "start-end,start-end" list of 1-based line ranges (arena-owned) or
|
|
* NULL. This only marks what we can DETECT: the absence of a flag is NOT a
|
|
* completeness guarantee. Callers should treat a flagged file as "prefer
|
|
* grep here", never treat an unflagged file as provably complete. */
|
|
bool parse_incomplete;
|
|
const char *error_ranges;
|
|
int error_region_count;
|
|
bool is_test_file;
|
|
int imports_count;
|
|
TSTree *cached_tree; // retained parse tree (caller frees via cbm_free_tree)
|
|
CBMLanguage cached_lang; // language of cached tree (for parser selection)
|
|
|
|
// Retained source bytes — copied into `arena` by the parallel
|
|
// extract pass so the fused cross-file LSP step in resolve_worker
|
|
// can run without re-reading the file from disk. NULL when the
|
|
// file exceeded the per-file (100 MB) or total (2 GB) retention
|
|
// cap; in that case the cross-file LSP step is skipped for this
|
|
// file (defs/calls already extracted are unaffected).
|
|
const char *source;
|
|
int source_len;
|
|
} CBMFileResult;
|
|
|
|
// --- Enclosing function cache ---
|
|
// Avoids repeated parent-chain walks for nodes within the same function body.
|
|
// Each entry records a function's byte range and its precomputed QN.
|
|
#define EFC_SIZE 64 // power of 2 for fast modulo
|
|
|
|
typedef struct {
|
|
uint32_t start_byte;
|
|
uint32_t end_byte;
|
|
const char *qn;
|
|
} EFCEntry;
|
|
|
|
typedef struct {
|
|
EFCEntry entries[EFC_SIZE];
|
|
int count;
|
|
} EFCache;
|
|
|
|
// --- Extraction context passed to sub-extractors ---
|
|
|
|
// Module-level string constant map (for constant propagation)
|
|
#define CBM_MAX_STRING_CONSTANTS 256
|
|
typedef struct {
|
|
const char *names[CBM_MAX_STRING_CONSTANTS];
|
|
const char *values[CBM_MAX_STRING_CONSTANTS];
|
|
int count;
|
|
} CBMStringConstantMap;
|
|
|
|
typedef struct {
|
|
CBMArena *arena;
|
|
CBMFileResult *result;
|
|
const char *source;
|
|
int source_len;
|
|
CBMLanguage language;
|
|
const char *project;
|
|
const char *rel_path;
|
|
const char *module_qn;
|
|
TSNode root;
|
|
EFCache ef_cache; // enclosing function cache
|
|
const char *enclosing_class_qn; // for nested class QN computation
|
|
CBMStringConstantMap string_constants; // module-level NAME = "value" pairs
|
|
} CBMExtractCtx;
|
|
|
|
// --- Public API ---
|
|
|
|
// Bind third-party allocators (tree-sitter, sqlite3) to mimalloc as
|
|
// defense-in-depth, so they never depend on the fragile MI_OVERRIDE symbol
|
|
// override (#424). MUST be called as the very first statement of main(), before
|
|
// any sqlite3_open*/sqlite3_initialize (SQLITE_CONFIG_MALLOC returns
|
|
// SQLITE_MISUSE once sqlite has initialized).
|
|
// Idempotent (static guard); intended for single-threaded startup. cbm_init()
|
|
// also calls it so non-main entry points (pipeline passes) still get the binds.
|
|
// In the test build (no CBM_BIND_TS_ALLOCATOR) this is a no-op.
|
|
void cbm_alloc_init(void);
|
|
|
|
// Initialize the library. Call once at startup. Returns 0 on success.
|
|
int cbm_init(void);
|
|
|
|
// True when rel_path is in the crash-quarantine set — the newline-delimited list
|
|
// of files (CBM_INDEX_QUARANTINE_FILE) the crash supervisor pinned as crashers
|
|
// during its single-threaded recovery re-run. Loaded once, lazily; read-only
|
|
// after load. cbm_extract_file short-circuits such files to an empty result so no
|
|
// pass can crash on them; the pipeline extract loops call this to also REPORT the
|
|
// skip as phase="crash". Always false (cheap no-op) when the env var is unset.
|
|
bool cbm_index_is_quarantined(const char *rel_path);
|
|
|
|
// Phase a quarantined file was pinned under: "crash" (a fault signal) or "hang"
|
|
// (killed for making no progress). Returns NULL when rel_path is not quarantined.
|
|
// Drives the same lazy once-load as cbm_index_is_quarantined. Used by the pipeline
|
|
// extract loops to report the skip's phase in skipped[] (falls back to "crash").
|
|
const char *cbm_index_quarantine_phase(const char *rel_path);
|
|
|
|
// Crash-supervisor marker journal (parallel-safe): appends "S <rel_path>" /
|
|
// "D <rel_path>" to CBM_INDEX_MARKER_FILE. Files with an S but no D form the
|
|
// parent's crash/hang suspect set. No-ops when the env var is unset.
|
|
// cbm_extract_file journals its own start/done; long-running per-file phases
|
|
// (cross-LSP resolve) call these around their per-file work so a hang there
|
|
// is attributed to the RIGHT file instead of a stale extraction marker.
|
|
void cbm_index_mark_start(const char *rel_path);
|
|
void cbm_index_mark_done(const char *rel_path);
|
|
|
|
// Extract all data from one file. Caller must call cbm_free_result().
|
|
// source must remain valid for the duration of the call.
|
|
// timeout_micros: per-file parse timeout in microseconds (0 = no timeout).
|
|
CBMFileResult *cbm_extract_file(const char *source, int source_len, CBMLanguage language,
|
|
const char *project, const char *rel_path, int64_t timeout_micros,
|
|
const char **extra_defines, // NULL-terminated, or NULL
|
|
const char **include_paths // NULL-terminated, or NULL
|
|
);
|
|
|
|
// Free all memory associated with a result.
|
|
void cbm_free_result(CBMFileResult *result);
|
|
|
|
// Free only the cached tree from a result (caller retained it for reuse).
|
|
void cbm_free_tree(CBMFileResult *result);
|
|
|
|
// Free a standalone TSTree pointer (for Go layer cleanup).
|
|
void cbm_free_tree_ptr(TSTree *tree);
|
|
|
|
// Reset the thread-local parser's internal state, releasing slab-allocated
|
|
// subtrees. Must be called BEFORE cbm_slab_reset_thread() so the slab rebuild
|
|
// doesn't corrupt live parser state.
|
|
void cbm_reset_thread_parser(void);
|
|
|
|
// Destroy the thread-local parser. Call on worker thread exit.
|
|
void cbm_destroy_thread_parser(void);
|
|
|
|
// Shutdown the library. Call once at exit.
|
|
void cbm_shutdown(void);
|
|
|
|
// Profiling: get accumulated parse/extraction times and file count.
|
|
typedef struct {
|
|
uint64_t *parse_ns;
|
|
uint64_t *extract_ns;
|
|
uint64_t *files;
|
|
} cbm_profile_out_t;
|
|
void cbm_get_profile(cbm_profile_out_t out);
|
|
uint64_t cbm_get_lsp_ns(void);
|
|
uint64_t cbm_get_preprocess_ns(void);
|
|
uint64_t cbm_get_files_preprocessed(void);
|
|
void cbm_reset_profile(void);
|
|
|
|
// Toggle C/C++ preprocessor Macro-node extraction (#375). The pipeline enables
|
|
// it only for full/advanced index modes (it dominates extraction on macro-dense
|
|
// codebases). Default ON. Set before extraction; read-only during.
|
|
void cbm_set_macro_extraction(int enabled);
|
|
int cbm_macro_extraction_enabled(void);
|
|
|
|
// --- Internal helpers used by extractors ---
|
|
|
|
// Growable array push functions (arena-allocated, no individual free needed).
|
|
void cbm_defs_push(CBMDefArray *arr, CBMArena *a, CBMDefinition def);
|
|
void cbm_calls_push(CBMCallArray *arr, CBMArena *a, CBMCall call);
|
|
void cbm_imports_push(CBMImportArray *arr, CBMArena *a, CBMImport imp);
|
|
void cbm_usages_push(CBMUsageArray *arr, CBMArena *a, CBMUsage usage);
|
|
void cbm_throws_push(CBMThrowArray *arr, CBMArena *a, CBMThrow thr);
|
|
void cbm_rw_push(CBMRWArray *arr, CBMArena *a, CBMReadWrite rw);
|
|
void cbm_typerefs_push(CBMTypeRefArray *arr, CBMArena *a, CBMTypeRef tr);
|
|
void cbm_envaccess_push(CBMEnvAccessArray *arr, CBMArena *a, CBMEnvAccess ea);
|
|
void cbm_typeassign_push(CBMTypeAssignArray *arr, CBMArena *a, CBMTypeAssign ta);
|
|
void cbm_stringref_push(CBMStringRefArray *arr, CBMArena *a, CBMStringRef sr);
|
|
void cbm_infrabinding_push(CBMInfraBindingArray *arr, CBMArena *a, CBMInfraBinding ib);
|
|
void cbm_impltrait_push(CBMImplTraitArray *arr, CBMArena *a, CBMImplTrait it);
|
|
void cbm_resolvedcall_push(CBMResolvedCallArray *arr, CBMArena *a, CBMResolvedCall rc);
|
|
void cbm_channels_push(CBMChannelArray *arr, CBMArena *a, CBMChannel ch);
|
|
|
|
// --- Sub-extractor entry points ---
|
|
|
|
void cbm_extract_definitions(CBMExtractCtx *ctx);
|
|
void cbm_extract_imports(CBMExtractCtx *ctx);
|
|
void cbm_extract_usages(CBMExtractCtx *ctx);
|
|
void cbm_extract_semantic(CBMExtractCtx *ctx);
|
|
void cbm_extract_type_refs(CBMExtractCtx *ctx);
|
|
void cbm_extract_env_accesses(CBMExtractCtx *ctx);
|
|
void cbm_extract_type_assigns(CBMExtractCtx *ctx);
|
|
void cbm_extract_channels(CBMExtractCtx *ctx);
|
|
|
|
// Single-pass unified extraction (replaces the 7 calls above except defs+imports).
|
|
void cbm_extract_unified(CBMExtractCtx *ctx);
|
|
|
|
// K8s / Kustomize semantic extractor (called when language is CBM_LANG_K8S or CBM_LANG_KUSTOMIZE).
|
|
void cbm_extract_k8s(CBMExtractCtx *ctx);
|
|
|
|
// --- Label predicates ---
|
|
|
|
// True when `label` names a TYPE-LIKE container definition — a node that can own
|
|
// methods/fields, be a base/embedded type, satisfy/declare an interface, and be a
|
|
// target of name→type resolution. The canonical set is:
|
|
// Class, Struct, Interface, Enum, Type, Trait.
|
|
// Single source of truth for every type-resolution / registry-seeding /
|
|
// INHERITS·IMPLEMENTS / LSP-type-registrar consumer, so adding a new type-like
|
|
// label (e.g. "Struct" for Rust/Go/Swift/D structs) updates them all at once
|
|
// instead of scattering `|| strcmp(label,"Struct")==0` across the tree.
|
|
// `label` may be NULL (returns false). Defined in helpers.c.
|
|
bool cbm_label_is_type_like(const char *label);
|
|
|
|
#endif // CBM_H
|