Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions ArchUnitNET/Loader/LoadTasks/AddMethodDependencies.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,16 @@ var calledMethodReference in calledMethodReferences.Except(visitedMethodReferenc
{
visitedMethodReferences.Add(calledMethodReference);

var calledType = _typeFactory.GetOrCreateStubTypeInstanceFromTypeReference(
calledMethodReference.DeclaringType
);
var calledMethodMember = _typeFactory.GetOrCreateMethodMemberFromMethodReference(
calledType,
calledMethodReference
);

bodyTypes.AddRange(calledMethodMember.MemberGenericArguments);

if (calledMethodReference.IsCompilerGenerated())
{
MethodDefinition calledMethodDefinition;
Expand Down Expand Up @@ -314,14 +324,6 @@ var dep in CreateMethodBodyDependenciesRecursive(
}
else
{
var calledType = _typeFactory.GetOrCreateStubTypeInstanceFromTypeReference(
calledMethodReference.DeclaringType
);
var calledMethodMember =
_typeFactory.GetOrCreateMethodMemberFromMethodReference(
calledType,
calledMethodReference
);
yield return calledMethodMember;
}
}
Expand Down
70 changes: 64 additions & 6 deletions ArchUnitNETTests/Dependencies/GenericMemberDependenciesTests.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,71 @@
namespace ArchUnitNETTests.Dependencies
using System;
using System.Linq;
using ArchUnitNET.Domain;
using ArchUnitNET.Domain.Dependencies;
using ArchUnitNET.Domain.Extensions;
using Xunit;

namespace ArchUnitNETTests.Dependencies
{
public class GenericMemberDependenciesTests { }
public class GenericMemberDependenciesTests
{
[Fact]
public void GenericArgumentsFromMethodCallLocalFuncTest()
{
var architecture = StaticTestArchitectures.ArchUnitNETTestArchitecture;
var classWithGenericMethodCall = architecture.GetClassOfType(
typeof(ClassWithGenericMethodCall)
);
var genericArgumentClass = architecture.GetClassOfType(typeof(GenericArgumentClass));
var methodMember = (MethodMember)
classWithGenericMethodCall.Members.WhereNameIs("OuterFunc()").First();
Assert.Contains(
methodMember.Dependencies,
dependency =>
dependency is BodyTypeMemberDependency bodyTypeMemberDependency
&& bodyTypeMemberDependency.Target.Equals(genericArgumentClass)
);
}

internal class GenericClass<T>
[Fact]
public void GenericArgumentsFromMethodCallTest()
{
var architecture = StaticTestArchitectures.ArchUnitNETTestArchitecture;
var classWithGenericMethodCall = architecture.GetClassOfType(
typeof(ClassWithGenericMethodCall)
);
var genericArgumentClass = architecture.GetClassOfType(
typeof(OtherGenericArgumentClass)
);
var methodMember = (MethodMember)
classWithGenericMethodCall.Members.WhereNameIs("OuterFunc()").First();
Assert.Contains(
methodMember.Dependencies,
dependency =>
dependency is BodyTypeMemberDependency bodyTypeMemberDependency
&& bodyTypeMemberDependency.Target.Equals(genericArgumentClass)
);
}
}

internal class ClassWithGenericMethodCall
{
public M GenericMethod<M>(T t)
where M : new()
public void OuterFunc()
{
LocalFunc<GenericArgumentClass>();
PrivateFunc<OtherGenericArgumentClass>();

void LocalFunc<T>()
{
throw new NotImplementedException($"Called with type {typeof(T)}");
}
}

private static void PrivateFunc<T>()
{
return new M();
throw new NotImplementedException($"Called with type {typeof(T)}");
}
}

internal class OtherGenericArgumentClass { }
}