From ec928fca146d6b6e680870493f5b9e0818abd22a Mon Sep 17 00:00:00 2001 From: Boring3 <16686147+Nyrest@users.noreply.github.com> Date: Thu, 15 Aug 2024 11:06:17 +0800 Subject: [PATCH] Refactor generators --- .../Gen/GeneratorOptionsRelatedGenerator.cs | 41 +---- .../CodeGenerator.cs | 18 ++- .../CodeGenerators/ClrAllocatorGenerator.cs | 7 +- .../FastCreateInstanceGenerator.cs | 7 +- .../CodeGenerators/FastNewCoreGenerator.cs | 10 +- .../FastNewDelegateGenerator.cs | 10 +- .../FastNewVisibilityGenerator.cs | 10 +- .../FastTryCreateInstanceGenerator.cs | 7 +- .../CodeGenerators/GenerationInfoGenerator.cs | 10 +- .../CodeGenerators/ThrowHelperGenerator.cs | 10 +- .../FastGenericNew.SourceGenerator.props | 2 - .../Generator.cs | 83 +++-------- .../GeneratorOptions.cs | 32 ++-- .../Utilities/GeneratorInstance{T}.cs | 15 -- ...odeGenerator.PreProcessorRelatedCheck.g.cs | 10 -- .../GeneratorOptions.ctor.g.cs | 2 - src/FastGenericNew/FastGenericNew.csproj | 3 + .../ClrAllocator.g.cs | 140 ------------------ .../_GenerationInfo.g.cs | 4 - 19 files changed, 99 insertions(+), 322 deletions(-) delete mode 100644 src/FastGenericNew.SourceGenerator/Utilities/GeneratorInstance{T}.cs delete mode 100644 src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/CodeGenerator.PreProcessorRelatedCheck.g.cs delete mode 100644 src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/ClrAllocator.g.cs diff --git a/src/FastGenericNew.SourceGenerator.InternalGenerator/Gen/GeneratorOptionsRelatedGenerator.cs b/src/FastGenericNew.SourceGenerator.InternalGenerator/Gen/GeneratorOptionsRelatedGenerator.cs index 51acec4..98011f2 100644 --- a/src/FastGenericNew.SourceGenerator.InternalGenerator/Gen/GeneratorOptionsRelatedGenerator.cs +++ b/src/FastGenericNew.SourceGenerator.InternalGenerator/Gen/GeneratorOptionsRelatedGenerator.cs @@ -55,13 +55,12 @@ private static void BuildSource(in SourceProductionContext context, Compilation .ToArray(); BuildGeneratorOptionsConstructor(in context, symbolsWithAttrData); BuildCodeBuilderPreProcessorDefinitions(in context, symbolsWithAttrData); - BuildCodeGeneratorExtraCheck(in context, symbolsWithAttrData); } public static void BuildGeneratorOptionsConstructor(in SourceProductionContext context, (IPropertySymbol symbol, AttributeData attrData)[] symbolsWithAttrData) { const string indent = " "; - StringBuilder sb = new StringBuilder(""" + StringBuilder sb = new(""" #nullable enable namespace FastGenericNew.SourceGenerator; @@ -94,7 +93,7 @@ public GeneratorOptions(AnalyzerConfigOptionsProvider? provider) public static void BuildCodeBuilderPreProcessorDefinitions(in SourceProductionContext context, (IPropertySymbol symbol, AttributeData attrData)[] symbolsWithAttrData) { - StringBuilder sb = new StringBuilder(""" + StringBuilder sb = new(""" #nullable enable namespace FastGenericNew.SourceGenerator.Utilities; @@ -124,41 +123,5 @@ private partial void _Write_PreProcessorDefinitions() """); context.AddSource("CodeBuilder.PreProcessor.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8)); } - - public static void BuildCodeGeneratorExtraCheck(in SourceProductionContext context, (IPropertySymbol symbol, AttributeData attrData)[] symbolsWithAttrData) - { - const string indent = " "; - StringBuilder sb = new StringBuilder(""" -#nullable enable - -namespace FastGenericNew.SourceGenerator; - -partial class CodeGenerator -{ - private static partial bool PreProcessorRelatedCheck(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - -""", 4096); - bool isFirst = true; - foreach (var (symbol, attrData) in symbolsWithAttrData) - { - if (!attrData.TryGetNamedArgument(GeneratorOptionAttributeGenerator.Arg_PresentPreProcessor, out bool value) || !value) - continue; - var propertyName = symbol.Name; - sb.Append(indent); - - if (!isFirst) - { - sb.Append("|| "); - } - else isFirst = false; - sb.AppendLine($"oldValue.{propertyName} != newValue.{propertyName}"); - } - if (isFirst) sb.Append("false"); - sb.Append(""" -; -} -"""); - context.AddSource("CodeGenerator.PreProcessorRelatedCheck.g.cs", SourceText.From(sb.ToString(), Encoding.UTF8)); - } } } diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerator.cs index 37de576..11a9538 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerator.cs @@ -4,14 +4,16 @@ public abstract partial class CodeGenerator { public abstract string Filename { get; } - public virtual bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - oldValue.Namespace != newValue.Namespace - || oldValue.MaxParameterCount != newValue.MaxParameterCount - || oldValue.AlertGeneratedFile != newValue.AlertGeneratedFile - || oldValue.PrettyOutput != newValue.PrettyOutput - || PreProcessorRelatedCheck(in oldValue, in newValue); - public abstract CodeGenerationResult Generate(in GeneratorOptions options); - private static partial bool PreProcessorRelatedCheck(in GeneratorOptions oldValue, in GeneratorOptions newValue); + public virtual GeneratorOptions GetOptionsSubset(GeneratorOptions options) + { + return new GeneratorOptions() with + { + Namespace = options.Namespace, + MaxParameterCount = options.MaxParameterCount, + AlertGeneratedFile = options.AlertGeneratedFile, + PrettyOutput = options.PrettyOutput + }; + } } diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/ClrAllocatorGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/ClrAllocatorGenerator.cs index bc9a74b..8195fdd 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/ClrAllocatorGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/ClrAllocatorGenerator.cs @@ -145,8 +145,11 @@ public static T CreateInstance() return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) { - return base.ShouldUpdate(oldValue, newValue) && newValue.AllowUnsafeImplementation; + return base.GetOptionsSubset(options) with + { + AllowUnsafeImplementation = options.AllowUnsafeImplementation, + }; } } diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastCreateInstanceGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastCreateInstanceGenerator.cs index c6d9f28..a230bd7 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastCreateInstanceGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastCreateInstanceGenerator.cs @@ -122,8 +122,11 @@ public static T NewOrDefault< return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) { - return base.ShouldUpdate(oldValue, newValue) && newValue.GenerateCreateInstance; + return base.GetOptionsSubset(options) with + { + GenerateCreateInstance = options.GenerateCreateInstance, + }; } } \ No newline at end of file diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewCoreGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewCoreGenerator.cs index 06deeb1..cf21c6b 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewCoreGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewCoreGenerator.cs @@ -302,7 +302,11 @@ public override CodeGenerationResult Generate(in GeneratorOptions options) return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - base.ShouldUpdate(oldValue, newValue) - || oldValue.ForceFastNewDelegate != newValue.ForceFastNewDelegate; + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) + { + return base.GetOptionsSubset(options) with + { + ForceFastNewDelegate = options.ForceFastNewDelegate, + }; + } } \ No newline at end of file diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewDelegateGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewDelegateGenerator.cs index cfc148b..09a785c 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewDelegateGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewDelegateGenerator.cs @@ -34,7 +34,11 @@ public override CodeGenerationResult Generate(in GeneratorOptions options) return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - base.ShouldUpdate(oldValue, newValue) - || oldValue.ForceFastNewDelegate != newValue.ForceFastNewDelegate; + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) + { + return base.GetOptionsSubset(options) with + { + ForceFastNewDelegate = options.ForceFastNewDelegate, + }; + } } diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewVisibilityGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewVisibilityGenerator.cs index 98ed4dc..784464c 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewVisibilityGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastNewVisibilityGenerator.cs @@ -24,7 +24,11 @@ public override CodeGenerationResult Generate(in GeneratorOptions options) return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - base.ShouldUpdate(oldValue, newValue) - || oldValue.PublicFastNew != newValue.PublicFastNew; + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) + { + return base.GetOptionsSubset(options) with + { + PublicFastNew = options.PublicFastNew, + }; + } } \ No newline at end of file diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastTryCreateInstanceGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastTryCreateInstanceGenerator.cs index 2f710e5..c44538c 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/FastTryCreateInstanceGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/FastTryCreateInstanceGenerator.cs @@ -123,8 +123,11 @@ public static bool TryNewOrDefault< return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) { - return base.ShouldUpdate(oldValue, newValue) && newValue.GenerateTryCreateInstance; + return base.GetOptionsSubset(options) with + { + GenerateTryCreateInstance = options.GenerateTryCreateInstance, + }; } } diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/GenerationInfoGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/GenerationInfoGenerator.cs index 3cdf378..5a06148 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/GenerationInfoGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/GenerationInfoGenerator.cs @@ -82,7 +82,11 @@ public override CodeGenerationResult Generate(in GeneratorOptions options) return builder.BuildAndDispose(this); } - // Since this won't be invoked if the oldValue equals the newValue. - // So just do it. - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) => newValue.OutputGenerationInfo; + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) + { + return base.GetOptionsSubset(options) with + { + OutputGenerationInfo = options.OutputGenerationInfo, + }; + } } diff --git a/src/FastGenericNew.SourceGenerator/CodeGenerators/ThrowHelperGenerator.cs b/src/FastGenericNew.SourceGenerator/CodeGenerators/ThrowHelperGenerator.cs index c96cf4d..ef986c3 100644 --- a/src/FastGenericNew.SourceGenerator/CodeGenerators/ThrowHelperGenerator.cs +++ b/src/FastGenericNew.SourceGenerator/CodeGenerators/ThrowHelperGenerator.cs @@ -43,7 +43,11 @@ public static T SmartThrowImpl() return builder.BuildAndDispose(this); } - public override bool ShouldUpdate(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - oldValue.Namespace != newValue.Namespace - || oldValue.AlertGeneratedFile != newValue.AlertGeneratedFile; + public override GeneratorOptions GetOptionsSubset(GeneratorOptions options) + { + return base.GetOptionsSubset(options) with + { + AlertGeneratedFile = options.AlertGeneratedFile, + }; + } } \ No newline at end of file diff --git a/src/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.props b/src/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.props index 6b9db9c..b70e9cc 100644 --- a/src/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.props +++ b/src/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.props @@ -11,9 +11,7 @@ - - diff --git a/src/FastGenericNew.SourceGenerator/Generator.cs b/src/FastGenericNew.SourceGenerator/Generator.cs index afaa335..c7c1d9f 100644 --- a/src/FastGenericNew.SourceGenerator/Generator.cs +++ b/src/FastGenericNew.SourceGenerator/Generator.cs @@ -3,89 +3,48 @@ [Generator(LanguageNames.CSharp)] public unsafe class Generator : IIncrementalGenerator { - private static GeneratorOptions _lastOptions; - - private static readonly nint[] generatorPointers = Assembly + private static readonly CodeGenerator[] generators = Assembly .GetCallingAssembly() .GetTypes() .Where(static x => !x.IsAbstract && typeof(CodeGenerator).IsAssignableFrom(x)) - .Select(static x => - (nint) - typeof(GeneratorInstance<>) - .MakeGenericType(x) - .GetMethod(nameof(GeneratorInstance.Generate)) - .MethodHandle.GetFunctionPointer() - ) + .Select(static x => (CodeGenerator)Activator.CreateInstance(x)) .ToArray(); - private static readonly object _lock = new(); - public void Initialize(IncrementalGeneratorInitializationContext context) { - context.RegisterSourceOutput(context.AnalyzerConfigOptionsProvider.WithComparer(AnalyzerConfigComparer.Instance), BuildSource); - static void BuildSource(SourceProductionContext sourceContext, AnalyzerConfigOptionsProvider optionsProvider) + foreach (var generator in generators) { - var newOptions = new GeneratorOptions(optionsProvider); - - if (newOptions.DisableGeneratorCache) - { - _lastOptions = default; - } - - if (newOptions.MultiThreadedGeneration) - { - Parallel.ForEach(generatorPointers, nativePointer => - { - var function = (delegate* managed)nativePointer; - var result = function(in _lastOptions, in newOptions); - if (result.SourceText != null) - { - lock (_lock) - { - sourceContext.AddSource(result.Filename, result.SourceText); - } - } - if (result.Diagnostics != null) - { - lock (_lock) - { - foreach (Diagnostic diag in result.Diagnostics) - { - sourceContext.ReportDiagnostic(diag); - } - } - } - }); - } - else + var comparer = new AnalyzerConfigComparer(generator); + context.RegisterSourceOutput(context.AnalyzerConfigOptionsProvider.WithComparer(comparer), (SourceProductionContext sourceContext, AnalyzerConfigOptionsProvider optionsProvider) => { - foreach (var nativePointer in generatorPointers) + var options = new GeneratorOptions(optionsProvider); + var result = generator.Generate(in options); + if (result.SourceText != null) + sourceContext.AddSource(result.Filename, result.SourceText); + if (result.Diagnostics != null) { - var function = (delegate* managed)nativePointer; - var result = function(in _lastOptions, in newOptions); - if (result.SourceText != null) - sourceContext.AddSource(result.Filename, result.SourceText); - if (result.Diagnostics != null) + foreach (Diagnostic diag in result.Diagnostics) { - foreach (Diagnostic diag in result.Diagnostics) - { - sourceContext.ReportDiagnostic(diag); - } + sourceContext.ReportDiagnostic(diag); } } - } - _lastOptions = newOptions; + }); } } class AnalyzerConfigComparer : IEqualityComparer { - public static readonly AnalyzerConfigComparer Instance = new(); + private readonly CodeGenerator generator; + + public AnalyzerConfigComparer(CodeGenerator generator) + { + this.generator = generator; + } public bool Equals(AnalyzerConfigOptionsProvider x, AnalyzerConfigOptionsProvider y) => - new GeneratorOptions(x).Equals(new GeneratorOptions(y)); + generator.GetOptionsSubset(new GeneratorOptions(x)).Equals(generator.GetOptionsSubset(new GeneratorOptions(y))); public int GetHashCode(AnalyzerConfigOptionsProvider obj) => - new GeneratorOptions(obj).GetHashCode(); + generator.GetOptionsSubset(new GeneratorOptions(obj)).GetHashCode(); } } diff --git a/src/FastGenericNew.SourceGenerator/GeneratorOptions.cs b/src/FastGenericNew.SourceGenerator/GeneratorOptions.cs index 5435cfc..09af7af 100644 --- a/src/FastGenericNew.SourceGenerator/GeneratorOptions.cs +++ b/src/FastGenericNew.SourceGenerator/GeneratorOptions.cs @@ -3,49 +3,43 @@ public readonly partial record struct GeneratorOptions { [GeneratorOption(16)] - public int MaxParameterCount { get; } + public int MaxParameterCount { get; init; } [GeneratorOption(false)] - public bool PublicFastNewCore { get; } + public bool PublicFastNewCore { get; init; } [GeneratorOption(true)] - public bool GenerateTryCreateInstance { get; } + public bool GenerateTryCreateInstance { get; init; } [GeneratorOption(true)] - public bool GenerateCreateInstance { get; } + public bool GenerateCreateInstance { get; init; } [GeneratorOption(true)] - public bool GenerateTypeCreateInstance { get; } + public bool GenerateTypeCreateInstance { get; init; } [GeneratorOption(true)] - public bool NonPublicConstructorSupport { get; } + public bool NonPublicConstructorSupport { get; init; } [GeneratorOption("FastGenericNew")] - public string Namespace { get; } + public string Namespace { get; init; } [GeneratorOption(false)] - public bool ForceFastNewDelegate { get; } + public bool ForceFastNewDelegate { get; init; } [GeneratorOption(true)] - public bool AlertGeneratedFile { get; } - - [GeneratorOption(true)] - public bool DisableGeneratorCache { get; } + public bool AlertGeneratedFile { get; init; } [GeneratorOption(false)] - public bool PrettyOutput { get; } - - [GeneratorOption(true)] - public bool MultiThreadedGeneration { get; } + public bool PrettyOutput { get; init; } [GeneratorOption(false)] - public bool OutputGenerationInfo { get; } + public bool OutputGenerationInfo { get; init; } [GeneratorOption(false, PresentPreProcessor = true)] - public bool AllowUnsafeImplementation { get; } + public bool AllowUnsafeImplementation { get; init; } [GeneratorOption(false)] - public bool PublicFastNew { get; } + public bool PublicFastNew { get; init; } // ctor will be generated by InternalGenerator //public GeneratorOptions(AnalyzerConfigOptionsProvider? provider) diff --git a/src/FastGenericNew.SourceGenerator/Utilities/GeneratorInstance{T}.cs b/src/FastGenericNew.SourceGenerator/Utilities/GeneratorInstance{T}.cs deleted file mode 100644 index 06675f6..0000000 --- a/src/FastGenericNew.SourceGenerator/Utilities/GeneratorInstance{T}.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace FastGenericNew.SourceGenerator.Utilities; - -public static class GeneratorInstance where T : CodeGenerator, new() -{ - public static readonly T Instance = new(); - - private static CodeGenerationResult? _cachedResult; - - public static CodeGenerationResult Generate(in GeneratorOptions _oldOptions, in GeneratorOptions options) - { - return !Instance.ShouldUpdate(in _oldOptions, in options) && _cachedResult != null - ? _cachedResult - : (_cachedResult = Instance.Generate(in options)); - } -} diff --git a/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/CodeGenerator.PreProcessorRelatedCheck.g.cs b/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/CodeGenerator.PreProcessorRelatedCheck.g.cs deleted file mode 100644 index 252d135..0000000 --- a/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/CodeGenerator.PreProcessorRelatedCheck.g.cs +++ /dev/null @@ -1,10 +0,0 @@ -#nullable enable - -namespace FastGenericNew.SourceGenerator; - -partial class CodeGenerator -{ - private static partial bool PreProcessorRelatedCheck(in GeneratorOptions oldValue, in GeneratorOptions newValue) => - oldValue.AllowUnsafeImplementation != newValue.AllowUnsafeImplementation -; -} \ No newline at end of file diff --git a/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/GeneratorOptions.ctor.g.cs b/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/GeneratorOptions.ctor.g.cs index bd9dec8..10ac837 100644 --- a/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/GeneratorOptions.ctor.g.cs +++ b/src/FastGenericNew.SourceGenerator/_generated/FastGenericNew.SourceGenerator.InternalGenerator/FastGenericNew.SourceGenerator.InternalGenerator.Generator/GeneratorOptions.ctor.g.cs @@ -16,9 +16,7 @@ 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), 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); diff --git a/src/FastGenericNew/FastGenericNew.csproj b/src/FastGenericNew/FastGenericNew.csproj index 963b421..2e221fe 100644 --- a/src/FastGenericNew/FastGenericNew.csproj +++ b/src/FastGenericNew/FastGenericNew.csproj @@ -56,6 +56,9 @@ false + + + diff --git a/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/ClrAllocator.g.cs b/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/ClrAllocator.g.cs deleted file mode 100644 index 90e5298..0000000 --- a/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/ClrAllocator.g.cs +++ /dev/null @@ -1,140 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by FastGenericNew.SourceGenerator -// Please do not modify this file directly -// -//------------------------------------------------------------------------------ -#define FastNewPX_AllowUnsafeImplementation -#nullable enable -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using System.Reflection.Emit; -using System.ComponentModel; - -#if NET6_0_OR_GREATER && FastNewPX_AllowUnsafeImplementation -namespace @FastGenericNew -{ - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] - static unsafe class ClrAllocator - { - public static readonly delegate*, ref void*, ref delegate*, int*, void> GetActivationInfo; - - public static readonly bool IsSupported; - - static ClrAllocator() - { - foreach (var met in typeof(global::System.RuntimeTypeHandle).GetMethods(global::System.Reflection.BindingFlags.Static | global::System.Reflection.BindingFlags.NonPublic)) - { - if (met.Name == "GetActivationInfo" && (met.Attributes & global::System.Reflection.MethodAttributes.PinvokeImpl) != 0) - { - var parameters = met.GetParameters(); - // TODO Consider to use list pattern when available - // Double-check the method - if ( - parameters.Length == 5 - && parameters[0].ParameterType == Type.GetType("System.Runtime.CompilerServices.ObjectHandleOnStack", false) - && parameters[1].ParameterType == typeof(delegate**) - && parameters[2].ParameterType == typeof(void**) - && parameters[3].ParameterType == typeof(delegate**) - // && parameters[4].ParameterType == Type.GetType("Interop.BOOL", false) - ) - { - GetActivationInfo = (delegate*, ref void*, ref delegate*, int*, void>) - met.MethodHandle.GetFunctionPointer(); - IsSupported = true; - } - } - } - } - - public static void CtorNoopStub(object _) { } - [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining | global::System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] - public static object ThrowNotSupported(void* _) => throw new global::System.NotSupportedException(); - [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.NoInlining | global::System.Runtime.CompilerServices.MethodImplOptions.NoOptimization)] - public static object SmartThrow(void* _) => (object)global::@FastGenericNew.FastNewThrowHelper.SmartThrowImpl()!; - } - - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Never)] - static unsafe class ClrAllocator - { - private static readonly delegate* _pfnAllocator; - - private static readonly void* _allocatorFirstArg; - - private static readonly delegate* _pfnCtor; - - /// - /// TRUE means ClrAllocator<T> can fully replace to FastNewCore
- /// So this can be TRUE even the CreateInstance will throw an exception. - ///
- public static readonly bool IsSupported; - - static ClrAllocator() - { - if (!global::@FastGenericNew.ClrAllocator.IsSupported) goto MarkUnsupported; - var type = typeof(T); - - int _ctorIsPublic = default; - try - { - ((delegate*, ref void*, ref delegate*, int*, void>)global::@FastGenericNew.ClrAllocator.GetActivationInfo) - (Unsafe.AsPointer(ref type), ref _pfnAllocator, ref _allocatorFirstArg, ref _pfnCtor, &_ctorIsPublic); - } - catch - { - // Exceptions SmartThrow can handle. - //if (type.IsAbstract) goto GoSmartThrow; - - // GetActivationInfo has many extra limits - // https://github.com/dotnet/runtime/blob/a5ec8aa173e4bc76b173a70aa7fa3be1867011eb/src/coreclr/vm/reflectioninvocation.cpp#L1942:25 - - // Exceptions SmartThrow CAN NOT handle. - // Mark unsupported so FastGenericNew will use FastNewCore instead if hit any - // - if ( - type.IsArray // typeHandle.IsArray() - || type.IsByRefLike // pMT->IsByRefLike() - || type == typeof(string) // pMT->HasComponentSize() - || typeof(Delegate).IsAssignableFrom(type) // pMT->IsDelegate() - ) - goto MarkUnsupported; - } - - if (_pfnAllocator is null) - goto GoSmartThrow; - - if (_pfnCtor is null) - { - if(type.IsValueType) - _pfnCtor = &global::@FastGenericNew.ClrAllocator.CtorNoopStub; - else - goto GoSmartThrow; - } - - IsSupported = true; - return; - -GoSmartThrow: - _pfnAllocator = &global::@FastGenericNew.ClrAllocator.SmartThrow; - IsSupported = true; // read the comment of IsSupported - return; - -MarkUnsupported: - _pfnAllocator = &global::@FastGenericNew.ClrAllocator.ThrowNotSupported; - IsSupported = false; - return; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T CreateInstance() - { - var result = _pfnAllocator(_allocatorFirstArg); - _pfnCtor(result); - return (T)result; - } - } -} -#endif diff --git a/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/_GenerationInfo.g.cs b/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/_GenerationInfo.g.cs index add7e3e..134449c 100644 --- a/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/_GenerationInfo.g.cs +++ b/src/FastGenericNew/_generated/FastGenericNew.SourceGenerator/FastGenericNew.SourceGenerator.Generator/_GenerationInfo.g.cs @@ -16,9 +16,7 @@ Namespace = FastGenericNew ForceFastNewDelegate = False AlertGeneratedFile = True - DisableGeneratorCache = True PrettyOutput = True (default: False) - MultiThreadedGeneration = True OutputGenerationInfo = True (default: False) AllowUnsafeImplementation = False PublicFastNew = True (default: False) @@ -35,9 +33,7 @@ FastGenericNew False True - True True - True True False True