Add support to generate code for interface without a namespace (#46)

This commit is contained in:
Stef Heyenrath
2022-12-13 18:51:06 +01:00
committed by GitHub
parent 3eb9d8ce5f
commit 72a40e6f6a
13 changed files with 163 additions and 14 deletions
@@ -0,0 +1,9 @@
using Akka.Remote;
// namespace ProxyInterfaceConsumerForAkka.Interfaces; <-- no namespace
[ProxyInterfaceGenerator.Proxy(typeof(AddressUid))]
// ReSharper disable once CheckNamespace
public partial interface IAddressUid
{
}
@@ -7,6 +7,9 @@ public class Program
{
public static void Main()
{
Akka.Remote.AddressUid auid = null;
IAddressUid addressUidProxy = new AddressUidProxy(auid);
LocalActorRefProvider p = null;
ILocalActorRefProvider proxy = new LocalActorRefProviderProxy(p);
}
@@ -15,15 +15,16 @@
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />
<PackageReference Include="ProxyInterfaceGenerator" Version="0.0.24">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="TinyMapper" Version="3.0.3" />
</ItemGroup>
<!--<ItemGroup>
<ItemGroup>
<!--<PackageReference Include="ProxyInterfaceGenerator" Version="0.0.24">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>-->
<ProjectReference Include="..\..\src\ProxyInterfaceSourceGenerator\ProxyInterfaceSourceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>-->
</ItemGroup>
</Project>
@@ -59,6 +59,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
{
var extendsProxyClasses = GetExtendsProxyData(proxyData, classSymbol);
var @new = extendsProxyClasses.Any() ? "new " : string.Empty;
var (namespaceStart, namespaceEnd) = NamespaceBuilder.Build(ns);
return $@"//----------------------------------------------------------------------------------------
// <auto-generated>
@@ -72,8 +73,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
{(SupportsNullable ? "#nullable enable" : string.Empty)}
using System;
namespace {ns}
{{
{namespaceStart}
public partial interface {interfaceName}
{{
{@new}{classSymbol.Symbol} _Instance {{ get; }}
@@ -84,7 +84,7 @@ namespace {ns}
{GenerateEvents(classSymbol, proxyData.ProxyBaseClasses)}
}}
}}
{namespaceEnd}
{(SupportsNullable ? "#nullable disable" : string.Empty)}";
}
@@ -84,6 +84,8 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
configurationForMapster = GenerateMapperConfigurationForMapster();
}
var (namespaceStart, namespaceEnd) = NamespaceBuilder.Build(pd.Namespace);
return $@"//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator.
@@ -96,8 +98,7 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
{(SupportsNullable ? "#nullable enable" : string.Empty)}
using System;
namespace {pd.Namespace}
{{
{namespaceStart}
public {@abstract}partial class {className} : {extends}{interfaceName}
{{
public {@new}{targetClassSymbol.Symbol} _Instance {{ get; }}
@@ -117,7 +118,7 @@ namespace {pd.Namespace}
{configurationForMapster}
}}
}}
}}
{namespaceEnd}
{(SupportsNullable ? "#nullable disable" : string.Empty)}";
}
@@ -0,0 +1,15 @@
namespace ProxyInterfaceSourceGenerator.Utils;
internal static class NamespaceBuilder
{
public static (string Start, string End) Build(string ns)
{
var namespaceDefined = !string.IsNullOrEmpty(ns);
return
(
namespaceDefined ? $"namespace {ns}\r\n{{" : string.Empty,
namespaceDefined ? "}" : string.Empty
);
}
}
@@ -0,0 +1,27 @@
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
public partial interface INoNamespace
{
ProxyInterfaceSourceGeneratorTests.Source.NoNamespace _Instance { get; }
bool Test { get; set; }
}
#nullable disable
@@ -0,0 +1,36 @@
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
public partial class NoNamespaceProxy : INoNamespace
{
public ProxyInterfaceSourceGeneratorTests.Source.NoNamespace _Instance { get; }
public bool Test { get => _Instance.Test; set => _Instance.Test = value; }
public NoNamespaceProxy(ProxyInterfaceSourceGeneratorTests.Source.NoNamespace instance)
{
_Instance = instance;
}
}
#nullable disable
@@ -1,4 +1,5 @@
using System.IO;
using System.Linq;
using CSharp.SourceGenerators.Extensions;
using CSharp.SourceGenerators.Extensions.Models;
using FluentAssertions;
@@ -49,6 +50,48 @@ namespace ProxyInterfaceSourceGeneratorTests
result.Files.Should().HaveCount(1);
}
[Fact]
public void GenerateFiles_When_NoNamespace_Should_GenerateCorrectFiles()
{
// Arrange
var fileNames = new[]
{
"INoNamespace.g.cs",
"NoNamespaceProxy.g.cs"
};
var path = "./Source/INoNamespace.cs";
var sourceFile = new SourceFile
{
Path = path,
Text = File.ReadAllText(path),
AttributeToAddToInterface = new ExtraAttribute
{
Name = "ProxyInterfaceGenerator.Proxy",
ArgumentList = "typeof(ProxyInterfaceSourceGeneratorTests.Source.NoNamespace)"
}
};
// Act
var result = _sut.Execute(new[]
{
sourceFile
});
// Assert
result.Valid.Should().BeTrue();
result.Files.Should().HaveCount(fileNames.Length + 1);
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
{
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
builder.Path.Should().EndWith(fileName.fileName);
if (Write) File.WriteAllText($"../../../Destination/{fileName.fileName}", builder.Text);
builder.Text.Should().Be(File.ReadAllText($"../../../Destination/{fileName.fileName}"));
}
}
[Fact]
public void GenerateFiles_ForSingleClass_Should_GenerateCorrectFiles()
{
@@ -0,0 +1,6 @@
namespace ProxyInterfaceSourceGeneratorTests.Source.AkkaActor
{
public partial interface ILocalActorRefProvider
{
}
}
@@ -1,5 +1,3 @@
using Xunit.Sdk;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public class Human
@@ -0,0 +1,4 @@
// ReSharper disable once CheckNamespace
public partial interface INoNamespace
{
}
@@ -0,0 +1,6 @@
namespace ProxyInterfaceSourceGeneratorTests.Source;
public class NoNamespace
{
public bool Test { get; set; }
}