From 5bd40a61e78a02871edb6b2251315cb6c2f08555 Mon Sep 17 00:00:00 2001 From: Nikolay Pianikov Date: Fri, 26 Apr 2024 09:36:42 +0300 Subject: [PATCH] Refusing to use local functions --- .../Core/Code/BlockCodeBuilder.cs | 25 +------------------ .../Core/Code/VariablesBuilder.cs | 9 +++---- src/Pure.DI.Core/Core/Const.cs | 6 +++++ .../Core/DependencyGraphBuilder.cs | 9 ++++++- 4 files changed, 18 insertions(+), 31 deletions(-) create mode 100644 src/Pure.DI.Core/Core/Const.cs diff --git a/src/Pure.DI.Core/Core/Code/BlockCodeBuilder.cs b/src/Pure.DI.Core/Core/Code/BlockCodeBuilder.cs index e90ee8ca8..6387e59d1 100644 --- a/src/Pure.DI.Core/Core/Code/BlockCodeBuilder.cs +++ b/src/Pure.DI.Core/Core/Code/BlockCodeBuilder.cs @@ -130,30 +130,7 @@ variable.Node.Lifetime is Lifetime.Singleton or Lifetime.Scoped finally { info.HasCode = true; - if (block.Parent is not null - && info is { PerBlockRefCount: > 2, Code.Lines.Count: > 4 }) - { - var localFunctionsCode = ctx.LocalFunctionsCode; - var localMethodName = $"{Names.LocalMethodPrefix}{variable.VariableName}{Names.EnsureExistsMethodNamePostfix}"; - if (variable.Node.Binding.SemanticModel.Compilation.GetLanguageVersion() >= LanguageVersion.CSharp9) - { - localFunctionsCode.AppendLine($"[{Names.MethodImplAttribute}(({Names.MethodImplOptions})0x300)]"); - } - - localFunctionsCode.AppendLine($"void {localMethodName}()"); - localFunctionsCode.AppendLine("{"); - using (localFunctionsCode.Indent()) - { - localFunctionsCode.AppendLines(info.Code.Lines); - } - - localFunctionsCode.AppendLine("}"); - ctx.Code.AppendLine($"{localMethodName}();"); - } - else - { - ctx.Code.AppendLines(info.Code.Lines); - } + ctx.Code.AppendLines(info.Code.Lines); } } diff --git a/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs b/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs index 9c8ab4fca..a40e6f113 100644 --- a/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs +++ b/src/Pure.DI.Core/Core/Code/VariablesBuilder.cs @@ -18,17 +18,14 @@ public Block Build( rootBlock.Statements.AddFirst(rootVar); var blocks = new Stack(); blocks.Push(rootBlock); + var counter = 0; while (blocks.TryPop(out var currentBlock)) { - if (cancellationToken.IsCancellationRequested) - { - break; - } - var stack = new Stack(currentBlock.Statements); while (stack.TryPop(out var currentStatement)) { - if (stack.Count > 0xffff) + cancellationToken.ThrowIfCancellationRequested(); + if (counter++ > Const.MaxIterationsCount) { throw new CompileErrorException($"Cyclic dependency has been found.", rootNode.Binding.Source.GetLocation(), LogId.ErrorCyclicDependency); } diff --git a/src/Pure.DI.Core/Core/Const.cs b/src/Pure.DI.Core/Core/Const.cs new file mode 100644 index 000000000..022c58964 --- /dev/null +++ b/src/Pure.DI.Core/Core/Const.cs @@ -0,0 +1,6 @@ +namespace Pure.DI.Core; + +public static class Const +{ + public const int MaxIterationsCount = 0xffff; +} \ No newline at end of file diff --git a/src/Pure.DI.Core/Core/DependencyGraphBuilder.cs b/src/Pure.DI.Core/Core/DependencyGraphBuilder.cs index 7ddefa6f9..8975492ce 100644 --- a/src/Pure.DI.Core/Core/DependencyGraphBuilder.cs +++ b/src/Pure.DI.Core/Core/DependencyGraphBuilder.cs @@ -28,6 +28,7 @@ public IEnumerable TryBuild( var roots = new List(); foreach (var processingNode in nodes) { + cancellationToken.ThrowIfCancellationRequested(); var node = processingNode.Node; if (node.Binding.Id > maxId) { @@ -68,13 +69,19 @@ public IEnumerable TryBuild( var processed = new HashSet(); var notProcessed = new HashSet(); var edgesMap = new Dictionary>(); + var counter = 0; while (queue.TryDequeue(out var node)) { + cancellationToken.ThrowIfCancellationRequested(); + if (counter++ > Const.MaxIterationsCount) + { + throw new CompileErrorException($"Cyclic dependency has been found.", setup.Source.GetLocation(), LogId.ErrorCyclicDependency); + } + var targetNode = node.Node; var isProcessed = true; foreach (var (injection, hasExplicitDefaultValue, explicitDefaultValue) in node.Injections) { - cancellationToken.ThrowIfCancellationRequested(); if (map.TryGetValue(injection, out var sourceNode)) { if (!marker.IsMarkerBased(sourceNode.Type))