Skip to content

Commit

Permalink
Merge pull request #27 from Yeah69/release/3.0.0
Browse files Browse the repository at this point in the history
Release/3.0.0
  • Loading branch information
Yeah69 authored Oct 14, 2023
2 parents cb58881 + 1cacbe6 commit ff16581
Show file tree
Hide file tree
Showing 37 changed files with 425 additions and 57 deletions.
28 changes: 23 additions & 5 deletions Main/Configuration/CheckTypeProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ internal interface ICheckTypeProperties
IMethodSymbol? GetConstructorChoiceFor(INamedTypeSymbol implementationType);

bool ShouldBeDecorated(INamedTypeSymbol interfaceType);
IReadOnlyList<INamedTypeSymbol> GetSequenceFor(INamedTypeSymbol interfaceType, INamedTypeSymbol implementationType);
IReadOnlyList<INamedTypeSymbol> GetDecorationSequenceFor(INamedTypeSymbol interfaceType, INamedTypeSymbol implementationType);

INamedTypeSymbol? MapToSingleFittingImplementation(INamedTypeSymbol type, InjectionKey? injectionKey);
IReadOnlyList<INamedTypeSymbol> MapToImplementations(INamedTypeSymbol typeSymbol, InjectionKey? injectionKey);
Expand All @@ -88,6 +88,7 @@ internal abstract class CheckTypeProperties : ICheckTypeProperties

private readonly IDictionary<INamedTypeSymbol, IDictionary<ITypeSymbol, ISet<object>>> _typeToKeyToValue =
new Dictionary<INamedTypeSymbol, IDictionary<ITypeSymbol, ISet<object>>>();
private readonly IDictionary<INamedTypeSymbol, int> _decorationToOrdinal;

internal CheckTypeProperties(
ICurrentlyConsideredTypes currentlyConsideredTypes,
Expand Down Expand Up @@ -139,6 +140,23 @@ internal CheckTypeProperties(
implementationType.OriginalDefinition,
new Dictionary<ITypeSymbol, ISet<object>>{{keyType, new HashSet<object>{keyValue}}});
}

_decorationToOrdinal = currentlyConsideredTypes.DecoratorTypes
.SelectMany(d => d.GetAttributes().Select(a => (d, a)))
.Select(t =>
{
var (decorator, attribute) = t;
if (!currentlyConsideredTypes.DecorationOrdinalAttributeTypes.Any(a =>
CustomSymbolEqualityComparer.Default.Equals(a, attribute.AttributeClass)))
return ((INamedTypeSymbol DecorationImplementationType, int Ordinal)?)null;
return (
DecorationImplementationType: decorator,
Ordinal: attribute.ConstructorArguments[0].Value is int ordinal ? ordinal : 0);
})
.Where(t => t is not null)
.Select(t => t ?? throw new MsMeeseeks.DIE.ImpossibleDieException())
.Concat(currentlyConsideredTypes.DecorationOrdinalChoices)
.ToDictionary(t => t.DecorationImplementationType, t => t.Ordinal);
}

