From 4f2072884524c59f5cd75d1df4fad335b207a7e6 Mon Sep 17 00:00:00 2001 From: "fabien.menager" Date: Thu, 3 Aug 2023 21:16:25 +0200 Subject: [PATCH 1/2] Escape invalid identifiers for file constants --- src/ThisAssembly.Constants/Model.cs | 34 ++++++++++++++++--- .../Content/Docs/12. Readme (copy).txt | 1 + src/ThisAssembly.Tests/Tests.cs | 4 +++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/ThisAssembly.Tests/Content/Docs/12. Readme (copy).txt diff --git a/src/ThisAssembly.Constants/Model.cs b/src/ThisAssembly.Constants/Model.cs index 25ec0b69..f8664985 100644 --- a/src/ThisAssembly.Constants/Model.cs +++ b/src/ThisAssembly.Constants/Model.cs @@ -3,6 +3,8 @@ using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Text.RegularExpressions; +using Microsoft.CodeAnalysis.CSharp; [DebuggerDisplay("Values = {RootArea.Values.Count}")] record Model(Area RootArea) @@ -16,6 +18,27 @@ record Area(string Name, string Prefix) { public List NestedAreas { get; init; } = new(); public List Values { get; init; } = new(); + + private static string EscapeIdentifier(string identifier) + { + if (string.IsNullOrWhiteSpace(identifier)) + { + return "_"; + } + + var replaced = identifier + .Select(c => SyntaxFacts.IsIdentifierPartCharacter(c) ? c : '_') + .ToArray(); + + var result = Regex.Replace(new string(replaced), "(_)+", "_"); + + if (!SyntaxFacts.IsIdentifierStartCharacter(result[0])) + { + result = "_" + result; + } + + return result; + } public static Area Load(List constants, string rootArea = "Constants") { @@ -24,15 +47,18 @@ public static Area Load(List constants, string rootArea = "Constants") foreach (var constant in constants) { // Splits: ([area].)*[name] - var parts = constant.Name.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries); + var parts = constant.Name.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries) + .Select(EscapeIdentifier) + .ToArray(); + if (parts.Length <= 1) { - root.Values.Add(new Constant(constant.Name, constant.Value, constant.Comment)); + root.Values.Add(constant with { Name = EscapeIdentifier(constant.Name) }); } else { var area = GetArea(root, parts.Take(parts.Length - 1)); - var value = new Constant(parts.Skip(parts.Length - 1).First(), constant.Value, constant.Comment); + var value = constant with { Name = parts.Skip(parts.Length - 1).First() }; area.Values.Add(value); } @@ -74,4 +100,4 @@ static Area GetArea(Area area, IEnumerable areaPath) } [DebuggerDisplay("{Name} = {Value}")] -record Constant(string Name, string? Value, string? Comment); \ No newline at end of file +record Constant(string Name, string? Value, string? Comment); diff --git a/src/ThisAssembly.Tests/Content/Docs/12. Readme (copy).txt b/src/ThisAssembly.Tests/Content/Docs/12. Readme (copy).txt new file mode 100644 index 00000000..5f282702 --- /dev/null +++ b/src/ThisAssembly.Tests/Content/Docs/12. Readme (copy).txt @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/ThisAssembly.Tests/Tests.cs b/src/ThisAssembly.Tests/Tests.cs index 7a11d414..d9944274 100644 --- a/src/ThisAssembly.Tests/Tests.cs +++ b/src/ThisAssembly.Tests/Tests.cs @@ -35,6 +35,10 @@ public void CanUseConstants() public void CanUseFileConstants() => Assert.Equal(ThisAssembly.Constants.Content.Docs.License, Path.Combine("Content", "Docs", "License.md")); + [Fact] + public void CanUseFileConstantInvalidIdentifier() + => Assert.Equal(ThisAssembly.Constants.Content.Docs._12._Readme_copy_, Path.Combine("Content", "Docs", "12. Readme (copy).txt")); + [Fact] public void CanUseFileConstantLinkedFile() => Assert.Equal(ThisAssembly.Constants.Included.Readme, Path.Combine("Included", "Readme.txt")); From d940aa49531a9144e0c431e6b9690ca06d30b22f Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Wed, 30 Aug 2023 16:21:55 -0300 Subject: [PATCH 2/2] Apply dotnet format --- src/ThisAssembly.Constants/Model.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ThisAssembly.Constants/Model.cs b/src/ThisAssembly.Constants/Model.cs index f8664985..b48f7631 100644 --- a/src/ThisAssembly.Constants/Model.cs +++ b/src/ThisAssembly.Constants/Model.cs @@ -18,14 +18,14 @@ record Area(string Name, string Prefix) { public List NestedAreas { get; init; } = new(); public List Values { get; init; } = new(); - - private static string EscapeIdentifier(string identifier) + + static string EscapeIdentifier(string identifier) { if (string.IsNullOrWhiteSpace(identifier)) { return "_"; } - + var replaced = identifier .Select(c => SyntaxFacts.IsIdentifierPartCharacter(c) ? c : '_') .ToArray(); @@ -35,7 +35,7 @@ private static string EscapeIdentifier(string identifier) if (!SyntaxFacts.IsIdentifierStartCharacter(result[0])) { result = "_" + result; - } + } return result; } @@ -50,7 +50,7 @@ public static Area Load(List constants, string rootArea = "Constants") var parts = constant.Name.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries) .Select(EscapeIdentifier) .ToArray(); - + if (parts.Length <= 1) { root.Values.Add(constant with { Name = EscapeIdentifier(constant.Name) });