diff --git a/ArchUnitNET/Loader/LoadTasks/AddMethodDependencies.cs b/ArchUnitNET/Loader/LoadTasks/AddMethodDependencies.cs index 9055d7718..fd2734cd4 100644 --- a/ArchUnitNET/Loader/LoadTasks/AddMethodDependencies.cs +++ b/ArchUnitNET/Loader/LoadTasks/AddMethodDependencies.cs @@ -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; @@ -314,14 +324,6 @@ var dep in CreateMethodBodyDependenciesRecursive( } else { - var calledType = _typeFactory.GetOrCreateStubTypeInstanceFromTypeReference( - calledMethodReference.DeclaringType - ); - var calledMethodMember = - _typeFactory.GetOrCreateMethodMemberFromMethodReference( - calledType, - calledMethodReference - ); yield return calledMethodMember; } } diff --git a/ArchUnitNETTests/Dependencies/GenericMemberDependenciesTests.cs b/ArchUnitNETTests/Dependencies/GenericMemberDependenciesTests.cs index ebb41d97b..9d1a3340d 100644 --- a/ArchUnitNETTests/Dependencies/GenericMemberDependenciesTests.cs +++ b/ArchUnitNETTests/Dependencies/GenericMemberDependenciesTests.cs @@ -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 + [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(T t) - where M : new() + public void OuterFunc() + { + LocalFunc(); + PrivateFunc(); + + void LocalFunc() + { + throw new NotImplementedException($"Called with type {typeof(T)}"); + } + } + + private static void PrivateFunc() { - return new M(); + throw new NotImplementedException($"Called with type {typeof(T)}"); } } + + internal class OtherGenericArgumentClass { } }