diff --git a/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs b/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs index 159e7bb13..8d39661c0 100644 --- a/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs +++ b/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Reflection; using System.Text; -using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -83,6 +82,7 @@ public ClassTemplateInfo GenerateClassInfoForInterface(InterfaceDeclarationSynta ret.InterfaceName = GetInterfaceName(interfaceTree.Identifier); ret.GeneratedClassSuffix = ret.InterfaceName.Replace(".", ""); ret.Modifiers = interfaceTree.Modifiers.Select(t => t.ValueText).FirstOrDefault(m => m == "public" || m == "internal"); + ret.BaseClassNames = interfaceTree.BaseList?.Types.Select(t => t.ToString()).ToList(); if (interfaceTree.TypeParameterList != null) { @@ -168,6 +168,19 @@ public TemplateInformation GenerateTemplateInfoForInterfaceList(List c.BaseClassNames != null && c.BaseClassNames.Any())) + { + var methodsToAdd = ret.ClassList.Where(oc => c.BaseClassNames.Contains(oc.InterfaceName)).SelectMany(oc => oc.MethodList); + c.MethodList.AddRange(methodsToAdd); + } + return ret; } @@ -227,6 +240,7 @@ public class ClassTemplateInfo public string ConstraintClauses { get; set; } public string GeneratedClassSuffix { get; set; } public string InterfaceName { get; set; } + public List BaseClassNames { get; set; } public List MethodList { get; set; } public string Modifiers { get; set; } public string Namespace { get; set; } diff --git a/Refit.Tests/InheritedInterfacesApi.cs b/Refit.Tests/InheritedInterfacesApi.cs new file mode 100644 index 000000000..050830684 --- /dev/null +++ b/Refit.Tests/InheritedInterfacesApi.cs @@ -0,0 +1,27 @@ +using System.Threading.Tasks; +using Refit; // InterfaceStubGenerator looks for this +using static System.Math; // This is here to verify https://github.com/paulcbetts/refit/issues/283 + +namespace Refit.Tests +{ + [Headers("User-Agent: Refit Integration Tests")] + public interface IAmInterfaceA + { + [Get("/ping")] + Task Ping(); + } + + [Headers("User-Agent: Refit Integration Tests")] + public interface IAmInterfaceB + { + [Get("/pong")] + Task Pong(); + } + + [Headers("User-Agent: Refit Integration Tests")] + public interface IAmInterfaceC : IAmInterfaceB, IAmInterfaceA + { + [Get("/pang")] + Task Pang(); + } +} diff --git a/Refit.Tests/InterfaceStubGenerator.cs b/Refit.Tests/InterfaceStubGenerator.cs index 80f36b291..c4f02c794 100644 --- a/Refit.Tests/InterfaceStubGenerator.cs +++ b/Refit.Tests/InterfaceStubGenerator.cs @@ -27,9 +27,11 @@ public void GenerateInterfaceStubsSmokeTest() var result = fixture.GenerateInterfaceStubs(new[] { IntegrationTestHelper.GetPath("RestService.cs"), IntegrationTestHelper.GetPath("GitHubApi.cs"), + IntegrationTestHelper.GetPath("InheritedInterfacesApi.cs"), }); Assert.Contains("IGitHubApi", result); + Assert.Contains("IAmInterfaceC", result); } [Fact] @@ -92,7 +94,7 @@ public void GenerateClassInfoForInterfaceSmokeTest() Assert.Equal("IGitHubApi", result.InterfaceName); Assert.Equal("IGitHubApi", result.GeneratedClassSuffix); } - + [Fact] public void GenerateClassInfoForNestedInterfaceSmokeTest() { @@ -104,14 +106,14 @@ public void GenerateClassInfoForNestedInterfaceSmokeTest() .First(x => x.Identifier.ValueText == "INestedGitHubApi"); var result = fixture.GenerateClassInfoForInterface(input); - - Assert.Equal("TestNested.INestedGitHubApi",result.InterfaceName); - Assert.Equal("TestNestedINestedGitHubApi",result.GeneratedClassSuffix); + + Assert.Equal("TestNested.INestedGitHubApi", result.InterfaceName); + Assert.Equal("TestNestedINestedGitHubApi", result.GeneratedClassSuffix); Assert.Equal(8, result.MethodList.Count); Assert.Equal("GetUser", result.MethodList[0].Name); Assert.Equal("string userName", result.MethodList[0].ArgumentListWithTypes); } - + [Fact] public void GenerateTemplateInfoForInterfaceListSmokeTest() { @@ -126,6 +128,32 @@ public void GenerateTemplateInfoForInterfaceListSmokeTest() Assert.Equal(10, result.ClassList.Count); } + [Fact] + public void GenerateTemplateInfoForInheritedInterfacesListSmokeTest() + { + var file = CSharpSyntaxTree.ParseText(File.ReadAllText(IntegrationTestHelper.GetPath("InheritedInterfacesApi.cs"))); + var fixture = new InterfaceStubGenerator(); + + var input = file.GetRoot().DescendantNodes() + .OfType() + .ToList(); + + var result = fixture.GenerateTemplateInfoForInterfaceList(input); + Assert.Equal(3, result.ClassList.Count); + + var inherited = result.ClassList.First(c => c.InterfaceName == "IAmInterfaceC"); + + Assert.Equal(3, inherited.MethodList.Count); + var methodNames = inherited.MethodList.Select(m => m.Name).ToList(); + + Assert.Contains("Ping", methodNames); + Assert.Contains("Pong", methodNames); + Assert.Contains("Pang", methodNames); + + Assert.Equal("IAmInterfaceC", inherited.InterfaceName); + Assert.Equal("IAmInterfaceC", inherited.GeneratedClassSuffix); + } + [Fact] public void RetainsAliasesInUsings() {