From 229b4fe1f8a99ee60f6ba86ea190181314ef0429 Mon Sep 17 00:00:00 2001 From: Martin Vogel Date: Fri, 28 Aug 2026 13:26:59 +0200 Subject: [PATCH] feat(lang): CFML tag-dialect .cfc routing + embedded defs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Distilled from #1412 by @allanoepping. Fixes a real recall hole: tag-dialect .cfc components were routed to the cfscript grammar (extracting nothing), and bodies inside tag-dialect files are opaque cf_script_content to the cfml grammar — whole legacy components produced zero functions. Fix 1 — his .cfc dialect sniffer, nearly verbatim: cbm_disambiguate_cfc() reads a 16K head via cbm_fopen; / anywhere means tag dialect; a leading comments) or no markup at all keeps the old CFSCRIPT routing, so script-dialect files and read failures behave exactly as before. Wired in detect_file_language beside the existing _m/_cls/_inc sniffers, with his 8 direct tests. Fix 2 — his embedded-defs capability, re-based onto the shared machinery that superseded his mechanism mid-flight (#1852, merged after his last rebase): a cfml_embedded_imports spec row (cf_script_tag/cf_script_content -> CFSCRIPT), CFML added to the embedded-imports dispatch, and the extract_structure gate extended to CFML. Included ranges on the original buffer give absolute coordinates for free, so his line-number assertions hold verbatim, and calls inside blocks become extractable as a bonus. His ~90-line slice+shift implementation is deliberately NOT carried — it mirrored the sanctioned shape of its day, which #1852 replaced. One correctness guard the port needed: the Vue attribute resolver is now gated to Vue — cf_script_tag carries no lang=/src= attributes, and running the resolver would have silently rewritten CFML's embedded language from CFSCRIPT to the resolver's JavaScript default. His embedded extraction test (line remap + ERROR-cascade case) carries over verbatim and binds: reverting the spec/gate wiring fails it at ASSERT(has_def(r, "Function", "greet")). Suites: extraction, language, edge_imports, lang_contract, grammar_labels, grammar_regression — 637/0. Co-authored-by: Allan Oepping Signed-off-by: Martin Vogel --- internal/cbm/extract_imports.c | 17 +++++- internal/cbm/lang_specs.c | 10 +++- src/discover/discover.c | 4 ++ src/discover/discover.h | 6 +++ src/discover/language.c | 77 +++++++++++++++++++++++++++- tests/test_extraction.c | 76 +++++++++++++++++++++------ tests/test_language.c | 94 ++++++++++++++++++++++++++++++++++ 7 files changed, 264 insertions(+), 20 deletions(-) diff --git a/internal/cbm/extract_imports.c b/internal/cbm/extract_imports.c index 538335b0e8..2d8ed1e4ea 100644 --- a/internal/cbm/extract_imports.c +++ b/internal/cbm/extract_imports.c @@ -1588,8 +1588,18 @@ static void parse_embedded_imports(CBMExtractCtx *ctx) { embedded_collect_content_nodes(ctx->root, e, hits, &hit_count, MAX_EMBEDDED_BLOCKS); for (int i = 0; i < hit_count; i++) { CBMLanguage embedded_language = e->embedded_language; - bool extract_structure = ctx->language == CBM_LANG_VUE; - if (extract_structure && + /* Structure (defs + calls), not just imports, for hosts whose + * embedded language carries real code. Vue since #1852; CFML's + * since the #1412 distillation. */ + bool extract_structure = + ctx->language == CBM_LANG_VUE || ctx->language == CBM_LANG_CFML; + /* The attribute resolver is Vue's: it inspects