More options (#5)

* update generator and tests

* Add ImplementationOptions

* option tests

* fix some tests

* UseExtendedInterfaces with flag enum parsing

* add test for using base interfaces instead of interface

* add ProxyForBaseInterface

* add extra overload

* don't put new if we're replacing interfaces

* really remove AutoMapper

* remove akka and fix up interface

* Bigger bump for version

* adjust readme
This commit is contained in:
Adam Hathcock
2024-05-24 13:16:14 +01:00
committed by GitHub
parent 622f361de5
commit 6391515c19
77 changed files with 868 additions and 278 deletions
+34 -2
View File
@@ -1,14 +1,36 @@
# ProxyInterfaceGenerator # Speckle.ProxyGenerator
This is a fork of a library that almost gets us there but needed some new functionality to achieve a goal: successfully wrap a library we cannot modify and have interfaces in a separate assembly.
Modifications have been mainly due that the primary interfaces need to be in a different assembly.
## Usage so far
Interface Assembly:
- Base interfaces usable by anyone and Unit tests
Api Assembly:
- Proxy Interfaces that inherit from the base interfaces
- Proxy attribute references wrapped Api
New needs: base interface is used by wrappers. Need to ignore members from wrapped api on demand.
## Old Docs
This project uses Source Generation to generate an interface and a Proxy class for classes. This project uses Source Generation to generate an interface and a Proxy class for classes.
This makes it possible to wrap external classes which do not have an interface, in a Proxy class which makes it easier to Mock and use DI. This makes it possible to wrap external classes which do not have an interface, in a Proxy class which makes it easier to Mock and use DI.
It supports: It supports:
- properties - properties
- methods - methods
- events - events
- implicit and explicit operators - implicit and explicit operators
## Install ## Install
[![NuGet Badge](https://buildstats.info/nuget/ProxyInterfaceGenerator)](https://www.nuget.org/packages/ProxyInterfaceGenerator) [![NuGet Badge](https://buildstats.info/nuget/ProxyInterfaceGenerator)](https://www.nuget.org/packages/ProxyInterfaceGenerator)
You can install from NuGet using the following command in the package manager window: You can install from NuGet using the following command in the package manager window:
@@ -20,7 +42,9 @@ Or via the Visual Studio NuGet package manager or if you use the `dotnet` comman
`dotnet add package ProxyInterfaceGenerator` `dotnet add package ProxyInterfaceGenerator`
## Usage ## Usage
### Given: an external existing class which does not implement an interface ### Given: an external existing class which does not implement an interface
``` c# ``` c#
public sealed class Person public sealed class Person
{ {
@@ -34,6 +58,7 @@ public sealed class Person
``` ```
### Create a partial interface ### Create a partial interface
And annotate this with `ProxyInterfaceGenerator.Proxy[...]` and with the Type which needs to be wrapped: And annotate this with `ProxyInterfaceGenerator.Proxy[...]` and with the Type which needs to be wrapped:
``` c# ``` c#
@@ -44,6 +69,7 @@ public partial interface IPerson
``` ```
#### ProxyBaseClasses #### ProxyBaseClasses
In case also want to proxy the properties/methods/events from the base class(es), use this: In case also want to proxy the properties/methods/events from the base class(es), use this:
``` c# ``` c#
@@ -54,6 +80,7 @@ public partial interface IPerson
``` ```
#### ProxyClassAccessibility #### ProxyClassAccessibility
By default, the generated Proxy class is `public`. If you want to create the Proxy class as `internal`, use the following: By default, the generated Proxy class is `public`. If you want to create the Proxy class as `internal`, use the following:
``` c# ``` c#
@@ -66,7 +93,9 @@ public partial interface IPerson
### When the code is compiled, this source generator creates the following ### When the code is compiled, this source generator creates the following
#### :one: An additional partial interface #### :one: An additional partial interface
Which defines the same properties and methods as in the external class. Which defines the same properties and methods as in the external class.
``` c# ``` c#
public partial interface IPerson public partial interface IPerson
{ {
@@ -77,6 +106,7 @@ public partial interface IPerson
``` ```
#### :two: A Proxy class #### :two: A Proxy class
Which takes the external class in the constructor and wraps all public properties, events and methods. Which takes the external class in the constructor and wraps all public properties, events and methods.
``` c# ``` c#
@@ -104,6 +134,7 @@ public class PersonProxy : IPerson
:star: By default the accessibility from the generated Proxy class is `public`. :star: By default the accessibility from the generated Proxy class is `public`.
### :three: Use it ### :three: Use it
``` c# ``` c#
IPerson p = new PersonProxy(new Person()); IPerson p = new PersonProxy(new Person());
p.Name = "test"; p.Name = "test";
@@ -111,4 +142,5 @@ p.HelloWorld("stef");
``` ```
# References # References
- https://route2roslyn.netlify.app/symbols-for-dummies/
- <https://route2roslyn.netlify.app/symbols-for-dummies/>
-9
View File
@@ -29,8 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceSourceGenerat
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceConsumerForPnP", "src-examples\ProxyInterfaceConsumerForPnP\ProxyInterfaceConsumerForPnP.csproj", "{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceConsumerForPnP", "src-examples\ProxyInterfaceConsumerForPnP\ProxyInterfaceConsumerForPnP.csproj", "{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceConsumerForAkka", "src-examples\ProxyInterfaceConsumerForAkka\ProxyInterfaceConsumerForAkka.csproj", "{590908DF-A813-467A-94E4-3500020D0D54}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceConsumerViaNuGet", "src-examples\ProxyInterfaceConsumerViaNuGet\ProxyInterfaceConsumerViaNuGet.csproj", "{1EA000E4-6103-4577-8D98-BDDA3BE458A2}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceConsumerViaNuGet", "src-examples\ProxyInterfaceConsumerViaNuGet\ProxyInterfaceConsumerViaNuGet.csproj", "{1EA000E4-6103-4577-8D98-BDDA3BE458A2}"
EndProject EndProject
Global Global
@@ -63,12 +61,6 @@ Global
{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}.DebugAttach|Any CPU.Build.0 = Debug|Any CPU {5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}.DebugAttach|Any CPU.Build.0 = Debug|Any CPU
{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}.Release|Any CPU.ActiveCfg = Release|Any CPU {5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}.Release|Any CPU.Build.0 = Release|Any CPU {5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}.Release|Any CPU.Build.0 = Release|Any CPU
{590908DF-A813-467A-94E4-3500020D0D54}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{590908DF-A813-467A-94E4-3500020D0D54}.Debug|Any CPU.Build.0 = Debug|Any CPU
{590908DF-A813-467A-94E4-3500020D0D54}.DebugAttach|Any CPU.ActiveCfg = Debug|Any CPU
{590908DF-A813-467A-94E4-3500020D0D54}.DebugAttach|Any CPU.Build.0 = Debug|Any CPU
{590908DF-A813-467A-94E4-3500020D0D54}.Release|Any CPU.ActiveCfg = Release|Any CPU
{590908DF-A813-467A-94E4-3500020D0D54}.Release|Any CPU.Build.0 = Release|Any CPU
{1EA000E4-6103-4577-8D98-BDDA3BE458A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1EA000E4-6103-4577-8D98-BDDA3BE458A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1EA000E4-6103-4577-8D98-BDDA3BE458A2}.Debug|Any CPU.Build.0 = Debug|Any CPU {1EA000E4-6103-4577-8D98-BDDA3BE458A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EA000E4-6103-4577-8D98-BDDA3BE458A2}.DebugAttach|Any CPU.ActiveCfg = Debug|Any CPU {1EA000E4-6103-4577-8D98-BDDA3BE458A2}.DebugAttach|Any CPU.ActiveCfg = Debug|Any CPU
@@ -84,7 +76,6 @@ Global
{7E0A10EE-CCC3-4281-9541-B0AF037D3DF9} = {38BA087F-EDA1-4F8A-A140-85B84791B815} {7E0A10EE-CCC3-4281-9541-B0AF037D3DF9} = {38BA087F-EDA1-4F8A-A140-85B84791B815}
{1BDB9046-D6D1-4FB4-AAB5-F24E33EEAE0A} = {19009F5B-3267-45E2-A8B6-89F2AB47D72C} {1BDB9046-D6D1-4FB4-AAB5-F24E33EEAE0A} = {19009F5B-3267-45E2-A8B6-89F2AB47D72C}
{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C} = {38BA087F-EDA1-4F8A-A140-85B84791B815} {5F7DA2C5-B908-4B57-9F5F-BADF1216D89C} = {38BA087F-EDA1-4F8A-A140-85B84791B815}
{590908DF-A813-467A-94E4-3500020D0D54} = {38BA087F-EDA1-4F8A-A140-85B84791B815}
{1EA000E4-6103-4577-8D98-BDDA3BE458A2} = {38BA087F-EDA1-4F8A-A140-85B84791B815} {1EA000E4-6103-4577-8D98-BDDA3BE458A2} = {38BA087F-EDA1-4F8A-A140-85B84791B815}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
@@ -1,8 +1,9 @@
using System.Net.Http; using System.Net.Http;
using Speckle.ProxyGenerator;
namespace ProxyInterfaceConsumer.Http; namespace ProxyInterfaceConsumer.Http;
[Speckle.ProxyGenerator.Proxy(typeof(HttpClient), true)] [Speckle.ProxyGenerator.Proxy(typeof(HttpClient), ImplementationOptions.ProxyBaseClasses)]
public partial interface IHttpClient : IHttpMessageInvoker { } public partial interface IHttpClient : IHttpMessageInvoker { }
[Speckle.ProxyGenerator.Proxy(typeof(HttpMessageInvoker))] [Speckle.ProxyGenerator.Proxy(typeof(HttpMessageInvoker))]
@@ -2,7 +2,7 @@ using Speckle.ProxyGenerator;
namespace ProxyInterfaceConsumer namespace ProxyInterfaceConsumer
{ {
[Proxy(typeof(Address), false, ProxyClassAccessibility.Public, new[] { "Weird" })] [Proxy(typeof(Address), ImplementationOptions.ProxyBaseClasses, ProxyClassAccessibility.Public, new[] { "Weird" })]
public partial interface IAddress public partial interface IAddress
{ {
public void Weird() public void Weird()
@@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -12,7 +13,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3"> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
@@ -1,7 +0,0 @@
using Akka.Remote;
// namespace ProxyInterfaceConsumerForAkka.Interfaces; <-- no namespace
[Speckle.ProxyGenerator.Proxy(typeof(AddressUid))]
// ReSharper disable once CheckNamespace
public partial interface IAddressUid { }
@@ -1,7 +0,0 @@
using Akka.Actor;
namespace ProxyInterfaceConsumerForAkka.Interfaces
{
[Speckle.ProxyGenerator.Proxy(typeof(LocalActorRefProvider))]
public partial interface ILocalActorRefProvider { }
}
@@ -1,18 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using Akka.Actor;
using ProxyInterfaceConsumerForAkka.Interfaces;
namespace ProxyInterfaceConsumerForAkka;
public class Program
{
[SuppressMessage("ReSharper", "NullableWarningSuppressionIsUsed")]
public static void Main()
{
Akka.Remote.AddressUid auid = null!;
IAddressUid addressUidProxy = new AddressUidProxy(auid);
LocalActorRefProvider p = null!;
ILocalActorRefProvider proxy = new LocalActorRefProviderProxy(p);
}
}
@@ -1,30 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Akka.Remote" Version="1.4.47" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="3.10.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />
<PackageReference Include="TinyMapper" Version="3.0.3" />
</ItemGroup>
<ItemGroup>
<!--<PackageReference Include="ProxyInterfaceGenerator" Version="0.0.24">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>-->
<ProjectReference Include="..\..\src\Speckle.ProxyGenerator\Speckle.ProxyGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
</ItemGroup>
</Project>
@@ -7,7 +7,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<!--<PackageReference Include="AutoMapper" Version="10.1.1" />-->
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3"> <PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
@@ -10,7 +10,6 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="ProxyInterfaceGenerator" Version="0.1.0"> <PackageReference Include="ProxyInterfaceGenerator" Version="0.1.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
@@ -48,7 +48,8 @@ internal static class NamedTypeSymbolExtensions
public static List<INamedTypeSymbol> ResolveImplementedInterfaces( public static List<INamedTypeSymbol> ResolveImplementedInterfaces(
this INamedTypeSymbol symbol, this INamedTypeSymbol symbol,
bool proxyBaseClasses bool proxyBaseClasses,
bool proxyInterfaces
) )
{ {
// Members implemented by us or base classes should go here. // Members implemented by us or base classes should go here.
@@ -58,7 +59,11 @@ internal static class NamedTypeSymbolExtensions
.ToList(); .ToList();
// Direct interfaces, recursive interfaces or base class interfaces should go here. // Direct interfaces, recursive interfaces or base class interfaces should go here.
var interfaces = new List<INamedTypeSymbol>(symbol.Interfaces); var interfaces = new List<INamedTypeSymbol>();
if (proxyInterfaces)
{
interfaces.AddRange(symbol.Interfaces);
}
var baseType = symbol.BaseType; var baseType = symbol.BaseType;
while ( while (
proxyBaseClasses proxyBaseClasses
@@ -69,7 +74,10 @@ internal static class NamedTypeSymbolExtensions
publicMembers.AddRange( publicMembers.AddRange(
baseType.GetMembers().Where(m => m.DeclaredAccessibility == Accessibility.Public) baseType.GetMembers().Where(m => m.DeclaredAccessibility == Accessibility.Public)
); );
interfaces.AddRange(baseType.Interfaces); if (proxyInterfaces)
{
interfaces.AddRange(baseType.Interfaces);
}
baseType = baseType.BaseType; baseType = baseType.BaseType;
} }
@@ -100,4 +108,13 @@ internal static class NamedTypeSymbolExtensions
return realizedInterfaces; return realizedInterfaces;
} }
public static IEnumerable<INamedTypeSymbol> ResolveBaseInterfaces(
this INamedTypeSymbol symbol, List<INamedTypeSymbol> previousInterfaces
)
{
// Direct interfaces, recursive interfaces or base class interfaces should go here.
var interfaces = new List<INamedTypeSymbol>(symbol.Interfaces);
return interfaces.Except(previousInterfaces);
}
} }
@@ -11,6 +11,7 @@ namespace Speckle.ProxyGenerator.FileGenerators;
internal abstract class BaseGenerator internal abstract class BaseGenerator
{ {
protected const string globalPrefix = "global::";
protected readonly Context Context; protected readonly Context Context;
protected readonly bool SupportsNullable; protected readonly bool SupportsNullable;
@@ -35,6 +36,11 @@ internal abstract class BaseGenerator
[NotNullWhen(true)] out ProxyData? proxyData [NotNullWhen(true)] out ProxyData? proxyData
) )
{ {
proxyData = Context.Candidates.Values.FirstOrDefault(x => x.FullQualifiedMappedTypeName == type);
if (proxyData is not null)
{
return true;
}
proxyData = Context.Candidates.Values.FirstOrDefault(x => x.FullQualifiedTypeName == type); proxyData = Context.Candidates.Values.FirstOrDefault(x => x.FullQualifiedTypeName == type);
return proxyData != null; return proxyData != null;
} }
@@ -214,7 +220,6 @@ internal abstract class BaseGenerator
) )
{ {
classSymbol = default; classSymbol = default;
const string globalPrefix = "global::";
if (name.StartsWith(globalPrefix, StringComparison.Ordinal)) if (name.StartsWith(globalPrefix, StringComparison.Ordinal))
{ {
name = name.Substring(globalPrefix.Length); name = name.Substring(globalPrefix.Length);
@@ -283,8 +288,7 @@ internal abstract class BaseGenerator
} }
protected IReadOnlyList<ProxyData> GetExtendsProxyData( protected IReadOnlyList<ProxyData> GetExtendsProxyData(
ProxyData proxyData, ClassSymbol targetClassSymbol, bool useFullQualifiedMappedTypeName
ClassSymbol targetClassSymbol
) )
{ {
var extendsProxyClasses = new List<ProxyData>(); var extendsProxyClasses = new List<ProxyData>();
@@ -293,10 +297,22 @@ internal abstract class BaseGenerator
var candidate = Context.Candidates.Values.FirstOrDefault(ci => var candidate = Context.Candidates.Values.FirstOrDefault(ci =>
ci.FullQualifiedTypeName == baseType.ToFullyQualifiedDisplayString() ci.FullQualifiedTypeName == baseType.ToFullyQualifiedDisplayString()
); );
if (candidate is not null) if (useFullQualifiedMappedTypeName)
{ {
extendsProxyClasses.Add(candidate); //is a candidate and overrides
break; if (candidate?.FullQualifiedMappedTypeName != null)
{
extendsProxyClasses.Add(candidate);
break;
}
}
else
{
if (candidate != null)
{
extendsProxyClasses.Add(candidate);
break;
}
} }
} }
return extendsProxyClasses; return extendsProxyClasses;
@@ -29,34 +29,38 @@ namespace Speckle.ProxyGenerator
internal sealed class ProxyAttribute : Attribute internal sealed class ProxyAttribute : Attribute
{{ {{
public Type Type {{ get; }} public Type Type {{ get; }}
public bool ProxyBaseClasses {{ get; }} public ImplementationOptions Options {{ get; }}
public ProxyClassAccessibility Accessibility {{ get; }} public ProxyClassAccessibility Accessibility {{ get; }}
public string[]? MembersToIgnore {{ get; }} public string[]? MembersToIgnore {{ get; }}
public ProxyAttribute(Type type) : this(type, false, ProxyClassAccessibility.Public) public ProxyAttribute(Type type) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public)
{{ {{
}} }}
public ProxyAttribute(Type type, bool proxyBaseClasses) : this(type, proxyBaseClasses, ProxyClassAccessibility.Public) public ProxyAttribute(Type type, ImplementationOptions options) : this(type, options, ProxyClassAccessibility.Public)
{{ {{
}} }}
public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, false, accessibility) public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, ImplementationOptions.None, accessibility)
{{ {{
}} }}
public ProxyAttribute(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility) : this(type, proxyBaseClasses, accessibility, null) public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility) : this(type, options, accessibility, null)
{{ {{
}} }}
public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, false, ProxyClassAccessibility.Public, null) public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public, null)
{{ {{
}} }}
public ProxyAttribute(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility, string[]? membersToIgnore) public ProxyAttribute(Type type, ImplementationOptions options, string[]? membersToIgnore) : this(type, options, ProxyClassAccessibility.Public, null)
{{
}}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility, string[]? membersToIgnore)
{{ {{
Type = type; Type = type;
ProxyBaseClasses = proxyBaseClasses; Options = options;
Accessibility = accessibility; Accessibility = accessibility;
MembersToIgnore = membersToIgnore; MembersToIgnore = membersToIgnore;
}} }}
@@ -69,6 +73,19 @@ namespace Speckle.ProxyGenerator
Internal = 1 Internal = 1
}} }}
[Flags]
internal enum ImplementationOptions
{{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}}
{supportsNullable.IIf("#nullable restore")} {supportsNullable.IIf("#nullable restore")}
}}" }}"
); );
@@ -5,14 +5,14 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
using Speckle.ProxyGenerator.Enums; using Speckle.ProxyGenerator.Enums;
using Speckle.ProxyGenerator.Extensions; using Speckle.ProxyGenerator.Extensions;
using Speckle.ProxyGenerator.Models; using Speckle.ProxyGenerator.Models;
using Speckle.ProxyGenerator.Types;
using Speckle.ProxyGenerator.Utils; using Speckle.ProxyGenerator.Utils;
namespace Speckle.ProxyGenerator.FileGenerators; namespace Speckle.ProxyGenerator.FileGenerators;
internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
{ {
private IReadOnlyCollection<INamedTypeSymbol> _implementedInterfaces = private List<INamedTypeSymbol> _implementedInterfaces = new();
new List<INamedTypeSymbol>();
public PartialInterfacesGenerator(Context context, bool supportsNullable) public PartialInterfacesGenerator(Context context, bool supportsNullable)
: base(context, supportsNullable) { } : base(context, supportsNullable) { }
@@ -67,7 +67,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
fileData = new FileData( fileData = new FileData(
$"{sourceInterfaceSymbol.Symbol.GetFullMetadataName()}.g.cs", $"{sourceInterfaceSymbol.Symbol.GetFullMetadataName()}.g.cs",
CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, interfaceName, pd) CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, sourceInterfaceSymbol,interfaceName, pd)
); );
return true; return true;
@@ -76,21 +76,41 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
private string CreatePartialInterfaceCode( private string CreatePartialInterfaceCode(
string ns, string ns,
ClassSymbol classSymbol, ClassSymbol classSymbol,
ClassSymbol interfaceSymbol,
string interfaceName, string interfaceName,
ProxyData proxyData ProxyData proxyData
) )
{ {
var extendsProxyClasses = GetExtendsProxyData(proxyData, classSymbol); _implementedInterfaces.Clear();
_implementedInterfaces = classSymbol.Symbol.ResolveImplementedInterfaces( _implementedInterfaces.AddRange(classSymbol.Symbol.ResolveImplementedInterfaces(
proxyData.ProxyBaseClasses proxyData.Options.HasFlag(ImplementationOptions.ProxyBaseClasses),
); proxyData.Options.HasFlag(ImplementationOptions.ProxyInterfaces)
));
if (proxyData.Options.HasFlag(ImplementationOptions.UseExtendedInterfaces))
{
var bases = interfaceSymbol.Symbol.ResolveBaseInterfaces(_implementedInterfaces).ToList();
if (bases.Count == 1 && proxyData.Options.HasFlag(ImplementationOptions.ProxyForBaseInterface))
{
proxyData.FullQualifiedMappedTypeName = globalPrefix + bases.Single().GetFullMetadataName();
}
_implementedInterfaces.AddRange(bases);
//don't readd self
if (_implementedInterfaces.Contains(interfaceSymbol.Symbol))
{
_implementedInterfaces.Remove(interfaceSymbol.Symbol);
}
}
_implementedInterfaces = _implementedInterfaces.Distinct().ToList();
var isNew = GetExtendsProxyData(classSymbol, proxyData.Options.HasFlag(ImplementationOptions.UseExtendedInterfaces)).Any();
var implementedInterfacesNames = _implementedInterfaces var implementedInterfacesNames = _implementedInterfaces
.Select(i => i.ToFullyQualifiedDisplayString()) .Select(i => i.ToFullyQualifiedDisplayString())
.ToArray(); .ToArray();
var implements = implementedInterfacesNames.Any() var implements = implementedInterfacesNames.Any()
? $" : {string.Join(", ", implementedInterfacesNames)}" ? $" : {string.Join(", ", implementedInterfacesNames)}"
: string.Empty; : string.Empty;
var @new = extendsProxyClasses.Any() ? "new " : string.Empty; var @new = isNew ? "new " : string.Empty;
var (namespaceStart, namespaceEnd) = NamespaceBuilder.Build(ns); var (namespaceStart, namespaceEnd) = NamespaceBuilder.Build(ns);
var events = GenerateEvents(classSymbol, proxyData); var events = GenerateEvents(classSymbol, proxyData);
var properties = GenerateProperties(classSymbol, proxyData); var properties = GenerateProperties(classSymbol, proxyData);
@@ -98,7 +118,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
return $@"//---------------------------------------------------------------------------------------- return $@"//----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,42 +0,0 @@
using System.Text;
using Speckle.ProxyGenerator.Extensions;
namespace Speckle.ProxyGenerator.FileGenerators;
internal partial class ProxyClassesGenerator
{
private static string GeneratePrivateAutoMapper()
{
return " private readonly IMapper _mapper;";
}
private string GenerateMapperConfigurationForAutoMapper()
{
var str = new StringBuilder();
str.AppendLine(" _mapper = new MapperConfiguration(cfg =>");
str.AppendLine(" {");
foreach (var replacedType in Context.ReplacedTypes)
{
TryFindProxyDataByTypeName(replacedType.Key, out var fullTypeName);
var classNameProxy =
$"{fullTypeName!.NamespaceDot}{fullTypeName.ShortMetadataName}Proxy";
var instance =
$"instance{(replacedType.Key + replacedType.Value).GetDeterministicHashCodeAsString()}";
var proxy =
$"proxy{(replacedType.Value + replacedType.Key).GetDeterministicHashCodeAsString()}";
str.AppendLine(
$" cfg.CreateMap<{replacedType.Key}, {replacedType.Value}>().ConstructUsing({instance} => new {classNameProxy}({instance}));"
);
str.AppendLine(
$" cfg.CreateMap<{replacedType.Value}, {replacedType.Key}>().ConstructUsing({proxy} => (({classNameProxy}) {proxy})._Instance);"
);
str.AppendLine();
}
str.AppendLine(" }).CreateMapper();");
return str.ToString();
}
}
@@ -54,7 +54,7 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
var className = targetClassSymbol.Symbol.ResolveProxyClassName(); var className = targetClassSymbol.Symbol.ResolveProxyClassName();
var constructorName = $"{targetClassSymbol.Symbol.Name}Proxy"; var constructorName = $"{targetClassSymbol.Symbol.Name}Proxy";
var extendsProxyClasses = GetExtendsProxyData(pd, targetClassSymbol); var extendsProxyClasses = GetExtendsProxyData(targetClassSymbol, false);
fileData = new FileData( fileData = new FileData(
$"{targetClassSymbol.Symbol.GetFullMetadataName()}Proxy.g.cs", $"{targetClassSymbol.Symbol.GetFullMetadataName()}Proxy.g.cs",
@@ -117,7 +117,7 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
return $@"//---------------------------------------------------------------------------------------- return $@"//----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -10,18 +10,20 @@ internal class ProxyData
public string ShortInterfaceName { get; } public string ShortInterfaceName { get; }
public string FullInterfaceName { get; } private string _fullInterfaceName;
public string FullInterfaceName => FullQualifiedMappedTypeName ?? _fullInterfaceName;
public string FullQualifiedTypeName { get; } public string FullQualifiedTypeName { get; }
public string? FullQualifiedMappedTypeName { get; set; }
public string ShortMetadataName { get; } public string ShortMetadataName { get; }
public string FullMetadataTypeName { get; } public string FullMetadataTypeName { get; }
public List<string> Usings { get; } public List<string> Usings { get; }
public bool ProxyBaseClasses { get; } public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { get; } public ProxyClassAccessibility Accessibility { get; }
public string[] MembersToIgnore { get; } public string[] MembersToIgnore { get; }
@@ -34,7 +36,7 @@ internal class ProxyData
string shortMetadataTypeName, string shortMetadataTypeName,
string fullMetadataTypeName, string fullMetadataTypeName,
List<string> usings, List<string> usings,
bool proxyBaseClasses, ImplementationOptions options,
ProxyClassAccessibility accessibility, ProxyClassAccessibility accessibility,
string[] membersToIgnore string[] membersToIgnore
) )
@@ -43,7 +45,7 @@ internal class ProxyData
NamespaceDot = namespaceDot ?? throw new ArgumentNullException(nameof(namespaceDot)); NamespaceDot = namespaceDot ?? throw new ArgumentNullException(nameof(namespaceDot));
ShortInterfaceName = ShortInterfaceName =
shortInterfaceName ?? throw new ArgumentNullException(nameof(shortInterfaceName)); shortInterfaceName ?? throw new ArgumentNullException(nameof(shortInterfaceName));
FullInterfaceName = _fullInterfaceName =
fullInterfaceName ?? throw new ArgumentNullException(nameof(fullInterfaceName)); fullInterfaceName ?? throw new ArgumentNullException(nameof(fullInterfaceName));
FullQualifiedTypeName = FullQualifiedTypeName =
fullQualifiedTypeName ?? throw new ArgumentNullException(nameof(fullQualifiedTypeName)); fullQualifiedTypeName ?? throw new ArgumentNullException(nameof(fullQualifiedTypeName));
@@ -52,7 +54,7 @@ internal class ProxyData
FullMetadataTypeName = FullMetadataTypeName =
fullMetadataTypeName ?? throw new ArgumentNullException(nameof(fullMetadataTypeName)); fullMetadataTypeName ?? throw new ArgumentNullException(nameof(fullMetadataTypeName));
Usings = usings ?? throw new ArgumentNullException(nameof(usings)); Usings = usings ?? throw new ArgumentNullException(nameof(usings));
ProxyBaseClasses = proxyBaseClasses; Options = options;
Accessibility = accessibility; Accessibility = accessibility;
MembersToIgnore = membersToIgnore; MembersToIgnore = membersToIgnore;
} }
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Version>0.1.2</Version> <Version>0.1.5</Version>
<TargetFramework>netstandard2.0</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>Latest</LangVersion> <LangVersion>Latest</LangVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
@@ -48,34 +48,20 @@ internal static class AttributeArgumentListParser
result = result with { MembersToIgnore = membersToIgnore }; result = result with { MembersToIgnore = membersToIgnore };
continue; continue;
} }
if (TryParseAsBoolean(argument.Expression, out var proxyBaseClasses))
{
result = result with { ProxyBaseClasses = proxyBaseClasses };
continue;
}
if (TryParseAsEnum<ProxyClassAccessibility>(argument.Expression, out var accessibility)) if (TryParseAsEnum<ProxyClassAccessibility>(argument.Expression, out var accessibility))
{ {
result = result with { Accessibility = accessibility }; result = result with { Accessibility = accessibility };
} }
if (TryParseAsEnum<ImplementationOptions>(argument.Expression, out var options))
{
result = result with { Options = options };
}
} }
return result; return result;
} }
private static bool TryParseAsBoolean(ExpressionSyntax expressionSyntax, out bool value)
{
value = default;
if (expressionSyntax is LiteralExpressionSyntax literalExpressionSyntax)
{
value = literalExpressionSyntax.Kind() == SyntaxKind.TrueLiteralExpression;
return true;
}
return false;
}
private static bool TryParseAsType( private static bool TryParseAsType(
ExpressionSyntax expressionSyntax, ExpressionSyntax expressionSyntax,
SemanticModel semanticModel, SemanticModel semanticModel,
@@ -100,22 +86,27 @@ internal static class AttributeArgumentListParser
} }
private static bool TryParseAsEnum<TEnum>(ExpressionSyntax expressionSyntax, out TEnum value) private static bool TryParseAsEnum<TEnum>(ExpressionSyntax expressionSyntax, out TEnum value)
where TEnum : struct where TEnum : struct, Enum
{ {
var enumAsString = expressionSyntax.ToString(); var enumAsString = expressionSyntax.ToString();
if (
enumAsString.Length > typeof(TEnum).Name.Length
&& Enum.TryParse(
expressionSyntax.ToString().Substring(typeof(TEnum).Name.Length + 1),
out value
)
)
{
return true;
}
value = default; value = default;
return false; if (!enumAsString.Contains(typeof(TEnum).Name))
{
return false;
}
var splitter = new[] {$"{typeof(TEnum).Name}."};
var vals = enumAsString.Split(splitter, StringSplitOptions.RemoveEmptyEntries).Select(x => x.TrimEnd(' ', '|'));
long l = 0;
foreach (var v in vals)
{
if (Enum.TryParse<TEnum>(v, out var e))
{
l |= Convert.ToInt64(e);
}
}
value = (TEnum)Enum.ToObject(typeof(TEnum), l);;
return true;
} }
private static bool TryParseAsStringArray(ExpressionSyntax expressionSyntax, out string[] value) private static bool TryParseAsStringArray(ExpressionSyntax expressionSyntax, out string[] value)
@@ -99,7 +99,7 @@ internal class ProxySyntaxReceiver : ISyntaxContextReceiver
fullMetadataTypeName: metadataName, fullMetadataTypeName: metadataName,
shortMetadataTypeName: metadataName.Split('.').Last(), shortMetadataTypeName: metadataName.Split('.').Last(),
usings: usings, usings: usings,
proxyBaseClasses: fluentBuilderAttributeArguments.ProxyBaseClasses, options: fluentBuilderAttributeArguments.Options,
accessibility: fluentBuilderAttributeArguments.Accessibility, accessibility: fluentBuilderAttributeArguments.Accessibility,
membersToIgnore: fluentBuilderAttributeArguments.MembersToIgnore membersToIgnore: fluentBuilderAttributeArguments.MembersToIgnore
); );
@@ -5,7 +5,7 @@ internal record ProxyInterfaceGeneratorAttributeArguments(
string MetadataName string MetadataName
) )
{ {
public bool ProxyBaseClasses { get; set; } public ImplementationOptions Options { get; set; }
public ProxyClassAccessibility Accessibility { get; set; } public ProxyClassAccessibility Accessibility { get; set; }
public string[] MembersToIgnore { get; set; } = []; public string[] MembersToIgnore { get; set; } = [];
@@ -7,3 +7,17 @@ internal enum ProxyClassAccessibility
Internal = 1 Internal = 1
} }
[Flags]
internal enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis;
using Speckle.ProxyGenerator.Models; using Speckle.ProxyGenerator.Models;
using Speckle.ProxyGenerator.Types;
namespace Speckle.ProxyGenerator.Utils; namespace Speckle.ProxyGenerator.Utils;
@@ -108,7 +109,7 @@ internal static class MemberHelper
var ownMembers = membersQuery.ToList(); var ownMembers = membersQuery.ToList();
var ownMemberNames = ownMembers.Select(x => x.Name); var ownMemberNames = ownMembers.Select(x => x.Name);
if (!proxyData.ProxyBaseClasses) if (!proxyData.Options.HasFlag(ImplementationOptions.ProxyBaseClasses))
{ {
return ownMembers; return ownMembers;
} }
@@ -35,7 +35,7 @@ public class AkkaTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(Akka.Actor.LocalActorRefProvider)" ArgumentList = new [] {"typeof(Akka.Actor.LocalActorRefProvider)","ImplementationOptions.ProxyInterfaces"}
} }
}; };
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source namespace ProxyInterfaceSourceGeneratorTests.Source
{ {
public partial interface IHttpMessageInvoker : global::System.IDisposable public partial interface IHttpMessageInvoker
{ {
global::System.Net.Http.HttpMessageInvoker _Instance { get; } global::System.Net.Http.HttpMessageInvoker _Instance { get; }
@@ -20,6 +20,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
global::System.Net.Http.HttpResponseMessage Send(global::System.Net.Http.HttpRequestMessage request, global::System.Threading.CancellationToken cancellationToken); global::System.Net.Http.HttpResponseMessage Send(global::System.Net.Http.HttpRequestMessage request, global::System.Threading.CancellationToken cancellationToken);
global::System.Threading.Tasks.Task<global::System.Net.Http.HttpResponseMessage> SendAsync(global::System.Net.Http.HttpRequestMessage request, global::System.Threading.CancellationToken cancellationToken); global::System.Threading.Tasks.Task<global::System.Net.Http.HttpResponseMessage> SendAsync(global::System.Net.Http.HttpRequestMessage request, global::System.Threading.CancellationToken cancellationToken);
void Dispose();
} }
} }
#nullable restore #nullable restore
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source.PnP namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
{ {
public partial interface IClientObject : global::Microsoft.SharePoint.Client.IFromJson public partial interface IClientObject
{ {
global::Microsoft.SharePoint.Client.ClientObject _Instance { get; } global::Microsoft.SharePoint.Client.ClientObject _Instance { get; }
@@ -31,6 +31,12 @@ namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
global::ProxyInterfaceSourceGeneratorTests.Source.PnP.IClientObject TypedObject { get; } global::ProxyInterfaceSourceGeneratorTests.Source.PnP.IClientObject TypedObject { get; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
void FromJson(global::Microsoft.SharePoint.Client.JsonReader reader);
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
bool CustomFromJson(global::Microsoft.SharePoint.Client.JsonReader reader);
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
void Retrieve(); void Retrieve();
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source.PnP namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
{ {
public partial interface IClientRuntimeContext : global::System.IDisposable public partial interface IClientRuntimeContext
{ {
global::Microsoft.SharePoint.Client.ClientRuntimeContext _Instance { get; } global::Microsoft.SharePoint.Client.ClientRuntimeContext _Instance { get; }
@@ -76,6 +76,8 @@ namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
global::System.Collections.Generic.IEnumerable<T> LoadQuery<T>(global::Microsoft.SharePoint.Client.ClientObjectCollection<T> clientObjects) where T : Microsoft.SharePoint.Client.ClientObject; global::System.Collections.Generic.IEnumerable<T> LoadQuery<T>(global::Microsoft.SharePoint.Client.ClientObjectCollection<T> clientObjects) where T : Microsoft.SharePoint.Client.ClientObject;
global::System.Collections.Generic.IEnumerable<T> LoadQuery<T>(global::System.Linq.IQueryable<T> clientObjects) where T : Microsoft.SharePoint.Client.ClientObject; global::System.Collections.Generic.IEnumerable<T> LoadQuery<T>(global::System.Linq.IQueryable<T> clientObjects) where T : Microsoft.SharePoint.Client.ClientObject;
void Dispose();
} }
} }
#nullable restore #nullable restore
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source.PnP namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
{ {
public partial interface ISecurableObject public partial interface ISecurableObject : global::ProxyInterfaceSourceGeneratorTests.Source.PnP.IClientObject
{ {
new global::Microsoft.SharePoint.Client.SecurableObject _Instance { get; } new global::Microsoft.SharePoint.Client.SecurableObject _Instance { get; }
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source.PnP namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
{ {
public partial interface IWeb public partial interface IWeb : global::ProxyInterfaceSourceGeneratorTests.Source.PnP.ISecurableObject
{ {
new global::Microsoft.SharePoint.Client.Web _Instance { get; } new global::Microsoft.SharePoint.Client.Web _Instance { get; }
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,6 +1,6 @@
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -1,14 +1,24 @@
using CSharp.SourceGenerators.Extensions; using CSharp.SourceGenerators.Extensions;
using CSharp.SourceGenerators.Extensions.Models; using CSharp.SourceGenerators.Extensions.Models;
using FluentAssertions; using FluentAssertions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax;
using ProxyInterfaceSourceGeneratorTests.Source.Disposable; using ProxyInterfaceSourceGeneratorTests.Source.Disposable;
using Speckle.ProxyGenerator; using Speckle.ProxyGenerator;
using Xunit.Abstractions;
namespace ProxyInterfaceSourceGeneratorTests; namespace ProxyInterfaceSourceGeneratorTests;
[Flags]
public enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
public class InheritedInterfaceTests public class InheritedInterfaceTests
{ {
private const string Namespace = "ProxyInterfaceSourceGeneratorTests.Source.Disposable"; private const string Namespace = "ProxyInterfaceSourceGeneratorTests.Source.Disposable";
@@ -25,10 +35,10 @@ public class InheritedInterfaceTests
} }
[Theory] [Theory]
[InlineData(false, false)] [InlineData(ImplementationOptions.None, false)]
[InlineData(true, true)] [InlineData(ImplementationOptions.ProxyBaseClasses | ImplementationOptions.ProxyInterfaces, true)]
public void GenerateFiles_InheritedInterface_InheritFromBaseClass( public void GenerateFiles_InheritedInterface_InheritFromBaseClass(
bool proxyBaseClass, ImplementationOptions options,
bool inheritBaseInterface bool inheritBaseInterface
) )
{ {
@@ -39,7 +49,7 @@ public class InheritedInterfaceTests
// Arrange // Arrange
string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"]; string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"];
var path = $"./Source/Disposable/{interfaceName}.cs"; var path = $"./Source/Disposable/{interfaceName}.cs";
SourceFile sourceFile = CreateSourceFile(path, name, proxyBaseClass); SourceFile sourceFile = CreateSourceFile(path, name,options);
// Act // Act
var result = _sut.Execute([sourceFile]); var result = _sut.Execute([sourceFile]);
@@ -72,7 +82,7 @@ public class InheritedInterfaceTests
string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"]; string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"];
var path = $"./Source/Disposable/{interfaceName}.cs"; var path = $"./Source/Disposable/{interfaceName}.cs";
SourceFile sourceFile = CreateSourceFile(path, name, true); SourceFile sourceFile = CreateSourceFile(path, name, ImplementationOptions.ProxyInterfaces | ImplementationOptions.ProxyBaseClasses | ImplementationOptions.UseExtendedInterfaces);
// Act // Act
var result = _sut.Execute([sourceFile]); var result = _sut.Execute([sourceFile]);
@@ -88,9 +98,9 @@ public class InheritedInterfaceTests
// Assert // Assert
Assert.Single(interfaceDeclarations); Assert.Single(interfaceDeclarations);
var baseList = interfaceDeclarations.First().BaseList!; var baseList = interfaceDeclarations.First().BaseList;
Assert.Equal(2, baseList.Types.Count); Assert.Equal(2, baseList?.Types.Count);
var type1 = (QualifiedNameSyntax)baseList.Types[0].Type; var type1 = (QualifiedNameSyntax)baseList!.Types[0].Type;
var type2 = (QualifiedNameSyntax)baseList.Types[1].Type; var type2 = (QualifiedNameSyntax)baseList.Types[1].Type;
Assert.Equal(nameof(IDisposable), type1.Right.Identifier.Text); Assert.Equal(nameof(IDisposable), type1.Right.Identifier.Text);
Assert.Equal(nameof(IUpdate<string>), type2.Right.Identifier.Text); Assert.Equal(nameof(IUpdate<string>), type2.Right.Identifier.Text);
@@ -107,7 +117,7 @@ public class InheritedInterfaceTests
string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"]; string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"];
var interfaceIndex = 1; var interfaceIndex = 1;
var path = $"./Source/Disposable/{interfaceName}.cs"; var path = $"./Source/Disposable/{interfaceName}.cs";
SourceFile sourceFile = CreateSourceFile(path, name, true); SourceFile sourceFile = CreateSourceFile(path, name, ImplementationOptions.UseExtendedInterfaces);
// Act // Act
var result = _sut.Execute([sourceFile]); var result = _sut.Execute([sourceFile]);
@@ -130,9 +140,26 @@ public class InheritedInterfaceTests
Assert.True(noInterfaceImplementationFound); Assert.True(noInterfaceImplementationFound);
} }
private static SourceFile CreateSourceFile(string path, string name, bool extend) private static SourceFile CreateSourceFile(string path, string name, ImplementationOptions options)
{ {
var extendString = extend.ToString().ToLowerInvariant(); var o = string.Empty;
foreach (var val in Enum.GetValues<ImplementationOptions>())
{
if (!options.HasFlag(val))
{
continue;
}
if (o.Length > 0)
{
o += " | ";
}
o += "ImplementationOptions." + val.ToString();
}
if (o.Length == 0)
{
o = "ImplementationOptions.None";
}
return new SourceFile return new SourceFile
{ {
Path = path, Path = path,
@@ -140,7 +167,7 @@ public class InheritedInterfaceTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = $"typeof({Namespace}.{name}), {extendString}" ArgumentList = $"typeof({Namespace}.{name}), {o}"
} }
}; };
} }
@@ -45,7 +45,7 @@ public class PnPTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(Microsoft.SharePoint.Client.ClientObject)" ArgumentList = new [] { "typeof(Microsoft.SharePoint.Client.ClientObject)", "ImplementationOptions.UseExtendedInterfaces"}
} }
}; };
@@ -57,7 +57,7 @@ public class PnPTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(SecurableObject)" // Only name, no namespace ArgumentList =new [] { "typeof(SecurableObject)" , "ImplementationOptions.UseExtendedInterfaces"}// Only name, no namespace
} }
}; };
@@ -69,7 +69,7 @@ public class PnPTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(Web)" // Only name, no namespace ArgumentList = new [] { "typeof(Web)", "ImplementationOptions.UseExtendedInterfaces"} // Only name, no namespace
} }
}; };
@@ -81,7 +81,7 @@ public class PnPTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(Microsoft.SharePoint.Client.ClientRuntimeContext)" ArgumentList = new [] { "typeof(Microsoft.SharePoint.Client.ClientRuntimeContext)", "ImplementationOptions.UseExtendedInterfaces"}
} }
}; };
@@ -93,7 +93,7 @@ public class PnPTests
AttributeToAddToInterface = new ExtraAttribute AttributeToAddToInterface = new ExtraAttribute
{ {
Name = "Speckle.ProxyGenerator.Proxy", Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(ClientContext)" // Only name, no namespace ArgumentList =new [] { "typeof(Microsoft.SharePoint.Client.ClientContext)", "ImplementationOptions.UseExtendedInterfaces"} // Only name, no namespace
} }
}; };
@@ -11,6 +11,7 @@
// </auto-generated> // </auto-generated>
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
#nullable enable
using System; using System;
namespace Speckle.ProxyGenerator namespace Speckle.ProxyGenerator
@@ -19,34 +20,38 @@ namespace Speckle.ProxyGenerator
internal sealed class ProxyAttribute : Attribute internal sealed class ProxyAttribute : Attribute
{ {
public Type Type { get; } public Type Type { get; }
public bool ProxyBaseClasses { get; } public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { get; } public ProxyClassAccessibility Accessibility { get; }
public string[]? MembersToIgnore { get; } public string[]? MembersToIgnore { get; }
public ProxyAttribute(Type type) : this(type, false, ProxyClassAccessibility.Public) public ProxyAttribute(Type type) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public)
{ {
} }
public ProxyAttribute(Type type, bool proxyBaseClasses) : this(type, proxyBaseClasses, ProxyClassAccessibility.Public) public ProxyAttribute(Type type, ImplementationOptions options) : this(type, options, ProxyClassAccessibility.Public)
{ {
} }
public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, false, accessibility) public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, ImplementationOptions.None, accessibility)
{ {
} }
public ProxyAttribute(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility) : this(type, proxyBaseClasses, accessibility, null) public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility) : this(type, options, accessibility, null)
{ {
} }
public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, false, ProxyClassAccessibility.Public, null) public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public, null)
{ {
} }
public ProxyAttribute(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility, string[]? membersToIgnore) public ProxyAttribute(Type type, ImplementationOptions options, string[]? membersToIgnore) : this(type, options, ProxyClassAccessibility.Public, null)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility, string[]? membersToIgnore)
{ {
Type = type; Type = type;
ProxyBaseClasses = proxyBaseClasses; Options = options;
Accessibility = accessibility; Accessibility = accessibility;
MembersToIgnore = membersToIgnore; MembersToIgnore = membersToIgnore;
} }
@@ -59,6 +64,20 @@ namespace Speckle.ProxyGenerator
Internal = 1 Internal = 1
} }
[Flags]
internal enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
#nullable restore
} }
}, },
{ {
@@ -66,7 +85,7 @@ namespace Speckle.ProxyGenerator
Source: Source:
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -94,7 +113,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
Source: Source:
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -11,6 +11,7 @@
// </auto-generated> // </auto-generated>
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
#nullable enable
using System; using System;
namespace Speckle.ProxyGenerator namespace Speckle.ProxyGenerator
@@ -19,34 +20,38 @@ namespace Speckle.ProxyGenerator
internal sealed class ProxyAttribute : Attribute internal sealed class ProxyAttribute : Attribute
{ {
public Type Type { get; } public Type Type { get; }
public bool ProxyBaseClasses { get; } public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { get; } public ProxyClassAccessibility Accessibility { get; }
public string[]? MembersToIgnore { get; } public string[]? MembersToIgnore { get; }
public ProxyAttribute(Type type) : this(type, false, ProxyClassAccessibility.Public) public ProxyAttribute(Type type) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public)
{ {
} }
public ProxyAttribute(Type type, bool proxyBaseClasses) : this(type, proxyBaseClasses, ProxyClassAccessibility.Public) public ProxyAttribute(Type type, ImplementationOptions options) : this(type, options, ProxyClassAccessibility.Public)
{ {
} }
public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, false, accessibility) public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, ImplementationOptions.None, accessibility)
{ {
} }
public ProxyAttribute(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility) : this(type, proxyBaseClasses, accessibility, null) public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility) : this(type, options, accessibility, null)
{ {
} }
public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, false, ProxyClassAccessibility.Public, null) public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public, null)
{ {
} }
public ProxyAttribute(Type type, bool proxyBaseClasses, ProxyClassAccessibility accessibility, string[]? membersToIgnore) public ProxyAttribute(Type type, ImplementationOptions options, string[]? membersToIgnore) : this(type, options, ProxyClassAccessibility.Public, null)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility, string[]? membersToIgnore)
{ {
Type = type; Type = type;
ProxyBaseClasses = proxyBaseClasses; Options = options;
Accessibility = accessibility; Accessibility = accessibility;
MembersToIgnore = membersToIgnore; MembersToIgnore = membersToIgnore;
} }
@@ -59,6 +64,20 @@ namespace Speckle.ProxyGenerator
Internal = 1 Internal = 1
} }
[Flags]
internal enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
#nullable restore
} }
}, },
{ {
@@ -66,7 +85,7 @@ namespace Speckle.ProxyGenerator
Source: Source:
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -96,7 +115,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
Source: Source:
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // This code was generated by https://github.com/specklesystems/ProxyGenerator.
// //
// Changes to this file may cause incorrect behavior and will be lost if // Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated. // the code is regenerated.
@@ -0,0 +1,165 @@
[
{
HintName: Speckle.ProxyGenerator.Extra.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace Speckle.ProxyGenerator
{
[AttributeUsage(AttributeTargets.Interface)]
internal sealed class ProxyAttribute : Attribute
{
public Type Type { get; }
public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { get; }
public string[]? MembersToIgnore { get; }
public ProxyAttribute(Type type) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public)
{
}
public ProxyAttribute(Type type, ImplementationOptions options) : this(type, options, ProxyClassAccessibility.Public)
{
}
public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, ImplementationOptions.None, accessibility)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility) : this(type, options, accessibility, null)
{
}
public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public, null)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, string[]? membersToIgnore) : this(type, options, ProxyClassAccessibility.Public, null)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility, string[]? membersToIgnore)
{
Type = type;
Options = options;
Accessibility = accessibility;
MembersToIgnore = membersToIgnore;
}
}
[Flags]
internal enum ProxyClassAccessibility
{
Public = 0,
Internal = 1
}
[Flags]
internal enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
#nullable restore
}
},
{
HintName: ProxyInterfaceSourceGeneratorTests.Source.IFoo2.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial interface IFoo2 : global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2Base
{
global::ProxyInterfaceSourceGeneratorTests.Source.Foo2 _Instance { get; }
global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2[] Foos { get; set; }
int Weird { get; set; }
global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2[] DoSomethingAndGetAnArrayOfFoos();
}
}
#nullable restore
},
{
HintName: ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial class Foo2Proxy : global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2
{
public global::ProxyInterfaceSourceGeneratorTests.Source.Foo2 _Instance { get; }
public global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2[] Foos { get => Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2[]>(_Instance.Foos); set => _Instance.Foos = Mapster.TypeAdapter.Adapt<ProxyInterfaceSourceGeneratorTests.Source.Foo2[]>(value); }
public int Weird { get => _Instance.Weird; set => _Instance.Weird = value; }
public global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2[] DoSomethingAndGetAnArrayOfFoos()
{
var result_1603865878 = _Instance.DoSomethingAndGetAnArrayOfFoos();
return Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2[]>(result_1603865878);
}
public int Weird2()
{
var result__1602200929 = _Instance.Weird2();
return result__1602200929;
}
public Foo2Proxy(global::ProxyInterfaceSourceGeneratorTests.Source.Foo2 instance)
{
_Instance = instance;
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.Foo2, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2>.NewConfig().ConstructUsing(instance1325374861 => new global::ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy(instance1325374861));
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2, global::ProxyInterfaceSourceGeneratorTests.Source.Foo2>.NewConfig().MapWith(proxy1047178445 => ((global::ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy) proxy1047178445)._Instance);
}
}
}
#nullable restore
}
]
@@ -0,0 +1,213 @@
[
{
HintName: Speckle.ProxyGenerator.Extra.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace Speckle.ProxyGenerator
{
[AttributeUsage(AttributeTargets.Interface)]
internal sealed class ProxyAttribute : Attribute
{
public Type Type { get; }
public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { get; }
public string[]? MembersToIgnore { get; }
public ProxyAttribute(Type type) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public)
{
}
public ProxyAttribute(Type type, ImplementationOptions options) : this(type, options, ProxyClassAccessibility.Public)
{
}
public ProxyAttribute(Type type, ProxyClassAccessibility accessibility) : this(type, ImplementationOptions.None, accessibility)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility) : this(type, options, accessibility, null)
{
}
public ProxyAttribute(Type type, string[]? membersToIgnore) : this(type, ImplementationOptions.None, ProxyClassAccessibility.Public, null)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, string[]? membersToIgnore) : this(type, options, ProxyClassAccessibility.Public, null)
{
}
public ProxyAttribute(Type type, ImplementationOptions options, ProxyClassAccessibility accessibility, string[]? membersToIgnore)
{
Type = type;
Options = options;
Accessibility = accessibility;
MembersToIgnore = membersToIgnore;
}
}
[Flags]
internal enum ProxyClassAccessibility
{
Public = 0,
Internal = 1
}
[Flags]
internal enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
#nullable restore
}
},
{
HintName: ProxyInterfaceSourceGeneratorTests.Source.IFoo3Proxy.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial interface IFoo3Proxy : global::ProxyInterfaceSourceGeneratorTests.Source.IFoo3
{
global::ProxyInterfaceSourceGeneratorTests.Source.Foo3 _Instance { get; }
}
}
#nullable restore
},
{
HintName: ProxyInterfaceSourceGeneratorTests.Source.IBar3Proxy.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial interface IBar3Proxy : global::ProxyInterfaceSourceGeneratorTests.Source.IBar3
{
global::ProxyInterfaceSourceGeneratorTests.Source.Bar3 _Instance { get; }
}
}
#nullable restore
},
{
HintName: ProxyInterfaceSourceGeneratorTests.Source.Foo3Proxy.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial class Foo3Proxy : global::ProxyInterfaceSourceGeneratorTests.Source.IFoo3
{
public global::ProxyInterfaceSourceGeneratorTests.Source.Foo3 _Instance { get; }
public global::ProxyInterfaceSourceGeneratorTests.Source.IBar3 Weird()
{
var result_867036441 = _Instance.Weird();
return Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IBar3>(result_867036441);
}
public Foo3Proxy(global::ProxyInterfaceSourceGeneratorTests.Source.Foo3 instance)
{
_Instance = instance;
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.Bar3, global::ProxyInterfaceSourceGeneratorTests.Source.IBar3>.NewConfig().ConstructUsing(instance969373361 => new global::ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy(instance969373361));
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.IBar3, global::ProxyInterfaceSourceGeneratorTests.Source.Bar3>.NewConfig().MapWith(proxy339001485 => ((global::ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy) proxy339001485)._Instance);
}
}
}
#nullable restore
},
{
HintName: ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy.g.cs,
Source:
//----------------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by https://github.com/specklesystems/ProxyGenerator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial class Bar3Proxy : global::ProxyInterfaceSourceGeneratorTests.Source.IBar3
{
public global::ProxyInterfaceSourceGeneratorTests.Source.Bar3 _Instance { get; }
public Bar3Proxy(global::ProxyInterfaceSourceGeneratorTests.Source.Bar3 instance)
{
_Instance = instance;
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.Bar3, global::ProxyInterfaceSourceGeneratorTests.Source.IBar3>.NewConfig().ConstructUsing(instance969373361 => new global::ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy(instance969373361));
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.IBar3, global::ProxyInterfaceSourceGeneratorTests.Source.Bar3>.NewConfig().MapWith(proxy339001485 => ((global::ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy) proxy339001485)._Instance);
}
}
}
#nullable restore
}
]
@@ -104,7 +104,7 @@ public class ProxyInterfaceSourceGeneratorTest
ArgumentList = new[] ArgumentList = new[]
{ {
"typeof(ProxyInterfaceSourceGeneratorTests.Source.Foo2)", "typeof(ProxyInterfaceSourceGeneratorTests.Source.Foo2)",
"false", "ImplementationOptions.None",
"ProxyClassAccessibility.Public", "ProxyClassAccessibility.Public",
"new []{\"Weird\",\"NotHere\"}" "new []{\"Weird\",\"NotHere\"}"
} }
@@ -123,6 +123,100 @@ public class ProxyInterfaceSourceGeneratorTest
return Verify(results); return Verify(results);
} }
[Fact]
public Task GenerateFiles_ForClassWith_BaseInterface()
{
// Arrange
var fileNames = new[]
{
"ProxyInterfaceSourceGeneratorTests.Source.IFoo2.g.cs",
"ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy.g.cs"
};
var path = "./Source/IFoo2.cs";
var sourceFile = new SourceFile
{
Path = path,
Text = File.ReadAllText(path),
AttributeToAddToInterface = new ExtraAttribute
{
Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = new[]
{
"typeof(ProxyInterfaceSourceGeneratorTests.Source.Foo2)",
"ImplementationOptions.UseExtendedInterfaces", "ProxyClassAccessibility.Public"
}
}
};
// Act
var result = _sut.Execute(new[] { sourceFile });
// Assert
result.Valid.Should().BeTrue();
result.Files.Should().HaveCount(fileNames.Length + 1);
// Verify
var results = result.GeneratorDriver.GetRunResult().Results.First().GeneratedSources;
return Verify(results);
}
[Fact]
public Task GenerateFiles_ForClassWith_Extended()
{
// Arrange
var fileNames = new[]
{
"ProxyInterfaceSourceGeneratorTests.Source.IFoo3Proxy.g.cs",
"ProxyInterfaceSourceGeneratorTests.Source.Foo3Proxy.g.cs",
"ProxyInterfaceSourceGeneratorTests.Source.IBar3Proxy.g.cs",
"ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy.g.cs"
};
var path = "./Source/IFoo3Proxy.cs";
var sourceFile = new SourceFile
{
Path = path,
Text = File.ReadAllText(path),
AttributeToAddToInterface = new ExtraAttribute
{
Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = new[]
{
"typeof(ProxyInterfaceSourceGeneratorTests.Source.Foo3)",
"ImplementationOptions.UseExtendedInterfaces | ImplementationOptions.ProxyForBaseInterface",
"ProxyClassAccessibility.Public"
}
}
};
var path2 = "./Source/IBar3Proxy.cs";
var sourceFile2 = new SourceFile
{
Path = path2,
Text = File.ReadAllText(path2),
AttributeToAddToInterface = new ExtraAttribute
{
Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = new[]
{
"typeof(ProxyInterfaceSourceGeneratorTests.Source.Bar3)",
"ImplementationOptions.UseExtendedInterfaces | ImplementationOptions.ProxyForBaseInterface",
"ProxyClassAccessibility.Public"
}
}
};
// Act
var result = _sut.Execute(new[] { sourceFile, sourceFile2 });
// Assert
result.Valid.Should().BeTrue();
result.Files.Should().HaveCount(fileNames.Length + 1);
// Verify
var results = result.GeneratorDriver.GetRunResult().Results.First().GeneratedSources;
return Verify(results);
}
[Fact] [Fact]
public void GenerateFiles_ForGenericType_Should_GenerateCorrectFiles() public void GenerateFiles_ForGenericType_Should_GenerateCorrectFiles()
{ {
@@ -351,7 +445,7 @@ public class ProxyInterfaceSourceGeneratorTest
ArgumentList = new[] ArgumentList = new[]
{ {
"typeof(ProxyInterfaceSourceGeneratorTests.Source.PersonExtends)", "typeof(ProxyInterfaceSourceGeneratorTests.Source.PersonExtends)",
"true" "ImplementationOptions.ProxyBaseClasses"
} }
} }
}; };
@@ -688,7 +782,7 @@ public class ProxyInterfaceSourceGeneratorTest
ArgumentList = new[] ArgumentList = new[]
{ {
$"typeof(ProxyInterfaceSourceGeneratorTests.Namespace{x}.{@class})", $"typeof(ProxyInterfaceSourceGeneratorTests.Namespace{x}.{@class})",
"true" "ImplementationOptions.ProxyBaseClasses"
} }
} }
}; };
@@ -11,7 +11,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Akka.Remote" Version="1.4.47" /> <PackageReference Include="Akka.Remote" Version="1.4.47" />
<PackageReference Include="AutoMapper" Version="11.0.1" />
<PackageReference Include="CultureAwareTesting.xUnit" Version="0.0.1" /> <PackageReference Include="CultureAwareTesting.xUnit" Version="0.0.1" />
<PackageReference Include="FluentAssertions" Version="6.9.0" /> <PackageReference Include="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.3.0" />
@@ -64,6 +63,12 @@
<Compile Update="Source\IGeneric.cs"> <Compile Update="Source\IGeneric.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile> </Compile>
<Compile Update="Source\IFoo3.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
<Compile Update="Source\Foo3.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
</ItemGroup> </ItemGroup>
</Project> </Project>
@@ -0,0 +1,15 @@
using System.Diagnostics.CodeAnalysis;
namespace ProxyInterfaceSourceGeneratorTests.Source;
public class Foo3
{
public Bar3 Weird()
{
throw new NotImplementedException();
}
}
public class Bar3
{
}
@@ -0,0 +1,5 @@
namespace ProxyInterfaceSourceGeneratorTests.Source;
public partial interface IBar3
{
}
@@ -0,0 +1,7 @@
namespace ProxyInterfaceSourceGeneratorTests.Source;
public partial interface IBar3Proxy : IBar3
{
}
@@ -1,4 +1,8 @@
namespace ProxyInterfaceSourceGeneratorTests.Source namespace ProxyInterfaceSourceGeneratorTests.Source
{ {
public partial interface IFoo2 { } public partial interface IFoo2: IFoo2Base { }
public partial interface IFoo2Base
{
int Weird2();
}
} }
@@ -0,0 +1,8 @@
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial interface IFoo3
{
IBar3 Weird();
}
}
@@ -0,0 +1,3 @@
namespace ProxyInterfaceSourceGeneratorTests.Source;
public partial interface IFoo3Proxy: IFoo3 { }