Skip to content

Commit

Permalink
Merge pull request #883 from Dreamescaper/usings_fix
Browse files Browse the repository at this point in the history
Usings fix
  • Loading branch information
clairernovotny authored Apr 1, 2020
2 parents 77437ae + a9ee988 commit d5e55c0
Show file tree
Hide file tree
Showing 8 changed files with 1,500 additions and 822 deletions.
18 changes: 17 additions & 1 deletion InterfaceStubGenerator.Core/InterfaceStubGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,25 @@ public ClassTemplateInfo GenerateClassInfoForInterface(InterfaceDeclarationSynta
var rootNode = interfaceTree.Parent;
while (rootNode.Parent != null) rootNode = rootNode.Parent;

var usings = rootNode.DescendantNodes()
var usingsInsideNamespace = ns?.DescendantNodes()
.OfType<UsingDirectiveSyntax>()
.Select(x => $"{x.Alias} {x.StaticKeyword} {x.Name}".TrimStart())
?? Enumerable.Empty<string>();

var usingsOutsideNamespace = rootNode.DescendantNodes(x => !x.IsKind(SyntaxKind.NamespaceDeclaration))
.OfType<UsingDirectiveSyntax>()
.Select(x =>
{
// Globally qualify namespace name to avoid conflicts when put inside namespace.
var name = x.Name.ToString();
var globallyQualifiedName = name.Contains("::")
? name
: "global::" + name;

return $"{x.Alias} {x.StaticKeyword} {globallyQualifiedName}".TrimStart();
});

var usings = usingsInsideNamespace.Concat(usingsOutsideNamespace)
.Distinct()
.Where(x => x != "System" && x != "System.Net.Http" && x != "System.Collections.Generic" && x != "System.Linq")
.Select(x => new UsingDeclaration { Item = x });
Expand Down
20 changes: 18 additions & 2 deletions Refit.Tests/InterfaceStubGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ public void RetainsAliasesInUsings()
var input = syntaxTree.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>().ToList();
var result = fixture.GenerateTemplateInfoForInterfaceList(input);
var classTemplate = result.ClassList[0];
var usingList = classTemplate.UsingList.Select(x => x.Item).ToList();
var usingList = classTemplate.UsingList.Select(x => x.Item.Replace("global::", "")).ToList();
Assert.Contains("SomeType = CollisionA.SomeType", usingList);
Assert.Contains("CollisionB", usingList);
}
Expand All @@ -218,7 +218,7 @@ public void AvoidsTypeCollisions(string interfaceName, string usingCsv)
var result = fixture.GenerateTemplateInfoForInterfaceList(input);

var classItem = result.ClassList.Single(c => c.InterfaceName == interfaceName);
var usingList = classItem.UsingList.Select(x => x.Item);
var usingList = classItem.UsingList.Select(x => x.Item.Replace("global::", ""));
var expected = usingCsv.Split(',');
Assert.Equal(usingList, expected);

Expand All @@ -229,6 +229,22 @@ IEnumerable<InterfaceDeclarationSyntax> getInterfaces(string fileName)
}
}

[Fact]
public void HandlesReducedUsingsInsideNamespace()
{
var fixture = new InterfaceStubGenerator();

var syntaxTree = CSharpSyntaxTree.ParseText(File.ReadAllText(IntegrationTestHelper.GetPath("ReducedUsingInsideNamespaceApi.cs")));
var input = syntaxTree.GetRoot().DescendantNodes().OfType<InterfaceDeclarationSyntax>().ToList();
var result = fixture.GenerateTemplateInfoForInterfaceList(input);
var classTemplate = result.ClassList[0];
var usingList = classTemplate.UsingList.Select(x => x.Item).ToList();

Assert.Contains("ModelNamespace", usingList);
Assert.Contains("global::System.Threading.Tasks", usingList);
Assert.Contains("global::Refit", usingList);
}

[Fact]
public void GenerateInterfaceStubsWithoutNamespaceSmokeTest()
{
Expand Down
34 changes: 34 additions & 0 deletions Refit.Tests/NamespaceOverlapApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using Common.Helper;
using Refit.Tests.Common;
// InterfaceStubGenerator looks for this
using Refit;

namespace Refit.Tests
{
[SomeHelper]
public interface INamespaceOverlapApi
{
[Get("/")]
Task<SomeOtherType> SomeRequest();
}

public static class NamespaceOverlapApi
{
public static INamespaceOverlapApi Create()
{
return RestService.For<INamespaceOverlapApi>("http://somewhere.com");
}
}
}

namespace Common.Helper
{
public class SomeHelperAttribute : Attribute { }
}

namespace Refit.Tests.Common
{
public class SomeOtherType { }
}
18 changes: 18 additions & 0 deletions Refit.Tests/NamespaceWithGlobalAliasApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using global::System.Threading.Tasks;
using Refit; // InterfaceStubGenerator looks for this

namespace Refit.Tests
{
using global::Refit.Tests.SomeNamespace;

public interface NamespaceWithGlobalAliasApi
{
[Get("/")]
Task<SomeType> SomeRequest();
}
}

namespace Refit.Tests.SomeNamespace
{
public class SomeType { }
}
18 changes: 18 additions & 0 deletions Refit.Tests/ReducedUsingInsideNamespaceApi.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Threading.Tasks;
using Refit; // InterfaceStubGenerator looks for this

namespace Refit.Tests
{
using ModelNamespace;

public interface IReducedUsingInsideNamespaceApi
{
[Get("/")]
Task<SomeType> SomeRequest();
}
}

namespace Refit.Tests.ModelNamespace
{
public class SomeType { }
}
Loading

0 comments on commit d5e55c0

Please sign in to comment.