fix(extraction): blank a C macro call's designated-initializer arguments before parsing - #1733
Open
danusha2345 wants to merge 1 commit into
Open
Conversation
…nts before parsing tree-sitter-c has no rule for `.field = value` as a call argument. A statement-level `MACRO(a, b, .x = …, .y = …, …);` parses with an ERROR per argument, and past roughly a hundred of them the grammar's error recovery gives up on the enclosing function: the function_definition runs to the end of the file, the function after it produces no node at all, and every later function is nested under the first (colbymchenry#1729). betaflight resets each config struct that way — `resetPidProfile` was lines 168–1667 in the graph against 168–309 in the source, with 45 functions as its children; 310 such functions in 73 files across the tree. Name matching read the nesting as a scope (colbymchenry#1230), so exact-match declined those 45 for every cross-file caller and the fuzzy fallback carried 117 real calls at 0.5. blankCDesignatedMacroArgs runs at the head of preParseCSource: a statement-level call of a macro-cased name whose argument list holds a designator (`.name =` or `[index] =` at argument depth) has that list emptied to spaces, newlines kept, so `RESET_CONFIG(\n\n…\n);` parses cleanly and every offset survives. The references inside the initializer are the price; the broken parse was not yielding them either. The pre-parse runs before the kernel route point, so both arms see the same bytes and the kernel needs no change. betaflight fork, 2,109 C files, against b9ca4b7: resetPidProfile 168–309, nested C functions 310 → 265 (the rest are `#if`-damaged HAL sources, a different shape), +3 function nodes (`isTpaActive` and two more the old parse dropped), 117 fuzzy calls → 118 exact-match calls, 45 `contains` edges moved from resetPidProfile to the file node. Nothing else moved. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1729. Standalone off
main(b9ca4b7), one commit, pre-parse only — the blank runs before the kernel route point, so both extraction arms receive the same bytes and the kernel needs no change.What
tree-sitter-c has no rule for
.field = valueas a call argument. A statement-levelparses with an ERROR per argument, and past roughly a hundred of them the grammar's error recovery gives up on the enclosing function: the
function_definitionruns to the end of the file, the function after it produces no node at all, and every later one is nested under the first. That is not a matter of shape — the issue's three-function reproduction, and every smaller variant I tried (trailing comma or not, nested designators, array designators), keeps correct extents with the ERRORs local. It is the count: a prefix search over betaflight's realresetPidProfilebreaks at the 104th–106th argument whatever those lines contain.blankCDesignatedMacroArgsruns at the head ofpreParseCSource, in the style of the other blanks there: a statement-level call ();follows) of a macro-cased name whose argument list holds a designator at argument depth —.name =or[index] =, not==— has that list emptied to spaces with newlines kept, soRESET_CONFIG(\n\n…\n);parses cleanly and every byte offset survives.log(.5)andOTHER_MACRO(a == b, c)are left alone. The references inside the initializer are the price; the broken parse was not yielding them either.Measured
betaflight fork, 2,109
.cfiles, indexed atb9ca4b7and at this branch, wasm arm:resetPidProfileextentisTpaActiveand two more the old parse dropped)Edge-set delta, rows keyed with
resolvedBy: 117fuzzycalls intopid.cgone and 118exact-matchcalls in their place — the same 117 callers now resolve through the strategy that should have had them (they were declined as unreachable closures, #1230, and picked up by the fuzzy fallback at 0.5), plus one call onto the recoveredisTpaActive; 45containsedges moved fromresetPidProfileto the file node, 48 file-levelcontainsin their place. Nothing else moved.The 265 that remain nested are a different shape —
#if-damaged STM32 HAL sources (stm32h7xx_ll_utils.c,…_ll_tim.c), where both preprocessor branches are kept and the braces do not balance — and are the deferral case the kernel route already documents; not this PR's.Tests
extraction.test.ts: the blank itself (offsets and line count preserved,);keeps its column, designators gone,log(.5)anda == buntouched) and an end-to-end index of a 120-field macro call followed by two functions — before the changeresetProfileran to the last line andgwas missing; after it the three functions have their own extents and top-level qualified names. Suite: 624/624.Interaction with #1718: that PR gates C/C++ out of the nesting check on the resolver side, which is the right guard regardless (C has no nested named functions) and still covers the 265; this PR fixes the extraction that produced the nesting for the designated-initializer case.
🤖 Generated with Claude Code