Files
wehub-resource-sync 41cb1c0170
OpenSSF Scorecard / scorecard (push) Failing after 0s
DCO / dco (push) Failing after 0s
CodeQL SAST / analyze (push) Failing after 1s
Deploy Pages / deploy (push) Failing after 1s
chore: import upstream snapshot with attribution
2026-07-13 12:28:05 +08:00

601 lines
18 KiB
C

/*
* repro_invariant_breadth.c -- Cross-language CALLS callable-sourcing invariant.
*
* INVARIANT (gap #6, QUALITY_ANALYSIS.md):
* For every language, a function call written INSIDE a function body must
* produce a CALLS edge whose source node carries label "Function" or "Method"
* (i.e. callable-sourced). It must NOT be sourced at a "Module" node.
* Calls at the top level of a file may legitimately be Module-sourced; only
* in-body calls are asserted here.
*
* QUALITY_ANALYSIS.md gap #6 reports 27 languages failing this. This file
* is the "large breadth table" — one per-language case, table-driven, asserting
* the invariant across 26 languages.
*
* Fixture design rule:
* Each fixture defines exactly TWO functions: a callee (helper) and a caller
* (run) that calls helper strictly INSIDE its body. There are NO top-level
* calls in any fixture. This means ANY Module-sourced CALLS edge is a
* direct violation of the invariant.
*
* Expected RED/GREEN split (as of QUALITY_ANALYSIS.md, 2026-06-24):
* GREEN (already correctly callable-sourced, regression guards):
* elixir, ocaml, fortran, pascal, cuda, d, glsl, hlsl, ispc,
* odin, slang, squirrel, vimscript, cairo (14 cases)
*
* RED (module-sourced or no CALLS at all -- reproduces the gap):
* r, julia, dart, groovy, commonlisp, powershell, ada, clojure,
* fsharp, racket, rescript, scheme (12 cases)
*
* Note: the "suspicious" group (r, julia, ...) from QUALITY_ANALYSIS may be
* GREEN because the calls-breadth table (test_lang_contract.c) already shows
* expect_calls=true for most. The module-sourcing assertion is STRICTER: a
* language can produce a CALLS edge (calls >= 1) but still fail here if the
* edge is sourced at Module rather than Function. Individual case comments
* explain the known failure mode where root-caused.
*
* How to read results:
* PASS -- callable-sourced (Function/Method), no Module-sourced in-body calls.
* If currently GREEN: regression guard -- a future grammar/pipeline
* change that breaks sourcing will turn it RED.
* If currently RED: the bug is confirmed reproduced; fix the
* enclosing-function detection for this language.
*/
#include "test_framework.h"
#include "repro_harness.h"
#include <store/store.h>
#include <stdio.h>
#include <string.h>
/* ---- helper: count CALLS edges by source-node label --------------------- */
static int ib_calls_from_label(cbm_store_t *store, const char *project,
const char *label) {
cbm_edge_t *edges = NULL;
int edge_count = 0;
if (cbm_store_find_edges_by_type(store, project, "CALLS",
&edges, &edge_count) != CBM_STORE_OK) {
return -1;
}
int total = 0;
for (int i = 0; i < edge_count; i++) {
cbm_node_t src = {0};
if (cbm_store_find_node_by_id(store, edges[i].source_id,
&src) != CBM_STORE_OK) {
continue;
}
if (src.label && strcmp(src.label, label) == 0) {
total++;
}
cbm_node_free_fields(&src);
}
cbm_store_free_edges(edges, edge_count);
return total;
}
static int ib_callable_calls(cbm_store_t *store, const char *project) {
int fn = ib_calls_from_label(store, project, "Function");
int mt = ib_calls_from_label(store, project, "Method");
if (fn < 0 || mt < 0) {
return -1;
}
return fn + mt;
}
static int ib_module_calls(cbm_store_t *store, const char *project) {
return ib_calls_from_label(store, project, "Module");
}
/* ---- per-case result struct --------------------------------------------- */
typedef struct {
int ok; /* graph DB opened */
int calls; /* total CALLS edges */
int callable_calls; /* CALLS sourced at Function or Method */
int module_calls; /* CALLS sourced at Module */
} IBMetrics;
static IBMetrics ib_metrics(const char *filename, const char *content) {
RProj lp;
cbm_store_t *store = rh_index(&lp, filename, content);
IBMetrics m = {0};
if (store) {
m.ok = 1;
m.calls = rh_count_edges(store, lp.project, "CALLS");
m.callable_calls = ib_callable_calls(store, lp.project);
m.module_calls = ib_module_calls(store, lp.project);
}
rh_cleanup(&lp, store);
return m;
}
/* ---- breadth case table ------------------------------------------------- */
typedef struct {
const char *lang; /* human-readable language name */
const char *filename; /* fixture filename (extension selects grammar) */
const char *src; /* fixture source — caller inside a function body only */
int expect_callable; /* 1: calls should be callable-sourced (GREEN target) */
const char *gap_note; /* root cause for known gaps (NULL if expected GREEN) */
} IBCase;
/*
* Fixture rule: helper() is the callee; run() is the caller.
* The call to helper() is strictly inside the body of run().
* No top-level calls anywhere in the fixture.
*/
static const IBCase IB_CASES[] = {
/* ------------------------------------------------------------------ */
/* SUSPICIOUS / LIKELY-BROKEN GROUP */
/* QUALITY_ANALYSIS lists these as "expected-true but suspicious". */
/* They have expect_calls=true in the calls-breadth table, meaning a */
/* CALLS edge is produced -- but it may still be Module-sourced. */
/* ------------------------------------------------------------------ */
{
"r", "a.R",
"helper <- function(x) {\n"
" x * 2\n"
"}\n"
"\n"
"run <- function() {\n"
" helper(21)\n"
"}\n",
/*
* R: extract_calls.c has an R branch that reads the callee from the
* call node's first child. However, enclosing-function detection
* for R may fall back to Module if func_kinds_for_lang does not
* include R's "function_definition" node type. RED when the CALLS
* edge is sourced at Module instead of the "run" Function node.
*/
0, "R enclosing-function detection likely missing from func_kinds_for_lang; "
"call may be sourced at Module"
},
{
"julia", "a.jl",
"function helper(x)\n"
" return x + 1\n"
"end\n"
"\n"
"function run(n)\n"
" return helper(n)\n"
"end\n",
/*
* Julia: same issue -- function body extraction may not detect the
* enclosing Julia function node correctly, sourcing the call at Module.
*/
0, "Julia enclosing-function detection may not map function_definition to "
"a callable QN; call sourced at Module"
},
/* ------------------------------------------------------------------ */
/* EXPECTED-GREEN GROUP (regression guards) */
/* These languages have correct callable-sourcing in the current build.*/
/* A regression that breaks enclosing-function detection for any of */
/* them will turn the corresponding case RED. */
/* ------------------------------------------------------------------ */
{
"elixir", "a.ex",
"defmodule Sample do\n"
" def helper(x) do\n"
" x + 1\n"
" end\n"
"\n"
" def run do\n"
" helper(41)\n"
" end\n"
"end\n",
1, NULL
},
{
"ocaml", "a.ml",
"let helper x = x + 1\n"
"\n"
"let run () =\n"
" let result = helper 41 in\n"
" print_int result\n",
1, NULL
},
{
"fortran", "a.f90",
"function helper(x) result(y)\n"
" integer, intent(in) :: x\n"
" integer :: y\n"
" y = x + 1\n"
"end function helper\n"
"\n"
"function run(n) result(total)\n"
" integer, intent(in) :: n\n"
" integer :: total\n"
" total = helper(n) + helper(n + 1)\n"
"end function run\n",
1, NULL
},
{
"pascal", "a.pas",
"procedure Helper(x: Integer);\n"
"begin\n"
" WriteLn(x);\n"
"end;\n"
"\n"
"procedure Run;\n"
"begin\n"
" Helper(1);\n"
"end;\n",
1, NULL
},
{
"cuda", "a.cu",
"__device__ int helper(int x) {\n"
" return x * 2;\n"
"}\n"
"\n"
"__global__ void run(int *out) {\n"
" out[0] = helper(21);\n"
"}\n",
1, NULL
},
{
"d", "a.d",
"int helper(int x)\n"
"{\n"
" return x + 1;\n"
"}\n"
"\n"
"void run()\n"
"{\n"
" int y = helper(41);\n"
"}\n",
1, NULL
},
{
"glsl", "a.glsl",
"float helper(float x) {\n"
" return x * 2.0;\n"
"}\n"
"\n"
"void run() {\n"
" float y = helper(3.0);\n"
"}\n",
1, NULL
},
{
"hlsl", "a.hlsl",
"float helper(float x)\n"
"{\n"
" return x * 2.0;\n"
"}\n"
"\n"
"float run(float v)\n"
"{\n"
" return helper(v) + 1.0;\n"
"}\n",
1, NULL
},
{
"ispc", "a.ispc",
"static inline uniform float helper(uniform float x) {\n"
" return x * 2.0f;\n"
"}\n"
"\n"
"export void run(uniform float in[], uniform float out[],\n"
" uniform int n) {\n"
" foreach (i = 0 ... n) {\n"
" out[i] = helper(in[i]);\n"
" }\n"
"}\n",
1, NULL
},
{
"odin", "a.odin",
"package fixture\n"
"\n"
"helper :: proc() -> int {\n"
"\treturn 42\n"
"}\n"
"\n"
"run :: proc() {\n"
"\tx := helper()\n"
"\t_ = x\n"
"}\n",
1, NULL
},
{
"slang", "a.slang",
"void helper()\n"
"{\n"
" int x = 1;\n"
"}\n"
"\n"
"void run()\n"
"{\n"
" helper();\n"
"}\n",
1, NULL
},
{
"squirrel", "a.nut",
"function helper(x) {\n"
" return x + 1;\n"
"}\n"
"\n"
"function run() {\n"
" return helper(41);\n"
"}\n",
1, NULL
},
{
"vimscript", "a.vim",
"function! Helper() abort\n"
" return 1\n"
"endfunction\n"
"\n"
"function! Run() abort\n"
" call Helper()\n"
"endfunction\n",
1, NULL
},
{
"cairo", "a.cairo",
"fn helper(x: felt252) -> felt252 {\n"
" x + 1\n"
"}\n"
"\n"
"fn run() -> felt252 {\n"
" helper(41)\n"
"}\n",
1, NULL
},
/* ------------------------------------------------------------------ */
/* KNOWN-GAP GROUP */
/* These languages fail in the existing calls-breadth contract too */
/* (expect_calls=false in test_lang_contract.c CALL_CASES). */
/* The primary gap is callee extraction; callable-sourcing cannot be */
/* verified until a CALLS edge exists. Both invariants are asserted: */
/* calls >= 1 AND module_calls == 0. */
/* ------------------------------------------------------------------ */
{
"dart", "a.dart",
"void helper() {\n"
" print('helper');\n"
"}\n"
"\n"
"void run() {\n"
" helper();\n"
"}\n",
/*
* Dart: selector call node carries no callee field and the first child
* is not an identifier; no dart branch in extract_calls.c. No CALLS
* edge is produced at all, so callable-sourcing cannot be tested
* independently. Both gaps (no CALLS + callable-sourcing) are RED.
*/
0, "selector call node: no callee field, first child not identifier; "
"no dart branch in extract_calls.c"
},
{
"groovy", "a.groovy",
"def helper() {\n"
" println 'helping'\n"
"}\n"
"\n"
"def run() {\n"
" helper()\n"
"}\n",
/*
* Groovy: function_call callee not on a function/name field and first
* child is not 'identifier'; no groovy branch in extract_calls.c.
*/
0, "function_call callee not on function/name field; "
"first child is not identifier; no groovy branch in extract_calls.c"
},
{
"commonlisp", "a.lisp",
"(defun helper (x)\n"
" (* x 2))\n"
"\n"
"(defun run ()\n"
" (helper 21))\n",
/*
* Common Lisp: list_lit call head is sym_lit not identifier;
* no commonlisp branch in extract_callee_name.
*/
0, "list_lit call head is sym_lit not identifier; "
"no commonlisp branch in extract_callee_name"
},
{
"powershell", "a.ps1",
"function helper {\n"
" Write-Output 'hi'\n"
"}\n"
"\n"
"function run {\n"
" helper\n"
"}\n",
/*
* PowerShell: command node child is command_name not identifier;
* extract_scripting_callee handles MATLAB not PowerShell.
*/
0, "command node child is command_name not identifier; "
"extract_scripting_callee handles MATLAB not PowerShell"
},
{
"ada", "a.adb",
"procedure Run is\n"
" procedure Helper is\n"
" begin\n"
" null;\n"
" end Helper;\n"
"begin\n"
" Helper;\n"
"end Run;\n",
/*
* Ada: procedure_call_statement callee did not resolve to a CALLS edge;
* no Ada branch in extract_calls.c.
*/
0, "procedure_call_statement callee not resolved; "
"no Ada branch in extract_calls.c"
},
{
"clojure", "a.clj",
"(defn helper [] 42)\n"
"\n"
"(defn run [] (helper))\n",
/*
* Clojure: lisp call is a list_lit whose head is a sym_lit (not a
* field, not a first-child 'identifier'); no lisp branch in
* extract_callee_name.
*/
0, "list_lit head is sym_lit not identifier; "
"no lisp/clojure branch in extract_callee_name"
},
{
"fsharp", "a.fs",
"let helper x = x + 1\n"
"\n"
"let run () = helper 41\n",
/*
* F#: application_expression callee head is a long_identifier_or_op
* wrapper, not a bare identifier/field; no fsharp callee branch.
*/
0, "application_expression callee head is long_identifier_or_op wrapper; "
"no fsharp callee branch in extract_callee_name"
},
{
"racket", "a.rkt",
"#lang racket\n"
"\n"
"(define (helper x)\n"
" (+ x 1))\n"
"\n"
"(define (run)\n"
" (helper 41))\n",
/*
* Racket: lisp call is a 'list' whose head is a 'symbol' (grammar has
* no 'identifier' node); no racket branch in extract_callee_name.
*/
0, "list head is symbol not identifier; "
"no racket branch in extract_callee_name"
},
{
"rescript", "a.res",
"let helper = (x) => x + 1\n"
"\n"
"let run = () => helper(41)\n",
/*
* ReScript: call_expression 'function' field is a 'value_identifier'
* (not in extract_callee_from_fields' accepted type list).
*/
0, "call_expression function field is value_identifier; "
"not in extract_callee_from_fields accepted type list"
},
{
"scheme", "a.scm",
"(define (helper x)\n"
" (* x 2))\n"
"\n"
"(define (run)\n"
" (helper 21))\n",
/*
* Scheme: lisp call is a 'list' whose head is a 'symbol';
* no scheme branch in extract_callee_name.
*/
0, "list head is symbol not identifier; "
"no scheme branch in extract_callee_name"
},
};
enum { IB_CASES_COUNT = (int)(sizeof(IB_CASES) / sizeof(IB_CASES[0])) };
/* ---- single table-driven test ------------------------------------------- */
/*
* repro_invariant_breadth_callable_sourcing
*
* Iterates every case in IB_CASES. For each language:
* 1. Indexes the single-file fixture through the full production pipeline.
* 2. Counts CALLS edges and their source-node labels.
* 3. Asserts:
* a. store opened (pipeline did not crash hard)
* b. calls >= 1 (the call was detected at all)
* c. callable_calls >= 1 (at least one CALLS edge is Function/Method-sourced)
* d. module_calls == 0 (no CALLS edge is Module-sourced for an in-body call)
*
* For expect_callable=0 cases (known gaps), the test still asserts all four
* conditions -- so those cases are RED (that IS the deliverable: a confirmed,
* reproducible, durable bug registration for each gap language).
*
* For expect_callable=1 cases (regression guards), the test must PASS.
* A future grammar or pipeline regression that breaks callable-sourcing for
* a GREEN language will immediately turn it RED here.
*/
TEST(repro_invariant_breadth_callable_sourcing) {
int failures = 0;
for (int i = 0; i < IB_CASES_COUNT; i++) {
const IBCase *c = &IB_CASES[i];
IBMetrics m = ib_metrics(c->filename, c->src);
int pass = (m.ok && m.calls >= 1 && m.callable_calls >= 1 &&
m.module_calls == 0);
if (!pass) {
fprintf(stderr,
" [INV-BREADTH] FAIL %-12s ok=%d calls=%d "
"callable=%d module=%d%s%s\n",
c->lang, m.ok, m.calls, m.callable_calls,
m.module_calls,
c->gap_note ? " -- " : "",
c->gap_note ? c->gap_note : "");
failures++;
} else {
fprintf(stderr,
" [INV-BREADTH] PASS %-12s calls=%d callable=%d "
"module=%d\n",
c->lang, m.calls, m.callable_calls, m.module_calls);
}
}
fprintf(stderr,
" [INV-BREADTH] %d langs checked: %d FAILURES "
"(each = callable-sourcing invariant violated or no CALLS at all)\n",
IB_CASES_COUNT, failures);
ASSERT_EQ(failures, 0);
PASS();
}
/* ---- suite --------------------------------------------------------------- */
SUITE(repro_invariant_breadth) {
RUN_TEST(repro_invariant_breadth_callable_sourcing);
}