MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / process_if_statement

Function process_if_statement

internal/cbm/lsp/php_lsp.c:2196–2307  ·  view source on GitHub ↗

Walk an `if_statement` (or `else_if_clause`) honoring narrowing. * * Tree-sitter-php's `if_statement` emits children as: an optional `if` * keyword, a parenthesized_expression (condition), and one or more * statement-shaped bodies (the if-body, optionally followed by * else_if_clause / else_clause). We narrow on the condition then walk * EVERY non-condition named child as the body — only the

Source from the content-addressed store, hash-verified

2194 * scope sequentially for the remainder of the enclosing function.
2195 */
2196static void process_if_statement(PHPLSPContext *ctx, TSNode node) {
2197 /* Find condition: first parenthesized_expression child. */
2198 TSNode cond;
2199 memset(&cond, 0, sizeof(cond));
2200 uint32_t nc = ts_node_child_count(node);
2201 for (uint32_t i = 0; i < nc; i++) {
2202 TSNode c = ts_node_child(node, i);
2203 if (ts_node_is_null(c) || !ts_node_is_named(c))
2204 continue;
2205 if (strcmp(ts_node_type(c), "parenthesized_expression") == 0) {
2206 cond = c;
2207 break;
2208 }
2209 }
2210 /* Collect all conjunctive narrowings: `$x instanceof Foo && is_int($y)`
2211 * narrows BOTH $x and $y in the if-body. */
2212 php_narrowing_t nws[8] = {{0}};
2213 int nw_count = ts_node_is_null(cond) ? 0 : parse_narrowing_collect(ctx, cond, nws, 8);
2214 bool has_nw = nw_count > 0;
2215
2216 /* Detect negative narrowing: condition is `!P` and P is a narrowing
2217 * predicate. We unwrap one level of unary `!`. */
2218 php_narrowing_t neg_nw = {0};
2219 bool has_neg_nw = false;
2220 if (!ts_node_is_null(cond)) {
2221 TSNode inner;
2222 memset(&inner, 0, sizeof(inner));
2223 /* Unwrap parenthesized_expression. */
2224 TSNode probe = cond;
2225 for (int loop = 0; loop < 4; loop++) {
2226 if (strcmp(ts_node_type(probe), "parenthesized_expression") == 0) {
2227 uint32_t pnc = ts_node_child_count(probe);
2228 TSNode next;
2229 memset(&next, 0, sizeof(next));
2230 for (uint32_t i = 0; i < pnc; i++) {
2231 TSNode c = ts_node_child(probe, i);
2232 if (!ts_node_is_null(c) && ts_node_is_named(c)) {
2233 next = c;
2234 break;
2235 }
2236 }
2237 if (ts_node_is_null(next))
2238 break;
2239 probe = next;
2240 } else {
2241 break;
2242 }
2243 }
2244 if (strcmp(ts_node_type(probe), "unary_op_expression") == 0) {
2245 /* Find the operator child; if it's `!`, parse the inner expr. */
2246 TSNode op = ts_node_child_by_field_name(probe, "operator", 8);
2247 char *opt = !ts_node_is_null(op) ? php_node_text(ctx, op) : NULL;
2248 if (opt && strcmp(opt, "!") == 0) {
2249 TSNode operand = ts_node_child_by_field_name(probe, "operand", 7);
2250 if (ts_node_is_null(operand)) {
2251 uint32_t unc = ts_node_child_count(probe);
2252 for (uint32_t i = 0; i < unc; i++) {
2253 TSNode c = ts_node_child(probe, i);

Callers 1

Calls 7

parse_narrowing_collectFunction · 0.85
php_node_textFunction · 0.85
parse_narrowingFunction · 0.85
stmt_is_terminatorFunction · 0.85
walk_with_narrowingsFunction · 0.85
cbm_scope_bindFunction · 0.85

Tested by

no test coverage detected