public DisposalType ShouldDisposalBeManaged(INamedTypeSymbol implementationType)
Expand Down Expand Up @@ -227,7 +245,7 @@ when implementationType.InstanceConstructors.SingleOrDefault(c => c.Parameters.L

public bool ShouldBeDecorated(INamedTypeSymbol interfaceType) => _currentlyConsideredTypes.InterfaceToDecorators.ContainsKey(interfaceType.UnboundIfGeneric());

public IReadOnlyList<INamedTypeSymbol> GetSequenceFor(INamedTypeSymbol interfaceType, INamedTypeSymbol implementationType)
public IReadOnlyList<INamedTypeSymbol> GetDecorationSequenceFor(INamedTypeSymbol interfaceType, INamedTypeSymbol implementationType)
{
IEnumerable<INamedTypeSymbol> sequence = Array.Empty<INamedTypeSymbol>();
bool found = false;
Expand All @@ -246,9 +264,9 @@ public IReadOnlyList<INamedTypeSymbol> GetSequenceFor(INamedTypeSymbol interface
}
}

if (!found && _currentlyConsideredTypes.InterfaceToDecorators.TryGetValue(interfaceType.UnboundIfGeneric(), out var allDecorators)
&& allDecorators.Count == 1)
sequence = allDecorators;
if (!found && _currentlyConsideredTypes.InterfaceToDecorators.TryGetValue(interfaceType.UnboundIfGeneric(), out var allDecorators))
sequence = allDecorators
.OrderBy(d => _decorationToOrdinal.TryGetValue(d, out var ordinal) ? ordinal : 0);

return sequence
.Select(imp =>
Expand Down
26 changes: 26 additions & 0 deletions Main/Configuration/CurrentlyConsideredTypesBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ internal interface ICurrentlyConsideredTypes
IImmutableSet<INamedTypeSymbol> CompositeTypes { get; }
IImmutableSet<INamedTypeSymbol> InjectionKeyAttributeTypes { get; }
IImmutableSet<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)> InjectionKeyChoices { get; }
IImmutableSet<INamedTypeSymbol> DecorationOrdinalAttributeTypes { get; }
IImmutableSet<(INamedTypeSymbol DecorationImplementationType, int Ordinal)> DecorationOrdinalChoices { get; }
IReadOnlyDictionary<ISymbol?, INamedTypeSymbol> InterfaceToComposite { get; }
IReadOnlyDictionary<INamedTypeSymbol, IMethodSymbol> ImplementationToConstructorChoice { get; }
IReadOnlyDictionary<ISymbol?, IReadOnlyList<INamedTypeSymbol>> InterfaceToDecorators { get; }
Expand Down Expand Up @@ -415,6 +417,28 @@ public CurrentlyConsideredTypesBase(

InjectionKeyChoices = injectionKeyChoices;

var decorationOrdinalAttributeTypes = ImmutableHashSet<INamedTypeSymbol>.Empty;
foreach (var typesFromAttribute in typesFromAttributes)
{
decorationOrdinalAttributeTypes = decorationOrdinalAttributeTypes.Except(typesFromAttribute.FilterDecorationOrdinalAttributeTypes);
decorationOrdinalAttributeTypes = decorationOrdinalAttributeTypes.Union(typesFromAttribute.DecorationOrdinalAttributeTypes);
}

DecorationOrdinalAttributeTypes = decorationOrdinalAttributeTypes;

var decorationOrdinalChoices =
ImmutableHashSet<(INamedTypeSymbol DecorationImplementationType, int Ordinal)>.Empty;

foreach (var types in typesFromAttributes)
{
decorationOrdinalChoices = decorationOrdinalChoices.Except(
decorationOrdinalChoices.Where(t =>
types.FilterDecorationOrdinalChoices.Contains(t.DecorationImplementationType)));
decorationOrdinalChoices = decorationOrdinalChoices.Union(types.DecorationOrdinalChoices);
}

DecorationOrdinalChoices = decorationOrdinalChoices;

return;

IImmutableSet<INamedTypeSymbol> GetSetOfTypesWithProperties(
Expand Down Expand Up @@ -463,6 +487,8 @@ IImmutableSet<INamedTypeSymbol> GetSetOfTypesWithProperties(
public IImmutableSet<INamedTypeSymbol> CompositeTypes { get; }
public IImmutableSet<INamedTypeSymbol> InjectionKeyAttributeTypes { get; }
public IImmutableSet<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)> InjectionKeyChoices { get; }
public IImmutableSet<INamedTypeSymbol> DecorationOrdinalAttributeTypes { get; }
public IImmutableSet<(INamedTypeSymbol DecorationImplementationType, int Ordinal)> DecorationOrdinalChoices { get; }

public IReadOnlyDictionary<ISymbol?, INamedTypeSymbol> InterfaceToComposite { get; }
public IReadOnlyDictionary<INamedTypeSymbol, IMethodSymbol> ImplementationToConstructorChoice { get; }
Expand Down
71 changes: 66 additions & 5 deletions Main/Configuration/TypesFromAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ internal interface ITypesFromAttributesBase
IImmutableSet<(INamedTypeSymbol, IReadOnlyList<INamedTypeSymbol>)> ImplementationCollectionChoices { get; }
IImmutableSet<INamedTypeSymbol> InjectionKeyAttributeTypes { get; }
IImmutableSet<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)> InjectionKeyChoices { get; }
IImmutableSet<INamedTypeSymbol> DecorationOrdinalAttributeTypes { get; }
IImmutableSet<(INamedTypeSymbol, int)> DecorationOrdinalChoices { get; }
IImmutableSet<INamedTypeSymbol> FilterImplementation { get; }
IImmutableSet<INamedTypeSymbol> FilterTransientAbstraction { get; }
IImmutableSet<INamedTypeSymbol> FilterSyncTransientAbstraction { get; }
Expand Down Expand Up @@ -72,6 +74,8 @@ internal interface ITypesFromAttributesBase
IImmutableSet<INamedTypeSymbol> FilterImplementationCollectionChoices { get; }
IImmutableSet<INamedTypeSymbol> FilterInjectionKeyAttributeTypes { get; }
IImmutableSet<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)> FilterInjectionKeyChoices { get; }
IImmutableSet<INamedTypeSymbol> FilterDecorationOrdinalAttributeTypes { get; }
IImmutableSet<INamedTypeSymbol> FilterDecorationOrdinalChoices { get; }
}

