Skip to content

Commit

Permalink
#55 Incorrect source generated
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed May 20, 2024
1 parent 88f5808 commit 77e6968
Show file tree
Hide file tree
Showing 7 changed files with 273 additions and 80 deletions.
100 changes: 45 additions & 55 deletions src/Pure.DI.Core/Core/Code/BlockCodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,8 @@ public void Build(BuildContext ctx, in Block block)

var localMethodName = $"{Names.EnsureExistsMethodNamePrefix}_{variable.VariableDeclarationName}".Replace("__", "_");
var info = block.Current.Info;
if (info.HasLocalMethod)
{
ctx.Code.AppendLine($"{localMethodName}();");
return;
}

var code = new LinesBuilder();
var isEmpty = false;
try
{
var level = ctx.Level;
Expand Down Expand Up @@ -66,11 +61,27 @@ public void Build(BuildContext ctx, in Block block)
code.IncIndent();
ctx = ctx with { Level = level + 1 };
}


var content = new LinesBuilder();
foreach (var statement in block.Statements)
{
ctx.StatementBuilder.Build(ctx with { Variable = statement.Current, Code = code }, statement);
ctx.StatementBuilder.Build(ctx with { Variable = statement.Current, Code = content }, statement);
}

if (content.Count == 0)
{
isEmpty = true;
return;
}

if (info.HasLocalMethod)
{
ctx.Code.AppendLine($"{localMethodName}();");
isEmpty = true;
return;
}

code.AppendLines(content.Lines);

if (!toCheckExistence)
{
Expand Down Expand Up @@ -114,58 +125,37 @@ public void Build(BuildContext ctx, in Block block)
}
finally
{
if (block.Parent is not null
&& info is { PerBlockRefCount: > 1 }
&& code.Count > 11)
if (!isEmpty)
{
var localMethodCode = ctx.LocalFunctionsCode;
if (variable.Node.Binding.SemanticModel.Compilation.GetLanguageVersion() >= LanguageVersion.CSharp9)
{
localMethodCode.AppendLine($"[{Names.MethodImplAttributeName}({Names.MethodImplAggressiveInlining})]");
}

localMethodCode.AppendLine($"void {localMethodName}()");
localMethodCode.AppendLine("{");
using (localMethodCode.Indent())
if (block.Parent is not null
&& info is { PerBlockRefCount: > 1 }
&& code.Count > 11)
{
localMethodCode.AppendLines(code.Lines);
var localMethodCode = ctx.LocalFunctionsCode;
if (variable.Node.Binding.SemanticModel.Compilation.GetLanguageVersion() >= LanguageVersion.CSharp9)
{
localMethodCode.AppendLine($"[{Names.MethodImplAttributeName}({Names.MethodImplAggressiveInlining})]");
}

localMethodCode.AppendLine($"void {localMethodName}()");
localMethodCode.AppendLine("{");
using (localMethodCode.Indent())
{
localMethodCode.AppendLines(code.Lines);
}

localMethodCode.AppendLine("}");
code = new LinesBuilder();
code.AppendLine($"{localMethodName}();");
info.HasLocalMethod = true;
}

localMethodCode.AppendLine("}");
code = new LinesBuilder();
code.AppendLine($"{localMethodName}();");
info.HasLocalMethod = true;

ctx.Code.AppendLines(code.Lines);
}

ctx.Code.AppendLines(code.Lines);
}
}

private static bool IsNewInstanceRequired(Variable variable)
{
if (variable.Node.Lifetime == Lifetime.Transient)
{
return true;
}

if (variable.Current.HasCycle)
{
return false;
}

var owners = variable
.GetPath()
.Skip(1)
.TakeWhile(i => !i.Current.IsLazy)
.OfType<Block>()
.ToArray();

if (variable.Info.Owners.Intersect(owners).Any())
{
return false;
}

variable.Info.Owners.Add(owners.FirstOrDefault());
return true;
}
private static bool IsNewInstanceRequired(Variable variable) =>
variable.Node.Lifetime == Lifetime.Transient
|| !variable.Current.HasCycle;
}
9 changes: 1 addition & 8 deletions src/Pure.DI.Core/Core/Code/StatementCodeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,15 @@ public void Build(BuildContext ctx, in IStatement statement)
switch (statement)
{
case Variable variable:
if (variable.GetPath().OfType<Block>().Any(block => variable.Info.IsCreated(block)))
if (!variable.Info.Create(variable.ParentBlock))
{
break;
}

variable.Info.MarkAsCreated(variable.ParentBlock);
variableBuilder.Build(ctx, variable);
break;

case Block block:
var blockVariable = block.Current;
if (blockVariable.GetPath().OfType<Block>().Any(b => blockVariable.Info.IsCreated(b)))
{
break;
}

blockBuilder.Build(ctx, block);
break;
}
Expand Down
17 changes: 4 additions & 13 deletions src/Pure.DI.Core/Core/Code/VariableInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
internal class VariableInfo
{
private readonly HashSet<int> _perBlockRefCounts = [];
public readonly HashSet<Block> Owners = [];
public readonly HashSet<Block> Created = [];
private readonly HashSet<Block> _parentBlocks = [];
public bool HasLocalMethod;

public int RefCount { get; private set; } = 1;
Expand All @@ -16,22 +15,14 @@ public void AddRef(Block parentBlock)
RefCount++;
_perBlockRefCounts.Add(parentBlock.Id);
}

public bool MarkAsCreated(Block block)
{
return Created.Add(block);
}

public bool IsCreated(Block block)
{
return Created.Contains(block);
}
public bool Create(Block parentBlock) =>
_parentBlocks.Add(parentBlock);

public void Reset()
{
_perBlockRefCounts.Clear();
Owners.Clear();
Created.Clear();
_parentBlocks.Clear();
RefCount = 1;
HasLocalMethod = false;
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Pure.DI.IntegrationTests/CtorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public static void Main()
}

[Fact]
public async Task ShouldSupportUseParameterLessCtor()
public async Task ShouldSupportUseParameterlessCtor()
{
// Given

Expand Down
2 changes: 1 addition & 1 deletion tests/Pure.DI.IntegrationTests/FactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1157,7 +1157,7 @@ public static void Main()

// Then
result.Success.ShouldBeTrue(result);
result.GeneratedCode.Split(Environment.NewLine).Count(i => i.Contains(" = new Sample.Dependency2();")).ShouldBe(1);
result.GeneratedCode.Split(Environment.NewLine).Count(i => i.Contains(" = new Sample.Dependency2();")).ShouldBe(2);
}

[Fact]
Expand Down
Loading

0 comments on commit 77e6968

Please sign in to comment.