test(csharp): cover builtin-not-fabricated and struct primary-ctor (#2829)

Adds the two cases the deep-dive flagged: a built-in-typed primary-ctor param
(int count) must not fabricate a referenced node, and the branch's struct_declaration
claim is locked by a struct primary-ctor test. Also adds the CHANGELOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
safishamsi
2026-08-18 18:07:12 +01:00
co-authored by Claude Opus 4.8
parent 3e8ec33994
commit 1eb356cde1
2 changed files with 37 additions and 0 deletions
+1
View File
@@ -4,6 +4,7 @@ Full release notes with details on each version: [GitHub Releases](https://githu
## 0.9.47 (unreleased)
- Fix: a C# 12 primary constructor's parameters are now walked, so `class Svc(IRepo repo)` emits the `references` edge to `IRepo` and calls through `repo` resolve — previously the class silently dropped its dependency; built-in and type-parameter types are not fabricated (#2829, thanks @brobl2008).
- Fix: AST-derived INFERRED edges now carry a rubric `confidence_score` keyed to the relation (`uses` 0.95, `indirect_call`/unresolved cross-file `calls` 0.85) instead of landing at the rubric-forbidden 0.5 or a flat 0.8; the INFERRED default moves 0.5→0.55 so every score-less INFERRED edge is on the discrete rubric set (#2813, thanks @abhay-codes07).
- Fix: a legacy `graph.json` that stored a numeric edge `confidence` (from a pre-enum version) no longer warns once per edge on every incremental reload; the numeric value is normalized to the `INFERRED` tag with the original float preserved in `confidence_score` (thanks @Trantor-develops).
+36
View File
@@ -740,3 +740,39 @@ def test_primary_constructor_type_parameter_is_not_referenced(tmp_path):
labels = {n["id"]: n["label"] for n in r["nodes"]}
assert not [t for s, t in refs if s == holder and labels.get(t) == "T"], \
"a type parameter must not be emitted as a referenced type"
def test_primary_constructor_builtin_param_is_not_fabricated(tmp_path):
"""A built-in-typed primary-ctor parameter (`int count`) must not fabricate a
referenced type node — only real type dependencies get a references edge."""
_, r = _calls(tmp_path, {
"S.cs": (
"public interface IDep { bool Plain(); }\n"
"public class Holder(IDep dep, int count) {\n"
" public bool Run() { return dep.Plain(); }\n"
"}\n"
)
})
holder = _find(r, "Holder", "holder")
refs = _refs(r)
idep = _find(r, "IDep", "idep")
assert (holder, idep) in refs, "the real dependency must still be referenced"
labels = {n["id"]: n["label"] for n in r["nodes"]}
assert not [t for s, t in refs if s == holder and labels.get(t) in ("int", "Int32")], \
"a built-in parameter type must not become a referenced node"
def test_struct_primary_constructor_parameter_emits_references_edge(tmp_path):
"""The branch also covers `struct` primary constructors, not just class/record."""
_, r = _calls(tmp_path, {
"S.cs": (
"public interface IDep { bool Plain(); }\n"
"public struct Holder(IDep dep) {\n"
" public bool Run() { return dep.Plain(); }\n"
"}\n"
)
})
holder = _find(r, "Holder", "holder")
idep = _find(r, "IDep", "idep")
assert (holder, idep) in _refs(r), \
"a struct primary-constructor parameter type must produce a references edge"