Files
wehub-resource-sync 41cb1c0170
OpenSSF Scorecard / scorecard (push) Failing after 0s
DCO / dco (push) Failing after 0s
CodeQL SAST / analyze (push) Failing after 1s
Deploy Pages / deploy (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:28:05 +08:00

135 lines
5.2 KiB
C

#ifndef CBM_LSP_PHP_LSP_H
#define CBM_LSP_PHP_LSP_H
#include "type_rep.h"
#include "scope.h"
#include "type_registry.h"
#include "../cbm.h"
#include "go_lsp.h" /* CBMLSPDef reused across languages */
/* PHPLSPContext — per-file state for PHP type-aware call resolution.
* Mirrors GoLSPContext / CLSPContext structure. */
typedef struct {
CBMArena *arena;
const char *source;
int source_len;
const CBMTypeRegistry *registry;
CBMScope *current_scope;
/* Namespace state. PHP files declare a single namespace
* (or use the global namespace if none); empty string means global. */
const char *current_namespace_qn;
/* `use` clause map.
* use_kinds[i] selects whether the local maps a class, function, or const. */
const char **use_local_names;
const char **use_target_qns;
enum { CBM_PHP_USE_CLASS = 0, CBM_PHP_USE_FUNCTION, CBM_PHP_USE_CONST } *use_kinds;
int use_count;
int use_cap;
/* Current function/method/class context. */
const char *enclosing_func_qn;
const char *enclosing_class_qn; /* NULL outside class body */
const char *enclosing_parent_qn; /* parent class QN (for parent::), or NULL */
const char *module_qn;
/* Output: resolved calls accumulate here. */
CBMResolvedCallArray *resolved_calls;
/* @phpstan-type alias map (per-file, populated from class docblocks).
* Used by resolve_phpdoc_type before generic name resolution so user
* type aliases like `@phpstan-type UserId int|string` and references
* to `UserId` in @var/@param/@return all resolve to the aliased type.
*/
const char **phpstan_alias_names; /* arena-allocated, NULL-terminated */
const CBMType **phpstan_alias_types;
int phpstan_alias_count;
int phpstan_alias_cap;
/* Recursion guard for php_eval_expr_type. */
int eval_depth;
/* AST-walk recursion depth for php_resolve_calls_in_node (guards stack
* overflow on deeply-nested/cyclic files; see cbm_lsp_max_walk_depth).
* Zero via memset. */
int walk_depth;
/* Debug mode (CBM_LSP_DEBUG env). */
bool debug;
} PHPLSPContext;
/* Initialize a PHPLSPContext for processing one file. */
void php_lsp_init(PHPLSPContext *ctx, CBMArena *arena, const char *source, int source_len,
const CBMTypeRegistry *registry, const char *module_qn,
CBMResolvedCallArray *out);
/* Add a `use` mapping. */
void php_lsp_add_use(PHPLSPContext *ctx, const char *local_name, const char *target_qn,
int use_kind);
/* Process a file's AST: walk top-level decls, then function/method bodies. */
void php_lsp_process_file(PHPLSPContext *ctx, TSNode root);
/* Evaluate a PHP expression's type. May return NULL / CBM_TYPE_UNKNOWN. */
const CBMType *php_eval_expr_type(PHPLSPContext *ctx, TSNode node);
/* Parse a PHP type-AST node (named_type, primitive_type, union_type, ...) to CBMType. */
const CBMType *php_parse_type_node(PHPLSPContext *ctx, TSNode node);
/* Resolve a class name (bare or qualified) using current namespace + use map. */
const char *php_resolve_class_name(PHPLSPContext *ctx, const char *name);
/* Look up a method on a class, walking parent chain (registry-based). */
const CBMRegisteredFunc *php_lookup_method(PHPLSPContext *ctx, const char *class_qn,
const char *method_name);
/* Entry point: build registry from file defs + stdlib + composer (if present),
* then run resolution. Called from cbm_extract_file(). */
void cbm_run_php_lsp(CBMArena *arena, CBMFileResult *result, const char *source, int source_len,
TSNode root);
/* Register PHP stdlib + curated framework types into a registry. */
void cbm_php_stdlib_register(CBMTypeRegistry *reg, CBMArena *arena);
/* --- Cross-file LSP resolution ---
*
* Mirrors cbm_run_py_lsp_cross / cbm_run_ts_lsp_cross. Caller supplies the
* combined CBMLSPDef[] (file-local + cross-file) and a resolved import map
* (use → target QN). Imports are added as CLASS-kind uses; file-internal
* `use` declarations from the AST are layered on top by process_file.
*
* Reuses go_lsp.h's CBMLSPDef so cross-language registration is uniform. */
void cbm_run_php_lsp_cross(
CBMArena *arena,
const char *source, int source_len,
const char *module_qn,
CBMLSPDef *defs, int def_count,
const char **import_names, const char **import_qns, int import_count,
TSTree *cached_tree, /* NULL = parse internally */
CBMResolvedCallArray *out);
/* --- Batch cross-file LSP --- */
/* Per-file input for batch PHP LSP processing. */
typedef struct {
const char *source;
int source_len;
const char *module_qn;
TSTree *cached_tree; /* NULL = parse internally */
CBMLSPDef *defs; /* combined file-local + cross-file defs */
int def_count;
const char **import_names; /* parallel arrays, import_count long */
const char **import_qns;
int import_count;
} CBMBatchPHPLSPFile;
/* Process multiple PHP files' cross-file LSP in one call. out must point to
* file_count pre-zeroed CBMResolvedCallArray structs. */
void cbm_batch_php_lsp_cross(
CBMArena *arena,
CBMBatchPHPLSPFile *files, int file_count,
CBMResolvedCallArray *out);
#endif /* CBM_LSP_PHP_LSP_H */