Problem
CodeBlocker ships exactly two scopes — Scope ({ … }) and ScopeWithTrailingSemicolon ({ … };). Every real generator built on it re-implements the same handful of shapes on top of raw WriteLine.
From ktsu.Semantics' LogarithmicScalesGenerator alone:
cb.WriteLine("#nullable enable");
cb.NewLine();
cb.WriteLine("namespace ktsu.Semantics.Quantities;");
cb.NewLine();
cb.WriteLine("using System;");
cb.WriteLine("using System.Globalization;");
cb.WriteLine("using System.Numerics;");
cb.NewLine();
None of that is domain-specific, and hand-writing it means every generator gets to invent its own spacing conventions.
Proposal
Add the shapes that recur in generated C#. Suggested surface, all opt-in:
Scopes
ParenScope / BracketScope — ( … ) and [ … ], for long argument lists and collection expressions.
IndentScope — indent without braces, for continuation lines (generic constraints, chained calls).
RegionScope — #region name … #endregion.
DirectiveScope — #if COND … #endif.
PragmaScope — #pragma warning disable CSxxxx … #pragma warning restore CSxxxx, which is easy to get wrong by hand and leaks if unbalanced.
Directive and preamble helpers
WriteNullableEnable() / WriteNullableDisable().
WriteAutoGeneratedHeader(string? copyright = null) — the // <auto-generated /> preamble every generator emits.
WriteFileScopedNamespace(string) and WriteUsings(IEnumerable<string>), with consistent blank-line handling.
Each scope should follow the existing ktsu.ScopedAction pattern so it composes with using the same way Scope does, and should respect the configured indent string and newline (#81).
Notes
- Keep the additions purely additive — no change to
Scope / ScopeWithTrailingSemicolon.
- These are C#-flavoured but harmless for other curly-brace languages; if that becomes a problem, a later issue can split language-specific helpers into their own namespace.
- Balance is the point: an unbalanced
#pragma warning disable or #region in generated source is a compile-time or IDE-level annoyance that is tedious to trace back.
Acceptance criteria
Context
Part of ktsu-dev/Semantics#181 — generalizing the code-generation stack so more projects can use it.
Problem
CodeBlockerships exactly two scopes —Scope({…}) andScopeWithTrailingSemicolon({…};). Every real generator built on it re-implements the same handful of shapes on top of rawWriteLine.From
ktsu.Semantics'LogarithmicScalesGeneratoralone:None of that is domain-specific, and hand-writing it means every generator gets to invent its own spacing conventions.
Proposal
Add the shapes that recur in generated C#. Suggested surface, all opt-in:
Scopes
ParenScope/BracketScope—(…)and[…], for long argument lists and collection expressions.IndentScope— indent without braces, for continuation lines (generic constraints, chained calls).RegionScope—#region name…#endregion.DirectiveScope—#if COND…#endif.PragmaScope—#pragma warning disable CSxxxx…#pragma warning restore CSxxxx, which is easy to get wrong by hand and leaks if unbalanced.Directive and preamble helpers
WriteNullableEnable()/WriteNullableDisable().WriteAutoGeneratedHeader(string? copyright = null)— the// <auto-generated />preamble every generator emits.WriteFileScopedNamespace(string)andWriteUsings(IEnumerable<string>), with consistent blank-line handling.Each scope should follow the existing
ktsu.ScopedActionpattern so it composes withusingthe same wayScopedoes, and should respect the configured indent string and newline (#81).Notes
Scope/ScopeWithTrailingSemicolon.#pragma warning disableor#regionin generated source is a compile-time or IDE-level annoyance that is tedious to trace back.Acceptance criteria
README.mdgains a short example per new scope.Context
Part of ktsu-dev/Semantics#181 — generalizing the code-generation stack so more projects can use it.