diff options
author | pCYSl5EDgo <31692496+pCYSl5EDgo@users.noreply.github.com> | 2022-02-13 00:14:41 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-13 00:14:41 +0300 |
commit | 8da2ab05f9cc1b1c2c3dd5e32a57ec57ecb4dbd8 (patch) | |
tree | ab791d4d8e610c6249b64b4ae62e34baa11b7980 | |
parent | 71a223ac73b9e91a82ecbcdf4119f47d1262711a (diff) |
Fix nullable annotation errorneous handling (#1395)
* Fix nullable member file name handling
Generating multiple files including the letter '?'.
Invalid file name char should be avoided.
-rw-r--r-- | global.json | 2 | ||||
-rw-r--r-- | sandbox/TestData2/A.cs | 3 | ||||
-rw-r--r-- | sandbox/TestData2/B.cs | 3 | ||||
-rw-r--r-- | sandbox/TestData2/C.cs | 3 | ||||
-rw-r--r-- | src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs | 7 | ||||
-rw-r--r-- | src/MessagePack.GeneratorCore/CodeGenerator.cs | 72 |
6 files changed, 79 insertions, 11 deletions
diff --git a/global.json b/global.json index d46619b0..2645bb53 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.101", + "version": "6.0.102", "rollForward": "patch", "allowPrerelease": false } diff --git a/sandbox/TestData2/A.cs b/sandbox/TestData2/A.cs index d32265ab..a7eeef9d 100644 --- a/sandbox/TestData2/A.cs +++ b/sandbox/TestData2/A.cs @@ -3,11 +3,12 @@ #pragma warning disable SA1307 // Accessible fields should begin with upper-case letter #pragma warning disable SA1401 // Fields should be private +#nullable enable namespace TestData2; [MessagePackObject(true)] public class A { - public int a; public List<B> bs; public C c; + public int a; public List<B?>? bs; public C? c; } diff --git a/sandbox/TestData2/B.cs b/sandbox/TestData2/B.cs index 70e9f358..d9c4029e 100644 --- a/sandbox/TestData2/B.cs +++ b/sandbox/TestData2/B.cs @@ -3,11 +3,12 @@ #pragma warning disable SA1307 // Accessible fields should begin with upper-case letter #pragma warning disable SA1401 // Fields should be private +#nullable enable namespace TestData2; [MessagePackObject(true)] public class B { - public List<A> ass; public C c; public int a; + public List<A?>? ass; public C? c; public int a; } diff --git a/sandbox/TestData2/C.cs b/sandbox/TestData2/C.cs index 5de4a080..741517ff 100644 --- a/sandbox/TestData2/C.cs +++ b/sandbox/TestData2/C.cs @@ -3,11 +3,12 @@ #pragma warning disable SA1307 // Accessible fields should begin with upper-case letter #pragma warning disable SA1401 // Fields should be private +#nullable enable namespace TestData2; [MessagePackObject(true)] public class C { - public B b; public int a; + public B? b; public int a; } diff --git a/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs b/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs index d2537dcd..935ceb87 100644 --- a/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs +++ b/src/MessagePack.GeneratorCore/CodeAnalysis/TypeCollector.cs @@ -971,10 +971,11 @@ namespace MessagePackCompiler.CodeAnalysis { var name = type.ContainingType is object ? GetMinimallyQualifiedClassName(type.ContainingType) + "_" : string.Empty; name += type.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat); - name = name.Replace(".", "_"); - name = name.Replace("<", "_"); - name = name.Replace(">", "_"); + name = name.Replace('.', '_'); + name = name.Replace('<', '_'); + name = name.Replace('>', '_'); name = Regex.Replace(name, @"\[([,])*\]", match => $"Array{match.Length - 1}"); + name = name.Replace("?", string.Empty); return name; } diff --git a/src/MessagePack.GeneratorCore/CodeGenerator.cs b/src/MessagePack.GeneratorCore/CodeGenerator.cs index f9654693..1f48973e 100644 --- a/src/MessagePack.GeneratorCore/CodeGenerator.cs +++ b/src/MessagePack.GeneratorCore/CodeGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; @@ -16,6 +17,8 @@ namespace MessagePackCompiler { public class CodeGenerator { + private static readonly HashSet<char> InvalidFileCharSet = new(Path.GetInvalidFileNameChars()); + private static readonly Encoding NoBomUtf8 = new UTF8Encoding(false); private readonly Action<string> logger; @@ -212,15 +215,76 @@ namespace MessagePackCompiler private Task OutputToDirAsync(string dir, string ns, string name, string multipleOutSymbol, string text) { - if (multipleOutSymbol == string.Empty) + var builder = new StringBuilder(); + void AppendDir(string dir) + { + if (dir.Length != 0) + { + builder.Append(dir); + if (dir[dir.Length - 1] != Path.DirectorySeparatorChar && dir[dir.Length - 1] != Path.AltDirectorySeparatorChar) + { + builder.Append(Path.DirectorySeparatorChar); + } + } + } + + void AppendChar(char c) + { + if (c == '.' || InvalidFileCharSet.Contains(c)) + { + builder.Append('_'); + } + else + { + builder.Append(c); + } + } + + void Append(string text) { - return OutputAsync(Path.Combine(dir, $"{ns}_{name}".Replace(".", "_").Replace("global::", string.Empty) + ".cs"), text); + var span = text.AsSpan(); + while (!span.IsEmpty) + { + var index = span.IndexOf("global::".AsSpan()); + if (index == -1) + { + foreach (var c in span) + { + AppendChar(c); + } + + break; + } + + if (index == 0) + { + span = span.Slice("global::".Length); + continue; + } + + foreach (var c in span.Slice(0, index)) + { + AppendChar(c); + } + + span = span.Slice(index + "global::".Length); + } } - else + + AppendDir(dir); + + if (!string.IsNullOrWhiteSpace(multipleOutSymbol)) { text = $"#if {multipleOutSymbol}" + Environment.NewLine + text + Environment.NewLine + "#endif"; - return OutputAsync(Path.Combine(dir, MultiSymbolToSafeFilePath(multipleOutSymbol), $"{ns}_{name}".Replace(".", "_").Replace("global::", string.Empty) + ".cs"), text); + AppendDir(MultiSymbolToSafeFilePath(multipleOutSymbol)); } + + Append(ns); + builder.Append('_'); + Append(name); + builder.Append(".cs"); + + return OutputAsync(builder.ToString(), text); } private Task OutputAsync(string path, string text) |