From 2e164a2176430052f3dd404836b6cc7a1c34db24 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Aug 2023 20:02:49 +0200 Subject: [PATCH 01/12] Add RequiresLocationAttribute polyfill --- PolySharp.sln | 4 +++- README.md | 1 + src/PolySharp.Package/README.md | 1 + ...pilerServices.RequiresLocationAttribute.cs | 20 +++++++++++++++++++ .../PolyfillsGenerator.TypeForwards.cs | 3 ++- 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.RequiresLocationAttribute.cs diff --git a/PolySharp.sln b/PolySharp.sln index 3f99876..b933183 100644 --- a/PolySharp.sln +++ b/PolySharp.sln @@ -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}" @@ -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 diff --git a/README.md b/README.md index 829185a..f011ef1 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ 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)) 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 `11.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. diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index 8423e6e..849a1af 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -47,6 +47,7 @@ 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)) 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 `11.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. diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.RequiresLocationAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.RequiresLocationAttribute.cs new file mode 100644 index 0000000..53ea973 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.RequiresLocationAttribute.cs @@ -0,0 +1,20 @@ +// +#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 +{ + /// + /// Reserved for use by a compiler for tracking metadata. + /// This attribute should not be used by developers in source code. + /// + [global::System.AttributeUsage(global::System.AttributeTargets.Parameter, Inherited = false)] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + internal sealed class RequiresLocationAttribute : global::System.Attribute + { + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/PolyfillsGenerator.TypeForwards.cs b/src/PolySharp.SourceGenerators/PolyfillsGenerator.TypeForwards.cs index 2740694..afb6f35 100644 --- a/src/PolySharp.SourceGenerators/PolyfillsGenerator.TypeForwards.cs +++ b/src/PolySharp.SourceGenerators/PolyfillsGenerator.TypeForwards.cs @@ -17,7 +17,8 @@ partial class PolyfillsGenerator private static readonly ImmutableArray ModreqCandidateFullyQualifiedTypeNames = ImmutableArray.Create( "System.Index", "System.Range", - "System.Runtime.CompilerServices.IsExternalInit"); + "System.Runtime.CompilerServices.IsExternalInit", + "System.Runtime.CompilerServices.RequiresLocationAttribute"); /// /// Gets the types from the BCL that should potentially receive type forwards. From 70f095edf9670c2d79717af8009c65c9b02ec86f Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sun, 20 Aug 2023 20:08:42 +0200 Subject: [PATCH 02/12] Add CollectionBuilderAttribute polyfill --- README.md | 1 + src/PolySharp.Package/README.md | 1 + ...ilerServices.CollectionBuilderAttribute.cs | 48 +++++++++++++++++++ ...ilerServices.ModuleInitializerAttribute.cs | 3 -- ...ioning.RequiresPreviewFeaturesAttribute.cs | 4 +- 5 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.CollectionBuilderAttribute.cs diff --git a/README.md b/README.md index f011ef1..10af449 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[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)) 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 `11.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. diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index 849a1af..d2ddbd5 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -48,6 +48,7 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[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)) 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 `11.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. diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.CollectionBuilderAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.CollectionBuilderAttribute.cs new file mode 100644 index 0000000..d1a037e --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.CollectionBuilderAttribute.cs @@ -0,0 +1,48 @@ +// +#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 +{ + [global::System.AttributeUsage( + global::System.AttributeTargets.Class | + global::System.AttributeTargets.Struct | + global::System.AttributeTargets.Interface, + Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + internal sealed class CollectionBuilderAttribute : Attribute + { + /// + /// Initialize the attribute to refer to the method on the type. + /// + /// The type of the builder to use to construct the collection. + /// The name of the method on the builder to use to construct the collection. + /// + /// must refer to a static method that accepts a single parameter of + /// type and returns an instance of the collection being built containing + /// a copy of the data from that span. In future releases of .NET, additional patterns may be supported. + /// + public CollectionBuilderAttribute(Type builderType, string methodName) + { + BuilderType = builderType; + MethodName = methodName; + } + + /// + /// Gets the type of the builder to use to construct the collection. + /// + public Type BuilderType { get; } + + /// + /// Gets the name of the method on the builder to use to construct the collection. + /// + /// + /// This should match the metadata name of the target method. + /// For example, this might be ".ctor" if targeting the type's constructor. + /// + public string MethodName { get; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ModuleInitializerAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ModuleInitializerAttribute.cs index d2cc394..19711cc 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ModuleInitializerAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.CompilerServices.ModuleInitializerAttribute.cs @@ -31,8 +31,5 @@ namespace System.Runtime.CompilerServices [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : global::System.Attribute { - public ModuleInitializerAttribute() - { - } } } \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.Versioning.RequiresPreviewFeaturesAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.Versioning.RequiresPreviewFeaturesAttribute.cs index 9e27d93..153f0ca 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.Versioning.RequiresPreviewFeaturesAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Runtime.Versioning.RequiresPreviewFeaturesAttribute.cs @@ -26,7 +26,9 @@ internal sealed class RequiresPreviewFeaturesAttribute : global::System.Attribut /// /// Initializes a new instance of the class. /// - public RequiresPreviewFeaturesAttribute() { } + public RequiresPreviewFeaturesAttribute() + { + } /// /// Initializes a new instance of the class with the specified message. From 64a79a79b584847edcbfe54c63692648fed49d53 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 20 Sep 2023 13:42:59 +0200 Subject: [PATCH 03/12] Add UnsafeAccessorAttribute polyfill --- README.md | 1 + src/PolySharp.Package/README.md | 1 + ...ompilerServices.UnsafeAccessorAttribute.cs | 80 +++++++++++++++++++ ...ime.CompilerServices.UnsafeAccessorKind.cs | 40 ++++++++++ 4 files changed, 122 insertions(+) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs diff --git a/README.md b/README.md index 10af449..839361a 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ 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)) # Options ⚙️ diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index d2ddbd5..89c43ac 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -71,6 +71,7 @@ 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)) # Options ⚙️ diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs new file mode 100644 index 0000000..0a2591c --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorAttribute.cs @@ -0,0 +1,80 @@ +// +#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 +{ + /// + /// Provides access to an inaccessible member of a specific type. + /// + /// + /// This attribute may be applied to an extern static method. + /// The implementation of the extern static 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 extern + /// method will throw or . + /// Only the specific type defined will be examined for inaccessible members. The type hierarchy + /// is not walked looking for a match. + /// + /// For , + /// , + /// , + /// and , the type of + /// the first argument of the annotated extern method identifies the owning type. + /// The value of the first argument is treated as this pointer for instance fields and methods. + /// The first argument must be passed as ref for instance fields and methods on structs. + /// The value of the first argument is not used by the implementation for static 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 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 nameof mechanism and define the property. + /// + /// + /// public void Method(Class c) + /// { + /// PrivateMethod(c); + /// + /// [UnsafeAccessor(UnsafeAccessorKind.Method, Name = nameof(PrivateMethod))] + /// extern static void PrivateMethod(Class c); + /// } + /// + /// + [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 + { + /// + /// Instantiates an + /// providing access to a member of kind . + /// + /// The kind of the target to which access is provided. + public UnsafeAccessorAttribute(global::System.Runtime.CompilerServices.UnsafeAccessorKind kind) + { + Kind = kind; + } + + /// + /// Gets the kind of member to which access is provided. + /// + public global::System.Runtime.CompilerServices.UnsafeAccessorKind Kind { get; } + + /// + /// Gets or sets the name of the member to which access is provided. + /// + /// + /// The name defaults to the annotated method name if not specified. + /// The name must be unset/null for . + /// + public string? Name { get; set; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.cs new file mode 100644 index 0000000..7cb4fc3 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.UnsafeAccessorKind.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.Runtime.CompilerServices +{ + /// + /// Specifies the kind of target to which an is providing access. + /// + internal enum UnsafeAccessorKind + { + /// + /// Provide access to a constructor. + /// + Constructor, + + /// + /// Provide access to a method. + /// + Method, + + /// + /// Provide access to a static method. + /// + StaticMethod, + + /// + /// Provide access to a field. + /// + Field, + + /// + /// Provide access to a static field. + /// + StaticField + } +} \ No newline at end of file From ddfe9e294930fa645dbe5053669b695a9767d208 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Sat, 11 Nov 2023 23:57:39 +0100 Subject: [PATCH 04/12] Add ExperimentalAttribute polyfill --- README.md | 1 + src/PolySharp.Package/README.md | 1 + ...tics.CodeAnalysis.ExperimentalAttribute.cs | 62 +++++++++++++++++++ tests/PolySharp.Tests/LanguageFeatures.cs | 5 ++ 4 files changed, 69 insertions(+) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/System.Diagnostics.CodeAnalysis.ExperimentalAttribute.cs diff --git a/README.md b/README.md index 839361a..e012d56 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,7 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[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 `` MSBuild property in your project. For instance, by adding `11.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. diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index 89c43ac..e620188 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -49,6 +49,7 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[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 `` MSBuild property in your project. For instance, by adding `11.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. diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/System.Diagnostics.CodeAnalysis.ExperimentalAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Diagnostics.CodeAnalysis.ExperimentalAttribute.cs new file mode 100644 index 0000000..0ffefc8 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/System.Diagnostics.CodeAnalysis.ExperimentalAttribute.cs @@ -0,0 +1,62 @@ +// +#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 an API is experimental and it may change in the future. + /// + /// + /// This attribute allows call sites to be flagged with a diagnostic that indicates that an experimental + /// feature is used. Authors can use this attribute to ship preview features in their assemblies. + /// + [global::System.AttributeUsage( + global::System.AttributeTargets.Assembly | + global::System.AttributeTargets.Module | + global::System.AttributeTargets.Class | + global::System.AttributeTargets.Struct | + global::System.AttributeTargets.Enum | + global::System.AttributeTargets.Constructor | + global::System.AttributeTargets.Method | + global::System.AttributeTargets.Property | + global::System.AttributeTargets.Field | + global::System.AttributeTargets.Event | + global::System.AttributeTargets.Interface | + global::System.AttributeTargets.Delegate, + Inherited = false)] + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + internal sealed class ExperimentalAttribute : global::System.Attribute + { + /// + /// Initializes a new instance of the class, + /// specifying the ID that the compiler will use when reporting a use of the API the attribute applies to. + /// + /// The ID that the compiler will use when reporting a use of the API the attribute applies to. + public ExperimentalAttribute(string diagnosticId) + { + DiagnosticId = diagnosticId; + } + + /// + /// Gets the ID that the compiler will use when reporting a use of the API the attribute applies to. + /// + /// The unique diagnostic ID. + /// + /// The diagnostic ID is shown in build output for warnings and errors. + /// This property represents the unique ID that can be used to suppress the warnings or errors, if needed. + /// + public string DiagnosticId { get; } + + /// + /// Gets or sets the URL for corresponding documentation. + /// The API accepts a format string instead of an actual URL, creating a generic URL that includes the diagnostic ID. + /// + /// The format string that represents a URL to corresponding documentation. + /// An example format string is https://contoso.com/obsoletion-warnings/{0}. + public string? UrlFormat { get; set; } + } +} \ No newline at end of file diff --git a/tests/PolySharp.Tests/LanguageFeatures.cs b/tests/PolySharp.Tests/LanguageFeatures.cs index 498eb1b..ff14210 100644 --- a/tests/PolySharp.Tests/LanguageFeatures.cs +++ b/tests/PolySharp.Tests/LanguageFeatures.cs @@ -101,6 +101,11 @@ public void TakeRegex([StringSyntax(StringSyntaxAttribute.Regex)] string pattern public static void InitializeModule() { } + + [Experimental("PS0001")] + public void ExperimentalMethod() + { + } } internal class TestClassWithRequiredMembers From 9b5972c0bfd9086caef1117d91bc91a7a33a056a Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 14 Nov 2023 23:23:23 +0100 Subject: [PATCH 05/12] Add global.json file for .NET 8 SDK --- global.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 global.json diff --git a/global.json b/global.json new file mode 100644 index 0000000..789bff3 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "8.0.100", + "rollForward": "latestFeature", + "allowPrerelease": false + } +} \ No newline at end of file From cc6c38e16e3863b2aca1f770181b393059f86622 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 14 Nov 2023 23:25:46 +0100 Subject: [PATCH 06/12] Switch solution to C# 12 --- Directory.Build.props | 2 +- .../Helpers/EquatableArray{T}.cs | 18 +++++------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 023b02b..4d7793f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ true - 11.0 + 12.0 enable true diff --git a/src/PolySharp.SourceGenerators/Helpers/EquatableArray{T}.cs b/src/PolySharp.SourceGenerators/Helpers/EquatableArray{T}.cs index 74b57dc..95eb9af 100644 --- a/src/PolySharp.SourceGenerators/Helpers/EquatableArray{T}.cs +++ b/src/PolySharp.SourceGenerators/Helpers/EquatableArray{T}.cs @@ -33,22 +33,14 @@ public static EquatableArray AsEquatableArray(this ImmutableArray array /// An imutable, equatable array. This is equivalent to but with value equality support. /// /// The type of values in the array. -internal readonly struct EquatableArray : IEquatable>, IEnumerable +/// The input to wrap. +internal readonly struct EquatableArray(ImmutableArray array) : IEquatable>, IEnumerable where T : IEquatable { /// /// The underlying array. /// - private readonly T[]? array; - - /// - /// Creates a new instance. - /// - /// The input to wrap. - public EquatableArray(ImmutableArray array) - { - this.array = Unsafe.As, T[]?>(ref array); - } + private readonly T[]? array = Unsafe.As, T[]?>(ref array); /// /// Gets a reference to an item at a specified position within the array. @@ -144,7 +136,7 @@ public static EquatableArray FromImmutableArray(ImmutableArray array) /// A wrapping the current items. public ReadOnlySpan AsSpan() { - return AsImmutableArray().AsSpan(); + return new(this.array); } /// @@ -153,7 +145,7 @@ public ReadOnlySpan AsSpan() /// The newly instantiated array. public T[] ToArray() { - return AsImmutableArray().ToArray(); + return [.. AsSpan()]; } /// From de6b8bab3f02d81bc842d2b5cadbb9f986b4309b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 14 Nov 2023 23:33:43 +0100 Subject: [PATCH 07/12] Add .NET 8 TFM in tests, update dependencies --- tests/PolySharp.NuGet/PolySharp.NuGet.csproj | 2 +- tests/PolySharp.Tests/PolySharp.Tests.csproj | 2 +- .../PolySharp.TypeForwards.Tests.csproj | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/PolySharp.NuGet/PolySharp.NuGet.csproj b/tests/PolySharp.NuGet/PolySharp.NuGet.csproj index 9797912..6580709 100644 --- a/tests/PolySharp.NuGet/PolySharp.NuGet.csproj +++ b/tests/PolySharp.NuGet/PolySharp.NuGet.csproj @@ -1,7 +1,7 @@ - net472;net48;net481;netstandard2.0;net6.0;net7.0 + net472;net48;net481;netstandard2.0;net6.0;net7.0;net8.0 https://api.nuget.org/v3/index.json; ..\..\artifacts; diff --git a/tests/PolySharp.Tests/PolySharp.Tests.csproj b/tests/PolySharp.Tests/PolySharp.Tests.csproj index 3a77e03..bce7973 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 + net472;net48;netstandard2.0;netstandard2.1;net6.0;net7.0;net8.0 true diff --git a/tests/PolySharp.TypeForwards.Tests/PolySharp.TypeForwards.Tests.csproj b/tests/PolySharp.TypeForwards.Tests/PolySharp.TypeForwards.Tests.csproj index a93070c..3b176d6 100644 --- a/tests/PolySharp.TypeForwards.Tests/PolySharp.TypeForwards.Tests.csproj +++ b/tests/PolySharp.TypeForwards.Tests/PolySharp.TypeForwards.Tests.csproj @@ -1,7 +1,7 @@ - net472;net48;net6.0;net7.0 + net472;net48;net6.0;net7.0;net8.0 $(NoWarn);CS1591 true @@ -11,9 +11,9 @@ - - - + + + From f19ef6cd5f85a7d68ca6199d47237625841a9960 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 14 Nov 2023 23:53:31 +0100 Subject: [PATCH 08/12] Add type forwarding test for [RequiresLocation] --- .../TypeForwardTests.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/PolySharp.TypeForwards.Tests/TypeForwardTests.cs b/tests/PolySharp.TypeForwards.Tests/TypeForwardTests.cs index 8379ffe..a9990ef 100644 --- a/tests/PolySharp.TypeForwards.Tests/TypeForwardTests.cs +++ b/tests/PolySharp.TypeForwards.Tests/TypeForwardTests.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Reflection; #if NET6_0_OR_GREATER using System.Runtime.CompilerServices; @@ -58,5 +59,32 @@ public void IsExternalInit_IsForwarded() #endif } + [TestMethod] + public void RequiresLocationAttribute_IsForwarded() + { + MethodInfo method = typeof(TypeForwardTests).GetMethod(nameof(MethodWithRefReadonlyParameter), BindingFlags.Static | BindingFlags.NonPublic)!; + ParameterInfo parameter = method.GetParameters()[0]; + CustomAttributeData attribute = parameter.CustomAttributes.Last(); + + Assert.AreEqual("System.Runtime.CompilerServices.RequiresLocationAttribute", attribute.AttributeType.FullName); + +#if NET8_0_OR_GREATER + Assert.AreEqual(typeof(object).Assembly, typeof(RequiresLocationAttribute).Assembly); + + string requiresLocationAttributeAssemblyName = typeof(RequiresLocationAttribute).Assembly.GetName().Name!; + + // Verify the type has been forwarded correctly + Assert.AreEqual(requiresLocationAttributeAssemblyName, attribute.AttributeType.Assembly.GetName().Name); + Assert.AreEqual(requiresLocationAttributeAssemblyName, typeof(TypeForwardTests).Assembly.GetType("System.Runtime.CompilerServices.RequiresLocationAttribute")!.Assembly.GetName().Name); +#else + // If RequiresLocationAttribute is not available, it should be polyfilled in this project + Assert.AreEqual("PolySharp.TypeForwards.Tests", attribute.AttributeType.Assembly.GetName().Name); +#endif + } + private sealed record Person(string Name); + + private static void MethodWithRefReadonlyParameter(ref readonly int x) + { + } } From 897ed98e33ee9bf43ee7e113fd817128ce34d2c8 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 15 Nov 2023 17:00:40 +0100 Subject: [PATCH 09/12] Update language version in readme files --- README.md | 4 ++-- src/PolySharp.Package/README.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e012d56..3006828 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# 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: @@ -53,7 +53,7 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[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 `` MSBuild property in your project. For instance, by adding `11.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 `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. 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)): diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index e620188..3f419dc 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# 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: @@ -51,7 +51,7 @@ Here's an example of some of the new features that **PolySharp** can enable down - `[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 `` MSBuild property in your project. For instance, by adding `11.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 `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. 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)): From 90c196a1d3fe9e3ef2db8afbd053733eb45851ab Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 22 Nov 2023 20:36:53 +0100 Subject: [PATCH 10/12] Add unit tests for new polyfill types --- tests/PolySharp.Tests/LanguageFeatures.cs | 30 +++++++++++++++++++++++ tests/PolySharp.Tests/RuntimeSupport.cs | 15 ++++++++++++ 2 files changed, 45 insertions(+) diff --git a/tests/PolySharp.Tests/LanguageFeatures.cs b/tests/PolySharp.Tests/LanguageFeatures.cs index ff14210..b7fd966 100644 --- a/tests/PolySharp.Tests/LanguageFeatures.cs +++ b/tests/PolySharp.Tests/LanguageFeatures.cs @@ -1,4 +1,6 @@ using System; +using System.Collections; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.Versioning; @@ -102,6 +104,10 @@ public static void InitializeModule() { } + public void RefReadonlyMethod(ref readonly int x) + { + } + [Experimental("PS0001")] public void ExperimentalMethod() { @@ -151,6 +157,30 @@ public static ReadOnlySpan TestRange(ReadOnlySpan numbers) } } +[CollectionBuilder(typeof(CollectionClass), nameof(Create))] +internal class CollectionClass : IEnumerable +{ + public CollectionClass Test() + { + return [1, 2, 3]; + } + + public static CollectionClass Create(ReadOnlySpan values) + { + return new(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return null!; + } + + IEnumerator IEnumerable.GetEnumerator() + { + return null!; + } +} + internal class AnotherTestClass { // CallerArgumentExpressionAttribute diff --git a/tests/PolySharp.Tests/RuntimeSupport.cs b/tests/PolySharp.Tests/RuntimeSupport.cs index 211cfaa..1e34a92 100644 --- a/tests/PolySharp.Tests/RuntimeSupport.cs +++ b/tests/PolySharp.Tests/RuntimeSupport.cs @@ -84,4 +84,19 @@ public void MakeUpSomeNewType() public void ReferenceSomeAssemblyFile() { } +} + +internal class AccessorApis +{ +#pragma warning disable IDE0044 + private int field; +#pragma warning restore IDE0044 + + [StackTraceHidden] + public void HideMe() + { + } + + [UnsafeAccessor(UnsafeAccessorKind.Field, Name = nameof(field))] + public static extern ref int GetField(RandomApis obj); } \ No newline at end of file From c06aad420f2c38a53bb55fc57766f6f2fa780a1b Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 22 Nov 2023 20:59:01 +0100 Subject: [PATCH 11/12] Add InlineArrayAttribute polyfill --- README.md | 1 + src/PolySharp.Package/README.md | 1 + ...e.CompilerServices.InlineArrayAttribute.cs | 44 +++++++++++++++++++ .../Models/SyntaxFixupType.cs | 8 +++- .../PolyfillsGenerator.Polyfills.cs | 19 ++++++++ tests/PolySharp.Tests/RuntimeSupport.cs | 12 ++++- 6 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.InlineArrayAttribute.cs diff --git a/README.md b/README.md index 3006828..99e942b 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ It also includes the following optional runtime-supported polyfills: - `[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 ⚙️ diff --git a/src/PolySharp.Package/README.md b/src/PolySharp.Package/README.md index 3f419dc..3aa6f4c 100644 --- a/src/PolySharp.Package/README.md +++ b/src/PolySharp.Package/README.md @@ -73,6 +73,7 @@ It also includes the following optional runtime-supported polyfills: - `[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 ⚙️ diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.InlineArrayAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.InlineArrayAttribute.cs new file mode 100644 index 0000000..6d3ccf0 --- /dev/null +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.CompilerServices.InlineArrayAttribute.cs @@ -0,0 +1,44 @@ +// +#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 +{ + /// + /// Indicates that the instance's storage is sequentially replicated "length" times. + /// + /// + /// + /// This attribute can be used to annotate a type with a single field. + /// The runtime will replicate that field in the actual type layout as many times as is specified. + /// + /// + /// Here's an example of how an inline array type with 8 values can be declared: + /// + /// [InlineArray(8)] + /// struct Float8InlineArray + /// { + /// private float _value; + /// } + /// + /// + /// + [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 + { + /// Creates a new instance with the specified length. + /// The number of sequential fields to replicate in the inline array type. + public InlineArrayAttribute(int length) + { + Length = length; + } + + /// Gets the number of sequential fields to replicate in the inline array type. + public int Length { get; } + } +} \ No newline at end of file diff --git a/src/PolySharp.SourceGenerators/Models/SyntaxFixupType.cs b/src/PolySharp.SourceGenerators/Models/SyntaxFixupType.cs index a89f62d..bc37406 100644 --- a/src/PolySharp.SourceGenerators/Models/SyntaxFixupType.cs +++ b/src/PolySharp.SourceGenerators/Models/SyntaxFixupType.cs @@ -27,5 +27,11 @@ internal enum SyntaxFixupType /// Generates the [UnmanagedCallersOnly] type in the InteropServices2 dummy namespace. /// /// This is needed when methods annotated with the attribute have to be assigned to delegates, which Roslyn will otherwise block. - UseInteropServices2ForUnmanagedCallersOnlyAttribute = 1 << 2 + UseInteropServices2ForUnmanagedCallersOnlyAttribute = 1 << 2, + + /// + /// Generates a global using for the [InlineArray] type in the dummy namespace. + /// + /// This is always needed when the type is used, as the usage is entirely blocked in the normal namespace. + EmitGlobalUsingForInlineArrayAttribute = 1 << 3 } diff --git a/src/PolySharp.SourceGenerators/PolyfillsGenerator.Polyfills.cs b/src/PolySharp.SourceGenerators/PolyfillsGenerator.Polyfills.cs index b826c9b..eec140e 100644 --- a/src/PolySharp.SourceGenerators/PolyfillsGenerator.Polyfills.cs +++ b/src/PolySharp.SourceGenerators/PolyfillsGenerator.Polyfills.cs @@ -154,6 +154,13 @@ static SyntaxFixupType GetSyntaxFixupType(Compilation compilation, string name) fixupType |= SyntaxFixupType.RemoveMethodImplAttributes; } + // Emit the global using for the dummy [InlineArray] type, if allowed + if (name is "System.Runtime.CompilerServices.InlineArrayAttribute" && + compilation.HasLanguageVersionAtLeastEqualTo(LanguageVersion.CSharp10)) + { + fixupType |= SyntaxFixupType.EmitGlobalUsingForInlineArrayAttribute; + } + return fixupType; } @@ -288,6 +295,18 @@ private void EmitGeneratedType(SourceProductionContext context, GeneratedType ty "System.Runtime.InteropServices2"); } + if ((type.FixupType & SyntaxFixupType.EmitGlobalUsingForInlineArrayAttribute) != 0) + { + // Generate a global using for [InlineArray] + adjustedSource = adjustedSource.Replace( + "namespace System.Runtime.CompilerServices2", + """ + global using InlineArrayAttribute = global::System.Runtime.CompilerServices2.InlineArrayAttribute; + + namespace System.Runtime.CompilerServices2 + """); + } + sourceText = SourceText.From(adjustedSource, Encoding.UTF8); } else diff --git a/tests/PolySharp.Tests/RuntimeSupport.cs b/tests/PolySharp.Tests/RuntimeSupport.cs index 1e34a92..a4593fb 100644 --- a/tests/PolySharp.Tests/RuntimeSupport.cs +++ b/tests/PolySharp.Tests/RuntimeSupport.cs @@ -88,9 +88,9 @@ public void ReferenceSomeAssemblyFile() internal class AccessorApis { -#pragma warning disable IDE0044 +#pragma warning disable CS0169, IDE0044 private int field; -#pragma warning restore IDE0044 +#pragma warning restore CS0169, IDE0044 [StackTraceHidden] public void HideMe() @@ -99,4 +99,12 @@ public void HideMe() [UnsafeAccessor(UnsafeAccessorKind.Field, Name = nameof(field))] public static extern ref int GetField(RandomApis obj); +} + +[InlineArray(16)] +internal struct Int8 +{ +#pragma warning disable CS0169, IDE0044, IDE0051 + private int value0; +#pragma warning restore CS0169, IDE0044, IDE0051 } \ No newline at end of file From d171c2e5b76f351e2c0f9cc8af730d641fcfe980 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Wed, 22 Nov 2023 21:00:16 +0100 Subject: [PATCH 12/12] Remove unnecessary [UnmanagedCallersOnly] constructor --- ...m.Runtime.InteropServices.UnmanagedCallersOnlyAttribute.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute.cs b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute.cs index 7cdf153..a2b1b22 100644 --- a/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute.cs +++ b/src/PolySharp.SourceGenerators/EmbeddedResources/RuntimeSupported/System.Runtime.InteropServices.UnmanagedCallersOnlyAttribute.cs @@ -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() - { - } - /// /// Optional. If omitted, the runtime will use the default platform calling convention. ///