Skip to content

Commit dbb65a4

Browse files
committed
chore: Update the implementation
1 parent fd80981 commit dbb65a4

File tree

7 files changed

+124
-367
lines changed

7 files changed

+124
-367
lines changed

src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Append.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public CSharpCodeBuilder Append(string? value)
197197
return this;
198198
}
199199

200-
if (value is "\n" or "\r")
200+
if (value is "\n" or "\r" or "\r\n")
201201
{
202202
return AppendLine(); // Handle new line characters
203203
}

src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Documentation.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ public CSharpCodeBuilder AppendXmlDocRemarks(string? remarks)
129129

130130
return EnsureNewLineForXmlDoc()
131131
.AppendLine("/// <remarks>")
132-
.AppendLine($"/// {remarks}")
132+
.Append("/// ")
133+
.AppendLine(remarks)
133134
.AppendLine("/// </remarks>");
134135
}
135136

@@ -176,6 +177,17 @@ public CSharpCodeBuilder AppendXmlDocException(string? exceptionType, string? de
176177
.AppendLine($"/// <exception cref=\"{exceptionType}\">{description}</exception>");
177178
}
178179

180+
/// <summary>
181+
/// Appends an XML documentation exception element.
182+
/// </summary>
183+
/// <param name="description">The description of when the exception is thrown.</param>
184+
/// <typeparam name="TException">The type of exception that can be thrown. Must be a subclass of <see cref="Exception"/>.</typeparam>
185+
/// <returns>The current <see cref="CSharpCodeBuilder"/> instance to allow for method chaining.</returns>
186+
/// <remarks>If the exception type or description is null or empty, the method returns without appending anything.</remarks>
187+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
188+
public CSharpCodeBuilder AppendXmlDocException<TException>(string? description)
189+
where TException : Exception => AppendXmlDocException(typeof(TException).Name, description);
190+
179191
/// <summary>
180192
/// Appends multiple XML documentation exception elements.
181193
/// </summary>

src/NetEvolve.CodeBuilder/CSharpCodeBuilder.Scope.cs

Lines changed: 67 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,75 +2,6 @@
22

33
using System;
44

5-
/// <summary>
6-
/// A disposable struct that manages indentation scope for a <see cref="CSharpCodeBuilder"/>.
7-
/// </summary>
8-
/// <remarks>
9-
/// This struct increments the indentation level when created and decrements it when disposed.
10-
/// It is designed to work with the 'using' statement to provide automatic indentation management.
11-
/// </remarks>
12-
public readonly struct ScopeHandler : IDisposable, IEquatable<ScopeHandler>
13-
{
14-
private readonly CSharpCodeBuilder _builder;
15-
16-
/// <summary>
17-
/// Initializes a new instance of the <see cref="ScopeHandler"/> struct and increments the indentation level.
18-
/// </summary>
19-
/// <param name="builder">The <see cref="CSharpCodeBuilder"/> instance to manage indentation for.</param>
20-
internal ScopeHandler(CSharpCodeBuilder builder)
21-
{
22-
_builder = builder;
23-
_builder.IncrementIndent();
24-
}
25-
26-
/// <summary>
27-
/// Decrements the indentation level when the scope is disposed.
28-
/// </summary>
29-
/// <remarks>
30-
/// This method is called automatically when the 'using' statement block ends.
31-
/// </remarks>
32-
public void Dispose()
33-
{
34-
_builder?.DecrementIndent();
35-
}
36-
37-
/// <summary>
38-
/// Determines whether the specified object is equal to the current instance.
39-
/// </summary>
40-
/// <param name="obj">The object to compare with the current instance.</param>
41-
/// <returns>Always returns <c>false</c> since ScopeHandler instances should not be compared.</returns>
42-
public override readonly bool Equals(object? obj) => false;
43-
44-
/// <summary>
45-
/// Determines whether the specified ScopeHandler is equal to the current instance.
46-
/// </summary>
47-
/// <param name="other">The ScopeHandler to compare with the current instance.</param>
48-
/// <returns>Always returns <c>false</c> since ScopeHandler instances should not be compared.</returns>
49-
public readonly bool Equals(ScopeHandler other) => false;
50-
51-
/// <summary>
52-
/// Returns the hash code for this instance.
53-
/// </summary>
54-
/// <returns>A hash code based on the internal builder reference.</returns>
55-
public override readonly int GetHashCode() => _builder?.GetHashCode() ?? 0;
56-
57-
/// <summary>
58-
/// Determines whether two ScopeHandler instances are equal.
59-
/// </summary>
60-
/// <param name="left">The first instance to compare.</param>
61-
/// <param name="right">The second instance to compare.</param>
62-
/// <returns>Always returns <c>false</c> since ScopeHandler instances should not be compared.</returns>
63-
public static bool operator ==(ScopeHandler left, ScopeHandler right) => false;
64-
65-
/// <summary>
66-
/// Determines whether two ScopeHandler instances are not equal.
67-
/// </summary>
68-
/// <param name="left">The first instance to compare.</param>
69-
/// <param name="right">The second instance to compare.</param>
70-
/// <returns>Always returns <c>true</c> since ScopeHandler instances should not be compared.</returns>
71-
public static bool operator !=(ScopeHandler left, ScopeHandler right) => true;
72-
}
73-
745
public partial record CSharpCodeBuilder
756
{
767
/// <summary>
@@ -90,5 +21,71 @@ public partial record CSharpCodeBuilder
9021
/// }
9122
/// </code>
9223
/// </example>
93-
public ScopeHandler Scope() => new(this);
24+
public IDisposable Scope() => new ScopeHandler(this);
25+
26+
/// <summary>
27+
/// A disposable struct that manages indentation scope for a <see cref="CSharpCodeBuilder"/>.
28+
/// </summary>
29+
/// <remarks>
30+
/// This struct increments the indentation level when created and decrements it when disposed.
31+
/// It is designed to work with the 'using' statement to provide automatic indentation management.
32+
/// </remarks>
33+
private readonly struct ScopeHandler : IDisposable, IEquatable<ScopeHandler>
34+
{
35+
private readonly CSharpCodeBuilder _builder;
36+
37+
/// <summary>
38+
/// Initializes a new instance of the <see cref="ScopeHandler"/> struct and increments the indentation level.
39+
/// </summary>
40+
/// <param name="builder">The <see cref="CSharpCodeBuilder"/> instance to manage indentation for.</param>
41+
internal ScopeHandler(CSharpCodeBuilder builder)
42+
{
43+
_builder = builder;
44+
_ = _builder.Append('{');
45+
}
46+
47+
/// <summary>
48+
/// Decrements the indentation level when the scope is disposed.
49+
/// </summary>
50+
/// <remarks>
51+
/// This method is called automatically when the 'using' statement block ends.
52+
/// </remarks>
53+
public void Dispose() => _ = _builder.Append('}');
54+
55+
/// <summary>
56+
/// Determines whether the specified object is equal to the current instance.
57+
/// </summary>
58+
/// <param name="obj">The object to compare with the current instance.</param>
59+
/// <returns>Always returns <c>false</c> since ScopeHandler instances should not be compared.</returns>
60+
public override readonly bool Equals(object? obj) => false;
61+
62+
/// <summary>
63+
/// Determines whether the specified ScopeHandler is equal to the current instance.
64+
/// </summary>
65+
/// <param name="other">The ScopeHandler to compare with the current instance.</param>
66+
/// <returns>Always returns <c>false</c> since ScopeHandler instances should not be compared.</returns>
67+
public readonly bool Equals(ScopeHandler other) => false;
68+
69+
/// <summary>
70+
/// Returns the hash code for this instance.
71+
/// </summary>
72+
/// <returns>A hash code based on the internal builder reference.</returns>
73+
public override readonly int GetHashCode() => _builder?.GetHashCode() ?? 0;
74+
75+
/// <summary>
76+
/// Determines whether two ScopeHandler instances are equal.
77+
/// </summary>
78+
/// <param name="_">The first instance to compare.</param>
79+
/// <param name="__">The second instance to compare.</param>
80+
/// <returns>Always returns <c>false</c> since ScopeHandler instances should not be compared.</returns>
81+
public static bool operator ==(ScopeHandler _, ScopeHandler __) => false;
82+
83+
/// <summary>
84+
/// Determines whether two ScopeHandler instances are not equal.
85+
/// </summary>
86+
/// <param name="_">The first instance to compare.</param>
87+
/// <param name="__">The second instance to compare.</param>
88+
/// <returns>Always returns <c>true</c> since ScopeHandler instances should not be compared.</returns>
89+
public static bool operator !=(ScopeHandler _, ScopeHandler __) => true;
90+
}
9491
}