internal interface IAssemblyTypesFromAttributes : ITypesFromAttributesBase {}
Expand Down Expand Up @@ -229,6 +233,9 @@ internal TypesFromAttributesBase(
InjectionKeyAttributeTypes = GetTypesFromAttribute(wellKnownTypesMiscellaneous.InjectionKeyMappingAttribute)
.Select(t => t.Item2)
.ToImmutableHashSet();
DecorationOrdinalAttributeTypes = GetTypesFromAttribute(wellKnownTypesMiscellaneous.DecorationOrdinalMappingAttribute)
.Select(t => t.Item2)
.ToImmutableHashSet();

FilterImplementation = GetImplementationTypesFromAttribute(wellKnownTypesAggregation.FilterImplementationAggregationAttribute);
FilterTransientAbstraction = GetAbstractionTypesFromAttribute(wellKnownTypesAggregation.FilterTransientAbstractionAggregationAttribute);
Expand All @@ -252,6 +259,9 @@ internal TypesFromAttributesBase(
FilterInjectionKeyAttributeTypes = GetTypesFromAttribute(wellKnownTypesMiscellaneous.FilterInjectionKeyMappingAttribute)
.Select(t => t.Item2)
.ToImmutableHashSet();
FilterDecorationOrdinalAttributeTypes = GetTypesFromAttribute(wellKnownTypesMiscellaneous.FilterDecorationOrdinalMappingAttribute)
.Select(t => t.Item2)
.ToImmutableHashSet();

void NotParsableAttribute(AttributeData ad) =>
localDiagLogger.Error(ErrorLogData.ValidationConfigurationAttribute(
Expand Down Expand Up @@ -871,23 +881,41 @@ IImmutableSet<IAssemblySymbol> GetAssemblies(INamedTypeSymbol attributeType) =>
? injectionKeyChoiceAttributes
: Enumerable.Empty<AttributeData>())
.Select(ParseInjectionKeyChoice)
.OfType<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)>());
.Where(t => t.HasValue)
.Select(t => t ?? throw new ImpossibleDieException()));

FilterInjectionKeyChoices = ImmutableHashSet.CreateRange(
(AttributeDictionary.TryGetValue(wellKnownTypesChoice.FilterInjectionKeyChoiceAttribute, out var filterInjectionKeyChoiceAttributes)
? filterInjectionKeyChoiceAttributes
: Enumerable.Empty<AttributeData>())
.Select(ParseInjectionKeyChoice)
.OfType<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)>());
.Where(t => t.HasValue)
.Select(t => t ?? throw new ImpossibleDieException()));

DecorationOrdinalChoices = ImmutableHashSet.CreateRange(
(AttributeDictionary.TryGetValue(wellKnownTypesChoice.DecorationOrdinalChoiceAttribute, out var decorationOrdinalChoiceAttributes)
? decorationOrdinalChoiceAttributes
: Enumerable.Empty<AttributeData>())
.Select(ParseDecorationOrdinalChoice)
.Where(t => t.HasValue)
.Select(t => t ?? throw new ImpossibleDieException()));

FilterDecorationOrdinalChoices = ImmutableHashSet.CreateRange(
(AttributeDictionary.TryGetValue(wellKnownTypesChoice.FilterDecorationOrdinalChoiceAttribute, out var filterDecorationOrdinalChoiceAttributes)
? filterDecorationOrdinalChoiceAttributes
: Enumerable.Empty<AttributeData>())
.Select(ParseFilterDecorationOrdinalChoice)
.OfType<INamedTypeSymbol>());


return;

(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)? ParseInjectionKeyChoice(
AttributeData injectionKeyChoiceAttribute)
{
if (injectionKeyChoiceAttribute.ConstructorArguments.Length < 2
|| injectionKeyChoiceAttribute.ConstructorArguments[0].Value is not object keyValue
|| injectionKeyChoiceAttribute.ConstructorArguments[0].Type is not {} keyType
|| injectionKeyChoiceAttribute.ConstructorArguments[0].Value is not { } keyValue
|| injectionKeyChoiceAttribute.ConstructorArguments[0].Type is not { } keyType
|| injectionKeyChoiceAttribute.ConstructorArguments[1].Value is not INamedTypeSymbol implementationType
|| !validateAttributes.ValidateImplementation(implementationType))
{
Expand All @@ -897,6 +925,35 @@ IImmutableSet<IAssemblySymbol> GetAssemblies(INamedTypeSymbol attributeType) =>

return (keyType, keyValue, implementationType);
}

(INamedTypeSymbol DecorationImplementationType, int Ordinal)? ParseDecorationOrdinalChoice(
AttributeData attribute)
{
if (attribute.ConstructorArguments.Length < 2
|| attribute.ConstructorArguments[0].Value is not INamedTypeSymbol decorationImplementationType
|| attribute.ConstructorArguments[1].Value is not int ordinal
|| !validateAttributes.ValidateImplementation(decorationImplementationType))
{
NotParsableAttribute(attribute);
return null;
}

return (decorationImplementationType, ordinal);
}

INamedTypeSymbol? ParseFilterDecorationOrdinalChoice(
AttributeData attribute)
{
if (attribute.ConstructorArguments.Length < 1
|| attribute.ConstructorArguments[0].Value is not INamedTypeSymbol filterDecorationImplementationType
|| !validateAttributes.ValidateImplementation(filterDecorationImplementationType))
{
NotParsableAttribute(attribute);
return null;
}

return filterDecorationImplementationType;
}
}

