From 401b2f507156a61c71ee081b139ff3ac8d7fc0f1 Mon Sep 17 00:00:00 2001 From: Nikolay Pianikov Date: Wed, 14 Aug 2024 11:31:49 +0300 Subject: [PATCH] Refactoring --- readme/a-few-partial-classes.md | 6 ++--- readme/async-disposable-scope.md | 2 +- readme/auto-scoped.md | 2 +- readme/check-for-a-root.md | 2 +- readme/global-compositions.md | 4 +-- readme/resolve-hint.md | 2 +- readme/scope.md | 2 +- readme/service-collection.md | 2 +- readme/service-provider.md | 2 +- readme/threadsafe-hint.md | 2 +- ...async-disposable-instances-in-delegates.md | 2 +- ...osable-instances-per-a-composition-root.md | 2 +- ...cking-disposable-instances-in-delegates.md | 2 +- ...osable-instances-per-a-composition-root.md | 2 +- samples/GrpcService/Composition.cs | 2 +- samples/ShroedingersCat/Program.cs | 2 +- samples/SingleRootAvaloniaApp/Composition.cs | 1 - samples/WebAPI/Composition.cs | 2 +- samples/WebApp/Composition.cs | 2 +- .../Core/AsyncDisposableSettings.cs | 3 --- src/Pure.DI.Core/Core/Attributes.cs | 2 -- src/Pure.DI.Core/Core/Code/ClassCommenter.cs | 8 +++--- .../Core/Code/FactoryCodeBuilder.cs | 6 ++--- src/Pure.DI.Core/Core/Code/Formatter.cs | 2 +- src/Pure.DI.Core/Core/Code/IFormatter.cs | 2 +- .../Core/Code/RootMethodsCommenter.cs | 4 +-- .../Core/DependenciesToLinesWalker.cs | 1 + src/Pure.DI.Core/Core/Generation.cs | 3 +++ src/Pure.DI.Core/Core/Generator.cs | 13 +++++++--- .../Core/IAsyncDisposableSettings.cs | 2 -- src/Pure.DI.Core/Core/IAttributes.cs | 2 -- src/Pure.DI.Core/Core/ITypeConstructor.cs | 2 +- .../Core/MetadataToLinesWalker.cs | 1 + .../Core/Models/MdGenericTypeArgument.cs | 1 + src/Pure.DI.Core/Core/Registry.cs | 1 + src/Pure.DI.Core/Core/SetupsBuilder.cs | 4 +-- src/Pure.DI.Core/Core/TypeConstructor.cs | 2 +- src/Pure.DI.Core/Generator.Composition.cs | 8 +++--- src/Pure.DI.Core/Generator.cs | 25 +++---------------- tests/Pure.DI.Example/IMyGenericService.cs | 3 ++- tests/Pure.DI.Example/MyGenericService.cs | 3 ++- .../LifetimesTests.cs | 2 +- .../TestExtensions.cs | 4 ++- .../Advanced/GlobalCompositionsScenario.cs | 4 +-- .../Advanced/SeveralPartialClassesScenario.cs | 6 ++--- ...ckingAsyncDisposableInDelegatesScenario.cs | 2 +- .../TrackingAsyncDisposableScenario.cs | 2 +- .../TrackingDisposableInDelegatesScenario.cs | 2 +- .../Advanced/TrackingDisposableScenario.cs | 2 +- .../BindAttributeForGenericTypeScenario.cs | 4 ++- .../ServiceCollectionScenario.cs | 2 +- .../ServiceProviderScenario.cs | 2 +- .../Hints/CheckForRootScenario.cs | 4 +-- .../Hints/ResolveHintScenario.cs | 2 +- .../Hints/ThreadSafeHintScenario.cs | 2 +- .../Lifetimes/AsyncDisposableScopeScenario.cs | 2 +- .../Lifetimes/AutoScopedScenario.cs | 2 +- .../Lifetimes/ScopeScenario.cs | 2 +- 58 files changed, 89 insertions(+), 98 deletions(-) create mode 100644 src/Pure.DI.Core/Core/Generation.cs diff --git a/readme/a-few-partial-classes.md b/readme/a-few-partial-classes.md index a7e46889f..81749b831 100644 --- a/readme/a-few-partial-classes.md +++ b/readme/a-few-partial-classes.md @@ -17,7 +17,7 @@ class Service(IDependency dependency) : IService; partial class Composition { // This method will not be called in runtime - void Setup1() => + static void Setup1() => DI.Setup() .Bind().To(); } @@ -25,7 +25,7 @@ partial class Composition partial class Composition { // This method will not be called in runtime - void Setup2() => + static void Setup2() => DI.Setup() .Bind().To(); } @@ -33,7 +33,7 @@ partial class Composition partial class Composition { // This method will not be called in runtime - private void Setup3() => + private static void Setup3() => DI.Setup() .Root("Root"); } diff --git a/readme/async-disposable-scope.md b/readme/async-disposable-scope.md index 7d680ddc6..3d03d9050 100644 --- a/readme/async-disposable-scope.md +++ b/readme/async-disposable-scope.md @@ -40,7 +40,7 @@ class Program(Func sessionFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() // This hint indicates to not generate methods such as Resolve .Hint(Hint.Resolve, "Off") diff --git a/readme/auto-scoped.md b/readme/auto-scoped.md index 918cfe882..3ad456cb1 100644 --- a/readme/auto-scoped.md +++ b/readme/auto-scoped.md @@ -28,7 +28,7 @@ class Program(Func serviceFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() // This hint indicates to not generate methods such as Resolve .Hint(Hint.Resolve, "Off") diff --git a/readme/check-for-a-root.md b/readme/check-for-a-root.md index 7d5ebf6e3..0a9b7dd55 100644 --- a/readme/check-for-a-root.md +++ b/readme/check-for-a-root.md @@ -29,7 +29,7 @@ partial class Composition internal static bool HasRoot(Type type, object? key = default) => Roots.Contains((type, key)); - void Setup() => + static void Setup() => DI.Setup() // Specifies to use the partial OnNewRoot method // to register each root diff --git a/readme/global-compositions.md b/readme/global-compositions.md index 0bfd14d3a..0d59b2c57 100644 --- a/readme/global-compositions.md +++ b/readme/global-compositions.md @@ -8,7 +8,7 @@ When the `Setup(name, kind)` method is called, the second optional parameter spe ```c# class MyGlobalComposition { - void Setup() => + static void Setup() => DI.Setup(kind: CompositionKind.Global) .Hint(Hint.ToString, "Off") .Hint(Hint.FormatCode, "Off"); @@ -16,7 +16,7 @@ class MyGlobalComposition class MyGlobalComposition2 { - void Setup() => + static void Setup() => DI.Setup(kind: CompositionKind.Global) .Hint(Hint.ToString, "On"); } diff --git a/readme/resolve-hint.md b/readme/resolve-hint.md index e29818511..cf7d24650 100644 --- a/readme/resolve-hint.md +++ b/readme/resolve-hint.md @@ -22,7 +22,7 @@ DI.Setup(nameof(Composition)) .Bind().To() .Root("DependencyRoot") .Bind().To() - .Root("Root");; + .Root("Root"); var composition = new Composition(); var service = composition.Root; diff --git a/readme/scope.md b/readme/scope.md index 5bcf1cc79..f739d59b7 100644 --- a/readme/scope.md +++ b/readme/scope.md @@ -38,7 +38,7 @@ class Program(Func sessionFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() // This hint indicates to not generate methods such as Resolve .Hint(Hint.Resolve, "Off") diff --git a/readme/service-collection.md b/readme/service-collection.md index 69d5587fb..d9d682da9 100644 --- a/readme/service-collection.md +++ b/readme/service-collection.md @@ -25,7 +25,7 @@ partial class Composition: ServiceProviderFactory public IServiceCollection ServiceCollection => CreateServiceCollection(this); - void Setup() => + static void Setup() => DI.Setup() .DependsOn(Base) .Bind("Dependency Key").As(Lifetime.Singleton).To() diff --git a/readme/service-provider.md b/readme/service-provider.md index e4d2536dc..756c6b269 100644 --- a/readme/service-provider.md +++ b/readme/service-provider.md @@ -22,7 +22,7 @@ class Service(IDependency dependency) : IService partial class Composition: IServiceProvider { - void Setup() => + static void Setup() => DI.Setup() // The following hint overrides the name of the // "object Resolve(Type type)" method in "GetService", diff --git a/readme/threadsafe-hint.md b/readme/threadsafe-hint.md index b44acc1ec..117af9ef8 100644 --- a/readme/threadsafe-hint.md +++ b/readme/threadsafe-hint.md @@ -21,7 +21,7 @@ DI.Setup(nameof(Composition)) .Hint(ThreadSafe, "Off") .Bind().To() .Bind().To() - .Root("Root");; + .Root("Root"); var composition = new Composition(); var service = composition.Root; diff --git a/readme/tracking-async-disposable-instances-in-delegates.md b/readme/tracking-async-disposable-instances-in-delegates.md index f32bad0bc..c21c144bf 100644 --- a/readme/tracking-async-disposable-instances-in-delegates.md +++ b/readme/tracking-async-disposable-instances-in-delegates.md @@ -40,7 +40,7 @@ class Service(Func> dependencyFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/readme/tracking-async-disposable-instances-per-a-composition-root.md b/readme/tracking-async-disposable-instances-per-a-composition-root.md index bf6cbe4aa..7ebe4caf9 100644 --- a/readme/tracking-async-disposable-instances-per-a-composition-root.md +++ b/readme/tracking-async-disposable-instances-per-a-composition-root.md @@ -32,7 +32,7 @@ class Service(IDependency dependency) : IService partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/readme/tracking-disposable-instances-in-delegates.md b/readme/tracking-disposable-instances-in-delegates.md index 07141f02e..ea862c592 100644 --- a/readme/tracking-disposable-instances-in-delegates.md +++ b/readme/tracking-disposable-instances-in-delegates.md @@ -33,7 +33,7 @@ class Service(Func> dependencyFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/readme/tracking-disposable-instances-per-a-composition-root.md b/readme/tracking-disposable-instances-per-a-composition-root.md index 813e83566..057637a31 100644 --- a/readme/tracking-disposable-instances-per-a-composition-root.md +++ b/readme/tracking-disposable-instances-per-a-composition-root.md @@ -28,7 +28,7 @@ class Service(IDependency dependency) : IService partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/samples/GrpcService/Composition.cs b/samples/GrpcService/Composition.cs index e424b86f8..29cf23311 100644 --- a/samples/GrpcService/Composition.cs +++ b/samples/GrpcService/Composition.cs @@ -10,7 +10,7 @@ namespace GrpcService; internal partial class Composition : ServiceProviderFactory { - void Setup() => DI.Setup() + static void Setup() => DI.Setup() .DependsOn(Base) // Specifies not to attempt to resolve types whose fully qualified name // begins with Microsoft.Extensions., Microsoft.AspNetCore. diff --git a/samples/ShroedingersCat/Program.cs b/samples/ShroedingersCat/Program.cs index 5e68e546e..9476b76aa 100644 --- a/samples/ShroedingersCat/Program.cs +++ b/samples/ShroedingersCat/Program.cs @@ -58,7 +58,7 @@ internal partial class Composition // [Conditional("DI")] attribute avoids generating IL code for the method that follows it. // Since this method is needed only at the compile time. [Conditional("DI")] - void Setup() => DI.Setup() + static void Setup() => DI.Setup() // Models a random subatomic event that may or may not occur .Bind().As(Singleton).To() // Quantum superposition of two states: Alive or Dead diff --git a/samples/SingleRootAvaloniaApp/Composition.cs b/samples/SingleRootAvaloniaApp/Composition.cs index 80633e2d0..a47c186c4 100644 --- a/samples/SingleRootAvaloniaApp/Composition.cs +++ b/samples/SingleRootAvaloniaApp/Composition.cs @@ -7,7 +7,6 @@ namespace AvaloniaApp; using Clock.Models; using Clock.ViewModels; using Pure.DI; -using Views; using static Pure.DI.Lifetime; internal partial class Composition diff --git a/samples/WebAPI/Composition.cs b/samples/WebAPI/Composition.cs index 01519e8b8..90ce50dce 100644 --- a/samples/WebAPI/Composition.cs +++ b/samples/WebAPI/Composition.cs @@ -12,7 +12,7 @@ namespace WebAPI; internal partial class Composition : ServiceProviderFactory { - void Setup() => DI.Setup() + static void Setup() => DI.Setup() .DependsOn(Base) // Specifies not to attempt to resolve types whose fully qualified name // begins with Microsoft.Extensions., Microsoft.AspNetCore. diff --git a/samples/WebApp/Composition.cs b/samples/WebApp/Composition.cs index 0d113ad26..99df88cdb 100644 --- a/samples/WebApp/Composition.cs +++ b/samples/WebApp/Composition.cs @@ -12,7 +12,7 @@ namespace WebApp; internal partial class Composition : ServiceProviderFactory { - void Setup() => DI.Setup() + static void Setup() => DI.Setup() .DependsOn(Base) // Specifies not to attempt to resolve types whose fully qualified name // begins with Microsoft.Extensions., Microsoft.AspNetCore. diff --git a/src/Pure.DI.Core/Core/AsyncDisposableSettings.cs b/src/Pure.DI.Core/Core/AsyncDisposableSettings.cs index 55b0c0869..5c4f57916 100644 --- a/src/Pure.DI.Core/Core/AsyncDisposableSettings.cs +++ b/src/Pure.DI.Core/Core/AsyncDisposableSettings.cs @@ -8,7 +8,4 @@ internal class AsyncDisposableSettings(ICache as asyncDisposableTypes.Get( compilation, i => i.GetTypeByMetadataName(Names.IAsyncDisposableInterfaceShortName)); - - public bool IsEnabled(Compilation compilation) => - TryGetAsyncDisposableType(compilation) is not null; } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/Attributes.cs b/src/Pure.DI.Core/Core/Attributes.cs index d1ea8fd2e..de1f21e9d 100644 --- a/src/Pure.DI.Core/Core/Attributes.cs +++ b/src/Pure.DI.Core/Core/Attributes.cs @@ -1,8 +1,6 @@ // ReSharper disable HeapView.DelegateAllocation namespace Pure.DI.Core; -using Microsoft.CodeAnalysis.Operations; - internal class Attributes(ISemantic semantic) : IAttributes { diff --git a/src/Pure.DI.Core/Core/Code/ClassCommenter.cs b/src/Pure.DI.Core/Core/Code/ClassCommenter.cs index dc42b4dc5..314cf0967 100644 --- a/src/Pure.DI.Core/Core/Code/ClassCommenter.cs +++ b/src/Pure.DI.Core/Core/Code/ClassCommenter.cs @@ -57,14 +57,14 @@ IReadOnlyCollection CreateRootTerms(Root root) var term = new StringBuilder(); if (root.IsPublic) { - term.Append(formatter.FormatRef(composition.Source.Source, root.Injection.Type)); + term.Append(formatter.FormatRef(root.Injection.Type)); term.Append(' '); term.Append(formatter.FormatRef(root)); } else { term.Append("Private composition root of type "); - term.Append(formatter.FormatRef(composition.Source.Source, root.Injection.Type)); + term.Append(formatter.FormatRef(root.Injection.Type)); term.Append('.'); } @@ -113,14 +113,14 @@ IReadOnlyCollection CreateRootTerms(Root root) IReadOnlyCollection CreateRootDescriptions(Root root) => root.Source.Comments.Count > 0 ? root.Source.Comments.Select(comments.Escape).ToList() - : [$"Provides a composition root of type {formatter.FormatRef(composition.Source.Source, root.Node.Type)}."]; + : [$"Provides a composition root of type {formatter.FormatRef(root.Node.Type)}."]; } var root = orderedRoots.FirstOrDefault(i => i.IsPublic); if (root is not null) { code.AppendLine("/// "); - code.AppendLine($"/// This example shows how to get an instance of type {formatter.FormatRef(composition.Source.Source, root.Node.Type)} using the composition root {formatter.FormatRef(root)}:"); + code.AppendLine($"/// This example shows how to get an instance of type {formatter.FormatRef(root.Node.Type)} using the composition root {formatter.FormatRef(root)}:"); code.AppendLine("/// "); code.AppendLine($"/// {(composition.TotalDisposablesCount == 0 ? "" : "using ")}var composition = new {composition.Source.Source.Name.ClassName}({string.Join(", ", composition.Args.Where(i => i.Node.Arg?.Source.Kind == ArgKind.Class).Select(arg => arg.VariableDeclarationName))});"); code.AppendLine($"/// var instance = composition.{formatter.Format(root)};"); diff --git a/src/Pure.DI.Core/Core/Code/FactoryCodeBuilder.cs b/src/Pure.DI.Core/Core/Code/FactoryCodeBuilder.cs index e4baba290..86596b6dd 100644 --- a/src/Pure.DI.Core/Core/Code/FactoryCodeBuilder.cs +++ b/src/Pure.DI.Core/Core/Code/FactoryCodeBuilder.cs @@ -70,14 +70,14 @@ public void Build(BuildContext ctx, in DpFactory factory) switch (member) { - case IFieldSymbol fieldSymbol: + case IFieldSymbol: value = SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, instance, SyntaxFactory.IdentifierName(member.Name)); break; - case IPropertySymbol propertySymbol: + case IPropertySymbol: value = SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, instance, @@ -97,7 +97,7 @@ public void Build(BuildContext ctx, in DpFactory factory) // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator foreach (var typeArg in methodSymbol.TypeArguments) { - var argType = typeConstructor.ConstructReversed(setup, binding.SemanticModel.Compilation, typeArg); + var argType = typeConstructor.ConstructReversed(typeArg); if (binding.TypeConstructor is { } bindingTypeConstructor) { argType = bindingTypeConstructor.Construct(setup, binding.SemanticModel.Compilation, argType); diff --git a/src/Pure.DI.Core/Core/Code/Formatter.cs b/src/Pure.DI.Core/Core/Code/Formatter.cs index 23e3a4ea4..01209f687 100644 --- a/src/Pure.DI.Core/Core/Code/Formatter.cs +++ b/src/Pure.DI.Core/Core/Code/Formatter.cs @@ -72,7 +72,7 @@ public string FormatRef(string text) return $""; } - public string FormatRef(MdSetup setup, ITypeSymbol type) + public string FormatRef(ITypeSymbol type) { #if ROSLYN4_8_OR_GREATER var originalDefinitionTypeName = type.OriginalDefinition.ToDisplayString(NullableFlowState.None, RefFormat); diff --git a/src/Pure.DI.Core/Core/Code/IFormatter.cs b/src/Pure.DI.Core/Core/Code/IFormatter.cs index 306467110..6e81dfee9 100644 --- a/src/Pure.DI.Core/Core/Code/IFormatter.cs +++ b/src/Pure.DI.Core/Core/Code/IFormatter.cs @@ -8,5 +8,5 @@ internal interface IFormatter string FormatRef(string text); - string FormatRef(MdSetup setup, ITypeSymbol type); + string FormatRef(ITypeSymbol type); } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/Code/RootMethodsCommenter.cs b/src/Pure.DI.Core/Core/Code/RootMethodsCommenter.cs index 1b2f08385..0fc8d40d7 100644 --- a/src/Pure.DI.Core/Core/Code/RootMethodsCommenter.cs +++ b/src/Pure.DI.Core/Core/Code/RootMethodsCommenter.cs @@ -29,7 +29,7 @@ public void AddComments(CompositionCode composition, Root root) } else { - code.AppendLine($"/// Provides a composition root of type {formatter.FormatRef(composition.Source.Source, root.Node.Type)}."); + code.AppendLine($"/// Provides a composition root of type {formatter.FormatRef(root.Node.Type)}."); } } finally @@ -43,7 +43,7 @@ public void AddComments(CompositionCode composition, Root root) } code.AppendLine("/// "); - code.AppendLine($"/// This example shows how to get an instance of type {formatter.FormatRef(composition.Source.Source, root.Node.Type)}:"); + code.AppendLine($"/// This example shows how to get an instance of type {formatter.FormatRef(root.Node.Type)}:"); code.AppendLine("/// "); code.AppendLine($"/// {(composition.TotalDisposablesCount == 0 ? "" : "using ")}var composition = new {composition.Source.Source.Name.ClassName}({string.Join(", ", composition.Args.Where(i => i.Node.Arg?.Source.Kind == ArgKind.Class).Select(arg => arg.VariableDeclarationName))});"); code.AppendLine($"/// var instance = composition.{formatter.Format(root)};"); diff --git a/src/Pure.DI.Core/Core/DependenciesToLinesWalker.cs b/src/Pure.DI.Core/Core/DependenciesToLinesWalker.cs index aba5444b4..65fdf1374 100644 --- a/src/Pure.DI.Core/Core/DependenciesToLinesWalker.cs +++ b/src/Pure.DI.Core/Core/DependenciesToLinesWalker.cs @@ -79,5 +79,6 @@ public override void VisitMethod(in Unit ctx, in DpMethod method) IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + // ReSharper disable once NotDisposedResourceIsReturned public IEnumerator GetEnumerator() => _lb.GetEnumerator(); } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/Generation.cs b/src/Pure.DI.Core/Core/Generation.cs new file mode 100644 index 000000000..e638b28ff --- /dev/null +++ b/src/Pure.DI.Core/Core/Generation.cs @@ -0,0 +1,3 @@ +namespace Pure.DI.Core; + +internal readonly record struct Generation; \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/Generator.cs b/src/Pure.DI.Core/Core/Generator.cs index 35024974e..ec4298401 100644 --- a/src/Pure.DI.Core/Core/Generator.cs +++ b/src/Pure.DI.Core/Core/Generator.cs @@ -10,10 +10,15 @@ internal sealed class Generator( IBuilder, IEnumerable> metadataBuilder, Func> codeBuilderFactory, CancellationToken cancellationToken) - : IBuilder, Unit> + : IBuilder, Generation> { - public Unit Build(IEnumerable updates) + public Generation Build(ImmutableArray updates) { + if (updates.IsDefaultOrEmpty) + { + return new Generation(); + } + if (globalOptions.TryGetProfilePath(out var profilePath)) { profiler.Profiling(profilePath); @@ -29,10 +34,10 @@ public Unit Build(IEnumerable updates) logObserver.OnCompleted(); } - return Unit.Shared; + return new Generation(); } - private void ProcessUpdates(IEnumerable updates) + private void ProcessUpdates(ImmutableArray updates) { foreach (var setup in metadataBuilder.Build(updates)) { diff --git a/src/Pure.DI.Core/Core/IAsyncDisposableSettings.cs b/src/Pure.DI.Core/Core/IAsyncDisposableSettings.cs index 2da4f6df1..532db05b7 100644 --- a/src/Pure.DI.Core/Core/IAsyncDisposableSettings.cs +++ b/src/Pure.DI.Core/Core/IAsyncDisposableSettings.cs @@ -3,6 +3,4 @@ internal interface IAsyncDisposableSettings { INamedTypeSymbol? TryGetAsyncDisposableType(Compilation compilation); - - bool IsEnabled(Compilation compilation); } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/IAttributes.cs b/src/Pure.DI.Core/Core/IAttributes.cs index 4c3febdf6..dc7d8df43 100644 --- a/src/Pure.DI.Core/Core/IAttributes.cs +++ b/src/Pure.DI.Core/Core/IAttributes.cs @@ -1,7 +1,5 @@ namespace Pure.DI.Core; -using Microsoft.CodeAnalysis.Operations; - internal interface IAttributes { T GetAttribute( diff --git a/src/Pure.DI.Core/Core/ITypeConstructor.cs b/src/Pure.DI.Core/Core/ITypeConstructor.cs index b75efdb7d..55a8989e5 100644 --- a/src/Pure.DI.Core/Core/ITypeConstructor.cs +++ b/src/Pure.DI.Core/Core/ITypeConstructor.cs @@ -6,5 +6,5 @@ internal interface ITypeConstructor ITypeSymbol Construct(MdSetup setup, Compilation compilation, ITypeSymbol type); - ITypeSymbol ConstructReversed(MdSetup setup, Compilation compilation, ITypeSymbol type); + ITypeSymbol ConstructReversed(ITypeSymbol type); } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/MetadataToLinesWalker.cs b/src/Pure.DI.Core/Core/MetadataToLinesWalker.cs index d89fd19da..7c7616dbd 100644 --- a/src/Pure.DI.Core/Core/MetadataToLinesWalker.cs +++ b/src/Pure.DI.Core/Core/MetadataToLinesWalker.cs @@ -61,5 +61,6 @@ public override void VisitFinish() IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + // ReSharper disable once NotDisposedResourceIsReturned public IEnumerator GetEnumerator() => _lb.GetEnumerator(); } \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/Models/MdGenericTypeArgument.cs b/src/Pure.DI.Core/Core/Models/MdGenericTypeArgument.cs index 6659e20eb..910af90bc 100644 --- a/src/Pure.DI.Core/Core/Models/MdGenericTypeArgument.cs +++ b/src/Pure.DI.Core/Core/Models/MdGenericTypeArgument.cs @@ -1,4 +1,5 @@ // ReSharper disable HeapView.ObjectAllocation +// ReSharper disable NotAccessedPositionalProperty.Global namespace Pure.DI.Core.Models; internal readonly record struct MdGenericTypeArgument( diff --git a/src/Pure.DI.Core/Core/Registry.cs b/src/Pure.DI.Core/Core/Registry.cs index 9a1c93d16..22f913752 100644 --- a/src/Pure.DI.Core/Core/Registry.cs +++ b/src/Pure.DI.Core/Core/Registry.cs @@ -1,4 +1,5 @@ // ReSharper disable ClassNeverInstantiated.Global +// ReSharper disable NotAccessedPositionalProperty.Local namespace Pure.DI.Core; internal class Registry: IRegistryManager, IRegistry diff --git a/src/Pure.DI.Core/Core/SetupsBuilder.cs b/src/Pure.DI.Core/Core/SetupsBuilder.cs index 6d87db82b..16d629b1b 100644 --- a/src/Pure.DI.Core/Core/SetupsBuilder.cs +++ b/src/Pure.DI.Core/Core/SetupsBuilder.cs @@ -221,12 +221,12 @@ from attribute in member.GetAttributes() if (methodSymbol.IsGenericMethod) { typeConstructor.TryBind(setup, contractType, methodSymbol.ReturnType); - contractType = typeConstructor.ConstructReversed(setup, semanticModel.Compilation, contractType); + contractType = typeConstructor.ConstructReversed(contractType); // ReSharper disable once ForeachCanBeConvertedToQueryUsingAnotherGetEnumerator foreach (var parameter in methodSymbol.Parameters) { - var paramType = typeConstructor.ConstructReversed(setup, binding.SemanticModel.Compilation, parameter.Type); + var paramType = typeConstructor.ConstructReversed(parameter.Type); resolvers.Add(CreateResolver(typeConstructor, parameter.Name, paramType, MdTag.ContextTag, ref position)); } } diff --git a/src/Pure.DI.Core/Core/TypeConstructor.cs b/src/Pure.DI.Core/Core/TypeConstructor.cs index b3f042e28..d91b52a9e 100644 --- a/src/Pure.DI.Core/Core/TypeConstructor.cs +++ b/src/Pure.DI.Core/Core/TypeConstructor.cs @@ -159,7 +159,7 @@ public ITypeSymbol Construct(MdSetup setup, Compilation compilation, ITypeSymbol } } - public ITypeSymbol ConstructReversed(MdSetup setup, Compilation compilation, ITypeSymbol type) + public ITypeSymbol ConstructReversed(ITypeSymbol type) { if (_reversedMap.Count == 0) { diff --git a/src/Pure.DI.Core/Generator.Composition.cs b/src/Pure.DI.Core/Generator.Composition.cs index 36b67fc9d..532506e1f 100644 --- a/src/Pure.DI.Core/Generator.Composition.cs +++ b/src/Pure.DI.Core/Generator.Composition.cs @@ -17,13 +17,15 @@ private void Setup() => DI.Setup(nameof(Generator)) .Hint(Hint.Resolve, "Off") // Roots - .Root>("Api") - .Root("Observers") - .Root, Unit>>("CreateGenerator", kind: RootKinds.Private) + .Root>(nameof(Api)) + .Root(nameof(Observers)) + .RootBind(nameof(Generate), kind: RootKinds.Internal, "internal") + .To((IBuilder, Generation> generator, ImmutableArray updates) => generator.Build(updates)) .RootArg("options") .RootArg("sources") .RootArg("diagnostic") + .RootArg>("updates") .RootArg("cancellationToken") // Transient diff --git a/src/Pure.DI.Core/Generator.cs b/src/Pure.DI.Core/Generator.cs index 0ef13ca9c..cfdfea8ad 100644 --- a/src/Pure.DI.Core/Generator.cs +++ b/src/Pure.DI.Core/Generator.cs @@ -7,31 +7,12 @@ public void Generate( AnalyzerConfigOptionsProvider analyzerConfigOptionsProvider, in SourceProductionContext sourceProductionContext, in ImmutableArray changes, - CancellationToken cancellationToken) - { - if (changes.IsEmpty) - { - return; - } - + CancellationToken cancellationToken) => + // ReSharper disable once ReturnValueOfPureMethodIsNotUsed Generate( new GeneratorOptions(parseOptions, analyzerConfigOptionsProvider), new GeneratorSources(sourceProductionContext), new GeneratorDiagnostic(sourceProductionContext), - changes.Select(change => new SyntaxUpdate(change.Node, change.SemanticModel)), + changes.Select(change => new SyntaxUpdate(change.Node, change.SemanticModel)).ToImmutableArray(), cancellationToken); - } - - internal void Generate( - IGeneratorOptions options, - IGeneratorSources sources, - IGeneratorDiagnostic diagnostic, - IEnumerable updates, - CancellationToken cancellationToken) => - CreateGenerator( - options: options, - sources: sources, - diagnostic: diagnostic, - cancellationToken: cancellationToken) - .Build(updates); } \ No newline at end of file diff --git a/tests/Pure.DI.Example/IMyGenericService.cs b/tests/Pure.DI.Example/IMyGenericService.cs index cfee44433..93812e6f3 100644 --- a/tests/Pure.DI.Example/IMyGenericService.cs +++ b/tests/Pure.DI.Example/IMyGenericService.cs @@ -1,4 +1,5 @@ -namespace Pure.DI.Integration; +// ReSharper disable UnusedParameter.Global +namespace Pure.DI.Integration; public interface IMyGenericService { diff --git a/tests/Pure.DI.Example/MyGenericService.cs b/tests/Pure.DI.Example/MyGenericService.cs index c7890565b..5fe6712f5 100644 --- a/tests/Pure.DI.Example/MyGenericService.cs +++ b/tests/Pure.DI.Example/MyGenericService.cs @@ -1,4 +1,5 @@ -namespace Pure.DI.Integration; +// ReSharper disable UnusedMember.Global +namespace Pure.DI.Integration; internal class MyGenericService(IMyDependency dependency, int id) : IMyGenericService { diff --git a/tests/Pure.DI.IntegrationTests/LifetimesTests.cs b/tests/Pure.DI.IntegrationTests/LifetimesTests.cs index 81ae4d026..c8cd2574e 100644 --- a/tests/Pure.DI.IntegrationTests/LifetimesTests.cs +++ b/tests/Pure.DI.IntegrationTests/LifetimesTests.cs @@ -2046,7 +2046,7 @@ public async Task ShouldSupportSingletonScopedPerResolveInEnumerable(string life // Given // When - var result = await $$""" + var result = await """ using System; using Pure.DI; using System.Collections.Generic; diff --git a/tests/Pure.DI.IntegrationTests/TestExtensions.cs b/tests/Pure.DI.IntegrationTests/TestExtensions.cs index 8af2c5159..ef984c106 100644 --- a/tests/Pure.DI.IntegrationTests/TestExtensions.cs +++ b/tests/Pure.DI.IntegrationTests/TestExtensions.cs @@ -28,6 +28,7 @@ namespace Pure.DI.IntegrationTests; public static class TestExtensions { + [SuppressMessage("Performance", "CA1806:Не игнорируйте результаты метода")] internal static async Task RunAsync(this string setupCode, Options? options = default) { var stdOut = new List(); @@ -70,7 +71,8 @@ internal static async Task RunAsync(this string setupCode, Options? opti var logEntryObserver = new Observer(); using var logEntryObserverToken = generator.Observers.Register(logEntryObserver); - generator.Generate(contextOptions.Object, contextProducer.Object, contextDiagnostic.Object, updates, CancellationToken.None); + // ReSharper disable once ReturnValueOfPureMethodIsNotUsed + generator.Generate(contextOptions.Object, contextProducer.Object, contextDiagnostic.Object, [..updates], CancellationToken.None); var logs = logEntryObserver.Values; var errors = logs.Where(i => i.Severity == DiagnosticSeverity.Error).ToImmutableArray(); diff --git a/tests/Pure.DI.UsageTests/Advanced/GlobalCompositionsScenario.cs b/tests/Pure.DI.UsageTests/Advanced/GlobalCompositionsScenario.cs index 776187ddf..bd0e1a3a6 100644 --- a/tests/Pure.DI.UsageTests/Advanced/GlobalCompositionsScenario.cs +++ b/tests/Pure.DI.UsageTests/Advanced/GlobalCompositionsScenario.cs @@ -15,7 +15,7 @@ namespace Pure.DI.UsageTests.Advanced.GlobalCompositionsScenario; // { class MyGlobalComposition { - void Setup() => + static void Setup() => DI.Setup(kind: CompositionKind.Global) .Hint(Hint.ToString, "Off") .Hint(Hint.FormatCode, "Off"); @@ -23,7 +23,7 @@ void Setup() => class MyGlobalComposition2 { - void Setup() => + static void Setup() => DI.Setup(kind: CompositionKind.Global) .Hint(Hint.ToString, "On"); } diff --git a/tests/Pure.DI.UsageTests/Advanced/SeveralPartialClassesScenario.cs b/tests/Pure.DI.UsageTests/Advanced/SeveralPartialClassesScenario.cs index 5c6837115..29893b3a4 100644 --- a/tests/Pure.DI.UsageTests/Advanced/SeveralPartialClassesScenario.cs +++ b/tests/Pure.DI.UsageTests/Advanced/SeveralPartialClassesScenario.cs @@ -29,7 +29,7 @@ class Service(IDependency dependency) : IService; partial class Composition { // This method will not be called in runtime - void Setup1() => + static void Setup1() => DI.Setup() .Bind().To(); } @@ -37,7 +37,7 @@ void Setup1() => partial class Composition { // This method will not be called in runtime - void Setup2() => + static void Setup2() => DI.Setup() .Bind().To(); } @@ -45,7 +45,7 @@ void Setup2() => partial class Composition { // This method will not be called in runtime - private void Setup3() => + private static void Setup3() => DI.Setup() .Root("Root"); } diff --git a/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableInDelegatesScenario.cs b/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableInDelegatesScenario.cs index e4e86fc5b..4dbd76f69 100644 --- a/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableInDelegatesScenario.cs +++ b/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableInDelegatesScenario.cs @@ -51,7 +51,7 @@ public ValueTask DisposeAsync() partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableScenario.cs b/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableScenario.cs index 0147560f1..4005ca271 100644 --- a/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableScenario.cs +++ b/tests/Pure.DI.UsageTests/Advanced/TrackingAsyncDisposableScenario.cs @@ -42,7 +42,7 @@ class Service(IDependency dependency) : IService partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableInDelegatesScenario.cs b/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableInDelegatesScenario.cs index ca468e69b..7860d35a5 100644 --- a/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableInDelegatesScenario.cs +++ b/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableInDelegatesScenario.cs @@ -44,7 +44,7 @@ class Service(Func> dependencyFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableScenario.cs b/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableScenario.cs index 2e5a732e2..f4e34a613 100644 --- a/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableScenario.cs +++ b/tests/Pure.DI.UsageTests/Advanced/TrackingDisposableScenario.cs @@ -38,7 +38,7 @@ class Service(IDependency dependency) : IService partial class Composition { - void Setup() => + static void Setup() => DI.Setup() .Bind().To() .Bind().To() diff --git a/tests/Pure.DI.UsageTests/Attributes/BindAttributeForGenericTypeScenario.cs b/tests/Pure.DI.UsageTests/Attributes/BindAttributeForGenericTypeScenario.cs index bc6e69cb1..4d336f4ff 100644 --- a/tests/Pure.DI.UsageTests/Attributes/BindAttributeForGenericTypeScenario.cs +++ b/tests/Pure.DI.UsageTests/Attributes/BindAttributeForGenericTypeScenario.cs @@ -10,6 +10,7 @@ // ReSharper disable ArrangeTypeModifiers // ReSharper disable MemberCanBeMadeStatic.Global // ReSharper disable UnusedTypeParameter +#pragma warning disable CA1822 namespace Pure.DI.UsageTests.Basics.BindAttributeForGenericTypeScenario; using Xunit; @@ -62,4 +63,5 @@ public void Run() // } composition.SaveClassDiagram(); } -} \ No newline at end of file +} +#pragma warning restore CA1822 \ No newline at end of file diff --git a/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceCollectionScenario.cs b/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceCollectionScenario.cs index aa56fda89..668ab3252 100644 --- a/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceCollectionScenario.cs +++ b/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceCollectionScenario.cs @@ -40,7 +40,7 @@ partial class Composition: ServiceProviderFactory public IServiceCollection ServiceCollection => CreateServiceCollection(this); - void Setup() => + static void Setup() => DI.Setup() .DependsOn(Base) .Bind("Dependency Key").As(Lifetime.Singleton).To() diff --git a/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceProviderScenario.cs b/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceProviderScenario.cs index b11ca45f1..cba3fca0b 100644 --- a/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceProviderScenario.cs +++ b/tests/Pure.DI.UsageTests/BaseClassLibrary/ServiceProviderScenario.cs @@ -34,7 +34,7 @@ class Service(IDependency dependency) : IService partial class Composition: IServiceProvider { - void Setup() => + static void Setup() => DI.Setup() // The following hint overrides the name of the // "object Resolve(Type type)" method in "GetService", diff --git a/tests/Pure.DI.UsageTests/Hints/CheckForRootScenario.cs b/tests/Pure.DI.UsageTests/Hints/CheckForRootScenario.cs index 209aa778b..f5b83d033 100644 --- a/tests/Pure.DI.UsageTests/Hints/CheckForRootScenario.cs +++ b/tests/Pure.DI.UsageTests/Hints/CheckForRootScenario.cs @@ -41,8 +41,8 @@ partial class Composition // Check that the root can be resolved by Resolve methods internal static bool HasRoot(Type type, object? key = default) => Roots.Contains((type, key)); - - void Setup() => + + static void Setup() => DI.Setup() // Specifies to use the partial OnNewRoot method // to register each root diff --git a/tests/Pure.DI.UsageTests/Hints/ResolveHintScenario.cs b/tests/Pure.DI.UsageTests/Hints/ResolveHintScenario.cs index cf1b7be5f..bbb12e91d 100644 --- a/tests/Pure.DI.UsageTests/Hints/ResolveHintScenario.cs +++ b/tests/Pure.DI.UsageTests/Hints/ResolveHintScenario.cs @@ -41,7 +41,7 @@ public void Run() .Bind().To() .Root("DependencyRoot") .Bind().To() - .Root("Root");; + .Root("Root"); var composition = new Composition(); var service = composition.Root; diff --git a/tests/Pure.DI.UsageTests/Hints/ThreadSafeHintScenario.cs b/tests/Pure.DI.UsageTests/Hints/ThreadSafeHintScenario.cs index b3690e487..f1b9e38ae 100644 --- a/tests/Pure.DI.UsageTests/Hints/ThreadSafeHintScenario.cs +++ b/tests/Pure.DI.UsageTests/Hints/ThreadSafeHintScenario.cs @@ -41,7 +41,7 @@ public void Run() .Hint(ThreadSafe, "Off") .Bind().To() .Bind().To() - .Root("Root");; + .Root("Root"); var composition = new Composition(); var service = composition.Root; diff --git a/tests/Pure.DI.UsageTests/Lifetimes/AsyncDisposableScopeScenario.cs b/tests/Pure.DI.UsageTests/Lifetimes/AsyncDisposableScopeScenario.cs index 2e0b2bdcc..dbd3107a5 100644 --- a/tests/Pure.DI.UsageTests/Lifetimes/AsyncDisposableScopeScenario.cs +++ b/tests/Pure.DI.UsageTests/Lifetimes/AsyncDisposableScopeScenario.cs @@ -53,7 +53,7 @@ class Program(Func sessionFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() // This hint indicates to not generate methods such as Resolve .Hint(Hint.Resolve, "Off") diff --git a/tests/Pure.DI.UsageTests/Lifetimes/AutoScopedScenario.cs b/tests/Pure.DI.UsageTests/Lifetimes/AutoScopedScenario.cs index e82696d6f..5ab017858 100644 --- a/tests/Pure.DI.UsageTests/Lifetimes/AutoScopedScenario.cs +++ b/tests/Pure.DI.UsageTests/Lifetimes/AutoScopedScenario.cs @@ -42,7 +42,7 @@ class Program(Func serviceFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() // This hint indicates to not generate methods such as Resolve .Hint(Hint.Resolve, "Off") diff --git a/tests/Pure.DI.UsageTests/Lifetimes/ScopeScenario.cs b/tests/Pure.DI.UsageTests/Lifetimes/ScopeScenario.cs index 309a84159..506d75b63 100644 --- a/tests/Pure.DI.UsageTests/Lifetimes/ScopeScenario.cs +++ b/tests/Pure.DI.UsageTests/Lifetimes/ScopeScenario.cs @@ -50,7 +50,7 @@ class Program(Func sessionFactory) partial class Composition { - void Setup() => + static void Setup() => DI.Setup() // This hint indicates to not generate methods such as Resolve .Hint(Hint.Resolve, "Off")