tests/NetEvolve.CodeBuilder.Tests.Integration/CSharpCodeBuilderTests.Formatting.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace NetEvolve.CodeBuilder.Tests.Integration;
1+
namespace NetEvolve.CodeBuilder.Tests.Integration;
22

33
public partial class CSharpCodeBuilderTests
44
{
@@ -114,4 +114,30 @@ public async Task GenerateEnum_WithDocumentation_Should_ProduceCorrectOutput()
114114

115115
_ = await Verify(result);
116116
}
117+
118+
[Test]
119+
public async Task Scopes_in_wild_nature()
120+
{
121+
var builder = new CSharpCodeBuilder()
122+
.AppendLine("namespace Hello.World;")
123+
.AppendLine()
124+
.AppendXmlDocSummary("Represents the status of an order.")
125+
.AppendLine("public enum Weekday");
126+
127+
using (builder.Scope())
128+
{
129+
_ = builder
130+
.AppendLine("Monday,")
131+
.AppendLine("Tuesday,")
132+
.AppendLine("Wednesday,")
133+
.AppendLine("Thursday,")
134+
.AppendLine("Friday,")
135+
.AppendLine("Saturday,")
136+
.AppendLine("Sunday,");
137+
}
138+
139+
var result = builder.ToString();
140+
141+
_ = await Verify(result);
142+
}
117143
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace Hello.World;
2+
3+
/// <summary>
4+
/// Represents the status of an order.
5+
/// </summary>
6+
public enum Weekday
7+
{
8+
Monday,
9+
Tuesday,
10+
Wednesday,
11+
Thursday,
12+
Friday,
13+
Saturday,
14+
Sunday,
15+
}

tests/NetEvolve.CodeBuilder.Tests.Unit/CSharpCodeBuilderTests.Documentation.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -726,7 +726,7 @@ public async Task AppendXmlDocException_WithGenericExceptionType_Should_AppendCo
726726
{
727727
var builder = new CSharpCodeBuilder();
728728

729-
var result = builder.AppendXmlDocException("InvalidOperationException", "Thrown when the operation is invalid");
729+
var result = builder.AppendXmlDocException<InvalidOperationException>("Thrown when the operation is invalid");
730730

731731
_ = await Assert.That(result).IsEqualTo(builder);
732732
_ = await Assert

0 commit comments

Comments
 (0)