Skip to content

Commit

Permalink
Move TryRegisterAlias into BuildContext and make it not static To…
Browse files Browse the repository at this point in the history
… solve a bug

* I Believe the bug was a some kind of race condition about what file got the alias first
  • Loading branch information
YarinOmesi committed Aug 5, 2023
1 parent 4eb1c02 commit fbc2414
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 48 deletions.
33 changes: 32 additions & 1 deletion TestsHelper.SourceGenerator/CodeBuilding/BuildContext.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using TestsHelper.SourceGenerator.CodeBuilding.Types;

namespace TestsHelper.SourceGenerator.CodeBuilding;

public readonly record struct BuildContext(FileBuilder FileBuilder);
public readonly record struct BuildContext(FileBuilder FileBuilder)
{
private readonly ISet<string> _nameAliases = new HashSet<string>();

private bool TryRegisterAlias(IType type, [NotNullWhen(true)] out AliasType? aliasType)
{
if (type.TryCreateAlias(out aliasType))
{
if (_nameAliases.Contains(aliasType.Name))
{
return true;
}

UsingDirectiveSyntax usingDirectiveSyntax = SyntaxFactory.UsingDirective(aliasType.AliasTo)
.WithAlias(SyntaxFactory.NameEquals(SyntaxFactory.IdentifierName(aliasType.Name)));

FileBuilder.AddUsing(usingDirectiveSyntax);
_nameAliases.Add(aliasType.Name);
return true;
}

return false;
}

public IType TryRegisterAlias(IType type) => TryRegisterAlias(type, out AliasType? aliasType) ? aliasType : type;
}
36 changes: 0 additions & 36 deletions TestsHelper.SourceGenerator/CodeBuilding/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using TestsHelper.SourceGenerator.CodeBuilding.Types;
using TestsHelper.SourceGenerator.MockFilling;

namespace TestsHelper.SourceGenerator.CodeBuilding;

Expand Down Expand Up @@ -65,35 +60,4 @@ string parameterName
builder.AddBodyStatement($"{field} = {parameterName};");
return parameterBuilder;
}

private static readonly Dictionary<string, ISet<string>> _fileNameToAliasName = new();

private static bool TryRegisterAlias(this IType type, FileBuilder builder, [NotNullWhen(true)] out AliasType? aliasType)
{
if (!_fileNameToAliasName.TryGetValue(builder.Name, out var names))
{
_fileNameToAliasName[builder.Name] = names = new HashSet<string>();
}

if (type.TryCreateAlias(out aliasType))
{
if (names.Contains(aliasType.Name))
{
return true;
}
UsingDirectiveSyntax usingDirectiveSyntax = SyntaxFactory.UsingDirective(aliasType.AliasTo)
.WithAlias(SyntaxFactory.NameEquals(SyntaxFactory.IdentifierName(aliasType.Name)));

builder.AddUsing(usingDirectiveSyntax);
names.Add(aliasType.Name);
return true;
}

return false;
}

public static IType TryRegisterAlias(this IType type, FileBuilder builder)
{
return type.TryRegisterAlias(builder, out AliasType? aliasType) ? aliasType : type;
}
}
4 changes: 2 additions & 2 deletions TestsHelper.SourceGenerator/CodeBuilding/FieldBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ protected FieldBuilder() { }

protected EqualsValueClauseSyntax? BuildInitializer(BuildContext context)
{
return Initializer.IsEmpty ? null : EqualsValueClause(ParseExpression(Initializer.ToString(context.FileBuilder)));
return Initializer.IsEmpty ? null : EqualsValueClause(ParseExpression(Initializer.ToString(context)));
}

public override MemberDeclarationSyntax Build(BuildContext context)
{
TypeSyntax type = Type.TryRegisterAlias(context.FileBuilder).Build();
TypeSyntax type = context.TryRegisterAlias(Type).Build();

return FieldDeclaration(VariableDeclaration(type)
.AddVariables(VariableDeclarator(Name).WithInitializer(BuildInitializer(context)))).WithModifiers(BuildModifiers());
Expand Down
2 changes: 1 addition & 1 deletion TestsHelper.SourceGenerator/CodeBuilding/MethodBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private MethodBuilder()

public override MemberDeclarationSyntax Build(BuildContext context)
{
TypeSyntax returnType = ReturnType.TryRegisterAlias(context.FileBuilder).Build();
TypeSyntax returnType = context.TryRegisterAlias(ReturnType).Build();

return SyntaxFactory.MethodDeclaration(returnType, identifier: SyntaxFactory.Identifier(Name))
.WithModifiers(BuildModifiers())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public abstract class MethodLikeBuilder : MemberBuilder
protected BlockSyntax BuildBody(BuildContext context)
{
return SyntaxFactory.Block(Body
.Select(stringWithTypes => stringWithTypes.ToString(context.FileBuilder))
.Select(stringWithTypes => stringWithTypes.ToString(context))
.Select(static s => SyntaxFactory.ParseStatement(s)));
}
protected ParameterListSyntax BuildParameters(BuildContext context)
Expand Down
4 changes: 2 additions & 2 deletions TestsHelper.SourceGenerator/CodeBuilding/ParameterBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ private ParameterBuilder(){}

public ParameterSyntax Build(BuildContext context)
{
TypeSyntax type = Type.TryRegisterAlias(context.FileBuilder).Build();
TypeSyntax type = context.TryRegisterAlias(Type).Build();

return Parameter(Identifier(Name))
.WithType(type)
.WithDefault(Initializer.IsEmpty ? null : EqualsValueClause(ParseExpression(Initializer.ToString(context.FileBuilder))));
.WithDefault(Initializer.IsEmpty ? null : EqualsValueClause(ParseExpression(Initializer.ToString(context))));
}

public static ParameterBuilder Create(IType type, string name, StringWithTypes? initializer = null) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private static PropertyDeclarationSyntax AddAccessor(PropertyDeclarationSyntax p

public override MemberDeclarationSyntax Build(BuildContext context)
{
TypeSyntax type = Type.TryRegisterAlias(context.FileBuilder).Build();
TypeSyntax type = context.TryRegisterAlias(Type).Build();

PropertyDeclarationSyntax syntax = SyntaxFactory.PropertyDeclaration(type, Name)
.WithModifiers(BuildModifiers())
Expand Down
8 changes: 4 additions & 4 deletions TestsHelper.SourceGenerator/CodeBuilding/StringWithTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ private StringWithTypes(List<OneOf<string, IType, StringWithTypes, MultipleValue
public void Add(OneOf<string, IType, StringWithTypes, MultipleValues<StringWithTypes>> a) => _components.Add(a);
public StringWithTypes TakeIf(bool condition) => condition ? this : Empty;

public string ToString(FileBuilder fileBuilder)
public string ToString(BuildContext context)
{
StringBuilder builder = new StringBuilder();

foreach (OneOf<string, IType, StringWithTypes, MultipleValues<StringWithTypes>> oneOf in _components)
{
string? text = oneOf.Match(
static s => s,
type => type.TryRegisterAlias(fileBuilder).MakeString(),
stringWithTypes => stringWithTypes.IsEmpty ? null : stringWithTypes.ToString(fileBuilder),
type => context.TryRegisterAlias(type).MakeString(),
stringWithTypes => stringWithTypes.IsEmpty ? null : stringWithTypes.ToString(context),
multipleStrings =>
string.Join(multipleStrings.Separator, multipleStrings.Values
.Where(types => !types.IsEmpty)
.Select(types => types.ToString(fileBuilder))
.Select(types => types.ToString(context))
)
);
if (text != null)
Expand Down

0 comments on commit fbc2414

Please sign in to comment.