Skip to content

Commit

Permalink
Merge pull request #108 from teo-tsirpanis/net9
Browse files Browse the repository at this point in the history
Add polyfills for .NET 9 attributes.
  • Loading branch information
Sergio0694 authored Nov 20, 2024
2 parents d519f71 + 81cedeb commit 06e5008
Show file tree
Hide file tree
Showing 13 changed files with 234 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>12.0</LangVersion>
<LangVersion>13.0</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

Expand Down
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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 `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>12.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` 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 `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>13.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` 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)):
Expand All @@ -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]`
Expand All @@ -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 ⚙️

Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"sdk": {
"version": "8.0.100",
"version": "9.0.100",
"rollForward": "latestFeature",
"allowPrerelease": false
}
}
}
13 changes: 10 additions & 3 deletions src/PolySharp.Package/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand Down Expand Up @@ -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 `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>12.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` 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 `<LangVersion>` MSBuild property in your project. For instance, by adding `<LangVersion>13.0</LangVersion>` (or your desired C# version) to the first `<PropertyGroup>` 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)):
Expand All @@ -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]`
Expand All @@ -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 ⚙️

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// <auto-generated/>
#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
{
/// <summary>
/// Indicates that the specified public static boolean get-only property
/// guards access to the specified feature.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
[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
{
/// <summary>
/// Initializes a new instance of the <see cref="global::System.Diagnostics.CodeAnalysis.FeatureGuardAttribute"/> class
/// with the specified feature type.
/// </summary>
/// <param name="featureType">
/// The type that represents the feature guarded by the property.
/// </param>
public FeatureGuardAttribute(global::System.Type featureType)
{
FeatureType = featureType;
}

/// <summary>
/// The type that represents the feature guarded by the property.
/// </summary>
public global::System.Type FeatureType { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <auto-generated/>
#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
{
/// <summary>
/// Indicates that the specified public static boolean get-only property
/// corresponds to the feature switch specified by name.
/// </summary>
/// <remarks>
/// IL rewriters and compilers can use this to substitute the return value
/// of the specified property with the value of the feature switch.
/// </remarks>
[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
{
/// <summary>
/// Initializes a new instance of the <see cref="global::System.Diagnostics.CodeAnalysis.FeatureSwitchDefinitionAttribute"/> class
/// with the specified feature switch name.
/// </summary>
/// <param name="switchName">
/// The name of the feature switch that provides the value for the specified property.
/// </param>
public FeatureSwitchDefinitionAttribute(string switchName)
{
SwitchName = switchName;
}

/// <summary>
/// The name of the feature switch that provides the value for the specified property.
/// </summary>
public string SwitchName { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// <auto-generated/>
#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
{
/// <summary>
/// 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.
/// </summary>
[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
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// <auto-generated/>
#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
{
/// <summary>
/// Specifies that the P/Invoke marked with this attribute should be linked in as a WASM import.
/// </summary>
/// <remarks>
/// See https://webassembly.github.io/spec/core/syntax/modules.html#imports.
/// </remarks>
[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
{
/// <summary>
/// Instance constructor.
/// </summary>
public WasmImportLinkageAttribute() { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// <auto-generated/>
#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
{
/// <summary>
/// Specifies the priority of a member in overload resolution. When unspecified, the default priority is 0.
/// </summary>
[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
{
/// <summary>
/// Initializes a new instance of the <see cref="global::System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute"/> class.
/// </summary>
/// <param name="priority">The priority of the attributed member. Higher numbers are prioritized, lower numbers are deprioritized. 0 is the default if no attribute is present.</param>
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}

/// <summary>
/// The priority of the member.
/// </summary>
public int Priority { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// <auto-generated/>
#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
{
/// <summary>
/// Indicates that a method will allow a variable number of arguments in its invocation.
/// </summary>
[global::System.AttributeUsage(global::System.AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : global::System.Attribute
{
}
}
29 changes: 27 additions & 2 deletions tests/PolySharp.Tests/LanguageFeatures.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,18 @@ public static ReadOnlySpan<int> TestRange(ReadOnlySpan<int> numbers)
[CollectionBuilder(typeof(CollectionClass), nameof(Create))]
internal class CollectionClass : IEnumerable<int>
{
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<int> values)
{
return new();
Expand Down Expand Up @@ -260,4 +267,22 @@ public void Start<TStateMachine>(ref TStateMachine stateMachine)
}
}

#endif
#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)
{
}
}
2 changes: 1 addition & 1 deletion tests/PolySharp.Tests/PolySharp.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net472;net48;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0</TargetFrameworks>
<TargetFrameworks>net472;net48;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0;net9.0</TargetFrameworks>
<PolySharpIncludeRuntimeSupportedAttributes>true</PolySharpIncludeRuntimeSupportedAttributes>
</PropertyGroup>

Expand Down

0 comments on commit 06e5008

Please sign in to comment.