DUI3-300 - add ProxyMap to source gen (#6)
This commit is contained in:
@@ -1,14 +1,22 @@
|
||||
using System.Text;
|
||||
using Speckle.ProxyGenerator.Extensions;
|
||||
using Speckle.ProxyGenerator.Models;
|
||||
|
||||
namespace Speckle.ProxyGenerator.FileGenerators;
|
||||
|
||||
internal record ProxyMapItem(string BaseType, string InterfaceType, string ProxyType);
|
||||
internal class ExtraFilesGenerator : IFileGenerator
|
||||
{
|
||||
private const string Name = "Speckle.ProxyGenerator.Extra.g.cs";
|
||||
|
||||
public FileData GenerateFile(bool supportsNullable)
|
||||
public FileData GenerateFile(List<ProxyMapItem> proxyMapItems, bool supportsNullable)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
foreach (var item in proxyMapItems)
|
||||
{
|
||||
sb.AppendLine(
|
||||
$"Add<{item.BaseType}, {item.InterfaceType}, {item.ProxyType}>(x => new {item.ProxyType}(x));");
|
||||
}
|
||||
return new FileData(
|
||||
$"{Name}",
|
||||
$@"//----------------------------------------------------------------------------------------
|
||||
@@ -86,6 +94,62 @@ namespace Speckle.ProxyGenerator
|
||||
|
||||
ProxyForBaseInterface = 8
|
||||
}}
|
||||
|
||||
public static class ProxyMap
|
||||
{{
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_revitToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_proxyToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_interfaceToRevit = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Func<object, object>> s_proxyFactory = new();
|
||||
|
||||
static ProxyMap()
|
||||
{{
|
||||
{sb}
|
||||
}}
|
||||
|
||||
private static void Add<T, TInterface, TProxy>(Func<T, TProxy> f)
|
||||
where T : class
|
||||
where TInterface : notnull
|
||||
where TProxy : TInterface
|
||||
{{
|
||||
s_revitToInterfaceMap.TryAdd(typeof(T), typeof(TInterface));
|
||||
s_proxyToInterfaceMap.TryAdd(typeof(TProxy), typeof(TInterface));
|
||||
s_proxyFactory.TryAdd(typeof(TInterface), w => f((T)w));
|
||||
s_interfaceToRevit.TryAdd(typeof(TInterface), typeof(T));
|
||||
}}
|
||||
|
||||
public static Type? GetMappedTypeFromHostType(Type type)
|
||||
{{
|
||||
if (s_revitToInterfaceMap.TryGetValue(type, out var t))
|
||||
{{
|
||||
return t;
|
||||
}}
|
||||
return null;
|
||||
}}
|
||||
|
||||
public static Type? GetMappedTypeFromProxyType(Type type)
|
||||
{{
|
||||
if (s_proxyToInterfaceMap.TryGetValue(type, out var t))
|
||||
{{
|
||||
return t;
|
||||
}}
|
||||
|
||||
return null;
|
||||
}}
|
||||
|
||||
public static Type? GetHostTypeFromMappedType(Type type)
|
||||
{{
|
||||
if (s_interfaceToRevit.TryGetValue(type, out var t))
|
||||
{{
|
||||
return t;
|
||||
}}
|
||||
|
||||
return null;
|
||||
}}
|
||||
|
||||
public static object CreateProxy(Type type, object toWrap) => s_proxyFactory[type](toWrap);
|
||||
public static T CreateProxy<T>(object toWrap) => (T)CreateProxy(typeof(T), toWrap);
|
||||
}}
|
||||
{supportsNullable.IIf("#nullable restore")}
|
||||
}}"
|
||||
);
|
||||
|
||||
@@ -4,5 +4,5 @@ namespace Speckle.ProxyGenerator.FileGenerators;
|
||||
|
||||
internal interface IFileGenerator
|
||||
{
|
||||
FileData GenerateFile(bool supportsNullable);
|
||||
FileData GenerateFile(List<ProxyMapItem> proxyMapItems, bool supportsNullable);
|
||||
}
|
||||
|
||||
@@ -12,8 +12,16 @@ namespace Speckle.ProxyGenerator.FileGenerators;
|
||||
|
||||
internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
{
|
||||
public ProxyClassesGenerator(Context context, bool supportsNullable)
|
||||
: base(context, supportsNullable) { }
|
||||
private readonly
|
||||
List<ProxyMapItem> _proxyMapItems;
|
||||
|
||||
public ProxyClassesGenerator(
|
||||
List<ProxyMapItem> proxyMapItems, Context context, bool supportsNullable)
|
||||
: base(context, supportsNullable)
|
||||
{
|
||||
_proxyMapItems = proxyMapItems;
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<FileData> GenerateFiles()
|
||||
{
|
||||
@@ -55,9 +63,13 @@ internal partial class ProxyClassesGenerator : BaseGenerator, IFilesGenerator
|
||||
var constructorName = $"{targetClassSymbol.Symbol.Name}Proxy";
|
||||
|
||||
var extendsProxyClasses = GetExtendsProxyData(targetClassSymbol, false);
|
||||
|
||||
var targetClass = targetClassSymbol.Symbol.GetFullMetadataName();
|
||||
if (!targetClassSymbol.Symbol.IsGenericType)
|
||||
{
|
||||
_proxyMapItems.Add(new(targetClass, interfaceName, $"{pd.NamespaceDot}{className}"));
|
||||
}
|
||||
fileData = new FileData(
|
||||
$"{targetClassSymbol.Symbol.GetFullMetadataName()}Proxy.g.cs",
|
||||
$"{targetClass}Proxy.g.cs",
|
||||
CreateProxyClassCode(
|
||||
pd,
|
||||
targetClassSymbol,
|
||||
|
||||
@@ -48,9 +48,10 @@ class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
// https://github.com/reactiveui/refit/blob/main/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs
|
||||
var supportsNullable = csharpParseOptions.LanguageVersion >= LanguageVersion.CSharp8;
|
||||
|
||||
GenerateProxyAttribute(context, receiver, supportsNullable);
|
||||
var proxyItems = new List<ProxyMapItem>();
|
||||
GeneratePartialInterfaces(context, receiver, supportsNullable);
|
||||
GenerateProxyClasses(context, receiver, supportsNullable);
|
||||
GenerateProxyClasses(proxyItems, context, receiver, supportsNullable);
|
||||
GenerateProxyAttribute(proxyItems, context, receiver, supportsNullable);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
@@ -66,6 +67,7 @@ class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
}
|
||||
|
||||
private void GenerateProxyAttribute(
|
||||
List<ProxyMapItem> proxyMapItems,
|
||||
GeneratorExecutionContext ctx,
|
||||
ProxySyntaxReceiver receiver,
|
||||
bool supportsNullable
|
||||
@@ -77,7 +79,7 @@ class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
Candidates = receiver.CandidateInterfaces
|
||||
};
|
||||
|
||||
var attributeData = _proxyAttributeGenerator.GenerateFile(supportsNullable);
|
||||
var attributeData = _proxyAttributeGenerator.GenerateFile(proxyMapItems, supportsNullable);
|
||||
context.GeneratorExecutionContext.AddSource(
|
||||
attributeData.FileName,
|
||||
SourceText.From(attributeData.Text, Encoding.UTF8)
|
||||
@@ -107,6 +109,7 @@ class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
}
|
||||
|
||||
private static void GenerateProxyClasses(
|
||||
List<ProxyMapItem> proxyMapItems,
|
||||
GeneratorExecutionContext ctx,
|
||||
ProxySyntaxReceiver receiver,
|
||||
bool supportsNullable
|
||||
@@ -118,7 +121,7 @@ class ProxyInterfaceCodeGenerator : ISourceGenerator
|
||||
Candidates = receiver.CandidateInterfaces
|
||||
};
|
||||
|
||||
var proxyClassesGenerator = new ProxyClassesGenerator(context, supportsNullable);
|
||||
var proxyClassesGenerator = new ProxyClassesGenerator(proxyMapItems, context, supportsNullable);
|
||||
foreach (var (fileName, text) in proxyClassesGenerator.GenerateFiles())
|
||||
{
|
||||
context.GeneratorExecutionContext.AddSource(
|
||||
|
||||
@@ -48,7 +48,7 @@ public class AkkaTests
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
|
||||
@@ -58,7 +58,7 @@ public class InheritedInterfaceTests
|
||||
result.Files.Should().HaveCount(fileNames.Length + 1);
|
||||
WriteFiles(fileNames, result);
|
||||
|
||||
var interfaceIndex = 1;
|
||||
var interfaceIndex = 0;
|
||||
var tree = result.Files[interfaceIndex].SyntaxTree;
|
||||
var root = tree.GetRoot();
|
||||
var interfaceDeclarations = root.DescendantNodes().OfType<InterfaceDeclarationSyntax>();
|
||||
@@ -91,7 +91,7 @@ public class InheritedInterfaceTests
|
||||
result.Files.Should().HaveCount(fileNames.Length + 1);
|
||||
WriteFiles(fileNames, result);
|
||||
|
||||
var interfaceIndex = 1;
|
||||
var interfaceIndex = 0;
|
||||
var tree = result.Files[interfaceIndex].SyntaxTree;
|
||||
var root = tree.GetRoot();
|
||||
var interfaceDeclarations = root.DescendantNodes().OfType<InterfaceDeclarationSyntax>();
|
||||
@@ -148,7 +148,6 @@ public class InheritedInterfaceTests
|
||||
|
||||
// Arrange
|
||||
string[] fileNames = [$"{Namespace}.{interfaceName}.g.cs", $"{Namespace}.{proxyName}.g.cs"];
|
||||
var interfaceIndex = 1;
|
||||
var path = $"./Source/Disposable/{interfaceName}.cs";
|
||||
SourceFile sourceFile = CreateSourceFile(path, name, ImplementationOptions.UseExtendedInterfaces);
|
||||
|
||||
@@ -159,6 +158,7 @@ public class InheritedInterfaceTests
|
||||
result.Files.Should().HaveCount(fileNames.Length + 1);
|
||||
WriteFiles(fileNames, result);
|
||||
|
||||
var interfaceIndex = 0;
|
||||
var tree = result.Files[interfaceIndex].SyntaxTree;
|
||||
var root = tree.GetRoot();
|
||||
var interfaceDeclarations = root.DescendantNodes().OfType<InterfaceDeclarationSyntax>();
|
||||
@@ -209,10 +209,11 @@ public class InheritedInterfaceTests
|
||||
{
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is always last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
File.WriteAllText($"{OutputPath}{fileName.fileName}", builder.Text);
|
||||
builder.Text.Should().Be(File.ReadAllText($"{OutputPath}{fileName.fileName}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ public class PnPTests
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
|
||||
+124
-59
@@ -1,4 +1,76 @@
|
||||
[
|
||||
{
|
||||
HintName: ProxyInterfaceSourceGeneratorTests.Source.IFoo.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 IFoo
|
||||
{
|
||||
global::ProxyInterfaceSourceGeneratorTests.Source.Foo _Instance { get; }
|
||||
|
||||
global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] Foos { get; set; }
|
||||
|
||||
global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] DoSomethingAndGetAnArrayOfFoos();
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
},
|
||||
{
|
||||
HintName: ProxyInterfaceSourceGeneratorTests.Source.FooProxy.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 FooProxy : global::ProxyInterfaceSourceGeneratorTests.Source.IFoo
|
||||
{
|
||||
public global::ProxyInterfaceSourceGeneratorTests.Source.Foo _Instance { get; }
|
||||
|
||||
public global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] Foos { get => Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[]>(_Instance.Foos); set => _Instance.Foos = Mapster.TypeAdapter.Adapt<ProxyInterfaceSourceGeneratorTests.Source.Foo[]>(value); }
|
||||
|
||||
public global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] DoSomethingAndGetAnArrayOfFoos()
|
||||
{
|
||||
var result_1603865878 = _Instance.DoSomethingAndGetAnArrayOfFoos();
|
||||
return Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[]>(result_1603865878);
|
||||
}
|
||||
|
||||
|
||||
public FooProxy(global::ProxyInterfaceSourceGeneratorTests.Source.Foo instance)
|
||||
{
|
||||
_Instance = instance;
|
||||
|
||||
|
||||
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.Foo, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo>.NewConfig().ConstructUsing(instance2058774601 => new global::ProxyInterfaceSourceGeneratorTests.Source.FooProxy(instance2058774601));
|
||||
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo, global::ProxyInterfaceSourceGeneratorTests.Source.Foo>.NewConfig().MapWith(proxy1662609081 => ((global::ProxyInterfaceSourceGeneratorTests.Source.FooProxy) proxy1662609081)._Instance);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
},
|
||||
{
|
||||
HintName: Speckle.ProxyGenerator.Extra.g.cs,
|
||||
Source:
|
||||
@@ -77,79 +149,72 @@ namespace Speckle.ProxyGenerator
|
||||
|
||||
ProxyForBaseInterface = 8
|
||||
}
|
||||
#nullable restore
|
||||
}
|
||||
},
|
||||
{
|
||||
HintName: ProxyInterfaceSourceGeneratorTests.Source.IFoo.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 IFoo
|
||||
public interface IProxyMap
|
||||
{
|
||||
global::ProxyInterfaceSourceGeneratorTests.Source.Foo _Instance { get; }
|
||||
Type? GetMappedTypeFromHostType(Type type);
|
||||
Type? GetMappedTypeFromProxyType(Type type);
|
||||
Type? GetHostTypeFromMappedType(Type type);
|
||||
|
||||
global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] Foos { get; set; }
|
||||
|
||||
global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] DoSomethingAndGetAnArrayOfFoos();
|
||||
object CreateProxy(Type type, object toWrap);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
},
|
||||
{
|
||||
HintName: ProxyInterfaceSourceGeneratorTests.Source.FooProxy.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 FooProxy : global::ProxyInterfaceSourceGeneratorTests.Source.IFoo
|
||||
public class ProxyMap : IProxyMap
|
||||
{
|
||||
public global::ProxyInterfaceSourceGeneratorTests.Source.Foo _Instance { get; }
|
||||
|
||||
public global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] Foos { get => Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[]>(_Instance.Foos); set => _Instance.Foos = Mapster.TypeAdapter.Adapt<ProxyInterfaceSourceGeneratorTests.Source.Foo[]>(value); }
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_revitToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_proxyToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_interfaceToRevit = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Func<object, object>> s_proxyFactory = new();
|
||||
|
||||
public global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[] DoSomethingAndGetAnArrayOfFoos()
|
||||
static ProxyMap()
|
||||
{
|
||||
Add<ProxyInterfaceSourceGeneratorTests.Source.Foo, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo, ProxyInterfaceSourceGeneratorTests.Source.FooProxy>(x => new ProxyInterfaceSourceGeneratorTests.Source.FooProxy(x));
|
||||
|
||||
}
|
||||
|
||||
private static void Add<T, TInterface, TProxy>(Func<T, TProxy> f)
|
||||
where T : class
|
||||
where TInterface : notnull
|
||||
where TProxy : TInterface
|
||||
{
|
||||
s_revitToInterfaceMap.TryAdd(typeof(T), typeof(TInterface));
|
||||
s_proxyToInterfaceMap.TryAdd(typeof(TProxy), typeof(TInterface));
|
||||
s_proxyFactory.TryAdd(typeof(TInterface), w => f((T)w));
|
||||
s_interfaceToRevit.TryAdd(typeof(TInterface), typeof(T));
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromHostType(Type type)
|
||||
{
|
||||
if (s_revitToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
var result_1603865878 = _Instance.DoSomethingAndGetAnArrayOfFoos();
|
||||
return Mapster.TypeAdapter.Adapt<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo[]>(result_1603865878);
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromProxyType(Type type)
|
||||
{
|
||||
if (s_proxyToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public FooProxy(global::ProxyInterfaceSourceGeneratorTests.Source.Foo instance)
|
||||
public Type? GetHostTypeFromMappedType(Type type)
|
||||
{
|
||||
if (s_interfaceToRevit.TryGetValue(type, out var t))
|
||||
{
|
||||
_Instance = instance;
|
||||
|
||||
|
||||
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.Foo, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo>.NewConfig().ConstructUsing(instance2058774601 => new global::ProxyInterfaceSourceGeneratorTests.Source.FooProxy(instance2058774601));
|
||||
Mapster.TypeAdapterConfig<global::ProxyInterfaceSourceGeneratorTests.Source.IFoo, global::ProxyInterfaceSourceGeneratorTests.Source.Foo>.NewConfig().MapWith(proxy1662609081 => ((global::ProxyInterfaceSourceGeneratorTests.Source.FooProxy) proxy1662609081)._Instance);
|
||||
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object CreateProxy(Type type, object toWrap) => s_proxyFactory[type](toWrap);
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
}
|
||||
}
|
||||
]
|
||||
+146
-81
@@ -1,85 +1,4 @@
|
||||
[
|
||||
{
|
||||
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:
|
||||
@@ -159,5 +78,151 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
},
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
public interface IProxyMap
|
||||
{
|
||||
Type? GetMappedTypeFromHostType(Type type);
|
||||
Type? GetMappedTypeFromProxyType(Type type);
|
||||
Type? GetHostTypeFromMappedType(Type type);
|
||||
|
||||
object CreateProxy(Type type, object toWrap);
|
||||
}
|
||||
|
||||
public class ProxyMap : IProxyMap
|
||||
{
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_revitToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_proxyToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_interfaceToRevit = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Func<object, object>> s_proxyFactory = new();
|
||||
|
||||
static ProxyMap()
|
||||
{
|
||||
Add<ProxyInterfaceSourceGeneratorTests.Source.Foo2, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2, ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy>(x => new ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy(x));
|
||||
|
||||
}
|
||||
|
||||
private static void Add<T, TInterface, TProxy>(Func<T, TProxy> f)
|
||||
where T : class
|
||||
where TInterface : notnull
|
||||
where TProxy : TInterface
|
||||
{
|
||||
s_revitToInterfaceMap.TryAdd(typeof(T), typeof(TInterface));
|
||||
s_proxyToInterfaceMap.TryAdd(typeof(TProxy), typeof(TInterface));
|
||||
s_proxyFactory.TryAdd(typeof(TInterface), w => f((T)w));
|
||||
s_interfaceToRevit.TryAdd(typeof(TInterface), typeof(T));
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromHostType(Type type)
|
||||
{
|
||||
if (s_revitToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromProxyType(Type type)
|
||||
{
|
||||
if (s_proxyToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetHostTypeFromMappedType(Type type)
|
||||
{
|
||||
if (s_interfaceToRevit.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object CreateProxy(Type type, object toWrap) => s_proxyFactory[type](toWrap);
|
||||
}
|
||||
#nullable restore
|
||||
}
|
||||
}
|
||||
]
|
||||
+146
-81
@@ -1,85 +1,4 @@
|
||||
[
|
||||
{
|
||||
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:
|
||||
@@ -161,5 +80,151 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
},
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
public interface IProxyMap
|
||||
{
|
||||
Type? GetMappedTypeFromHostType(Type type);
|
||||
Type? GetMappedTypeFromProxyType(Type type);
|
||||
Type? GetHostTypeFromMappedType(Type type);
|
||||
|
||||
object CreateProxy(Type type, object toWrap);
|
||||
}
|
||||
|
||||
public class ProxyMap : IProxyMap
|
||||
{
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_revitToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_proxyToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_interfaceToRevit = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Func<object, object>> s_proxyFactory = new();
|
||||
|
||||
static ProxyMap()
|
||||
{
|
||||
Add<ProxyInterfaceSourceGeneratorTests.Source.Foo2, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo2, ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy>(x => new ProxyInterfaceSourceGeneratorTests.Source.Foo2Proxy(x));
|
||||
|
||||
}
|
||||
|
||||
private static void Add<T, TInterface, TProxy>(Func<T, TProxy> f)
|
||||
where T : class
|
||||
where TInterface : notnull
|
||||
where TProxy : TInterface
|
||||
{
|
||||
s_revitToInterfaceMap.TryAdd(typeof(T), typeof(TInterface));
|
||||
s_proxyToInterfaceMap.TryAdd(typeof(TProxy), typeof(TInterface));
|
||||
s_proxyFactory.TryAdd(typeof(TInterface), w => f((T)w));
|
||||
s_interfaceToRevit.TryAdd(typeof(TInterface), typeof(T));
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromHostType(Type type)
|
||||
{
|
||||
if (s_revitToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromProxyType(Type type)
|
||||
{
|
||||
if (s_proxyToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetHostTypeFromMappedType(Type type)
|
||||
{
|
||||
if (s_interfaceToRevit.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object CreateProxy(Type type, object toWrap) => s_proxyFactory[type](toWrap);
|
||||
}
|
||||
#nullable restore
|
||||
}
|
||||
}
|
||||
]
|
||||
+147
-81
@@ -1,85 +1,4 @@
|
||||
[
|
||||
{
|
||||
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:
|
||||
@@ -209,5 +128,152 @@ namespace ProxyInterfaceSourceGeneratorTests.Source
|
||||
}
|
||||
}
|
||||
#nullable restore
|
||||
},
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
public interface IProxyMap
|
||||
{
|
||||
Type? GetMappedTypeFromHostType(Type type);
|
||||
Type? GetMappedTypeFromProxyType(Type type);
|
||||
Type? GetHostTypeFromMappedType(Type type);
|
||||
|
||||
object CreateProxy(Type type, object toWrap);
|
||||
}
|
||||
|
||||
public class ProxyMap : IProxyMap
|
||||
{
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_revitToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_proxyToInterfaceMap = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Type> s_interfaceToRevit = new();
|
||||
private static readonly global::System.Collections.Concurrent.ConcurrentDictionary<Type, Func<object, object>> s_proxyFactory = new();
|
||||
|
||||
static ProxyMap()
|
||||
{
|
||||
Add<ProxyInterfaceSourceGeneratorTests.Source.Foo3, global::ProxyInterfaceSourceGeneratorTests.Source.IFoo3, ProxyInterfaceSourceGeneratorTests.Source.Foo3Proxy>(x => new ProxyInterfaceSourceGeneratorTests.Source.Foo3Proxy(x));
|
||||
Add<ProxyInterfaceSourceGeneratorTests.Source.Bar3, global::ProxyInterfaceSourceGeneratorTests.Source.IBar3, ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy>(x => new ProxyInterfaceSourceGeneratorTests.Source.Bar3Proxy(x));
|
||||
|
||||
}
|
||||
|
||||
private static void Add<T, TInterface, TProxy>(Func<T, TProxy> f)
|
||||
where T : class
|
||||
where TInterface : notnull
|
||||
where TProxy : TInterface
|
||||
{
|
||||
s_revitToInterfaceMap.TryAdd(typeof(T), typeof(TInterface));
|
||||
s_proxyToInterfaceMap.TryAdd(typeof(TProxy), typeof(TInterface));
|
||||
s_proxyFactory.TryAdd(typeof(TInterface), w => f((T)w));
|
||||
s_interfaceToRevit.TryAdd(typeof(TInterface), typeof(T));
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromHostType(Type type)
|
||||
{
|
||||
if (s_revitToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetMappedTypeFromProxyType(Type type)
|
||||
{
|
||||
if (s_proxyToInterfaceMap.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type? GetHostTypeFromMappedType(Type type)
|
||||
{
|
||||
if (s_interfaceToRevit.TryGetValue(type, out var t))
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object CreateProxy(Type type, object toWrap) => s_proxyFactory[type](toWrap);
|
||||
}
|
||||
#nullable restore
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -248,7 +248,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
@@ -288,7 +288,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
@@ -328,7 +328,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index ]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
@@ -376,7 +376,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
@@ -416,7 +416,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
|
||||
foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index }))
|
||||
{
|
||||
var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute
|
||||
var builder = result.Files[fileName.index]; // attribute is last
|
||||
builder.Path.Should().EndWith(fileName.fileName);
|
||||
|
||||
if (Write)
|
||||
@@ -458,11 +458,11 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
result.Files.Should().HaveCount(3);
|
||||
|
||||
// Assert attribute
|
||||
var attribute = result.Files[0].SyntaxTree;
|
||||
var attribute = result.Files.Last().SyntaxTree;
|
||||
attribute.FilePath.Should().EndWith(attributeFilename);
|
||||
|
||||
// Assert interface
|
||||
var @interface = result.Files[1].SyntaxTree;
|
||||
var @interface = result.Files[0].SyntaxTree;
|
||||
@interface.FilePath.Should().EndWith(interfaceFilename);
|
||||
|
||||
var interfaceCode = @interface.ToString();
|
||||
@@ -474,7 +474,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
.And.Be(File.ReadAllText($"../../../Destination/{interfaceFilename}"));
|
||||
|
||||
// Assert Proxy
|
||||
var proxyClass = result.Files[2].SyntaxTree;
|
||||
var proxyClass = result.Files[1].SyntaxTree;
|
||||
proxyClass.FilePath.Should().EndWith(proxyClassFilename);
|
||||
|
||||
var proxyCode = proxyClass.ToString();
|
||||
@@ -518,7 +518,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
result.Files.Should().HaveCount(3);
|
||||
|
||||
// Assert interface
|
||||
var @interface = result.Files[1].SyntaxTree;
|
||||
var @interface = result.Files[0].SyntaxTree;
|
||||
@interface.FilePath.Should().EndWith(interfaceFilename);
|
||||
|
||||
var interfaceCode = @interface.ToString();
|
||||
@@ -530,7 +530,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
.And.Be(File.ReadAllText($"../../../Destination/{interfaceFilename}"));
|
||||
|
||||
// Assert Proxy
|
||||
var proxyClass = result.Files[2].SyntaxTree;
|
||||
var proxyClass = result.Files[1].SyntaxTree;
|
||||
proxyClass.FilePath.Should().EndWith(proxyClassFilename);
|
||||
|
||||
var proxyCode = proxyClass.ToString();
|
||||
@@ -584,11 +584,11 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
result.Files.Should().HaveCount(5);
|
||||
|
||||
// Assert attribute
|
||||
var attribute = result.Files[0].SyntaxTree;
|
||||
var attribute = result.Files.Last().SyntaxTree;
|
||||
attribute.FilePath.Should().EndWith(attributeFilename);
|
||||
|
||||
// Assert interface Human
|
||||
var interfaceHuman = result.Files[1].SyntaxTree;
|
||||
var interfaceHuman = result.Files[0].SyntaxTree;
|
||||
interfaceHuman.FilePath.Should().EndWith(interfaceHumanFilename);
|
||||
|
||||
var interfaceCodeHuman = interfaceHuman.ToString();
|
||||
@@ -600,7 +600,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
.And.Be(File.ReadAllText($"../../../Destination/{interfaceHumanFilename}"));
|
||||
|
||||
// Assert interface Person
|
||||
var interfacePerson = result.Files[2].SyntaxTree;
|
||||
var interfacePerson = result.Files[1].SyntaxTree;
|
||||
interfacePerson.FilePath.Should().EndWith(interfacePersonFilename);
|
||||
|
||||
var interfaceCodePerson = interfacePerson.ToString();
|
||||
@@ -690,11 +690,11 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
result.Files.Should().HaveCount(5);
|
||||
|
||||
// Assert attribute
|
||||
var attribute = result.Files[0].SyntaxTree;
|
||||
var attribute = result.Files.Last().SyntaxTree;
|
||||
attribute.FilePath.Should().EndWith(attributeFilename);
|
||||
|
||||
// Assert interface IHttpClient
|
||||
var interfaceIHttpClient = result.Files[1].SyntaxTree;
|
||||
var interfaceIHttpClient = result.Files[0].SyntaxTree;
|
||||
interfaceIHttpClient.FilePath.Should().EndWith(interfaceIHttpClientFilename);
|
||||
|
||||
var interfaceCodeIHttpClient = interfaceIHttpClient.ToString();
|
||||
@@ -709,7 +709,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
.And.Be(File.ReadAllText($"../../../Destination/{interfaceIHttpClientFilename}"));
|
||||
|
||||
// Assert interface IHttpMessageInvoker
|
||||
var interfaceIMessageInvoker = result.Files[2].SyntaxTree;
|
||||
var interfaceIMessageInvoker = result.Files[1].SyntaxTree;
|
||||
interfaceIMessageInvoker.FilePath.Should().EndWith(interfaceIHttpMessageInvokerFilename);
|
||||
|
||||
var interfaceCodeIMessageInvoker = interfaceIMessageInvoker.ToString();
|
||||
@@ -795,11 +795,11 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
result.Files.Should().HaveCount(3);
|
||||
|
||||
// Assert attribute
|
||||
var attribute = result.Files[0].SyntaxTree;
|
||||
var attribute = result.Files.Last().SyntaxTree;
|
||||
attribute.FilePath.Should().EndWith(attributeFilename);
|
||||
|
||||
// Assert interface
|
||||
var @interface = result.Files[1].SyntaxTree;
|
||||
var @interface = result.Files[0].SyntaxTree;
|
||||
@interface.FilePath.Should().EndWith(interfaceFilename);
|
||||
|
||||
var interfaceCode = @interface.ToString();
|
||||
@@ -811,7 +811,7 @@ public class ProxyInterfaceSourceGeneratorTest
|
||||
.And.Be(File.ReadAllText($"../../../Destination/{interfaceFilename}"));
|
||||
|
||||
// Assert Proxy
|
||||
var proxyClass = result.Files[2].SyntaxTree;
|
||||
var proxyClass = result.Files[1].SyntaxTree;
|
||||
proxyClass.FilePath.Should().EndWith(proxyClassFilename);
|
||||
|
||||
var proxyCode = proxyClass.ToString();
|
||||
|
||||
Reference in New Issue
Block a user