From 977424ef52d6303a0f132c11713abb804b37b36d Mon Sep 17 00:00:00 2001 From: Scott Beca Date: Thu, 9 Nov 2023 10:19:27 +1100 Subject: [PATCH] Fix some compiler errors that can occur with specific project setups --- contributing.md | 2 +- src/Consume/Consume.cs | 4 +++ src/Consume/Debug.cs | 29 +++++++++++++++++ .../ConsumeTasksWithNoMemory.csproj | 31 +++++++++++++++++++ src/Polyfill.sln | 6 ++++ src/Polyfill/Nullability/NullabilityInfo.cs | 1 + .../Nullability/NullabilityInfoContext.cs | 5 +++ src/Polyfill/PolyfillExtensions_Stream.cs | 4 +++ src/Polyfill/PolyfillExtensions_TextReader.cs | 2 +- src/Polyfill/PolyfillExtensions_TextWriter.cs | 2 +- src/Tests/NullabilitySync.cs | 15 +++++++++ 11 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/Consume/Debug.cs create mode 100644 src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj diff --git a/contributing.md b/contributing.md index cf958675..c8c03b35 100644 --- a/contributing.md +++ b/contributing.md @@ -192,7 +192,7 @@ Example: #pragma warning disable -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; diff --git a/src/Consume/Consume.cs b/src/Consume/Consume.cs index 7aabcae1..a7074f5d 100644 --- a/src/Consume/Consume.cs +++ b/src/Consume/Consume.cs @@ -98,6 +98,10 @@ class Consume var split = "a b".Split(' ', StringSplitOptions.RemoveEmptyEntries); split = "a b".Split(' ', 2, StringSplitOptions.RemoveEmptyEntries); var contains = "a b".Contains(' '); + + // Test to make sure there are no clashes in the Polyfill code with classes that + // might be defined in user code. See comments in Debug.cs for more details. + Debug.Log("Test log to make sure this is working"); } #if HTTPREFERENCED diff --git a/src/Consume/Debug.cs b/src/Consume/Debug.cs new file mode 100644 index 00000000..0b05cf42 --- /dev/null +++ b/src/Consume/Debug.cs @@ -0,0 +1,29 @@ +using System; + +// Test to make sure there are no clashes in the Polyfill code with classes that might be defined in user code. +// +// Some codebases, for better or for worse, define classes with names that match common classes in the base +// .NET libraries, like "Debug". This works find in those codebases because they are usually contained in the +// same namespace, or are guarded in some other way. But if a Polyfill attribute is imported and uses code like: +// Debug.Assert(genericParameter.IsGenericParameter); +// instead of a fully qualified name like: +// System.Debug.Assert(genericParameter.IsGenericParameter); +// then users of Polyfill will get errors like the following, which they can't easily fix: +// 'Debug' does not contain a definition for 'Assert' +// +// So, this file defines a custom Debug class to make sure that Polyfill code doesn't clash with user code. + +class Debug +{ + public static void Log(string content) => Console.WriteLine(content); + + public static void Log(ConsoleColor color, string content) + { + Console.ForegroundColor = color; + Console.WriteLine(content); + Console.ResetColor(); + } + + public static void LogWarning(string content) => Log(ConsoleColor.Yellow, content); + public static void LogError(string content) => Log(ConsoleColor.Red, content); +} diff --git a/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj new file mode 100644 index 00000000..7d099a5b --- /dev/null +++ b/src/ConsumeTasksWithNoMemory/ConsumeTasksWithNoMemory.csproj @@ -0,0 +1,31 @@ + + + true + netstandard2.0 + + + + + + + Pollyfill\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullable\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Nullability\%(RecursiveDir)%(Filename).cs + + + Pollyfill\IndexRange\%(RecursiveDir)%(Filename).cs + + + Pollyfill\Trimming\%(RecursiveDir)%(Filename).cs + + + Pollyfill\PlatformCompatibility\%(RecursiveDir)%(Filename).cs + + + + + \ No newline at end of file diff --git a/src/Polyfill.sln b/src/Polyfill.sln index 281d2726..f4df45fe 100644 --- a/src/Polyfill.sln +++ b/src/Polyfill.sln @@ -33,6 +33,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoRefsTests", "NoRefsTests\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeNoRefs", "ConsumeNoRefs\ConsumeNoRefs.csproj", "{B4DC96CA-C700-499F-A9A2-0C767DCF8C30}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsumeTasksWithNoMemory", "ConsumeTasksWithNoMemory\ConsumeTasksWithNoMemory.csproj", "{96EF1E04-5862-4D9E-B800-A6402F1ADF7A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,6 +77,10 @@ Global {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4DC96CA-C700-499F-A9A2-0C767DCF8C30}.Release|Any CPU.Build.0 = Release|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {96EF1E04-5862-4D9E-B800-A6402F1ADF7A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Polyfill/Nullability/NullabilityInfo.cs b/src/Polyfill/Nullability/NullabilityInfo.cs index 65b3d0db..5fc4d8b5 100644 --- a/src/Polyfill/Nullability/NullabilityInfo.cs +++ b/src/Polyfill/Nullability/NullabilityInfo.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Diagnostics.CodeAnalysis; + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. diff --git a/src/Polyfill/Nullability/NullabilityInfoContext.cs b/src/Polyfill/Nullability/NullabilityInfoContext.cs index a2939cdb..4ac7d429 100644 --- a/src/Polyfill/Nullability/NullabilityInfoContext.cs +++ b/src/Polyfill/Nullability/NullabilityInfoContext.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Diagnostics.CodeAnalysis; + // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. @@ -15,6 +16,10 @@ namespace System.Reflection { + // Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. + // See comments in Debug.cs in Consume project for more details. + using Debug = System.Diagnostics.Debug; + /// /// Provides APIs for populating nullability information/context from reflection members: /// , , and . diff --git a/src/Polyfill/PolyfillExtensions_Stream.cs b/src/Polyfill/PolyfillExtensions_Stream.cs index ed0ebb88..a5bba95c 100644 --- a/src/Polyfill/PolyfillExtensions_Stream.cs +++ b/src/Polyfill/PolyfillExtensions_Stream.cs @@ -13,6 +13,8 @@ static partial class PolyfillExtensions { +#if MEMORYREFERENCED + /// /// Asynchronously reads a sequence of bytes from the current stream, advances the position within the stream by /// the number of bytes read, and monitors cancellation requests. @@ -64,6 +66,8 @@ public static ValueTask WriteAsync( return new(target.WriteAsync(segment.Array!, segment.Offset, segment.Count, cancellationToken)); } +#endif + /// /// Asynchronously reads the bytes from the current stream and writes them to another stream, using a specified /// cancellation token. Both streams positions are advanced by the number of bytes copied. diff --git a/src/Polyfill/PolyfillExtensions_TextReader.cs b/src/Polyfill/PolyfillExtensions_TextReader.cs index 125951cb..e0db7e30 100644 --- a/src/Polyfill/PolyfillExtensions_TextReader.cs +++ b/src/Polyfill/PolyfillExtensions_TextReader.cs @@ -11,7 +11,7 @@ static partial class PolyfillExtensions { -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) /// /// Asynchronously reads the characters from the current stream into a memory block. /// diff --git a/src/Polyfill/PolyfillExtensions_TextWriter.cs b/src/Polyfill/PolyfillExtensions_TextWriter.cs index 2634d435..5a3a0404 100644 --- a/src/Polyfill/PolyfillExtensions_TextWriter.cs +++ b/src/Polyfill/PolyfillExtensions_TextWriter.cs @@ -2,7 +2,7 @@ #pragma warning disable -#if TASKSEXTENSIONSREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) +#if TASKSEXTENSIONSREFERENCED && MEMORYREFERENCED && (NETFRAMEWORK || NETSTANDARD2_0 || NETCOREAPP2_0) using System; using System.Buffers; diff --git a/src/Tests/NullabilitySync.cs b/src/Tests/NullabilitySync.cs index ceab6b5a..569e6ab8 100644 --- a/src/Tests/NullabilitySync.cs +++ b/src/Tests/NullabilitySync.cs @@ -50,6 +50,7 @@ public async Task Run() using System.Linq; using System.Diagnostics.CodeAnalysis; + """; var suffix = """ @@ -60,6 +61,7 @@ public async Task Run() infoContext = prefix + infoContext + suffix; infoContext = MakeInternal(infoContext); + infoContext = AddDebugClassFix(infoContext); OverWrite(infoContext, "NullabilityInfoContext.cs"); info = prefix + info + suffix; @@ -87,6 +89,19 @@ static string MakeInternal(string source) => sealed class """); + static string AddDebugClassFix(string source) => + source + .Replace( + "namespace System.Reflection\r\n{", + """ + namespace System.Reflection + { + // Some codebases define their own Debug class, which can cause clashes and compile errors if we aren't explicit here. + // See comments in Debug.cs in Consume project for more details. + using Debug = System.Diagnostics.Debug; + + """); + static void OverWrite(string content, string file) { var path = Path.Combine(dir, file);