Skip to content

Commit 023a4ed

Browse files
authored
refactor: Remove code duplications in SmartFormatter (#396)
* Remove code duplications in SmartFormatter * Remove redudant usings * Unify preprocessor directives
1 parent b1d6a5d commit 023a4ed

File tree

12 files changed

+38
-55
lines changed

12 files changed

+38
-55
lines changed

src/SmartFormat.Tests/Core/FormatterExtensionsTests.cs

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ public void Formatters_Can_Be_Initialized()
3434
var guid = Guid.NewGuid().ToString("N");
3535
var negatedAutoDetection = formatter.CanAutoDetect;
3636
formatter.Name = guid;
37-
formatter.GetType().GetProperty("Names")?.SetValue(formatter, new[] {guid}); // "Names" property is obsolete
37+
formatter.GetType().GetProperty("Name")?.SetValue(formatter, guid); // "Names" property is obsolete
3838
Assert.Multiple(() =>
3939
{
40-
Assert.That(formatter.GetType().GetProperty("Names")?.GetValue(formatter), Is.EqualTo(new[] { guid })); // "Names" property is obsolete
40+
Assert.That(formatter.GetType().GetProperty("Name")?.GetValue(formatter), Is.EqualTo(guid)); // "Names" property is obsolete
4141
Assert.That(formatter.Name, Is.EqualTo(guid));
4242
});
4343

@@ -116,7 +116,6 @@ public void Conditional_Formatter_With_Parenthesis(bool value, string expected)
116116

117117
#region: Custom Extensions :
118118

119-
[Test]
120119
[TestCase("{0}", 5, "TestExtension1 Options: , Format: ")]
121120
[TestCase("{0:N2}", 5, "TestExtension1 Options: , Format: N2")]
122121
public void Without_NamedFormatter_extensions_are_invoked_in_order(string format, object arg0, string expectedResult)
@@ -126,7 +125,6 @@ public void Without_NamedFormatter_extensions_are_invoked_in_order(string format
126125
Assert.That(actualResult, Is.EqualTo(expectedResult));
127126
}
128127

129-
[Test]
130128
[TestCase("{0:test1:}", 5, "TestExtension1 Options: , Format: ")]
131129
[TestCase("{0:test1():}", 5, "TestExtension1 Options: , Format: ")]
132130
[TestCase("{0:test1:N2}", 5, "TestExtension1 Options: , Format: N2")]

src/SmartFormat.Tests/Extensions/ListFormatterTests.cs

-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using System;
2-
using System.Collections;
32
using System.Collections.Generic;
43
using System.Globalization;
54
using System.Linq;
6-
using System.Threading;
75
using System.Threading.Tasks;
86
using NUnit.Framework;
97
using SmartFormat.Core.Formatting;

src/SmartFormat.Tests/TestSetup.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ public void RunAfterAnyTests()
2828
{
2929
// Nothing defined here
3030
}
31-
}
31+
}

src/SmartFormat.Tests/TestUtils/Person.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ public Person(string newName, Gender gender, DateTime newBirthday, string newAdd
2323

2424
private static int GetRandomNumber(int min, int max)
2525
{
26-
#if !NET6_0_OR_GREATER
26+
#if NET6_0_OR_GREATER
27+
return RandomNumberGenerator.GetInt32(min, max);
28+
#else
2729
var randomNumber = new byte[4];
2830
using var rng = RandomNumberGenerator.Create();
2931
rng.GetBytes(randomNumber);
3032
return Math.Abs(BitConverter.ToInt32(randomNumber, 0) % 10) + 1;
31-
#else
32-
return RandomNumberGenerator.GetInt32(min, max);
3333
#endif
3434
}
3535

src/SmartFormat/Core/Formatting/FormatDetails.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,4 @@ internal void Clear()
111111
Provider = null;
112112
FormattingException = null;
113113
}
114-
}
114+
}

src/SmartFormat/Core/Formatting/FormattingInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public void FormatAsChild(Format format, object? value)
186186
// recursive method call
187187
FormatDetails.Formatter.Format(nestedFormatInfo);
188188
}
189-
189+
190190
/// <summary>
191191
/// Creates a new <see cref="FormattingException"/>.
192192
/// </summary>
@@ -251,4 +251,4 @@ private void PostAlign(int textLength)
251251
var filler = -Alignment - textLength;
252252
if (filler > 0) FormatDetails.Output.Write(new string(FormatDetails.Settings.Formatter.AlignmentFillCharacter, filler), this);
253253
}
254-
}
254+
}

src/SmartFormat/Core/Formatting/ISelectorInfo.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,4 @@ public interface ISelectorInfo
5656
/// </summary>
5757
[EditorBrowsable(EditorBrowsableState.Advanced)]
5858
FormatDetails FormatDetails { get; }
59-
}
59+
}

