Skip to content

Commit

Permalink
Merge pull request #81 from Sergio0694/dev/net8-polyfills
Browse files Browse the repository at this point in the history
Add C# 12 and .NET 8 polyfills
  • Loading branch information
Sergio0694 authored Nov 22, 2023
2 parents 2689b7e + d171c2e commit 2a6e35e
Show file tree
Hide file tree
Showing 24 changed files with 447 additions and 35 deletions.
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>11.0</LangVersion>
<LangVersion>12.0</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>

Expand Down
4 changes: 3 additions & 1 deletion PolySharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolySharp.SourceGenerators"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projects", "Projects", "{8DAA0C71-4529-44EB-8994-DE331A3ADC52}"
ProjectSection(SolutionItems) = preProject
src\PolySharp.Package\icon.png = src\PolySharp.Package\icon.png
src\PolySharp.Package\PolySharp.Package.msbuildproj = src\PolySharp.Package\PolySharp.Package.msbuildproj
src\PolySharp.Package\README.md = src\PolySharp.Package\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D65D0307-1D0F-499D-945B-E33E71F251A4}"
Expand Down Expand Up @@ -37,7 +39,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolySharp.MinimumCSharpVers
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolySharp.PolySharpUseTypeAliasForUnmanagedCallersOnlyAttribute.Tests", "tests\PolySharp.PolySharpUseTypeAliasForUnmanagedCallersOnlyAttribute.Tests\PolySharp.PolySharpUseTypeAliasForUnmanagedCallersOnlyAttribute.Tests.csproj", "{C865CEDE-2DC9-4E1E-BB58-529E6E2A9DBB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolySharp.TypeForwards.Tests", "tests\PolySharp.TypeForwards.Tests\PolySharp.TypeForwards.Tests.csproj", "{AAF3B574-66F1-4EF0-936A-82390E30D539}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolySharp.TypeForwards.Tests", "tests\PolySharp.TypeForwards.Tests\PolySharp.TypeForwards.Tests.csproj", "{AAF3B574-66F1-4EF0-936A-82390E30D539}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
9 changes: 7 additions & 2 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# 11 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# 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.

Here's an example of some of the new features that **PolySharp** can enable downlevel:

Expand Down Expand Up @@ -49,8 +49,11 @@ Here's an example of some of the new features that **PolySharp** can enable down
- `[AsyncMethodBuilder]` (needed for [custom method builder types](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-10.0/async-method-builders))
- `[StringSyntax]` (needed to enable [syntax highlight in the IDE](https://github.com/dotnet/runtime/issues/62505))
- `[ModuleInitializer]` (needed to enable [custom module initializers](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-9.0/module-initializers))
- `[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))

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>11.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>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.

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 @@ -71,6 +74,8 @@ It also includes the following optional runtime-supported polyfills:
- `[UnsupportedOSPlatformGuard]`
- `[SuppressGCTransition]` (see [here](https://devblogs.microsoft.com/dotnet/improvements-in-native-code-interop-in-net-5-0/))
- `[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))

# Options ⚙️

Expand Down
7 changes: 7 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"sdk": {
"version": "8.0.100",
"rollForward": "latestFeature",
"allowPrerelease": false
}
}
9 changes: 7 additions & 2 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# 11 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# 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.

Here's an example of some of the new features that **PolySharp** can enable downlevel:

Expand Down Expand Up @@ -47,8 +47,11 @@ Here's an example of some of the new features that **PolySharp** can enable down
- `[AsyncMethodBuilder]` (needed for [custom method builder types](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-10.0/async-method-builders))
- `[StringSyntax]` (needed to enable [syntax highlight in the IDE](https://github.com/dotnet/runtime/issues/62505))
- `[ModuleInitializer]` (needed to enable [custom module initializers](https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/csharp-9.0/module-initializers))
- `[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))

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>11.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>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.

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 @@ -69,6 +72,8 @@ It also includes the following optional runtime-supported polyfills:
- `[UnsupportedOSPlatformGuard]`
- `[SuppressGCTransition]` (see [here](https://devblogs.microsoft.com/dotnet/improvements-in-native-code-interop-in-net-5-0/))
- `[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))

# Options ⚙️

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// <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.CompilerServices2
{
/// <summary>
/// Indicates that the instance's storage is sequentially replicated "length" times.
/// </summary>
/// <remarks>
/// <para>
/// This attribute can be used to annotate a <see langword="struct"/> type with a single field.
/// The runtime will replicate that field in the actual type layout as many times as is specified.
/// </para>
/// <para>
/// Here's an example of how an inline array type with 8 <see cref="float"/> values can be declared:
/// <code lang="csharp">
/// [InlineArray(8)]
/// struct Float8InlineArray
/// {
/// private float _value;
/// }
/// </code>
/// </para>
/// </remarks>
[global::System.AttributeUsage(global::System.AttributeTargets.Struct, AllowMultiple = false)]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")]
public sealed class InlineArrayAttribute : global::System.Attribute
{
/// <summary>Creates a new <see cref="global::System.Runtime.CompilerServices2.InlineArrayAttribute"/> instance with the specified length.</summary>
/// <param name="length">The number of sequential fields to replicate in the inline array type.</param>
public InlineArrayAttribute(int length)
{
Length = length;
}

/// <summary>Gets the number of sequential fields to replicate in the inline array type.</summary>
public int Length { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// <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>
/// Provides access to an inaccessible member of a specific type.
/// </summary>
/// <remarks>
/// This attribute may be applied to an <code>extern static</code> method.
/// The implementation of the <code>extern static</code> method annotated with
/// this attribute will be provided by the runtime based on the information in
/// the attribute and the signature of the method that the attribute is applied to.
/// The runtime will try to find the matching method or field and forward the call
/// to it. If the matching method or field is not found, the body of the <code>extern</code>
/// method will throw <see cref="global::System.MissingFieldException" /> or <see cref="global::System.MissingMethodException" />.
/// Only the specific type defined will be examined for inaccessible members. The type hierarchy
/// is not walked looking for a match.
///
/// For <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorKind.Method"/>,
/// <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod"/>,
/// <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorKind.Field"/>,
/// and <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticField"/>, the type of
/// the first argument of the annotated <code>extern</code> method identifies the owning type.
/// The value of the first argument is treated as <code>this</code> pointer for instance fields and methods.
/// The first argument must be passed as <code>ref</code> for instance fields and methods on structs.
/// The value of the first argument is not used by the implementation for <code>static</code> fields and methods.
///
/// Return type is considered for the signature match. modreqs and modopts are initially not considered for
/// the signature match. However, if an ambiguity exists ignoring modreqs and modopts, a precise match
/// is attempted. If an ambiguity still exists <see cref="global::System.Reflection.AmbiguousMatchException" /> is thrown.
///
/// By default, the attributed method's name dictates the name of the method/field. This can cause confusion
/// in some cases since language abstractions, like C# local functions, generate mangled IL names. The
/// solution to this is to use the <code>nameof</code> mechanism and define the <see cref="Name"/> property.
///
/// <code>
/// public void Method(Class c)
/// {
/// PrivateMethod(c);
///
/// [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(PrivateMethod))]
/// extern static void PrivateMethod(Class c);
/// }
/// </code>
/// </remarks>
[global::System.AttributeUsage(global::System.AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")]
internal sealed class UnsafeAccessorAttribute : global::System.Attribute
{
/// <summary>
/// Instantiates an <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorAttribute"/>
/// providing access to a member of kind <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorKind"/>.
/// </summary>
/// <param name="kind">The kind of the target to which access is provided.</param>
public UnsafeAccessorAttribute(global::System.Runtime.CompilerServices.UnsafeAccessorKind kind)
{
Kind = kind;
}

/// <summary>
/// Gets the kind of member to which access is provided.
/// </summary>
public global::System.Runtime.CompilerServices.UnsafeAccessorKind Kind { get; }

/// <summary>
/// Gets or sets the name of the member to which access is provided.
/// </summary>
/// <remarks>
/// The name defaults to the annotated method name if not specified.
/// The name must be unset/<code>null</code> for <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorKind.Constructor"/>.
/// </remarks>
public string? Name { get; set; }
}
}
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.Runtime.CompilerServices
{
/// <summary>
/// Specifies the kind of target to which an <see cref="global::System.Runtime.CompilerServices.UnsafeAccessorAttribute" /> is providing access.
/// </summary>
internal enum UnsafeAccessorKind
{
/// <summary>
/// Provide access to a constructor.
/// </summary>
Constructor,

/// <summary>
/// Provide access to a method.
/// </summary>
Method,

/// <summary>
/// Provide access to a static method.
/// </summary>
StaticMethod,

/// <summary>
/// Provide access to a field.
/// </summary>
Field,

/// <summary>
/// Provide access to a static field.
/// </summary>
StaticField
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ namespace System.Runtime.InteropServices
[global::System.Diagnostics.Conditional("MULTI_TARGETING_SUPPORT_ATTRIBUTES")]
internal sealed class UnmanagedCallersOnlyAttribute : global::System.Attribute
{
public UnmanagedCallersOnlyAttribute()
{
}

/// <summary>
/// Optional. If omitted, the runtime will use the default platform calling convention.
/// </summary>
Expand Down
Loading

0 comments on commit 2a6e35e

Please sign in to comment.