diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 04029d1..939981f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,7 +2,7 @@ Thank you for your interest in contributing to **PolySharp**! Below you'll find some info on how to get started with the project. -> **NOTE:** it is highly recommended to carfully read the [README](/README.md) first to get a general understanding of the library. +> **NOTE:** it is highly recommended to carefully read the [README](/README.md) first to get a general understanding of the library. ## 🙋 Questions, bug reports, feature proposals diff --git a/Directory.Build.props b/Directory.Build.props index 7226741..e67455d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ true - 12.0 + 13.0 enable true diff --git a/README.md b/README.md index 99e942b..85a8b87 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ # TLDR? What is this for? ✨ -Put simply: are you working on .NET Framework, or UWP, or some other older .NET runtime and still would like to use all the cool new features that C# 12 has? Well this library lets you do just that! It will generate for you all the "magic types" that the C# compiler needs to "see" in order for it to allow using new language features even if you're not using the latest framework out there. +Put simply: are you working on .NET Framework, or UWP, or some other older .NET runtime and still would like to use all the cool new features that C# 13 has? Well this library lets you do just that! It will generate for you all the "magic types" that the C# compiler needs to "see" in order for it to allow using new language features even if you're not using the latest framework out there. Here's an example of some of the new features that **PolySharp** can enable downlevel: @@ -52,8 +52,10 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[RequiresLocation]` (needed to enable [ref readonly parameters](https://github.com/dotnet/csharplang/issues/6010)) - `[CollectionBuilder]` (needed for [collection expressions](https://github.com/dotnet/csharplang/issues/5354)) - `[Experimental]` (needed for [experimental features](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-12.0/experimental-attribute)) +- `[OverloadResolutionPriority]` (needed for [overload resolution priority](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#overload-resolution-priority)) +- `[ParamsCollection]` (needed for [params collection](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections)) -To leverage them, make sure to bump your C# language version. You can do this by setting the `` MSBuild property in your project. For instance, by adding `12.0` (or your desired C# version) to the first `` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. +To leverage them, make sure to bump your C# language version. You can do this by setting the `` MSBuild property in your project. For instance, by adding `13.0` (or your desired C# version) to the first `` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. It also includes the following optional runtime-supported polyfills: - Reflection annotation attributes (see [docs](https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming)): @@ -64,7 +66,7 @@ It also includes the following optional runtime-supported polyfills: - `[UnconditionalSuppressMessage]` - `[RequiresAssemblyFiles]` - `[StackTraceHidden]` (see [here](https://makolyte.com/csharp-exclude-exception-throw-helper-methods-from-the-stack-trace/)) -- `[UnmanagedCallersOnly]` (see [docs](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute))) +- `[UnmanagedCallersOnly]` (see [docs](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute)) - Platform support annotation attributes (see [docs](https://learn.microsoft.com/dotnet/standard/analyzers/platform-compat-analyzer)): - `[ObsoletedOSPlatform]` - `[SupportedOSPlatform]` @@ -76,6 +78,11 @@ It also includes the following optional runtime-supported polyfills: - `[DisableRuntimeMarshalling]` (see [here](https://learn.microsoft.com/dotnet/standard/native-interop/disabled-marshalling)) - `[UnsafeAccessor]` (see [here](https://github.com/dotnet/runtime/issues/81741)) - `[InlineArray]` (see [here](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-12.0/inline-arrays)) +- `[DisableUserUnhandledExceptions]` (see [here](https://github.com/dotnet/runtime/issues/103105)) +- Attribute model for feature switches with trimming support (see [docs](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/runtime#attribute-model-for-feature-switches-with-trimming-support)): + - `[FeatureGuard]` + - `[FeatureSwitchDefinition]` +- `[WasmImportLinkage]` (see [here](https://github.com/dotnet/runtime/pull/93823)) # Options ⚙️ diff --git a/global.json b/global.json index 789bff3..41c9ad2 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { - "version": "8.0.100", + "version": "9.0.100", "rollForward": "latestFeature", "allowPrerelease": false } -} \ No newline at end of file +} diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index 3aa6f4c..c5ea60e 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -6,7 +6,7 @@ # TLDR? What is this for? ✨ -Put simply: are you working on .NET Framework, or UWP, or some other older .NET runtime and still would like to use all the cool new features that C# 12 has? Well this library lets you do just that! It will generate for you all the "magic types" that the C# compiler needs to "see" in order for it to allow using new language features even if you're not using the latest framework out there. +Put simply: are you working on .NET Framework, or UWP, or some other older .NET runtime and still would like to use all the cool new features that C# 13 has? Well this library lets you do just that! It will generate for you all the "magic types" that the C# compiler needs to "see" in order for it to allow using new language features even if you're not using the latest framework out there. Here's an example of some of the new features that **PolySharp** can enable downlevel: @@ -50,8 +50,10 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[RequiresLocation]` (needed to enable [ref readonly parameters](https://github.com/dotnet/csharplang/issues/6010)) - `[CollectionBuilder]` (needed for [collection expressions](https://github.com/dotnet/csharplang/issues/5354)) - `[Experimental]` (needed for [experimental features](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-12.0/experimental-attribute)) +- `[OverloadResolutionPriority]` (needed for [overload resolution priority](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#overload-resolution-priority)) +- `[ParamsCollection]` (needed for [params collection](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-13#params-collections)) -To leverage them, make sure to bump your C# language version. You can do this by setting the `` MSBuild property in your project. For instance, by adding `12.0` (or your desired C# version) to the first `` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. +To leverage them, make sure to bump your C# language version. You can do this by setting the `` MSBuild property in your project. For instance, by adding `13.0` (or your desired C# version) to the first `` of your .csproj file. For more info on this, [see here](https://sergiopedri.medium.com/enabling-and-using-c-9-features-on-older-and-unsupported-runtimes-ce384d8debb), but remember that you don't need to manually copy polyfills anymore: simply adding a reference to **PolySharp** will do this for you automatically. It also includes the following optional runtime-supported polyfills: - Reflection annotation attributes (see [docs](https://learn.microsoft.com/dotnet/core/deploying/trimming/prepare-libraries-for-trimming)): @@ -62,7 +64,7 @@ It also includes the following optional runtime-supported polyfills: - `[UnconditionalSuppressMessage]` - `[RequiresAssemblyFiles]` - `[StackTraceHidden]` (see [here](https://makolyte.com/csharp-exclude-exception-throw-helper-methods-from-the-stack-trace/)) -- `[UnmanagedCallersOnly]` (see [docs](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute))) +- `[UnmanagedCallersOnly]` (see [docs](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.unmanagedcallersonlyattribute)) - Platform support annotation attributes (see [docs](https://learn.microsoft.com/dotnet/standard/analyzers/platform-compat-analyzer)): - `[ObsoletedOSPlatform]` - `[SupportedOSPlatform]` @@ -74,6 +76,11 @@ It also includes the following optional runtime-supported polyfills: - `[DisableRuntimeMarshalling]` (see [here](https://learn.microsoft.com/dotnet/standard/native-interop/disabled-marshalling)) - `[UnsafeAccessor]` (see [here](https://github.com/dotnet/runtime/issues/81741)) - `[InlineArray]` (see [here](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-12.0/inline-arrays)) +- `[DisableUserUnhandledExceptions]` (see [here](https://github.com/dotnet/runtime/issues/103105)) +- Attribute model for feature switches with trimming support (see [docs](https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotnet-9/runtime#attribute-model-for-feature-switches-with-trimming-support)): + - `[FeatureGuard]` + - `[FeatureSwitchDefinition]` +- `[WasmImportLinkage]` (see [here](https://github.com/dotnet/runtime/pull/93823)) # Options ⚙️ diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.FeatureGuardAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.FeatureGuardAttribute.cs new file mode 100644 index 0000000..8fc64ac --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.FeatureGuardAttribute.cs @@ -0,0 +1,41 @@ +// +#pragma warning disable +#nullable enable annotations + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that the specified public static boolean get-only property + /// guards access to the specified feature. + /// + /// + /// Analyzers can use this to prevent warnings on calls to code that is + /// annotated as requiring that feature, when the callsite is guarded by a + /// call to the property. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Property, Inherited = false, AllowMultiple = true)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + internal sealed class FeatureGuardAttribute : global::System.Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified feature type. + /// + /// + /// The type that represents the feature guarded by the property. + /// + public FeatureGuardAttribute(global::System.Type featureType) + { + FeatureType = featureType; + } + + /// + /// The type that represents the feature guarded by the property. + /// + public global::System.Type FeatureType { get; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute.cs new file mode 100644 index 0000000..aa010fd --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute.cs @@ -0,0 +1,40 @@ +// +#pragma warning disable +#nullable enable annotations + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics.CodeAnalysis +{ + /// + /// Indicates that the specified public static boolean get-only property + /// corresponds to the feature switch specified by name. + /// + /// + /// IL rewriters and compilers can use this to substitute the return value + /// of the specified property with the value of the feature switch. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Property, Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + internal sealed class FeatureSwitchDefinitionAttribute : global::System.Attribute + { + /// + /// Initializes a new instance of the class + /// with the specified feature switch name. + /// + /// + /// The name of the feature switch that provides the value for the specified property. + /// + public FeatureSwitchDefinitionAttribute(string switchName) + { + SwitchName = switchName; + } + + /// + /// The name of the feature switch that provides the value for the specified property. + /// + public string SwitchName { get; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.DebuggerDisableUserUnhandledExceptionsAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.DebuggerDisableUserUnhandledExceptionsAttribute.cs new file mode 100644 index 0000000..6212cb9 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Diagnostics.DebuggerDisableUserUnhandledExceptionsAttribute.cs @@ -0,0 +1,21 @@ +// +#pragma warning disable +#nullable enable annotations + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics +{ + /// + /// If a .NET Debugger is attached which supports the Debugger.BreakForUserUnhandledException(Exception) API, + /// this attribute will prevent the debugger from breaking on user-unhandled exceptions when the + /// exception is caught by a method with this attribute, unless BreakForUserUnhandledException is called. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Method)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + internal sealed class DebuggerDisableUserUnhandledExceptionsAttribute : global::System.Attribute + { + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.WasmImportLinkageAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.WasmImportLinkageAttribute.cs new file mode 100644 index 0000000..b1f62fc --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.WasmImportLinkageAttribute.cs @@ -0,0 +1,26 @@ +// +#pragma warning disable +#nullable enable annotations + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.InteropServices +{ + /// + /// Specifies that the P/Invoke marked with this attribute should be linked in as a WASM import. + /// + /// + /// See https://webassembly.github.io/spec/core/syntax/modules.html#imports. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Method, Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")] + internal sealed class WasmImportLinkageAttribute : global::System.Attribute + { + /// + /// Instance constructor. + /// + public WasmImportLinkageAttribute() { } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute.cs new file mode 100644 index 0000000..bdaeaf6 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute.cs @@ -0,0 +1,36 @@ +// +#pragma warning disable +#nullable enable annotations + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + /// + /// Specifies the priority of a member in overload resolution. When unspecified, the default priority is 0. + /// + [global::System.AttributeUsage( + global::System.AttributeTargets.Method | + global::System.AttributeTargets.Constructor | + global::System.AttributeTargets.Property, + AllowMultiple = false, + Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + internal sealed class OverloadResolutionPriorityAttribute : global::System.Attribute + { + /// + /// Initializes a new instance of the class. + /// + /// The priority of the attributed member. Higher numbers are prioritized, lower numbers are deprioritized. 0 is the default if no attribute is present. + public OverloadResolutionPriorityAttribute(int priority) + { + Priority = priority; + } + + /// + /// The priority of the member. + /// + public int Priority { get; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ParamCollectionAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ParamCollectionAttribute.cs new file mode 100644 index 0000000..9874cfd --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ParamCollectionAttribute.cs @@ -0,0 +1,18 @@ +// +#pragma warning disable +#nullable enable annotations + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Runtime.CompilerServices +{ + /// + /// Indicates that a method will allow a variable number of arguments in its invocation. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + internal sealed class ParamCollectionAttribute : global::System.Attribute + { + } +} \ No newline at end of file diff --git a/tests/PolySharp.Tests/LanguageFeatures.cs b/tests/PolySharp.Tests/LanguageFeatures.cs index 694de40..d2558f6 100644 --- a/tests/PolySharp.Tests/LanguageFeatures.cs +++ b/tests/PolySharp.Tests/LanguageFeatures.cs @@ -162,11 +162,18 @@ public static ReadOnlySpan TestRange(ReadOnlySpan numbers) [CollectionBuilder(typeof(CollectionClass), nameof(Create))] internal class CollectionClass : IEnumerable { - public CollectionClass Test() + public static CollectionClass Test() { + Test2(1, 2, 3); + return [1, 2, 3]; } + public static void Test2(params CollectionClass collection) + { + + } + public static CollectionClass Create(ReadOnlySpan values) { return new(); @@ -260,4 +267,22 @@ public void Start(ref TStateMachine stateMachine) } } -#endif \ No newline at end of file +#endif + +internal static class OverloadResolutionPriorityTests +{ + public static void Test() + { + TestOverload(1); + } + + [Obsolete("Do not use", error: true)] + [OverloadResolutionPriority(-1)] + public static void TestOverload(int x) + { + } + + public static void TestOverload(int x, int y = 0) + { + } +} \ No newline at end of file diff --git a/tests/PolySharp.Tests/PolySharp.Tests.csproj b/tests/PolySharp.Tests/PolySharp.Tests.csproj index 08eb85f..5e8980e 100644 --- a/tests/PolySharp.Tests/PolySharp.Tests.csproj +++ b/tests/PolySharp.Tests/PolySharp.Tests.csproj @@ -1,7 +1,7 @@ - net472;net48;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0 + net472;net48;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0;net9.0 true