Skip to content

Commit

Permalink
Fix naming
Browse files Browse the repository at this point in the history
  • Loading branch information
afxres committed Dec 3, 2023
1 parent e982b66 commit 93a91ce
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

public sealed partial class CollectionConverterContext
{
private const string ConstructorParameter = "item";
private const string ConstructorArgument = "item";

private enum SourceKind
private enum ConstructorArgumentKind
{
Null,

Expand All @@ -21,16 +21,16 @@ private enum SourceKind
ListKeyValuePair,
}

private class TypeBaseInfo(SourceKind sourceKind, string expression)
private class TypeBaseInfo(ConstructorArgumentKind kind, string expression)
{
public SourceKind SourceKind { get; } = sourceKind;
public ConstructorArgumentKind ConstructorArgumentKind { get; } = kind;

public string Expression { get; } = expression;
public string ConstructorExpression { get; } = expression;
}

private class TypeInfo(SourceKind sourceKind, string expression, ImmutableArray<ITypeSymbol> elements) : TypeBaseInfo(sourceKind, expression)
private class TypeInfo(ConstructorArgumentKind kind, string expression, ImmutableArray<ITypeSymbol> types) : TypeBaseInfo(kind, expression)
{
public ImmutableArray<ITypeSymbol> ElementTypes { get; } = elements;
public ImmutableArray<ITypeSymbol> ElementTypes { get; } = types;
}

private class Resource(ImmutableDictionary<INamedTypeSymbol, TypeBaseInfo> supported, ImmutableHashSet<INamedTypeSymbol> unsupported, INamedTypeSymbol? enumerable, INamedTypeSymbol? dictionary, INamedTypeSymbol? readonlyDictionary)
Expand All @@ -48,55 +48,57 @@ private class Resource(ImmutableDictionary<INamedTypeSymbol, TypeBaseInfo> suppo

private static ImmutableDictionary<INamedTypeSymbol, TypeBaseInfo> CreateResourceForSupportedTypes(Compilation compilation)
{
static void Add(Compilation compilation, ImmutableDictionary<INamedTypeSymbol, TypeBaseInfo>.Builder builder, string name, SourceKind source, string method)
static void Register(Compilation compilation, ImmutableDictionary<INamedTypeSymbol, TypeBaseInfo>.Builder builder, string name, ConstructorArgumentKind source, string method)
{
if (compilation.GetTypeByMetadataName(name) is not { } type)
return;
builder.Add(type.ConstructUnboundGenericType(), new TypeBaseInfo(source, method));
}

var builder = ImmutableDictionary.CreateBuilder<INamedTypeSymbol, TypeBaseInfo>(SymbolEqualityComparer.Default);
var functor = (string name, SourceKind source, string method) => Add(compilation, builder, name, source, method);
functor.Invoke("System.Collections.Frozen.FrozenSet`1", SourceKind.List, $"System.Collections.Frozen.FrozenSet.ToFrozenSet({ConstructorParameter})");
functor.Invoke("System.Collections.Frozen.FrozenDictionary`2", SourceKind.ListKeyValuePair, $"System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary({ConstructorParameter})");
functor.Invoke("System.Collections.Generic.IList`1", SourceKind.List, ConstructorParameter);
functor.Invoke("System.Collections.Generic.ICollection`1", SourceKind.List, ConstructorParameter);
functor.Invoke("System.Collections.Generic.IEnumerable`1", SourceKind.List, ConstructorParameter);
functor.Invoke("System.Collections.Generic.IReadOnlyList`1", SourceKind.List, ConstructorParameter);
functor.Invoke("System.Collections.Generic.IReadOnlyCollection`1", SourceKind.List, ConstructorParameter);
functor.Invoke("System.Collections.Generic.ISet`1", SourceKind.HashSet, ConstructorParameter);
functor.Invoke("System.Collections.Generic.IReadOnlySet`1", SourceKind.HashSet, ConstructorParameter);
functor.Invoke("System.Collections.Generic.IDictionary`2", SourceKind.Dictionary, ConstructorParameter);
functor.Invoke("System.Collections.Generic.IReadOnlyDictionary`2", SourceKind.Dictionary, ConstructorParameter);
functor.Invoke("System.Collections.Immutable.IImmutableDictionary`2", SourceKind.ListKeyValuePair, $"System.Collections.Immutable.ImmutableDictionary.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.IImmutableList`1", SourceKind.List, $"System.Collections.Immutable.ImmutableList.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.IImmutableQueue`1", SourceKind.List, $"System.Collections.Immutable.ImmutableQueue.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.IImmutableSet`1", SourceKind.List, $"System.Collections.Immutable.ImmutableHashSet.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.ImmutableDictionary`2", SourceKind.ListKeyValuePair, $"System.Collections.Immutable.ImmutableDictionary.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.ImmutableHashSet`1", SourceKind.List, $"System.Collections.Immutable.ImmutableHashSet.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.ImmutableList`1", SourceKind.List, $"System.Collections.Immutable.ImmutableList.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.ImmutableQueue`1", SourceKind.List, $"System.Collections.Immutable.ImmutableQueue.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.ImmutableSortedDictionary`2", SourceKind.ListKeyValuePair, $"System.Collections.Immutable.ImmutableSortedDictionary.CreateRange({ConstructorParameter})");
functor.Invoke("System.Collections.Immutable.ImmutableSortedSet`1", SourceKind.List, $"System.Collections.Immutable.ImmutableSortedSet.CreateRange({ConstructorParameter})");

Register(compilation, builder, "System.Collections.Frozen.FrozenSet`1", ConstructorArgumentKind.List, $"System.Collections.Frozen.FrozenSet.ToFrozenSet({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Frozen.FrozenDictionary`2", ConstructorArgumentKind.ListKeyValuePair, $"System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Generic.IList`1", ConstructorArgumentKind.List, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.ICollection`1", ConstructorArgumentKind.List, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.IEnumerable`1", ConstructorArgumentKind.List, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.IReadOnlyList`1", ConstructorArgumentKind.List, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.IReadOnlyCollection`1", ConstructorArgumentKind.List, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.ISet`1", ConstructorArgumentKind.HashSet, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.IReadOnlySet`1", ConstructorArgumentKind.HashSet, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.IDictionary`2", ConstructorArgumentKind.Dictionary, ConstructorArgument);
Register(compilation, builder, "System.Collections.Generic.IReadOnlyDictionary`2", ConstructorArgumentKind.Dictionary, ConstructorArgument);
Register(compilation, builder, "System.Collections.Immutable.IImmutableDictionary`2", ConstructorArgumentKind.ListKeyValuePair, $"System.Collections.Immutable.ImmutableDictionary.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.IImmutableList`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableList.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.IImmutableQueue`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableQueue.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.IImmutableSet`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableHashSet.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.ImmutableDictionary`2", ConstructorArgumentKind.ListKeyValuePair, $"System.Collections.Immutable.ImmutableDictionary.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.ImmutableHashSet`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableHashSet.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.ImmutableList`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableList.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.ImmutableQueue`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableQueue.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.ImmutableSortedDictionary`2", ConstructorArgumentKind.ListKeyValuePair, $"System.Collections.Immutable.ImmutableSortedDictionary.CreateRange({ConstructorArgument})");
Register(compilation, builder, "System.Collections.Immutable.ImmutableSortedSet`1", ConstructorArgumentKind.List, $"System.Collections.Immutable.ImmutableSortedSet.CreateRange({ConstructorArgument})");

return builder.ToImmutable();
}

private static ImmutableHashSet<INamedTypeSymbol> CreateResourceForUnsupportedTypes(Compilation compilation)
{
static void Add(Compilation compilation, ImmutableHashSet<INamedTypeSymbol>.Builder builder, string name)
static void Register(Compilation compilation, ImmutableHashSet<INamedTypeSymbol>.Builder builder, string name)
{
if (compilation.GetTypeByMetadataName(name) is not { } type)
return;
_ = builder.Add(type.IsGenericType ? type.ConstructUnboundGenericType() : type);
}

var builder = ImmutableHashSet.CreateBuilder<INamedTypeSymbol>(SymbolEqualityComparer.Default);
var functor = (string name) => Add(compilation, builder, name);
functor.Invoke("System.String");
functor.Invoke("System.Collections.Generic.Stack`1");
functor.Invoke("System.Collections.Concurrent.ConcurrentStack`1");
functor.Invoke("System.Collections.Immutable.ImmutableStack`1");
functor.Invoke("System.Collections.Immutable.IImmutableStack`1");

Register(compilation, builder, "System.String");
Register(compilation, builder, "System.Collections.Generic.Stack`1");
Register(compilation, builder, "System.Collections.Concurrent.ConcurrentStack`1");
Register(compilation, builder, "System.Collections.Immutable.ImmutableStack`1");
Register(compilation, builder, "System.Collections.Immutable.IImmutableStack`1");

return builder.ToImmutable();
}

Expand Down Expand Up @@ -128,17 +130,17 @@ static bool HasConstructor(INamedTypeSymbol symbol, INamedTypeSymbol argument)
return null;
var dictionaryInterface = interfaces.FirstOrDefault(x => Implements(x, resource.UnboundIDictionaryType));
if (dictionaryInterface is not null && HasConstructor(symbol, dictionaryInterface))
return new TypeInfo(SourceKind.Dictionary, string.Empty, dictionaryInterface.TypeArguments);
return new TypeInfo(ConstructorArgumentKind.Dictionary, string.Empty, dictionaryInterface.TypeArguments);
var readonlyDictionaryInterface = interfaces.FirstOrDefault(x => Implements(x, resource.UnboundIReadOnlyDictionaryType));
if (readonlyDictionaryInterface is not null && HasConstructor(symbol, readonlyDictionaryInterface))
return new TypeInfo(SourceKind.Dictionary, string.Empty, readonlyDictionaryInterface.TypeArguments);
return new TypeInfo(ConstructorArgumentKind.Dictionary, string.Empty, readonlyDictionaryInterface.TypeArguments);
var enumerableInterface = enumerableInterfaces.Single();
var typeArguments = dictionaryInterface?.TypeArguments ?? readonlyDictionaryInterface?.TypeArguments;
var hasConstructor = HasConstructor(symbol, enumerableInterface);
var sourceKind = hasConstructor
? (typeArguments is null ? SourceKind.List : SourceKind.ListKeyValuePair)
: SourceKind.Null;
return new TypeInfo(sourceKind, string.Empty, typeArguments ?? enumerableInterface.TypeArguments);
var constructorArgumentKind = hasConstructor
? (typeArguments is null ? ConstructorArgumentKind.List : ConstructorArgumentKind.ListKeyValuePair)
: ConstructorArgumentKind.Null;
return new TypeInfo(constructorArgumentKind, string.Empty, typeArguments ?? enumerableInterface.TypeArguments);
}

private static TypeInfo? GetInfo(SourceGeneratorContext context, ITypeSymbol type)
Expand All @@ -152,7 +154,7 @@ static bool HasConstructor(INamedTypeSymbol symbol, INamedTypeSymbol argument)
if (resource.UnsupportedTypes.Contains(unboundOrOriginal))
return null;
if (unbound is not null && resource.SupportedTypes.TryGetValue(unbound, out var definition))
return new TypeInfo(definition.SourceKind, definition.Expression, symbol.TypeArguments);
return new TypeInfo(definition.ConstructorArgumentKind, definition.ConstructorExpression, symbol.TypeArguments);
return GetInfo(symbol, resource);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ private void AppendDecodeListKeyValuePair()
private void AppendDecodeMethod()
{
var info = this.info;
var action = info.SourceKind switch
var action = info.ConstructorArgumentKind switch
{
SourceKind.List => new Action(AppendDecodeList),
SourceKind.HashSet => new Action(AppendDecodeHashSet),
SourceKind.Dictionary => new Action(AppendDecodeDictionary),
SourceKind.ListKeyValuePair => new Action(AppendDecodeListKeyValuePair),
_ => null,
ConstructorArgumentKind.List => AppendDecodeList,
ConstructorArgumentKind.HashSet => AppendDecodeHashSet,
ConstructorArgumentKind.Dictionary => AppendDecodeDictionary,
ConstructorArgumentKind.ListKeyValuePair => AppendDecodeListKeyValuePair,
_ => default(Action),
};
Output.AppendIndent();
Output.AppendIndent(2, $"public override {SymbolTypeFullName} Decode(in System.ReadOnlySpan<byte> span)");
Expand All @@ -121,9 +121,9 @@ private void AppendDecodeMethod()
{
Output.AppendIndent(3, $"var body = span;");
action.Invoke();
var method = info.Expression;
var method = info.ConstructorExpression;
if (string.IsNullOrEmpty(method))
method = $"new {SymbolTypeFullName}({ConstructorParameter})";
method = $"new {SymbolTypeFullName}({ConstructorArgument})";
Output.AppendIndent(3, $"return {method};");
}
Output.AppendIndent(2, $"}}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,64 @@

public sealed partial class GenericConverterContext
{
private enum SelfKind
private enum TypeArgumentsOption
{
Exclude,
None,

Include,
IncludeReturnType,
}

private class TypeInfo(string name, SelfKind selfKind, ImmutableArray<ITypeSymbol> elements)
private class TypeInfo(string name, TypeArgumentsOption option, ImmutableArray<ITypeSymbol> elements)
{
public string Name { get; } = name;
public string TypeName { get; } = name;

public SelfKind SelfKind { get; } = selfKind;
public TypeArgumentsOption TypeArgumentsOption { get; } = option;

public ImmutableArray<ITypeSymbol> ElementTypes { get; } = elements;
}

private static ImmutableHashSet<INamedTypeSymbol> CreateResource(Compilation compilation)
{
var builder = ImmutableHashSet.CreateBuilder<INamedTypeSymbol>(SymbolEqualityComparer.Default);
void Add(string name)
static void Register(Compilation compilation, ImmutableHashSet<INamedTypeSymbol>.Builder builder, string name)
{
if (compilation.GetTypeByMetadataName(name)?.ConstructUnboundGenericType() is not { } type)
return;
_ = builder.Add(type);
}

Add("System.ArraySegment`1");
Add("System.Memory`1");
Add("System.Nullable`1");
Add("System.ReadOnlyMemory`1");
Add("System.Buffers.ReadOnlySequence`1");
Add("System.Collections.Generic.List`1");
Add("System.Collections.Generic.Dictionary`2");
Add("System.Collections.Generic.HashSet`1");
Add("System.Collections.Generic.KeyValuePair`2");
Add("System.Collections.Generic.LinkedList`1");
Add("System.Collections.Generic.PriorityQueue`2");
Add("System.Collections.Immutable.ImmutableArray`1");
var builder = ImmutableHashSet.CreateBuilder<INamedTypeSymbol>(SymbolEqualityComparer.Default);

Register(compilation, builder, "System.ArraySegment`1");
Register(compilation, builder, "System.Memory`1");
Register(compilation, builder, "System.Nullable`1");
Register(compilation, builder, "System.ReadOnlyMemory`1");
Register(compilation, builder, "System.Buffers.ReadOnlySequence`1");
Register(compilation, builder, "System.Collections.Generic.List`1");
Register(compilation, builder, "System.Collections.Generic.Dictionary`2");
Register(compilation, builder, "System.Collections.Generic.HashSet`1");
Register(compilation, builder, "System.Collections.Generic.KeyValuePair`2");
Register(compilation, builder, "System.Collections.Generic.LinkedList`1");
Register(compilation, builder, "System.Collections.Generic.PriorityQueue`2");
Register(compilation, builder, "System.Collections.Immutable.ImmutableArray`1");

return builder.ToImmutable();
}

private static TypeInfo? GetInfo(SourceGeneratorContext context, ITypeSymbol type)
{
if (type.TypeKind is TypeKind.Enum)
return new TypeInfo("Enum", SelfKind.Include, ImmutableArray.Create<ITypeSymbol>());
return new TypeInfo("Enum", TypeArgumentsOption.IncludeReturnType, ImmutableArray.Create<ITypeSymbol>());
if (type is IArrayTypeSymbol array)
return new TypeInfo(array.IsSZArray ? "Array" : "VariableBoundArray", array.IsSZArray ? SelfKind.Exclude : SelfKind.Include, ImmutableArray.Create(array.ElementType));
return array.IsSZArray
? new TypeInfo("Array", TypeArgumentsOption.None, ImmutableArray.Create(array.ElementType))
: new TypeInfo("VariableBoundArray", TypeArgumentsOption.IncludeReturnType, ImmutableArray.Create(array.ElementType));
if (type is not INamedTypeSymbol symbol || symbol.IsGenericType is false)
return null;
const string ResourceKey = "Generic";
var types = (ImmutableHashSet<INamedTypeSymbol>)context.GetOrCreateResource(ResourceKey, CreateResource);
var unbound = symbol.ConstructUnboundGenericType();
if (types.Contains(unbound))
return new TypeInfo(symbol.Name, SelfKind.Exclude, symbol.TypeArguments);
return new TypeInfo(symbol.Name, TypeArgumentsOption.None, symbol.TypeArguments);
return null;
}

Expand Down
Loading

0 comments on commit 93a91ce

Please sign in to comment.