C# looks a simple type name up namespace by namespace, innermost outward.
At each namespace N it checks the members of N, then the usings of the
namespace declaration enclosing the reference. The global namespace is
the last N, and its declaration is the compilation unit. So a type
declared without a namespace hides a type that only a compilation-unit
`using` imports, while a `using` inside a namespace body still wins over
the global namespace. Step 8b used to rank every using before the global
namespace.
- CBMCSUsing records whether a directive sits inside a namespace body
(in_namespace). cs_collect_imports tracks it per node, including the
compilation-unit siblings after a file-scoped namespace; the cross-file
entry pre-loads the pipeline import list without placement and the AST
walk upgrades it.
- cs_visible_namespaces ranks a simple name as: enclosing namespaces
innermost outward, namespace-body usings, the global namespace "", and
last the compilation-unit usings.
Ranking the global namespace that high also requires that only a type
proven global claims it. The vendored grammar does not parse a
`ref partial struct` with members, and error recovery dissolves the
enclosing namespace, so every type after it in that namespace surfaced
with no namespace. Mapped to "" those types outranked the real, imported
declaration: on dotnet/runtime 5,313 CALLS moved from implementation
files into reference assemblies (System.Runtime.cs, which declares
DefaultInterpolatedStringHandler as a `ref partial struct`).
cs_type_decl_namespace now returns "" only when the compilation unit
parsed without errors and NULL (unknown, invisible to step 8b, as on
main) otherwise; cs_top_level_namespace passes that through.
Tests:
- parallel_csharp_nested_type_and_global_namespace_binding: the
compilation-unit `using` probe now expects the global type (spec), and
a new namespace-body `using` probe expects the imported one. RED with
the previous order: cu_using=0/0.
- parallel_csharp_parse_damaged_namespace_is_not_global (sequential and
parallel). RED without the clean-parse rule: real=0 no_damaged=0 on
both paths.
- cs_lsp::cslsp_decl_namespace_global_needs_clean_parse: extractor
contract ("" for a clean global type, the namespace when found, never
"" after a parse error).
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>