Skip to content

Commit

Permalink
Merge pull request #35 from Yeah69/feature/open_generic_creates
Browse files Browse the repository at this point in the history
Feature/open generic creates
  • Loading branch information
Yeah69 authored Feb 10, 2024
2 parents db1312b + 62dd235 commit d13c4bb
Show file tree
Hide file tree
Showing 155 changed files with 3,037 additions and 722 deletions.
371 changes: 183 additions & 188 deletions Main/Configuration/CheckTypeProperties.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
using MrMeeseeks.DIE.Logging;
using MrMeeseeks.DIE.Utility;
using MrMeeseeks.SourceGeneratorUtility;
using MrMeeseeks.SourceGeneratorUtility.Extensions;

namespace MrMeeseeks.DIE;
namespace MrMeeseeks.DIE.Configuration;

internal interface IUserDefinedElements
{
Expand Down Expand Up @@ -155,7 +156,7 @@ IReadOnlyDictionary<INamedTypeSymbol, IMethodSymbol> GetInjectionMethods(string
{
var injectionMethodCandidates = dieMembers
.Where(s => s.Name.StartsWith(prefix))
.Where(s => s is IMethodSymbol { ReturnsVoid: true, Arity: 0, IsConditional: false, MethodKind: MethodKind.Ordinary } method
.Where(s => s is IMethodSymbol { ReturnsVoid: true, IsConditional: false, MethodKind: MethodKind.Ordinary } method
&& method.Parameters.Any(p => p.RefKind == RefKind.Out))
.OfType<IMethodSymbol>()
.Select(m =>
Expand Down Expand Up @@ -239,11 +240,11 @@ static ITypeSymbol GetAsyncUnwrappedType(ITypeSymbol type, WellKnownTypes wellKn
public IMethodSymbol? AddForDisposal { get; }
public IMethodSymbol? AddForDisposalAsync { get; }
public IMethodSymbol? GetConstructorParametersInjectionFor(INamedTypeSymbol type) =>
_constructorParametersInjectionMethods.TryGetValue(type, out var ret) ? ret : null;
_constructorParametersInjectionMethods.TryGetValue(type.UnboundIfGeneric(), out var ret) ? ret : null;

public IMethodSymbol? GetPropertiesInjectionFor(INamedTypeSymbol type) =>
_propertiesInjectionMethods.TryGetValue(type, out var ret) ? ret : null;
_propertiesInjectionMethods.TryGetValue(type.UnboundIfGeneric(), out var ret) ? ret : null;

public IMethodSymbol? GetInitializerParametersInjectionFor(INamedTypeSymbol type) =>
_initializerParametersInjectionMethods.TryGetValue(type, out var ret) ? ret : null;
_initializerParametersInjectionMethods.TryGetValue(type.UnboundIfGeneric(), out var ret) ? ret : null;
}
6 changes: 5 additions & 1 deletion Main/Contexts/ContainerWideContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ internal interface IContainerWideContext
WellKnownTypesChoice WellKnownTypesChoice { get; }
WellKnownTypesCollections WellKnownTypesCollections { get; }
WellKnownTypesMiscellaneous WellKnownTypesMiscellaneous { get; }
Compilation Compilation { get; }
}

internal class ContainerWideContext : IContainerWideContext, IContainerInstance
Expand All @@ -20,18 +21,21 @@ public ContainerWideContext(
WellKnownTypesAggregation wellKnownTypesAggregation,
WellKnownTypesChoice wellKnownTypesChoice,
WellKnownTypesCollections wellKnownTypesCollections,
WellKnownTypesMiscellaneous wellKnownTypesMiscellaneous)
WellKnownTypesMiscellaneous wellKnownTypesMiscellaneous,
Compilation compilation)
{
WellKnownTypes = wellKnownTypes;
WellKnownTypesAggregation = wellKnownTypesAggregation;
WellKnownTypesChoice = wellKnownTypesChoice;
WellKnownTypesCollections = wellKnownTypesCollections;
WellKnownTypesMiscellaneous = wellKnownTypesMiscellaneous;
Compilation = compilation;
}

public WellKnownTypes WellKnownTypes { get; }
public WellKnownTypesAggregation WellKnownTypesAggregation { get; }
public WellKnownTypesChoice WellKnownTypesChoice { get; }
public WellKnownTypesCollections WellKnownTypesCollections { get; }
public WellKnownTypesMiscellaneous WellKnownTypesMiscellaneous { get; }
public Compilation Compilation { get; }
}
3 changes: 2 additions & 1 deletion Main/ExecuteImpl.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using MrMeeseeks.DIE.Utility;

namespace MrMeeseeks.DIE;
Expand Down
46 changes: 42 additions & 4 deletions Main/Logging/DiagLogData.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using MrMeeseeks.DIE.Nodes.Ranges;
using MrMeeseeks.SourceGeneratorUtility;
using MrMeeseeks.SourceGeneratorUtility.Extensions;

Expand Down Expand Up @@ -80,11 +81,25 @@ internal static DiagLogData ValidationUserDefinedElement(
ISymbol userDefinedElement,
INamedTypeSymbol parentRange,
INamedTypeSymbol parentContainer,
string specification) =>
ValidationUserDefinedElementInner(userDefinedElement, parentRange.Name, parentContainer.Name, specification);

internal static DiagLogData ValidationUserDefinedElement(
ISymbol userDefinedElement,
IRangeNode parentRange,
IContainerNode parentContainer,
string specification) =>
ValidationUserDefinedElementInner(userDefinedElement, parentRange.Name, parentContainer.Name, specification);

internal static DiagLogData ValidationUserDefinedElementInner(
ISymbol userDefinedElement,
string parentRange,
string parentContainer,
string specification)
{
var rangeDescription = CustomSymbolEqualityComparer.Default.Equals(parentRange, parentContainer)
? $"parent-Container \"{parentContainer.Name}\""
: $"Range \"{parentRange.Name}\" in parent-Container \"{parentContainer.Name}\"";
var rangeDescription = Equals(parentRange, parentContainer)
? $"parent-Container \"{parentContainer}\""
: $"Range \"{parentRange}\" in parent-Container \"{parentContainer}\"";
return new(67,
3,
"Validation (User-Defined Element)",
Expand Down Expand Up @@ -130,7 +145,7 @@ internal static DiagLogData ImpossibleException(Guid code) =>
new(66,
2,
"Impossible Exception",
$"You've run into an exception which should be impossible. Please make a issue at https://github.com/Yeah69/MrMeeseeks.DIE/issues/new with code hint \"{code.ToString()}\".",
$"You've run into an exception which should be impossible. Please create an issue - if none exists for this code hint yet - at https://github.com/Yeah69/MrMeeseeks.DIE/issues/new with code hint \"{code.ToString()}\".",
DieExceptionKind.Impossible);

internal static DiagLogData CompilationError(string message) =>
Expand Down Expand Up @@ -211,6 +226,29 @@ internal static DiagLogData ValidationConfigurationAttribute(
$"The configuration attribute \"{attributeData.AttributeClass?.Name}\" (of \"{rangeDescription}\") isn't validly defined: {specification}",
null);
}

internal static DiagLogData ValidationUserDefinedElement(
ISymbol userDefinedElement,
IRangeNode parentRange,
IContainerNode parentContainer,
string specification) =>
ValidationUserDefinedElementInner(userDefinedElement, parentRange.Name, parentContainer.Name, specification);

internal static DiagLogData ValidationUserDefinedElementInner(
ISymbol userDefinedElement,
string parentRange,
string parentContainer,
string specification)
{
var rangeDescription = Equals(parentRange, parentContainer)
? $"parent-Container \"{parentContainer}\""
: $"Range \"{parentRange}\" in parent-Container \"{parentContainer}\"";
return new(71,
1,
"Validation (User-Defined Element)",
$"The user-defined element \"{userDefinedElement.Name}\" (of \"{rangeDescription}\") isn't validly defined: {specification}",
DieExceptionKind.Validation);
}

internal static DiagLogData Logging(string message) =>
new(0,
Expand Down
6 changes: 3 additions & 3 deletions Main/Main.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@

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

<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" PrivateAssets="all" GeneratePathProperty="true" />
<None Include="$(PkgMicrosoft_Bcl_AsyncInterfaces)\lib\netstandard2.0\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />

<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.4.0" PrivateAssets="all" GeneratePathProperty="true" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.8.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="3.0.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" />
<PackageReference Include="MrMeeseeks.SourceGeneratorUtility" Version="1.0.12" PrivateAssets="all" GeneratePathProperty="true" />
<None Include="$(PkgMrMeeseeks_SourceGeneratorUtility)\lib\netstandard2.0\*.dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>

Expand Down
12 changes: 7 additions & 5 deletions Main/Nodes/Elements/Delegates/DelegateBaseNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ internal abstract class DelegateBaseNode : IDelegateBaseNode
private readonly ITypeSymbol _innerType;

internal DelegateBaseNode(
INamedTypeSymbol delegateType,
(INamedTypeSymbol Outer, INamedTypeSymbol Inner) delegateTypes,
ILocalFunctionNode function,
IReadOnlyList<ITypeSymbol> typeParameters,

ILocalDiagLogger localDiagLogger,
IContainerNode parentContainer,
Expand All @@ -30,10 +31,11 @@ internal DelegateBaseNode(
_function = function;
_localDiagLogger = localDiagLogger;
_parentContainer = parentContainer;
MethodGroup = function.Name;
Reference = referenceGenerator.Generate(delegateType);
TypeFullName = delegateType.FullName();
_innerType = delegateType.TypeArguments.Last();
var genericsSuffix = typeParameters.Any() ? $"<{string.Join(", ", typeParameters.Select(p => p.FullName()))}>" : string.Empty;
MethodGroup = $"{function.Name}{genericsSuffix}";
Reference = referenceGenerator.Generate(delegateTypes.Inner);
TypeFullName = delegateTypes.Outer.FullName();
_innerType = delegateTypes.Inner.TypeArguments.Last();
}

public virtual void Build(PassedContext passedContext) =>
Expand Down
5 changes: 3 additions & 2 deletions Main/Nodes/Elements/Delegates/FuncNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ internal interface IFuncNode : IDelegateBaseNode
internal partial class FuncNode : DelegateBaseNode, IFuncNode
{
internal FuncNode(
INamedTypeSymbol funcType,
(INamedTypeSymbol Outer, INamedTypeSymbol Inner) delegateTypes,
ILocalFunctionNode function,
IReadOnlyList<ITypeSymbol> typeParameters,

ILocalDiagLogger localDiagLogger,
IContainerNode parentContainer,
IReferenceGenerator referenceGenerator)
: base(funcType, function, localDiagLogger, parentContainer, referenceGenerator)
: base(delegateTypes, function, typeParameters, localDiagLogger, parentContainer, referenceGenerator)
{
}
}
5 changes: 3 additions & 2 deletions Main/Nodes/Elements/Delegates/LazyNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ internal interface ILazyNode : IDelegateBaseNode
internal partial class LazyNode : DelegateBaseNode, ILazyNode
{
internal LazyNode(
INamedTypeSymbol lazyType,
(INamedTypeSymbol Outer, INamedTypeSymbol Inner) delegateTypes,
ILocalFunctionNode function,
IReadOnlyList<ITypeSymbol> typeParameters,

ILocalDiagLogger localDiagLogger,
IContainerNode parentContainer,
IReferenceGenerator referenceGenerator)
: base(lazyType, function, localDiagLogger, parentContainer, referenceGenerator)
: base(delegateTypes, function, typeParameters, localDiagLogger, parentContainer, referenceGenerator)
{
}
}
7 changes: 4 additions & 3 deletions Main/Nodes/Elements/Delegates/ThreadLocalNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ internal partial class ThreadLocalNode : DelegateBaseNode, IThreadLocalNode
private readonly IRangeNode _parentRange;

internal ThreadLocalNode(
INamedTypeSymbol threadLocalType,
(INamedTypeSymbol Outer, INamedTypeSymbol Inner) delegateTypes,
ILocalFunctionNode function,
IReadOnlyList<ITypeSymbol> typeParameters,

ILocalDiagLogger localDiagLogger,
IContainerNode parentContainer,
ITransientScopeWideContext transientScopeWideContext,
IReferenceGenerator referenceGenerator)
: base(threadLocalType, function, localDiagLogger, parentContainer, referenceGenerator)
: base(delegateTypes, function, typeParameters, localDiagLogger, parentContainer, referenceGenerator)
{
_threadLocalType = threadLocalType;
_threadLocalType = delegateTypes.Inner;
_parentRange = transientScopeWideContext.Range;
_checkTypeProperties = transientScopeWideContext.CheckTypeProperties;
}
Expand Down
3 changes: 3 additions & 0 deletions Main/Nodes/Elements/FunctionCalls/AsyncFunctionCallNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@ public AsyncFunctionCallNode(
SynchronicityDecision synchronicityDecision,
IFunctionNode calledFunction,
IReadOnlyList<(IParameterNode, IParameterNode)> parameters,
IReadOnlyList<ITypeSymbol> typeParameters,

IReferenceGenerator referenceGenerator,
IContainerWideContext containerWideContext)
{
OwnerReference = ownerReference;
FunctionName = calledFunction.Name;
Parameters = parameters;
TypeParameters = typeParameters;
SynchronicityDecision = synchronicityDecision;
_calledFunction = calledFunction;
Transformation = synchronicityDecision is SynchronicityDecision.AsyncValueTask
Expand Down Expand Up @@ -74,6 +76,7 @@ public void AdjustToCurrentCalledFunctionSynchronicity()
public string? OwnerReference { get; }
public string FunctionName { get; }
public IReadOnlyList<(IParameterNode, IParameterNode)> Parameters { get; }
public IReadOnlyList<ITypeSymbol> TypeParameters { get; }
public IFunctionNode CalledFunction => _calledFunction;
public bool Awaited { get; } = false;
}
11 changes: 8 additions & 3 deletions Main/Nodes/Elements/FunctionCalls/FunctionCallNode.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using MrMeeseeks.DIE.Nodes.Functions;
using MrMeeseeks.DIE.Visitors;
using MrMeeseeks.SourceGeneratorUtility.Extensions;

namespace MrMeeseeks.DIE.Nodes.Elements.FunctionCalls;

Expand All @@ -8,6 +9,7 @@ internal interface IFunctionCallNode : IElementNode, IAwaitableNode
string? OwnerReference { get; }
string FunctionName { get; }
IReadOnlyList<(IParameterNode, IParameterNode)> Parameters { get; }
IReadOnlyList<ITypeSymbol> TypeParameters { get; }
IFunctionNode CalledFunction { get; }
}

Expand All @@ -18,28 +20,31 @@ internal abstract class FunctionCallNode : IFunctionCallNode
public FunctionCallNode(
string? ownerReference,
IFunctionNode calledFunction,
ITypeSymbol callSideType,
IReadOnlyList<(IParameterNode, IParameterNode)> parameters,
IReadOnlyList<ITypeSymbol> typeParameters,

IReferenceGenerator referenceGenerator)
{
_calledFunction = calledFunction;
OwnerReference = ownerReference;
Parameters = parameters;
TypeParameters = typeParameters;
FunctionName = calledFunction.Name;
TypeFullName = callSideType.FullName();
Reference = referenceGenerator.Generate("functionCallResult");
}

public virtual void Build(PassedContext passedContext) { }

public abstract void Accept(INodeVisitor nodeVisitor);

public string TypeFullName =>
_calledFunction.AsyncTypeFullName
?? _calledFunction.ReturnedTypeFullName;
public string TypeFullName { get; }
public string Reference { get; }
public string FunctionName { get; }
public virtual string? OwnerReference { get; }
public IReadOnlyList<(IParameterNode, IParameterNode)> Parameters { get; }
public IReadOnlyList<ITypeSymbol> TypeParameters { get; }
public IFunctionNode CalledFunction => _calledFunction;

public bool Awaited => _calledFunction.SynchronicityDecision is not SynchronicityDecision.Sync;
Expand Down
4 changes: 3 additions & 1 deletion Main/Nodes/Elements/FunctionCalls/PlainFunctionCallNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ internal partial class PlainFunctionCallNode : FunctionCallNode, IPlainFunctionC
public PlainFunctionCallNode(
string? ownerReference,
IFunctionNode calledFunction,
ITypeSymbol callSideType,
IReadOnlyList<(IParameterNode, IParameterNode)> parameters,
IReadOnlyList<ITypeSymbol> typeParameters,

IReferenceGenerator referenceGenerator)
: base(ownerReference, calledFunction, parameters, referenceGenerator)
: base(ownerReference, calledFunction, callSideType, parameters, typeParameters, referenceGenerator)
{
}
}
4 changes: 3 additions & 1 deletion Main/Nodes/Elements/FunctionCalls/ScopeCallNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ public ScopeCallNode(
IScopeNode scope,
IRangeNode callingRange,
IFunctionNode calledFunction,
ITypeSymbol callSideType,
IReadOnlyList<(IParameterNode, IParameterNode)> parameters,
IReadOnlyList<ITypeSymbol> typeParameters,
IFunctionCallNode? initialization,

IReferenceGenerator referenceGenerator)
: base(null, calledFunction, parameters, referenceGenerator)
: base(null, calledFunction, callSideType, parameters, typeParameters, referenceGenerator)
{
_scope = scope;
_callingRange = callingRange;
Expand Down
4 changes: 3 additions & 1 deletion Main/Nodes/Elements/FunctionCalls/TransientScopeCallNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ public TransientScopeCallNode(
IContainerNode parentContainer,
IRangeNode callingRange,
IFunctionNode calledFunction,
ITypeSymbol callSideType,
IReadOnlyList<(IParameterNode, IParameterNode)> parameters,
IReadOnlyList<ITypeSymbol> typeParameters,
IFunctionCallNode? initialization,

IReferenceGenerator referenceGenerator)
: base(null, calledFunction, parameters, referenceGenerator)
: base(null, calledFunction, callSideType, parameters, typeParameters, referenceGenerator)
{
_scope = scope;
ContainerParameter = containerParameter;
Expand Down
Loading

0 comments on commit d13c4bb

Please sign in to comment.