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 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:
- properties
- methods
- events
- implicit and explicit operators
## Install
[![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:
@@ -20,7 +42,9 @@ Or via the Visual Studio NuGet package manager or if you use the `dotnet` comman
`dotnet add package ProxyInterfaceGenerator`
## Usage
### Given: an external existing class which does not implement an interface
``` c#
public sealed class Person
{
@@ -34,6 +58,7 @@ public sealed class Person
```
### Create a partial interface
And annotate this with `ProxyInterfaceGenerator.Proxy[...]` and with the Type which needs to be wrapped:
``` c#
@@ -44,6 +69,7 @@ public partial interface IPerson
```
#### ProxyBaseClasses
In case also want to proxy the properties/methods/events from the base class(es), use this:
``` c#
@@ -54,6 +80,7 @@ public partial interface IPerson
```
#### ProxyClassAccessibility
By default, the generated Proxy class is `public`. If you want to create the Proxy class as `internal`, use the following:
``` c#
@@ -66,7 +93,9 @@ public partial interface IPerson
### When the code is compiled, this source generator creates the following
#### :one: An additional partial interface
Which defines the same properties and methods as in the external class.
``` c#
public partial interface IPerson
{
@@ -77,6 +106,7 @@ public partial interface IPerson
```
#### :two: A Proxy class
Which takes the external class in the constructor and wraps all public properties, events and methods.
``` c#
@@ -104,6 +134,7 @@ public class PersonProxy : IPerson
:star: By default the accessibility from the generated Proxy class is `public`.
### :three: Use it
``` c#
IPerson p = new PersonProxy(new Person());
p.Name = "test";
@@ -111,4 +142,5 @@ p.HelloWorld("stef");
```
# 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
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProxyInterfaceConsumerForPnP", "src-examples\ProxyInterfaceConsumerForPnP\ProxyInterfaceConsumerForPnP.csproj", "{5F7DA2C5-B908-4B57-9F5F-BADF1216D89C}"
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}"
EndProject
Global
@@ -63,12 +61,6 @@ Global
{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.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.Build.0 = 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}
{1BDB9046-D6D1-4FB4-AAB5-F24E33EEAE0A} = {19009F5B-3267-45E2-A8B6-89F2AB47D72C}
{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}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
@@ -1,8 +1,9 @@
using System.Net.Http;
using Speckle.ProxyGenerator;
namespace ProxyInterfaceConsumer.Http;
[Speckle.ProxyGenerator.Proxy(typeof(HttpClient), true)]
[Speckle.ProxyGenerator.Proxy(typeof(HttpClient), ImplementationOptions.ProxyBaseClasses)]
public partial interface IHttpClient : IHttpMessageInvoker { }
[Speckle.ProxyGenerator.Proxy(typeof(HttpMessageInvoker))]
@@ -2,7 +2,7 @@ using Speckle.ProxyGenerator;
namespace ProxyInterfaceConsumer
{
[Proxy(typeof(Address), false, ProxyClassAccessibility.Public, new[] { "Weird" })]
[Proxy(typeof(Address), ImplementationOptions.ProxyBaseClasses, ProxyClassAccessibility.Public, new[] { "Weird" })]
public partial interface IAddress
{
public void Weird()
@@ -4,6 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<Nullable>enable</Nullable>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>
<ItemGroup>
@@ -12,7 +13,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<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>
<ItemGroup>
<!--<PackageReference Include="AutoMapper" Version="10.1.1" />-->
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3">
<PrivateAssets>all</PrivateAssets>
@@ -10,7 +10,6 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="ProxyInterfaceGenerator" Version="0.1.0">
<PrivateAssets>all</PrivateAssets>
@@ -48,7 +48,8 @@ internal static class NamedTypeSymbolExtensions
public static List<INamedTypeSymbol> ResolveImplementedInterfaces(
this INamedTypeSymbol symbol,
bool proxyBaseClasses
bool proxyBaseClasses,
bool proxyInterfaces
)
{
// Members implemented by us or base classes should go here.
@@ -58,7 +59,11 @@ internal static class NamedTypeSymbolExtensions
.ToList();
// 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;
while (
proxyBaseClasses
@@ -69,7 +74,10 @@ internal static class NamedTypeSymbolExtensions
publicMembers.AddRange(
baseType.GetMembers().Where(m => m.DeclaredAccessibility == Accessibility.Public)
);
interfaces.AddRange(baseType.Interfaces);
if (proxyInterfaces)
{
interfaces.AddRange(baseType.Interfaces);
}
baseType = baseType.BaseType;
}
@@ -100,4 +108,13 @@ internal static class NamedTypeSymbolExtensions
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
{
protected const string globalPrefix = "global::";
protected readonly Context Context;
protected readonly bool SupportsNullable;
@@ -35,6 +36,11 @@ internal abstract class BaseGenerator
[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);
return proxyData != null;
}
@@ -214,7 +220,6 @@ internal abstract class BaseGenerator
)
{
classSymbol = default;
const string globalPrefix = "global::";
if (name.StartsWith(globalPrefix, StringComparison.Ordinal))
{
name = name.Substring(globalPrefix.Length);
@@ -283,8 +288,7 @@ internal abstract class BaseGenerator
}
protected IReadOnlyList<ProxyData> GetExtendsProxyData(
ProxyData proxyData,
ClassSymbol targetClassSymbol
ClassSymbol targetClassSymbol, bool useFullQualifiedMappedTypeName
)
{
var extendsProxyClasses = new List<ProxyData>();
@@ -293,10 +297,22 @@ internal abstract class BaseGenerator
var candidate = Context.Candidates.Values.FirstOrDefault(ci =>
ci.FullQualifiedTypeName == baseType.ToFullyQualifiedDisplayString()
);
if (candidate is not null)
if (useFullQualifiedMappedTypeName)
{
extendsProxyClasses.Add(candidate);
break;
//is a candidate and overrides
if (candidate?.FullQualifiedMappedTypeName != null)
{
extendsProxyClasses.Add(candidate);
break;
}
}
else
{
if (candidate != null)
{
extendsProxyClasses.Add(candidate);
break;
}
}
}
return extendsProxyClasses;
@@ -29,34 +29,38 @@ namespace Speckle.ProxyGenerator
internal sealed class ProxyAttribute : Attribute
{{
public Type Type {{ get; }}
public bool ProxyBaseClasses {{ get; }}
public ImplementationOptions Options {{ get; }}
public ProxyClassAccessibility Accessibility {{ 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;
ProxyBaseClasses = proxyBaseClasses;
Options = options;
Accessibility = accessibility;
MembersToIgnore = membersToIgnore;
}}
@@ -69,6 +73,19 @@ namespace Speckle.ProxyGenerator
Internal = 1
}}
[Flags]
internal enum ImplementationOptions
{{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}}
{supportsNullable.IIf("#nullable restore")}
}}"
);
@@ -5,14 +5,14 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
using Speckle.ProxyGenerator.Enums;
using Speckle.ProxyGenerator.Extensions;
using Speckle.ProxyGenerator.Models;
using Speckle.ProxyGenerator.Types;
using Speckle.ProxyGenerator.Utils;
namespace Speckle.ProxyGenerator.FileGenerators;
internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
{
private IReadOnlyCollection<INamedTypeSymbol> _implementedInterfaces =
new List<INamedTypeSymbol>();
private List<INamedTypeSymbol> _implementedInterfaces = new();
public PartialInterfacesGenerator(Context context, bool supportsNullable)
: base(context, supportsNullable) { }
@@ -67,7 +67,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
fileData = new FileData(
$"{sourceInterfaceSymbol.Symbol.GetFullMetadataName()}.g.cs",
CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, interfaceName, pd)
CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, sourceInterfaceSymbol,interfaceName, pd)
);
return true;
@@ -76,21 +76,41 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
private string CreatePartialInterfaceCode(
string ns,
ClassSymbol classSymbol,
ClassSymbol interfaceSymbol,
string interfaceName,
ProxyData proxyData
)
{
var extendsProxyClasses = GetExtendsProxyData(proxyData, classSymbol);
_implementedInterfaces = classSymbol.Symbol.ResolveImplementedInterfaces(
proxyData.ProxyBaseClasses
);
_implementedInterfaces.Clear();
_implementedInterfaces.AddRange(classSymbol.Symbol.ResolveImplementedInterfaces(
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
.Select(i => i.ToFullyQualifiedDisplayString())
.ToArray();
var implements = implementedInterfacesNames.Any()
? $" : {string.Join(", ", implementedInterfacesNames)}"
: string.Empty;
var @new = extendsProxyClasses.Any() ? "new " : string.Empty;
var @new = isNew ? "new " : string.Empty;
var (namespaceStart, namespaceEnd) = NamespaceBuilder.Build(ns);
var events = GenerateEvents(classSymbol, proxyData);
var properties = GenerateProperties(classSymbol, proxyData);
@@ -98,7 +118,7 @@ internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator
return $@"//----------------------------------------------------------------------------------------
// <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
// 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 constructorName = $"{targetClassSymbol.Symbol.Name}Proxy";
var extendsProxyClasses = GetExtendsProxyData(pd, targetClassSymbol);
var extendsProxyClasses = GetExtendsProxyData(targetClassSymbol, false);
fileData = new FileData(
$"{targetClassSymbol.Symbol.GetFullMetadataName()}Proxy.g.cs",
@@ -117,7 +117,7 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
return $@"//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -10,18 +10,20 @@ internal class ProxyData
public string ShortInterfaceName { get; }
public string FullInterfaceName { get; }
private string _fullInterfaceName;
public string FullInterfaceName => FullQualifiedMappedTypeName ?? _fullInterfaceName;
public string FullQualifiedTypeName { get; }
public string? FullQualifiedMappedTypeName { get; set; }
public string ShortMetadataName { get; }
public string FullMetadataTypeName { get; }
public List<string> Usings { get; }
public bool ProxyBaseClasses { get; }
public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { get; }
public string[] MembersToIgnore { get; }
@@ -34,7 +36,7 @@ internal class ProxyData
string shortMetadataTypeName,
string fullMetadataTypeName,
List<string> usings,
bool proxyBaseClasses,
ImplementationOptions options,
ProxyClassAccessibility accessibility,
string[] membersToIgnore
)
@@ -43,7 +45,7 @@ internal class ProxyData
NamespaceDot = namespaceDot ?? throw new ArgumentNullException(nameof(namespaceDot));
ShortInterfaceName =
shortInterfaceName ?? throw new ArgumentNullException(nameof(shortInterfaceName));
FullInterfaceName =
_fullInterfaceName =
fullInterfaceName ?? throw new ArgumentNullException(nameof(fullInterfaceName));
FullQualifiedTypeName =
fullQualifiedTypeName ?? throw new ArgumentNullException(nameof(fullQualifiedTypeName));
@@ -52,7 +54,7 @@ internal class ProxyData
FullMetadataTypeName =
fullMetadataTypeName ?? throw new ArgumentNullException(nameof(fullMetadataTypeName));
Usings = usings ?? throw new ArgumentNullException(nameof(usings));
ProxyBaseClasses = proxyBaseClasses;
Options = options;
Accessibility = accessibility;
MembersToIgnore = membersToIgnore;
}
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>0.1.2</Version>
<Version>0.1.5</Version>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>Latest</LangVersion>
<Nullable>enable</Nullable>
@@ -48,34 +48,20 @@ internal static class AttributeArgumentListParser
result = result with { MembersToIgnore = membersToIgnore };
continue;
}
if (TryParseAsBoolean(argument.Expression, out var proxyBaseClasses))
{
result = result with { ProxyBaseClasses = proxyBaseClasses };
continue;
}
if (TryParseAsEnum<ProxyClassAccessibility>(argument.Expression, out var accessibility))
{
result = result with { Accessibility = accessibility };
}
if (TryParseAsEnum<ImplementationOptions>(argument.Expression, out var options))
{
result = result with { Options = options };
}
}
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(
ExpressionSyntax expressionSyntax,
SemanticModel semanticModel,
@@ -100,22 +86,27 @@ internal static class AttributeArgumentListParser
}
private static bool TryParseAsEnum<TEnum>(ExpressionSyntax expressionSyntax, out TEnum value)
where TEnum : struct
where TEnum : struct, Enum
{
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;
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)
@@ -99,7 +99,7 @@ internal class ProxySyntaxReceiver : ISyntaxContextReceiver
fullMetadataTypeName: metadataName,
shortMetadataTypeName: metadataName.Split('.').Last(),
usings: usings,
proxyBaseClasses: fluentBuilderAttributeArguments.ProxyBaseClasses,
options: fluentBuilderAttributeArguments.Options,
accessibility: fluentBuilderAttributeArguments.Accessibility,
membersToIgnore: fluentBuilderAttributeArguments.MembersToIgnore
);
@@ -5,7 +5,7 @@ internal record ProxyInterfaceGeneratorAttributeArguments(
string MetadataName
)
{
public bool ProxyBaseClasses { get; set; }
public ImplementationOptions Options { get; set; }
public ProxyClassAccessibility Accessibility { get; set; }
public string[] MembersToIgnore { get; set; } = [];
@@ -7,3 +7,17 @@ internal enum ProxyClassAccessibility
Internal = 1
}
[Flags]
internal enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using Speckle.ProxyGenerator.Models;
using Speckle.ProxyGenerator.Types;
namespace Speckle.ProxyGenerator.Utils;
@@ -108,7 +109,7 @@ internal static class MemberHelper
var ownMembers = membersQuery.ToList();
var ownMemberNames = ownMembers.Select(x => x.Name);
if (!proxyData.ProxyBaseClasses)
if (!proxyData.Options.HasFlag(ImplementationOptions.ProxyBaseClasses))
{
return ownMembers;
}
@@ -35,7 +35,7 @@ public class AkkaTests
AttributeToAddToInterface = new ExtraAttribute
{
Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = "typeof(Akka.Actor.LocalActorRefProvider)"
ArgumentList = new [] {"typeof(Akka.Actor.LocalActorRefProvider)","ImplementationOptions.ProxyInterfaces"}
}
};
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source
{
public partial interface IHttpMessageInvoker : global::System.IDisposable
public partial interface IHttpMessageInvoker
{
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.Threading.Tasks.Task<global::System.Net.Http.HttpResponseMessage> SendAsync(global::System.Net.Http.HttpRequestMessage request, global::System.Threading.CancellationToken cancellationToken);
void Dispose();
}
}
#nullable restore
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
{
public partial interface IClientObject : global::Microsoft.SharePoint.Client.IFromJson
public partial interface IClientObject
{
global::Microsoft.SharePoint.Client.ClientObject _Instance { get; }
@@ -31,6 +31,12 @@ namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
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)]
void Retrieve();
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -12,7 +12,7 @@ using System;
namespace ProxyInterfaceSourceGeneratorTests.Source.PnP
{
public partial interface IClientRuntimeContext : global::System.IDisposable
public partial interface IClientRuntimeContext
{
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::System.Linq.IQueryable<T> clientObjects) where T : Microsoft.SharePoint.Client.ClientObject;
void Dispose();
}
}
#nullable restore
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -12,7 +12,7 @@ using System;
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; }
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -12,7 +12,7 @@ using System;
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; }
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,6 +1,6 @@
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -1,14 +1,24 @@
using CSharp.SourceGenerators.Extensions;
using CSharp.SourceGenerators.Extensions.Models;
using FluentAssertions;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using ProxyInterfaceSourceGeneratorTests.Source.Disposable;
using Speckle.ProxyGenerator;
using Xunit.Abstractions;
namespace ProxyInterfaceSourceGeneratorTests;
[Flags]
public enum ImplementationOptions
{
None = 0,
ProxyBaseClasses = 1,
ProxyInterfaces = 2,
UseExtendedInterfaces = 4,
ProxyForBaseInterface = 8
}
public class InheritedInterfaceTests
{
private const string Namespace = "ProxyInterfaceSourceGeneratorTests.Source.Disposable";
@@ -25,10 +35,10 @@ public class InheritedInterfaceTests
}
[Theory]
[InlineData(false, false)]
[InlineData(true, true)]
[InlineData(ImplementationOptions.None, false)]
[InlineData(ImplementationOptions.ProxyBaseClasses | ImplementationOptions.ProxyInterfaces, true)]
public void GenerateFiles_InheritedInterface_InheritFromBaseClass(
bool proxyBaseClass,
ImplementationOptions options,
bool inheritBaseInterface
)
{
@@ -39,7 +49,7 @@ public class InheritedInterfaceTests
// Arrange
string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"];
var path = $"./Source/Disposable/{interfaceName}.cs";
SourceFile sourceFile = CreateSourceFile(path, name, proxyBaseClass);
SourceFile sourceFile = CreateSourceFile(path, name,options);
// Act
var result = _sut.Execute([sourceFile]);
@@ -72,7 +82,7 @@ public class InheritedInterfaceTests
string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.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
var result = _sut.Execute([sourceFile]);
@@ -88,9 +98,9 @@ public class InheritedInterfaceTests
// Assert
Assert.Single(interfaceDeclarations);
var baseList = interfaceDeclarations.First().BaseList!;
Assert.Equal(2, baseList.Types.Count);
var type1 = (QualifiedNameSyntax)baseList.Types[0].Type;
var baseList = interfaceDeclarations.First().BaseList;
Assert.Equal(2, baseList?.Types.Count);
var type1 = (QualifiedNameSyntax)baseList!.Types[0].Type;
var type2 = (QualifiedNameSyntax)baseList.Types[1].Type;
Assert.Equal(nameof(IDisposable), type1.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"];
var interfaceIndex = 1;
var path = $"./Source/Disposable/{interfaceName}.cs";
SourceFile sourceFile = CreateSourceFile(path, name, true);
SourceFile sourceFile = CreateSourceFile(path, name, ImplementationOptions.UseExtendedInterfaces);
// Act
var result = _sut.Execute([sourceFile]);
@@ -130,9 +140,26 @@ public class InheritedInterfaceTests
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
{
Path = path,
@@ -140,7 +167,7 @@ public class InheritedInterfaceTests
AttributeToAddToInterface = new ExtraAttribute
{
Name = "Speckle.ProxyGenerator.Proxy",
ArgumentList = $"typeof({Namespace}.{name}), {extendString}"
ArgumentList = $"typeof({Namespace}.{name}), {o}"
}
};
}
@@ -45,7 +45,7 @@ public class PnPTests
AttributeToAddToInterface = new ExtraAttribute
{
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
{
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
{
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
{
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
{
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>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace Speckle.ProxyGenerator
@@ -19,34 +20,38 @@ namespace Speckle.ProxyGenerator
internal sealed class ProxyAttribute : Attribute
{
public Type Type { get; }
public bool ProxyBaseClasses { get; }
public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { 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;
ProxyBaseClasses = proxyBaseClasses;
Options = options;
Accessibility = accessibility;
MembersToIgnore = membersToIgnore;
}
@@ -59,6 +64,20 @@ namespace Speckle.ProxyGenerator
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:
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -94,7 +113,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
Source:
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -11,6 +11,7 @@
// </auto-generated>
//----------------------------------------------------------------------------------------
#nullable enable
using System;
namespace Speckle.ProxyGenerator
@@ -19,34 +20,38 @@ namespace Speckle.ProxyGenerator
internal sealed class ProxyAttribute : Attribute
{
public Type Type { get; }
public bool ProxyBaseClasses { get; }
public ImplementationOptions Options { get; }
public ProxyClassAccessibility Accessibility { 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;
ProxyBaseClasses = proxyBaseClasses;
Options = options;
Accessibility = accessibility;
MembersToIgnore = membersToIgnore;
}
@@ -59,6 +64,20 @@ namespace Speckle.ProxyGenerator
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:
//----------------------------------------------------------------------------------------
// <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
// the code is regenerated.
@@ -96,7 +115,7 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
Source:
//----------------------------------------------------------------------------------------
// <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
// 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[]
{
"typeof(ProxyInterfaceSourceGeneratorTests.Source.Foo2)",
"false",
"ImplementationOptions.None",
"ProxyClassAccessibility.Public",
"new []{\"Weird\",\"NotHere\"}"
}
@@ -123,6 +123,100 @@ public class ProxyInterfaceSourceGeneratorTest
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]
public void GenerateFiles_ForGenericType_Should_GenerateCorrectFiles()
{
@@ -351,7 +445,7 @@ public class ProxyInterfaceSourceGeneratorTest
ArgumentList = new[]
{
"typeof(ProxyInterfaceSourceGeneratorTests.Source.PersonExtends)",
"true"
"ImplementationOptions.ProxyBaseClasses"
}
}
};
@@ -688,7 +782,7 @@ public class ProxyInterfaceSourceGeneratorTest
ArgumentList = new[]
{
$"typeof(ProxyInterfaceSourceGeneratorTests.Namespace{x}.{@class})",
"true"
"ImplementationOptions.ProxyBaseClasses"
}
}
};
@@ -11,7 +11,6 @@
<ItemGroup>
<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="FluentAssertions" Version="6.9.0" />
<PackageReference Include="Mapster" Version="7.3.0" />
@@ -64,6 +63,12 @@
<Compile Update="Source\IGeneric.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
<Compile Update="Source\IFoo3.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
<Compile Update="Source\Foo3.cs">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Compile>
</ItemGroup>
</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
{
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 { }