src/SmartFormat/Core/Parsing/Format.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ public IList<Format> Split(char search, int maxCount)
310310
{
311311
var splits = FindAll(search, maxCount);
312312
var splitList = SplitListPool.Instance.Get().Initialize(this, splits);
313-
313+
314314
// Keep track of the split lists we create,
315315
// so that they can be returned to the object pool for later reuse.
316316
_listOfSplitLists.Add(splitList);

src/SmartFormat/Core/Parsing/Parser.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
using System;
66
using System.Collections.Generic;
7-
using System.Linq;
87
using System.Runtime.CompilerServices;
98
using SmartFormat.Core.Settings;
109
using SmartFormat.Pooling.SmartPools;
@@ -24,7 +23,7 @@ public class Parser
2423
private IndexContainer _index;
2524
private string _inputFormat;
2625
private Format _resultFormat;
27-
26+
2827
#endregion
2928

3029
#region: Settings :

src/SmartFormat/SmartFormatter.cs

+25-36
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//
1+
//
22
// Copyright SmartFormat Project maintainers and contributors.
33
// Licensed under the MIT license.
44

@@ -255,7 +255,7 @@ public string Format(string format, params object?[] args)
255255
{
256256
return Format(null, format, (IList<object?>) args);
257257
}
258-
258+
259259
/// <summary>
260260
/// Replaces one or more format items in as specified string with the string representation of a specific object.
261261
/// </summary>
@@ -289,20 +289,9 @@ public string Format(IFormatProvider? provider, string format, params object?[]
289289
public string Format(IFormatProvider? provider, string format, IList<object?> args)
290290
{
291291
var formatParsed = Parser.ParseFormat(format); // The parser gets the Format from the pool
292-
293-
// Note: Making ZStringOutput a class instance variable has no advantage for speed,
294-
// but brings 10% less Gen 0 GC. Then, SmartFormatter would have to be IDisposable (dispose ZStringOutput)
295-
using var zsOutput = new ZStringOutput(ZStringBuilderUtilities.CalcCapacity(formatParsed));
296-
297-
var current = args.Count > 0 ? args[0] : args; // The first item is the default.
298-
299-
var formatDetails = FormatDetailsPool.Instance.Get().Initialize(this, formatParsed, args, provider, zsOutput);
300-
Format(formatDetails, formatParsed, current);
301-
302-
FormatDetailsPool.Instance.Return(formatDetails);
303-
FormatPool.Instance.Return(formatParsed);
304-
305-
return zsOutput.ToString();
292+
var result = Format(provider, formatParsed, args);
293+
FormatPool.Instance.Return(formatParsed);
294+
return result;
306295
}
307296

308297
#region ** Format overloads with cached Format **
@@ -353,15 +342,12 @@ public string Format(IFormatProvider? provider, Format formatParsed, IList<objec
353342
// Note: Making ZStringOutput a class instance variable has no advantage for speed,
354343
// but brings 10% less Gen 0 GC. Then, SmartFormatter would have to be IDisposable (to dispose ZStringOutput)
355344
using var zsOutput = new ZStringOutput(ZStringBuilderUtilities.CalcCapacity(formatParsed));
356-
var current = args.Count > 0 ? args[0] : args; // The first item is the default.
357-
var formatDetails = FormatDetailsPool.Instance.Get().Initialize(this, formatParsed, args, provider, zsOutput);
358-
Format(formatDetails, formatParsed, current);
359-
FormatDetailsPool.Instance.Return(formatDetails);
345+
FormatInto(zsOutput, provider, formatParsed, args);
360346
return zsOutput.ToString();
361347
}
362348

363349
#endregion
364-
350+
365351
/// <summary>
366352
/// Format the <see cref="FormattingInfo" /> argument.
367353
/// </summary>
@@ -407,7 +393,7 @@ public void Format(FormattingInfo formattingInfo)
407393
}
408394
}
409395
}
410-
396+
411397
private void Format(FormatDetails formatDetails, Format format, object? current)
412398
{
413399
var formattingInfo = FormattingInfoPool.Instance.Get().Initialize(formatDetails, format, current);
@@ -488,11 +474,11 @@ public void FormatInto(IOutput output, IFormatProvider? provider, Format formatP
488474
#endregion
489475

490476
#endregion
491-
477+
492478
#region: Private methods :
493479

494-
private void FormatError(FormatItem errorItem, Exception innerException, int startIndex,
495-
FormattingInfo formattingInfo)
480+
internal void FormatError(FormatItem errorItem, Exception innerException, int startIndex,
481+
IFormattingInfo formattingInfo)
496482
{
497483
OnFormattingFailure?.Invoke(this,
498484
new FormattingErrorEventArgs(errorItem.RawText, startIndex,
@@ -537,24 +523,26 @@ private void CheckForExtensions()
537523
/// Example: "{ChildOne.ChildTwo.ChildThree: {Four}}" where "{Four}" is a child placeholder.
538524
/// </remarks>
539525
/// <param name="formattingInfo"></param>
526+
/// <exception cref="FormattingException"></exception>
540527
private void EvaluateSelectors(FormattingInfo formattingInfo)
541528
{
542529
if (formattingInfo.Placeholder is null) return;
543-
530+
544531
var firstSelector = true;
545532
foreach (var selector in formattingInfo.Placeholder.Selectors)
546533
{
547534
// Don't evaluate empty selectors
548535
// (used e.g. for Settings.Parser.NullableOperator and Settings.Parser.ListIndexEndChar final operators)
549-
if(selector.Length == 0) continue;
550-
536+
if (selector.Length == 0) continue;
537+
538+
// Ensure ISelectorInfo implementation returns the current selector values
551539
formattingInfo.Selector = selector;
552540
// Do not evaluate alignment-only selectors
553541
if (formattingInfo.SelectorOperator.Length > 0 &&
554542
formattingInfo.SelectorOperator[0] == Settings.Parser.AlignmentOperator) continue;
555-
543+
556544
formattingInfo.Result = null;
557-
545+
558546
var handled = InvokeSourceExtensions(formattingInfo);
559547
if (handled) formattingInfo.CurrentValue = formattingInfo.Result;
560548

@@ -567,6 +555,7 @@ private void EvaluateSelectors(FormattingInfo formattingInfo)
567555
while (!handled && parentFormattingInfo.Parent != null)
568556
{
569557
parentFormattingInfo = parentFormattingInfo.Parent;
558+
// Ensure ISelectorInfo implementation returns the current selector values
570559
parentFormattingInfo.Selector = selector;
571560
parentFormattingInfo.Result = null;
572561
handled = InvokeSourceExtensions(parentFormattingInfo);
@@ -580,12 +569,12 @@ private void EvaluateSelectors(FormattingInfo formattingInfo)
580569
}
581570
}
582571

583-
private bool InvokeSourceExtensions(FormattingInfo formattingInfo)
572+
private bool InvokeSourceExtensions(ISelectorInfo selectorInfo)
584573
{
585574
// less GC than using Linq
586575
foreach (var sourceExtension in _sourceExtensions)
587576
{
588-
var handled = sourceExtension.TryEvaluateSelector(formattingInfo);
577+
var handled = sourceExtension.TryEvaluateSelector(selectorInfo);
589578
if (handled) return true;
590579
}
591580

@@ -623,7 +612,7 @@ private bool InvokeFormatterExtensions(FormattingInfo formattingInfo)
623612
// Compatibility mode does not support formatter extensions except this one:
624613
if (Settings.StringFormatCompatibility)
625614
{
626-
return
615+
return
627616
_formatterExtensions.First(fe => fe is DefaultFormatter)
628617
.TryEvaluateFormat(formattingInfo);
629618
}
@@ -636,18 +625,18 @@ private bool InvokeFormatterExtensions(FormattingInfo formattingInfo)
636625
foreach (var fe in _formatterExtensions)
637626
{
638627
if (!fe.Name.Equals(formatterName, comparison)) continue;
639-
628+
640629
formatterExtension = fe;
641630
break;
642631
}
643-
632+
644633
if (formatterExtension is null)
645634
throw formattingInfo.FormattingException($"No formatter with name '{formatterName}' found",
646635
formattingInfo.Format, formattingInfo.Selector?.SelectorIndex ?? -1);
647636

648637
return formatterExtension.TryEvaluateFormat(formattingInfo);
649638
}
650-
639+
651640
// Go through all (implicit) formatters which contain an empty name
652641
// much higher performance and less GC than using Linq
653642
foreach (var fe in _formatterExtensions)

src/SmartFormat/ZString/ZStringBuilder.cs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Diagnostics.CodeAnalysis;
8-
using System.Runtime.InteropServices.ComTypes;
98
using Cysharp.Text;
109

1110
namespace SmartFormat.ZString;

src/SmartFormat/ZString/ZStringWriter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public override string ToString()
144144
return _zw.ToString();
145145
}
146146

147-
#if !NETSTANDARD2_0 && !NETFRAMEWORK
147+
#if NETSTANDARD2_1 || NET6_0_OR_GREATER
148148

149149
/// <summary>
150150
/// Writes a span of characters.

0 commit comments

Comments
 (0)