Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FastNew_PublicFastNew option #80

Merged
merged 9 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
5.0.x
6.0.x
7.0.x
8.0.x
9.0.x
include-prerelease: true
- name: Restore dependencies
run: dotnet restore
Expand Down
4 changes: 3 additions & 1 deletion FastGenericNew.sln
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Root", "Root", "{F142034C-8
Benchmark_ReferenceType.png = Benchmark_ReferenceType.png
Benchmark_ValueType.png = Benchmark_ValueType.png
FastGenericNew.Shared.props = FastGenericNew.Shared.props
.github\workflows\publish.yml = .github\workflows\publish.yml
README.md = README.md
.github\workflows\tests.yml = .github\workflows\tests.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGenericNew.Tests", "src\FastGenericNew.Tests\FastGenericNew.Tests.csproj", "{7A750C15-4CF3-4F5B-BFA8-AFBB98827770}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGenericNew.Benchmarks", "src\FastGenericNew.Benchmarks\FastGenericNew.Benchmarks.csproj", "{24108B29-8FAD-4080-90B4-0A6A19CE06BE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastGenericNew.SourceGenerator.InternalGenerator", "src\FastGenericNew.SourceGenerator.InternalGenerator\FastGenericNew.SourceGenerator.InternalGenerator.csproj", "{33032C07-28EF-4AD6-BE00-32303BB9DA7B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGenericNew.SourceGenerator.InternalGenerator", "src\FastGenericNew.SourceGenerator.InternalGenerator\FastGenericNew.SourceGenerator.InternalGenerator.csproj", "{33032C07-28EF-4AD6-BE00-32303BB9DA7B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net461;net48</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net462;net481</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
Expand All @@ -25,6 +25,7 @@

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
5 changes: 2 additions & 3 deletions src/FastGenericNew.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@

ManualConfig config = ManualConfig.Create(DefaultConfig.Instance);
config.AddJob(
Job.Default.WithRuntime(ClrRuntime.Net461),
Job.Default.WithRuntime(ClrRuntime.Net48),
Job.Default.WithRuntime(CoreRuntime.Core31),
Job.Default.WithRuntime(ClrRuntime.Net462),
Job.Default.WithRuntime(ClrRuntime.Net481),
Job.Default.WithRuntime(CoreRuntime.Core60),
Job.Default.WithRuntime(CoreRuntime.Core80),
Job.Default.WithRuntime(CoreRuntime.Core90)
Expand Down
6 changes: 3 additions & 3 deletions src/FastGenericNew.Shared.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>3.2.0-preview1</Version>
<AssemblyVersion>3.2.0</AssemblyVersion>
<Version>3.3.0</Version>
<AssemblyVersion>3.3.0</AssemblyVersion>
</PropertyGroup>

<!-- Ensure the asset files are referenced in the project file -->
Expand Down Expand Up @@ -32,7 +32,7 @@ C# 10 Parameterless struct constructors Support (Both invokes or not)
<RepositoryUrl>https://github.com/Nyrest/FastGenericNew</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageProjectUrl>https://github.com/Nyrest/FastGenericNew</PackageProjectUrl>
<PackageTags>Performance, Fast, Generic, New, Expression, Optimization, CreateInstance, Activator, $(PackageTagsPostfix)</PackageTags>
<PackageTags>Performance, Fast, Generic, New, Expression, Optimization, CreateInstance, Activator, DynamicMethod, $(PackageTagsPostfix)</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>Logo.png</PackageIcon>
<IsPackable>true</IsPackable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ public override CodeGenerationResult Generate(in GeneratorOptions options)
builder.WriteFileHeader();
builder.StartNamespace();
builder.Indent(1);
builder.AppendKeyword("public static partial class");
builder.AppendKeyword("static partial class");
builder.Append(ClassName);
builder.StartBlock(1);

builder.AppendLine($@"
/// <summary>
/// <para>Create an instance of <typeparamref name=""T"" /></para>
/// <para>Returns <c><see langword=""new"" /> <typeparamref name=""T"" />()</c> if <typeparamref name=""T""/> is a <see cref=""ValueType""/>(struct)</para>
/// <para>This <b>CAN</b> call the Parameterless Constructor of the <see cref=""ValueType""/>(struct)</para>
/// <para>This <b>CAN</b> call the Parameterless Constructor for <see cref=""ValueType""/>(struct)</para>
/// </summary>
/// <typeparam name=""T"">The type to create.</typeparam>
/// <returns>A new instance of <typeparamref name=""T"" /></returns>
Expand All @@ -39,7 +38,7 @@ public static T CreateInstance<
return {options.GlobalNSDot()}{FastNewCoreGenerator.ClassName}<T>.{FastNewCoreGenerator.CompiledDelegateName}();
#else
return typeof(T).IsValueType
? System.Activator.CreateInstance<T>() // This will be optimized by JIT
? System.Activator.CreateInstance<T>() // Value Types will be optimized by JIT in CoreCLR

#if {ClrAllocatorGenerator.ppEnabled}
: ({options.GlobalNSDot()}{ClrAllocatorGenerator.ClassName}<T>.IsSupported
Expand All @@ -54,7 +53,7 @@ public static T CreateInstance<
/// <summary>
/// Create an instance of <typeparamref name=""T"" /> <br/>
/// Returns <c><see langword=""default"" />(<typeparamref name=""T"" />)</c> if <typeparamref name=""T""/> is a <see cref=""ValueType""/>(struct) <br/>
/// This <b>WILL NOT</b> call the Parameterless Constructor of the <see cref=""ValueType""/>(struct)
/// This <b>WILL NOT</b> call the Parameterless Constructor for <see cref=""ValueType""/>(struct)
/// </summary>
/// <typeparam name=""T"">The type to create.</typeparam>
/// <returns>A new instance of <typeparamref name=""T"" /></returns>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public override CodeGenerationResult Generate(in GeneratorOptions options)
builder.WriteFileHeader();
builder.StartNamespace();
builder.Indent(1);
builder.AppendKeyword("public static partial class");
builder.AppendKeyword("static partial class");
builder.Append(ClassName);

builder.StartBlock(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace FastGenericNew.SourceGenerator.CodeGenerators;

public class FastNewVisibilityGenerator : CodeGenerator<FastNewVisibilityGenerator>
{
public override string Filename => "FastNewVisibility.g.cs";

internal const string ClassName = "FastNew";

public override CodeGenerationResult Generate(in GeneratorOptions options)
{
CodeBuilder builder = new(1024, in options);
builder.WriteFileHeader();
builder.StartNamespace();
builder.Indent(1);

builder.AppendKeyword(options.PublicFastNew ? "public" : "internal");

builder.AppendKeyword("static partial class");
builder.Append(ClassName);
builder.StartBlock(1);
builder.EndBlock(1);
builder.EndNamespace();

return builder.BuildAndDispose(this);
}

public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) =>
base.ShouldUpdate(oldValue, newValue)
|| oldValue.PublicFastNew != newValue.PublicFastNew;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public override CodeGenerationResult Generate(in GeneratorOptions options)
builder.WriteFileHeader();
builder.StartNamespace();
builder.Indent(1);
builder.AppendKeyword("public static partial class");
builder.AppendKeyword("static partial class");
builder.Append(ClassName);

builder.StartBlock(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class ThrowHelperGenerator : CodeGenerator<ThrowHelperGenerator>
{
public override string Filename => "ThrowHelper.g.cs";

internal const string ClassName = "ThrowHelper";
internal const string ClassName = "FastNewThrowHelper";

internal const string SmartThrowName = "SmartThrowImpl";

Expand All @@ -15,15 +15,15 @@ public override CodeGenerationResult Generate(in GeneratorOptions options)
builder.StartNamespace();
builder.AppendLine(@$"
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)]
internal static partial class ThrowHelper
internal static partial class {ClassName}
{{
[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining | global::System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]
#if NET5_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute(""SmartThrowImpl``1()"", typeof({options.GlobalNSDot()}{ClassName}))]
#endif
");
builder.AppendLine(@$"
public static global::System.Reflection.MethodInfo GetSmartThrow<T>() => typeof({options.GlobalNSDot()}ThrowHelper).GetMethod(""SmartThrowImpl"", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)!.MakeGenericMethod(typeof(T));
public static global::System.Reflection.MethodInfo GetSmartThrow<T>() => typeof({options.GlobalNSDot()}{ClassName}).GetMethod(""SmartThrowImpl"", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)!.MakeGenericMethod(typeof(T));

[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining | global::System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)]
public static T SmartThrowImpl<T>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public override CodeGenerationResult Generate(in GeneratorOptions options)
builder.WriteFileHeader();
builder.StartNamespace();

builder.AppendKeyword("public static partial class");
builder.AppendKeyword("static partial class");
builder.Append(ClassName);

builder.StartBlock(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<!-- Library Properties -->
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>preview</LangVersion>
<LangVersion>11.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsRoslynComponent>true</IsRoslynComponent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@
<CompilerVisibleProperty Include="FastNew_MultiThreadedGeneration" />
<CompilerVisibleProperty Include="FastNew_OutputGenerationInfo" />
<CompilerVisibleProperty Include="FastNew_AllowUnsafeImplementation" />
<CompilerVisibleProperty Include="FastNew_PublicFastNew" />
</ItemGroup>
</Project>
5 changes: 4 additions & 1 deletion src/FastGenericNew.SourceGenerator/GeneratorOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public readonly partial record struct GeneratorOptions
[GeneratorOption(true)]
public bool AlertGeneratedFile { get; }

[GeneratorOption(false)]
[GeneratorOption(true)]
public bool DisableGeneratorCache { get; }

[GeneratorOption(false)]
Expand All @@ -44,6 +44,9 @@ public readonly partial record struct GeneratorOptions
[GeneratorOption(false, PresentPreProcessor = true)]
public bool AllowUnsafeImplementation { get; }

[GeneratorOption(false)]
public bool PublicFastNew { get; }

// ctor will be generated by InternalGenerator
//public GeneratorOptions(AnalyzerConfigOptionsProvider? provider)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ public GeneratorOptions(AnalyzerConfigOptionsProvider? provider)
Namespace = options.GetOrDefault(nameof(Namespace), "FastGenericNew");
ForceFastNewDelegate = options.GetOrDefault(nameof(ForceFastNewDelegate), false);
AlertGeneratedFile = options.GetOrDefault(nameof(AlertGeneratedFile), true);
DisableGeneratorCache = options.GetOrDefault(nameof(DisableGeneratorCache), false);
DisableGeneratorCache = options.GetOrDefault(nameof(DisableGeneratorCache), true);
PrettyOutput = options.GetOrDefault(nameof(PrettyOutput), false);
MultiThreadedGeneration = options.GetOrDefault(nameof(MultiThreadedGeneration), true);
OutputGenerationInfo = options.GetOrDefault(nameof(OutputGenerationInfo), false);
AllowUnsafeImplementation = options.GetOrDefault(nameof(AllowUnsafeImplementation), false);
PublicFastNew = options.GetOrDefault(nameof(PublicFastNew), false);
}
}
4 changes: 2 additions & 2 deletions src/FastGenericNew.Tests/FastGenericNew.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net9.0</TargetFrameworks>
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);net48</TargetFrameworks>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
Expand Down
8 changes: 8 additions & 0 deletions src/FastGenericNew.Tests/TestData.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;

Expand Down Expand Up @@ -35,6 +38,11 @@ public static class TestData
typeof(nint),
typeof(nuint),

#if NET8_0_OR_GREATER
typeof(Int128),
typeof(UInt128),
#endif

#endregion

typeof(DateTime),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ public class ExceptionsTest
[Test()]
public void ExceptionInterface()
{
if (!ClrAllocator<IEnumerable>.IsSupported) Assert.Ignore("Unsupported");
try
{
ClrAllocator<IEnumerable>.CreateInstance();
Assert.Fail("The expected exception is not thrown.");
}
catch (MissingMethodException e)
catch (Exception e)
{
Assert.IsTrue(e.Message.StartsWith("Cannot create an instance of an interface"));
}
Expand All @@ -20,6 +21,7 @@ public void ExceptionInterface()
[Test()]
public void ExceptionAbstract()
{
if (!ClrAllocator<Stream>.IsSupported) Assert.Ignore("Unsupported");
try
{
ClrAllocator<Stream>.CreateInstance();
Expand All @@ -34,6 +36,7 @@ public void ExceptionAbstract()
[Test()]
public void ExceptionPLString()
{
if (!ClrAllocator<string>.IsSupported) Assert.Ignore("Unsupported");
try
{
ClrAllocator<string>.CreateInstance();
Expand All @@ -49,6 +52,7 @@ public void ExceptionPLString()
[Test()]
public void ExceptionNotFoundNoParameter()
{
if (!ClrAllocator<DemoClassNoParamlessCtor>.IsSupported) Assert.Ignore("Unsupported");
try
{
ClrAllocator<DemoClassNoParamlessCtor>.CreateInstance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class ReferenceTypes
[Test]
public void Object()
{
if (!ClrAllocator<object>.IsSupported) Assert.Ignore("Unsupported");
var expected = Activator.CreateInstance<object>();
var actual = ClrAllocator<object>.CreateInstance();
Assert.IsTrue(expected.GetType() == actual.GetType());
Expand All @@ -17,6 +18,7 @@ public void Object()
[Parallelizable(ParallelScope.All)]
public void CommonTypes<T>()
{
if (!ClrAllocator<T>.IsSupported) Assert.Ignore("Unsupported");
var expected = Activator.CreateInstance<T>();
var actual = ClrAllocator<T>.CreateInstance();
Assert.AreEqual(expected, actual);
Expand All @@ -26,6 +28,7 @@ public void CommonTypes<T>()
[Parallelizable(ParallelScope.All)]
public void ParallelNew<T>()
{
if (!ClrAllocator<T>.IsSupported) Assert.Ignore("Unsupported");
const int count = 512;
T[] array = new T[count];
Parallel.For(0, count, new ParallelOptions() { MaxDegreeOfParallelism = count }, i =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public class ValueTypes
[Parallelizable(ParallelScope.All)]
public void CommonTypes<T>()
{
if (!ClrAllocator<T>.IsSupported) Assert.Ignore("Unsupported");
var expected = Activator.CreateInstance<T>();
var actual = FastNew<T>.CompiledDelegate();
Assert.AreEqual(expected, actual);
Expand Down
Loading
Loading