# 2. Language-agnostic method extraction via `child_by_field_name("body")` **Date:** 2026-07-03 **Status:** Accepted ## Context To analyze method-level behavioral conventions, we must extract the body of each function/method from the AST. The standard tree-sitter approach is `node.child_by_field_name("body")`, but this named field is not universal across all language grammars. We need one code path that works for all 10 supported languages without per-language branches. ## Decision Use `node.child_by_field_name("body")` as the primary extraction method. When it returns `None`, fall back to scanning the node's children for any child with a type containing `body`, `block`, or `compound_statement`. Parent nodes are further filtered to only include nodes whose type contains `function` or `method` — avoiding class bodies, loop bodies, and conditional blocks. This logic lives in `_find_method_bodies()` in `code.py`: ```python def walk(node): body = node.child_by_field_name("body") if not body: for child in node.children: ctype = child.type.lower() if "body" in ctype or "block" in ctype or ctype == "compound_statement": body = child; break if body: ptype = node.type.lower() if "function" in ptype or "method" in ptype: bodies.append(body) for child in node.children: walk(child) ``` ## Consequences **Positive:** - Works for 9/10 grammars via `child_by_field_name("body")` alone (Python, Go, Rust, JS, TS, Ruby, Java, C, C++). - Kotlin fallback works because the fwcd Kotlin grammar uses `function_body` as a child node type. - Zero per-language case analysis — just pattern matching on type strings. **Negative:** - Fallback relies on string matching (`"body" in ctype`) which could produce false positives if future grammar versions introduce new body-like types. - C/C++ `function_definition` uses `declarator` field for the function name, not `name` — affects name extraction but not body extraction. ## Alternatives Considered - **Grammar-specific field names**: Map each language to its body field name. Rejected because it creates a maintenance burden and violates the zero-adapters constraint. - **Top-down sibling traversal**: Walk from node start to next sibling to find the body. Fragile across grammars with different compound statement structures.