Skip to content

Busywork: build-tools; investigate / refactor to use IndentedTextWriter #3033

@mgravell

Description

@mgravell

tech-debt; context: generators in /eng/StackExchange.Redis.Build

(note that this has extensive changes in #3028, so do not touch until #3028 is merged)

PR feedback from #3028:

Suggest using System.CodeDom.Compiler.IndentedTextWriter here - handy for cleaner generation downstream

We currently use a StringBuilder with some simple counter logic to emit appropriately idiomatic C#, i.e. indented to the correct level to account for namespace/type-nesting, and all scopes inside that - methods/properties, if/while, etc; this is the same concept, but centralized; downside is that we lose the builder-style API; a compromise might be to wrap the IndentedTextWriter in our own readonly struct that simply re-exports the API, which could make the work minimal, i.e. (thought experiment only)

readonly struct OurCustomWriter(TextWriter output) : IDisposable {
    private readonly IndentedTextWriter inner = new(output);

    // various append etc lines here, builder-style

    public void Indent() => inner.Indent++; // possibly builder style
    public void Outdent() => inner.Indent--; // possibly builder style
    public void Dispose() => inner.Flush();
}

Similarly valid proposition: there's nothing special or precious about IndentedTextWriter; maybe simply doing a better job of wrapping our existing logic is sufficient?

sealed class OurCustomWriter() {
    private int indent;
    private readonly StringBuilder buffer = new();

    // various append etc lines here, builder-style, apply indent on fresh lines, etc

    public void Indent() => indent++; // possibly builder style
    public void Outdent() => indent--; // possibly builder style
    public string ToString() => buffer.ToString();
}

Technically there are also side benefits like being able to add efficient DISH-based append implementations, but: this is probably a moot point since DISH doesn't get the necessary APIs (.Text in particular) until .NET 10, and analyzers target netstandard2.0, and the more evil but usable [UnsafeAccessor] hack also requires runtime support: so: let's not even think about that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ⚙️ area:enginternal engineering changes; should not impact functionality or API🙌 up-for-grabs

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions