Skip to content

Commit

Permalink
Improvements in code generation performance
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Jan 9, 2024
1 parent d5ec672 commit 0f68209
Show file tree
Hide file tree
Showing 14 changed files with 138 additions and 105 deletions.
2 changes: 1 addition & 1 deletion src/Pure.DI.Core/Core/ArgDependencyNodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public IEnumerable<DependencyNode> Build(MdSetup setup)
continue;
}

yield return new DependencyNode(0, Arg: new DpArg(arg, binding));
yield return new DependencyNode(0, binding, Arg: new DpArg(arg, binding));
}
}
}
95 changes: 95 additions & 0 deletions src/Pure.DI.Core/Core/BindingBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
namespace Pure.DI.Core;

internal class BindingBuilder
{
private MdDefaultLifetime? _defaultLifetime;
private SemanticModel? _semanticModel;
private SyntaxNode? _source;
private MdLifetime? _lifetime;
private MdImplementation? _implementation;
private MdFactory? _factory;
private MdArg? _arg;
private readonly List<MdContract> _contracts = [];
private readonly List<MdTag> _tags = [];

public MdDefaultLifetime DefaultLifetime
{
set => _defaultLifetime = value;
}

public MdLifetime Lifetime
{
set => _lifetime = value;
}

public MdImplementation Implementation
{
set
{
_source = value.Source;
_semanticModel = value.SemanticModel;
_implementation = value;
}
}

public MdFactory Factory
{
set
{
_source = value.Source;
_semanticModel = value.SemanticModel;
_factory = value;
}
}

public MdArg Arg
{
set
{
_source = value.Source;
_semanticModel = value.SemanticModel;
_arg = value;
}
}

public void AddContract(in MdContract contract) =>
_contracts.Add(contract);

public void AddTag(in MdTag tag) =>
_tags.Add(tag);

public MdBinding Build(MdSetup setup)
{
try
{
if (_semanticModel is { } semanticModel
&& _source is { } source)
{
return new MdBinding(
0,
source,
setup,
semanticModel,
_contracts.ToImmutableArray(),
_tags.ToImmutableArray(),
_lifetime ?? _defaultLifetime?.Lifetime,
_implementation,
_factory,
_arg);
}

throw new CompileErrorException($"The binding is defined incorrectly.", setup.Source.GetLocation(), LogId.ErrorInvalidMetadata);
}
finally
{
_contracts.Clear();
_tags.Clear();
_source = default;
_semanticModel = default;
_lifetime = default;
_implementation = default;
_factory = default;
_arg = default;
}
}
}
14 changes: 7 additions & 7 deletions src/Pure.DI.Core/Core/Code/DependencyNodeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@ namespace Pure.DI.Core.Code;

internal static class DependencyNodeExtensions
{
public static bool IsArg(this in DependencyNode node) =>
public static bool IsArg(this DependencyNode node) =>
node.Arg is not null;

public static bool IsFactory(this in DependencyNode node) =>
public static bool IsFactory(this DependencyNode node) =>
node.Factory is not null;

public static bool IsEnumerable(this in DependencyNode node) =>
public static bool IsEnumerable(this DependencyNode node) =>
node.Construct is { Source.Kind: MdConstructKind.Enumerable };

public static bool IsAsyncEnumerable(this in DependencyNode node) =>
public static bool IsAsyncEnumerable(this DependencyNode node) =>
node.Construct is { Source.Kind: MdConstructKind.AsyncEnumerable };

private static bool IsDelegate(this in DependencyNode node) =>
private static bool IsDelegate(this DependencyNode node) =>
node.Type.TypeKind == TypeKind.Delegate;

public static bool IsLazy(this in DependencyNode node) =>
public static bool IsLazy(this DependencyNode node) =>
node.IsDelegate() || node.IsEnumerable() || node.IsAsyncEnumerable();

public static bool IsDisposable(this in DependencyNode node) =>
public static bool IsDisposable(this DependencyNode node) =>
node.Type.AllInterfaces.Any(i => i.SpecialType == SpecialType.System_IDisposable);
}
2 changes: 1 addition & 1 deletion src/Pure.DI.Core/Core/ConstructDependencyNodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public IEnumerable<DependencyNode> Build(MdSetup setup)
injections.Add(new Injection(contract.ContractType.WithNullableAnnotation(NullableAnnotation.NotAnnotated), tag));
}

yield return new DependencyNode(0, Construct: new DpConstruct(construct, binding, injections.ToImmutableArray()));
yield return new DependencyNode(0, binding, Construct: new DpConstruct(construct, binding, injections.ToImmutableArray()));
}
}
}
2 changes: 1 addition & 1 deletion src/Pure.DI.Core/Core/DependencyGraphBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ bool TryCreateOnCannotResolve(MdSetup mdSetup, DependencyNode ownerNode, Injecti
var injection = injectionInfo.Injection;
var dependency = map.TryGetValue(injection, out var sourceNode)
? new Dependency(true, sourceNode, injection, node.Node)
: new Dependency(false, new DependencyNode(0), injection, node.Node);
: new Dependency(false, new DependencyNode(0, node.Node.Binding), injection, node.Node);

edges.Add(dependency);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Pure.DI.Core/Core/FactoryDependencyNodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public IEnumerable<DependencyNode> Build(MdSetup setup)
injections.Add(new Injection(resolver.ContractType.WithNullableAnnotation(NullableAnnotation.NotAnnotated), resolver.Tag?.Value));
}

yield return new DependencyNode(0, Factory: new DpFactory(factory, binding, injections.ToImmutableArray()));
yield return new DependencyNode(0, binding, Factory: new DpFactory(factory, binding, injections.ToImmutableArray()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public IEnumerable<DependencyNode> Build(MdSetup setup)
}

private static IEnumerable<DependencyNode> CreateNodes(IEnumerable<DpImplementation> implementations) =>
implementations.Select((implementation, variantId) => new DependencyNode(variantId, Implementation: implementation));
implementations.Select((implementation, variantId) => new DependencyNode(variantId, implementation.Binding, Implementation: implementation));

private static int GetInjectionsCount(in DpImplementation implementation)
{
Expand Down
7 changes: 4 additions & 3 deletions src/Pure.DI.Core/Core/Models/DependencyNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Pure.DI.Core.Models;

internal readonly record struct DependencyNode(
internal record DependencyNode(
int Variation,
in MdBinding Binding,
ITypeSymbol Type,
Expand All @@ -12,14 +12,15 @@ internal readonly record struct DependencyNode(
{
public DependencyNode(
int Variation,
in MdBinding binding,
in DpRoot? Root = default,
in DpImplementation? Implementation = default,
in DpFactory? Factory = default,
in DpArg? Arg = default,
in DpConstruct? Construct = default)
:this(
Variation,
Root?.Binding ?? Implementation?.Binding ?? Factory?.Binding ?? Arg?.Binding ?? Construct?.Binding ?? new MdBinding(),
binding,
Root?.Source.RootType ?? Implementation?.Source.Type ?? Factory?.Source.Type ?? Arg?.Source.Type ?? Construct?.Source.Type!,
Root,
Implementation,
Expand All @@ -41,7 +42,7 @@ private IEnumerable<string> ToStrings(int indent) =>

public override string ToString() => string.Join(Environment.NewLine, ToStrings(0));

public bool Equals(DependencyNode other) => Binding.Equals(other.Binding);
public virtual bool Equals(DependencyNode? other) => Binding.Equals(other?.Binding);

public override int GetHashCode() => Binding.GetHashCode();
}
4 changes: 2 additions & 2 deletions src/Pure.DI.Core/Core/Models/MdBinding.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace Pure.DI.Core.Models;

internal readonly record struct MdBinding(
internal record MdBinding(
int Id,
in SyntaxNode Source,
in MdSetup SourceSetup,
Expand All @@ -20,7 +20,7 @@ public override string ToString()
return string.Join(Environment.NewLine, walker);
}

public bool Equals(MdBinding other) => Id == other.Id;
public virtual bool Equals(MdBinding? other) => Id == other?.Id;

public override int GetHashCode() => Id;
}
2 changes: 1 addition & 1 deletion src/Pure.DI.Core/Core/Names.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ internal static class Names
private const string SingletonVariablePrefix = "_singleton";
private const string ArgVariablePrefix = "_arg";

public static string GetVariableName(this in DependencyNode Node, int PerLifetimeId)
public static string GetVariableName(this DependencyNode Node, int PerLifetimeId)
{
var baseName = Node.Type.Name;
switch (Node)
Expand Down
2 changes: 1 addition & 1 deletion src/Pure.DI.Core/Core/RootDependencyNodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public IEnumerable<DependencyNode> Build(MdSetup setup)
ImmutableArray<MdContract>.Empty,
ImmutableArray<MdTag>.Empty);

yield return new DependencyNode(0, Root: new DpRoot(root, rootBinding, new Injection(root.RootType.WithNullableAnnotation(NullableAnnotation.NotAnnotated), root.Tag?.Value)));
yield return new DependencyNode(0, rootBinding, Root: new DpRoot(root, rootBinding, new Injection(root.RootType.WithNullableAnnotation(NullableAnnotation.NotAnnotated), root.Tag?.Value)));
}
}
}
Loading

0 comments on commit 0f68209

Please sign in to comment.