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

Function process_if_statement

internal/cbm/lsp/php_lsp.c:2014–2125  ·  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

2012 * scope sequentially for the remainder of the enclosing function.
2013 */
2014static void process_if_statement(PHPLSPContext *ctx, TSNode node) {
2015 /* Find condition: first parenthesized_expression child. */
2016 TSNode cond;
2017 memset(&cond, 0, sizeof(cond));
2018 uint32_t nc = ts_node_child_count(node);
2019 for (uint32_t i = 0; i < nc; i++) {
2020 TSNode c = ts_node_child(node, i);
2021 if (ts_node_is_null(c) || !ts_node_is_named(c))
2022 continue;
2023 if (strcmp(ts_node_type(c), "parenthesized_expression") == 0) {
2024 cond = c;
2025 break;
2026 }
2027 }
2028 /* Collect all conjunctive narrowings: `$x instanceof Foo && is_int($y)`
2029 * narrows BOTH $x and $y in the if-body. */
2030 php_narrowing_t nws[8] = {{0}};
2031 int nw_count = ts_node_is_null(cond) ? 0 : parse_narrowing_collect(ctx, cond, nws, 8);
2032 bool has_nw = nw_count > 0;
2033
2034 /* Detect negative narrowing: condition is `!P` and P is a narrowing
2035 * predicate. We unwrap one level of unary `!`. */
2036 php_narrowing_t neg_nw = {0};
2037 bool has_neg_nw = false;
2038 if (!ts_node_is_null(cond)) {
2039 TSNode inner;
2040 memset(&inner, 0, sizeof(inner));
2041 /* Unwrap parenthesized_expression. */
2042 TSNode probe = cond;
2043 for (int loop = 0; loop < 4; loop++) {
2044 if (strcmp(ts_node_type(probe), "parenthesized_expression") == 0) {
2045 uint32_t pnc = ts_node_child_count(probe);
2046 TSNode next;
2047 memset(&next, 0, sizeof(next));
2048 for (uint32_t i = 0; i < pnc; i++) {
2049 TSNode c = ts_node_child(probe, i);
2050 if (!ts_node_is_null(c) && ts_node_is_named(c)) {
2051 next = c;
2052 break;
2053 }
2054 }
2055 if (ts_node_is_null(next))
2056 break;
2057 probe = next;
2058 } else {
2059 break;
2060 }
2061 }
2062 if (strcmp(ts_node_type(probe), "unary_op_expression") == 0) {
2063 /* Find the operator child; if it's `!`, parse the inner expr. */
2064 TSNode op = ts_node_child_by_field_name(probe, "operator", 8);
2065 char *opt = !ts_node_is_null(op) ? php_node_text(ctx, op) : NULL;
2066 if (opt && strcmp(opt, "!") == 0) {
2067 TSNode operand = ts_node_child_by_field_name(probe, "operand", 7);
2068 if (ts_node_is_null(operand)) {
2069 uint32_t unc = ts_node_child_count(probe);
2070 for (uint32_t i = 0; i < unc; i++) {
2071 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