private IReadOnlyDictionary<ISymbol?, IGrouping<ISymbol?, AttributeData>> AttributeDictionary { get; }
Expand Down Expand Up @@ -991,8 +1048,10 @@ protected IImmutableSet<INamedTypeSymbol> GetImplementationTypesFromAttribute(
public IImmutableSet<(INamedTypeSymbol, INamedTypeSymbol)> ImplementationChoices { get; }
public IImmutableSet<(INamedTypeSymbol, IReadOnlyList<INamedTypeSymbol>)> ImplementationCollectionChoices { get; }
public IImmutableSet<INamedTypeSymbol> InjectionKeyAttributeTypes { get; }

public IImmutableSet<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)> InjectionKeyChoices { get; }
public IImmutableSet<INamedTypeSymbol> DecorationOrdinalAttributeTypes { get; }
public IImmutableSet<(INamedTypeSymbol, int)> DecorationOrdinalChoices { get; }

public IImmutableSet<INamedTypeSymbol> FilterImplementation { get; }
public IImmutableSet<INamedTypeSymbol> FilterTransientAbstraction { get; }
public IImmutableSet<INamedTypeSymbol> FilterSyncTransientAbstraction { get; }
Expand Down Expand Up @@ -1024,4 +1083,6 @@ protected IImmutableSet<INamedTypeSymbol> GetImplementationTypesFromAttribute(
public IImmutableSet<INamedTypeSymbol> FilterImplementationCollectionChoices { get; }
public IImmutableSet<INamedTypeSymbol> FilterInjectionKeyAttributeTypes { get; }
public IImmutableSet<(ITypeSymbol KeyType, object KeyValue, INamedTypeSymbol ImplementationType)> FilterInjectionKeyChoices { get; }
public IImmutableSet<INamedTypeSymbol> FilterDecorationOrdinalAttributeTypes { get; }
public IImmutableSet<INamedTypeSymbol> FilterDecorationOrdinalChoices { get; }
}
6 changes: 3 additions & 3 deletions Main/Main.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="MrMeeseeks.Visitor" Version="1.1.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="MsMeeseeks.DIE" Version="2.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="MrMeeseeks.Visitor" Version="1.1.0" PrivateAssets="all" />
<PackageReference Include="MsMeeseeks.DIE" Version="2.0.0" PrivateAssets="all" />

<None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

Expand All @@ -43,7 +43,7 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.4.0" PrivateAssets="all" GeneratePathProperty="true" />
<None Include="$(PkgMicrosoft_CodeAnalysis_CSharp_Workspaces)\lib\netstandard2.0\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

<PackageReference Include="MrMeeseeks.DIE.Configuration.Attributes" Version="2.1.1" GeneratePathProperty="true" />
<PackageReference Include="MrMeeseeks.DIE.Configuration.Attributes" Version="3.0.0-beta.0" GeneratePathProperty="true" />
<None Include="$(PkgMrMeeseeks_DIE_Configuration_Attributes)\lib\netstandard2.0\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

<PackageReference Include="MrMeeseeks.SourceGeneratorUtility" Version="1.0.11" PrivateAssets="all" GeneratePathProperty="true" />
Expand Down
2 changes: 1 addition & 1 deletion Main/Nodes/Mappers/ElementNodeMapperBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ protected IElementNode SwitchInterfaceWithPotentialDecoration(
passedContext,
mapper);

var decoratorSequence = _checkTypeProperties.GetSequenceFor(interfaceType, implementationType)
var decoratorSequence = _checkTypeProperties.GetDecorationSequenceFor(interfaceType, implementationType)
.Reverse()
.Append(implementationType)
.ToList();
Expand Down
3 changes: 1 addition & 2 deletions Main/Validation/Range/ValidateRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ public virtual void Validate(INamedTypeSymbol rangeType, INamedTypeSymbol contai
{
ValidateRangeAndBaseType(rangeType, false);

/* ToDo: Add with next breaking change release for range types only (not for base types)
if (!type.IsSealed) log("Has to be a sealed type."); */
if (!rangeType.IsSealed) LogError(rangeType, containerType, "Has to be a sealed type.");

var unfilteredMembers = _rangeUtility.GetUnfilteredMembers(rangeType);

Expand Down
Loading

0 comments on commit ff16581

Please sign in to comment.