mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
test: cover stacked C# attributes for #1692 (repro_issue1692)
A C# method carrying three stacked attributes ([Foo][Bar("x")][Baz]) must
end up with three DECORATES edges, one per bracket group. The fixture is
indexed through the real production pipeline (rh_index) and asserts
rh_count_edges(..., "DECORATES") == 3, so it exercises the MCP path rather
than the extractor in isolation.
Verified to actually reproduce: with find_jvm_modifiers() reverted to its
first-child lookup the suite goes red (decorates=1, expected 3), and green
again with the fix in place.
C#-only by design. Parsing the equivalent fixtures with the vendored
grammars shows `[A] [B] [C]` yields three sibling `attribute_list` nodes in
C#, while PHP's `#[A] #[B] #[C]` yields ONE `attribute_list` holding three
`attribute_group` children — the pre-fix lookup already found all of them,
so PHP could not hit this bug and a stacked-PHP fixture would pass either
way. Java/Kotlin/Swift use the `modifiers` wrapper, a single node that never
repeats. PHP's DECORATES path stays covered by mkc_c3_php8_attribute
(tests/test_matrix_known_classes.c).
Registered in repro_main.c and Makefile.cbm's TEST_REPRO_SRCS.
Signed-off-by: Jumaga2015 <jumaga2015@gmail.com>
This commit is contained in:
1 parent
6b23078c9d
commit
c4224cf3ef
3 files changed
+94
No files matched your search
@@ -677,6 +677,7 @@ TEST_REPRO_SRCS = \
|
||||
tests/repro/repro_issue787.c \
|
||||
tests/repro/repro_issue842.c \
|
||||
tests/repro/repro_issue964.c \
|
||||
tests/repro/repro_issue1692.c \
|
||||
tests/repro/repro_invariant_calls.c \
|
||||
tests/repro/repro_invariant_graph.c \
|
||||
tests/repro/repro_invariant_breadth.c \
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* repro_issue1692.c — Reproduce-first case for OPEN bug #1692.
|
||||
*
|
||||
* Issue: #1692 — "C#: ... ASP.NET Core [Route]/[HttpGet] attribute routes
|
||||
* not extracted (cross-repo-intelligence returns 0 edges)". The reporter's
|
||||
* repro 2 shows a class carrying three stacked attributes
|
||||
* ([ServiceFilter]/[Route]/[ApiController]) where DECORATES exists 13,964
|
||||
* times elsewhere in the same graph but zero times for that declaration.
|
||||
*
|
||||
* Root cause (traced further than the issue body): C# does not attach one
|
||||
* `attribute_list` wrapper holding every bracket group above a declaration —
|
||||
* each `[A]` / `[B]` / `[C]` line compiles to its OWN `attribute_list` node,
|
||||
* so a stack of three produces three separate `attribute_list` siblings
|
||||
* among the declaration's children. `find_jvm_modifiers()`
|
||||
* (internal/cbm/extract_defs.c) located that wrapper with
|
||||
* `ts_node_child_by_field_name(node, "attribute_list", ...)`, which only
|
||||
* ever returns the FIRST child registered under a repeated field — so only
|
||||
* the first bracket group's attribute(s) ever produced a DECORATES edge;
|
||||
* every attribute after the first was silently dropped, with no warning and
|
||||
* no staleness signal (confirmed indexed, not stale, via grafo_coverage in
|
||||
* the downstream McpDevGrafo-bugs.md BUG-004 report that led here).
|
||||
*
|
||||
* Expected (correct) behaviour:
|
||||
* A method carrying N stacked attributes gets exactly N outbound
|
||||
* DECORATES edges — not just one for the first bracket group.
|
||||
*
|
||||
* Why RED on current code: only the first attribute's DECORATES edge
|
||||
* exists, so the project-wide DECORATES count is 1, not 3.
|
||||
*
|
||||
* Scope — why this file is C#-only:
|
||||
* find_jvm_modifiers() shares ONE switch across Java/Kotlin/Swift/C#/PHP,
|
||||
* but only C# can reach this bug. Verified against the vendored grammars:
|
||||
* `[A] [B] [C]` in C# parses as THREE sibling `attribute_list` nodes, while
|
||||
* PHP's `#[A] #[B] #[C]` parses as ONE `attribute_list` holding three
|
||||
* `attribute_group` children — so the first-child lookup already found them
|
||||
* all and PHP never dropped an attribute. Java/Kotlin/Swift use the
|
||||
* `modifiers` wrapper, a single node that never repeats. PHP's DECORATES
|
||||
* path stays covered by mkc_c3_php8_attribute (test_matrix_known_classes.c);
|
||||
* a stacked-PHP fixture here would pass with or without the fix and prove
|
||||
* nothing. No other language reaches this function (`default` returns 0).
|
||||
*/
|
||||
|
||||
#include <foundation/compat.h>
|
||||
#include "test_framework.h"
|
||||
#include "repro_harness.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* ── Fixture: C# ───────────────────────────────────────────────────────────
|
||||
*
|
||||
* One C# method, three stacked attributes, nothing else in the file that
|
||||
* could carry a DECORATES edge — so a project-wide edge count is as precise
|
||||
* as scoping to the method node, without the extra node lookup.
|
||||
* ──────────────────────────────────────────────────────────────────────── */
|
||||
static const char *kStackedAttrsCs = "using System;\n"
|
||||
"\n"
|
||||
"namespace ReproNS\n"
|
||||
"{\n"
|
||||
" public class AttrController\n"
|
||||
" {\n"
|
||||
" [Foo]\n"
|
||||
" [Bar(\"x\")]\n"
|
||||
" [Baz]\n"
|
||||
" public void StackedAttrsMethod() { }\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
TEST(repro_issue1692_csharp_stacked_attributes_all_decorate) {
|
||||
RProj lp;
|
||||
cbm_store_t *store = rh_index(&lp, "StackedAttrs.cs", kStackedAttrsCs);
|
||||
ASSERT_NOT_NULL(store);
|
||||
|
||||
int decorates_count = rh_count_edges(store, lp.project, "DECORATES");
|
||||
if (decorates_count != 3) {
|
||||
fprintf(stderr,
|
||||
" [1692] FAIL decorates=%d (expected 3 — one per stacked [Foo][Bar][Baz]; "
|
||||
"only the first attribute_list's attribute(s) survive find_jvm_modifiers' "
|
||||
"single-field lookup)\n",
|
||||
decorates_count);
|
||||
}
|
||||
ASSERT_EQ(3, decorates_count); /* one DECORATES per stacked attribute, not just the first */
|
||||
|
||||
rh_cleanup(&lp, store);
|
||||
PASS();
|
||||
}
|
||||
|
||||
SUITE(repro_issue1692) {
|
||||
RUN_TEST(repro_issue1692_csharp_stacked_attributes_all_decorate);
|
||||
}
|
||||
@@ -91,6 +91,7 @@ extern void suite_repro_issue581(void);
|
||||
extern void suite_repro_issue787(void);
|
||||
extern void suite_repro_issue842(void);
|
||||
extern void suite_repro_issue964(void);
|
||||
extern void suite_repro_issue1692(void);
|
||||
/* NEW bugs found by the discovery sweep */
|
||||
extern void suite_repro_new_ts_class_field_arrow(void);
|
||||
extern void suite_repro_new_py_tuple_unpack(void);
|
||||
@@ -192,6 +193,7 @@ int main(void) {
|
||||
RUN_SUITE(repro_issue787);
|
||||
RUN_SUITE(repro_issue842);
|
||||
RUN_SUITE(repro_issue964);
|
||||
RUN_SUITE(repro_issue1692);
|
||||
RUN_SUITE(repro_invariant_calls);
|
||||
RUN_SUITE(repro_invariant_graph);
|
||||
RUN_SUITE(repro_invariant_breadth);
|
||||
|
||||
Reference in new issue
Block a user