Rocks icon indicating copy to clipboard operation
Rocks copied to clipboard

Improve Readability of Code Builders

Open MitchRazga opened this issue 1 month ago • 2 comments

Is your feature request related to a problem? Please describe. To make the code builders more readable, maintainable and performant, Rocks could make use of a custom InterpolatedStringHandler that automatically handles indentation, new-lines, string.Join etc.

With this, around 230 calls to writer.Indent could be removed entirely and the builder code would be significantly more readable. For example, code similar to below could now be a single call with an interpolated raw string literal:

writer.WriteLine($"internal {expectationsFullyQualifiedName}.Adornments.AdornmentsForHandler{memberIdentifier} This({instanceParameters})");
writer.WriteLine("{");
writer.Indent++;
writer.WriteLine("global::Rocks.Exceptions.ExpectationException.ThrowIf(this.Expectations.WasInstanceInvoked);");

I've developed one of these to use in my own codebase, so here is a snippet of what it can look like:

$$"""
// <auto-generated/>
#nullable enable

namespace {{containerNamespace}};

internal sealed partial class {{containerTypeName}} : {{interfaces:,}}
{
	private readonly Lock _lockObject = new();

	{{fields:newline}}

	public void Dispose()
	{
		{{disposables:newline}}
	}

	{{methods:newline}}
}
"""

Describe the solution you'd like Implement a SourceCodeInterpolatedStringHandler (or similar named) handler that will format code to simplify indentation, new-lines, string.Join etc.

Describe alternatives you've considered

  • Leave as is.
  • Increase the usage of raw string literals and interpolated strings where already possible.

Additional context With a custom InterpolatedStringHandler you can control internal buffers and format specific types differently. So in addition to readability, there are potentially signifcant performance benefits since you can now reuse buffers (reducing allocations), specify initial capacities (avoiding grow + copies that DefaultInterpolatedStringHandler will do) and avoid materializing intermediary strings.

Hopefully this will also reduce the time it takes to run Rocks.CodeGenerationTest a bit.

This would not change any generated code output but we may discover some existing indentation bugs.

MitchRazga avatar Oct 25 '25 17:10 MitchRazga

I would not be against this. I wrote a WriteLines() extension so I can do raw string literals with IndentedTextWriter when I can, but I'm sure I've missed some areas, and I don't think it's as efficient as it can be; it mostly helps with readability.

But again #394 is the main concern :)

JasonBock avatar Oct 26 '25 03:10 JasonBock

@MitchRazga I'll assign this to the 10.1.0 milestone. I don't think we'll have time to get this in with 10.0, but I'm interested in seeing what this can do, especially from a perf standpoint.

JasonBock avatar Nov 05 '25 13:11 JasonBock