update and format
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"isRoot": true,
|
||||||
|
"tools": {
|
||||||
|
"csharpier": {
|
||||||
|
"version": "0.28.2",
|
||||||
|
"commands": [
|
||||||
|
"dotnet-csharpier"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using FluentAssertions.Common;
|
using FluentAssertions.Common;
|
||||||
@@ -18,7 +19,11 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void GetSetIndexer_IsImplemented()
|
public void GetSetIndexer_IsImplemented()
|
||||||
{
|
{
|
||||||
var indexer = typeof(IAccessorsTestsService).GetIndexerByParameterTypes(new[] { typeof(string) });
|
var indexer = typeof(IAccessorsTestsService)
|
||||||
|
.GetProperties()
|
||||||
|
.First(x =>
|
||||||
|
x.GetIndexParameters().Select(x => x.ParameterType).Contains(typeof(string))
|
||||||
|
);
|
||||||
|
|
||||||
indexer.Should().NotBeNull();
|
indexer.Should().NotBeNull();
|
||||||
|
|
||||||
@@ -32,8 +37,10 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void PublicProperty_IsImplemented()
|
public void PublicProperty_IsImplemented()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop =
|
||||||
.GetProperty(nameof(IAccessorsTestsService.PublicProperty)) ?? throw new InvalidOperationException();
|
typeof(IAccessorsTestsService).GetProperty(
|
||||||
|
nameof(IAccessorsTestsService.PublicProperty)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
@@ -47,15 +54,19 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void InitProperty_IsImplemented()
|
public void InitProperty_IsImplemented()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop =
|
||||||
.GetProperty(nameof(IAccessorsTestsService.InitOnlyProperty)) ?? throw new InvalidOperationException();
|
typeof(IAccessorsTestsService).GetProperty(
|
||||||
|
nameof(IAccessorsTestsService.InitOnlyProperty)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
prop.GetMethod.Should().NotBeNull();
|
prop.GetMethod.Should().NotBeNull();
|
||||||
prop.SetMethod.Should().NotBeNull();
|
prop.SetMethod.Should().NotBeNull();
|
||||||
|
|
||||||
prop.SetMethod?.ReturnParameter?.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit));
|
prop.SetMethod?.ReturnParameter?.GetRequiredCustomModifiers()
|
||||||
|
.Should()
|
||||||
|
.Contain(typeof(IsExternalInit));
|
||||||
|
|
||||||
var _ = _sut.InitOnlyProperty;
|
var _ = _sut.InitOnlyProperty;
|
||||||
}
|
}
|
||||||
@@ -63,8 +74,10 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void PrivateSetter_IsOmitted()
|
public void PrivateSetter_IsOmitted()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop =
|
||||||
.GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateSetter)) ?? throw new InvalidOperationException();
|
typeof(IAccessorsTestsService).GetProperty(
|
||||||
|
nameof(IAccessorsTestsService.PropertyWithPrivateSetter)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
@@ -77,8 +90,10 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void PrivateGetter_IsOmitted()
|
public void PrivateGetter_IsOmitted()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop =
|
||||||
.GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateGetter)) ?? throw new InvalidOperationException();
|
typeof(IAccessorsTestsService).GetProperty(
|
||||||
|
nameof(IAccessorsTestsService.PropertyWithPrivateGetter)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
@@ -91,8 +106,10 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void ProtectedSetter_IsOmitted()
|
public void ProtectedSetter_IsOmitted()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop =
|
||||||
.GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedSetter)) ?? throw new InvalidOperationException();
|
typeof(IAccessorsTestsService).GetProperty(
|
||||||
|
nameof(IAccessorsTestsService.PropertyWithProtectedSetter)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
@@ -105,8 +122,10 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void ProtectedGetter_IsOmitted()
|
public void ProtectedGetter_IsOmitted()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop =
|
||||||
.GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedGetter)) ?? throw new InvalidOperationException();
|
typeof(IAccessorsTestsService).GetProperty(
|
||||||
|
nameof(IAccessorsTestsService.PropertyWithProtectedGetter)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
@@ -119,8 +138,9 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void IgnoredProperty_IsOmitted()
|
public void IgnoredProperty_IsOmitted()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop = typeof(IAccessorsTestsService).GetProperty(
|
||||||
.GetProperty(nameof(AccessorsTestsService.IgnoredProperty));
|
nameof(AccessorsTestsService.IgnoredProperty)
|
||||||
|
);
|
||||||
|
|
||||||
prop.Should().BeNull();
|
prop.Should().BeNull();
|
||||||
}
|
}
|
||||||
@@ -128,8 +148,9 @@ public class AccessorsGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void StaticProperty_IsOmitted()
|
public void StaticProperty_IsOmitted()
|
||||||
{
|
{
|
||||||
var prop = typeof(IAccessorsTestsService)
|
var prop = typeof(IAccessorsTestsService).GetProperty(
|
||||||
.GetProperty(nameof(AccessorsTestsService.StaticProperty));
|
nameof(AccessorsTestsService.StaticProperty)
|
||||||
|
);
|
||||||
|
|
||||||
prop.Should().BeNull();
|
prop.Should().BeNull();
|
||||||
}
|
}
|
||||||
@@ -142,9 +163,7 @@ internal class AccessorsTestsService : IAccessorsTestsService
|
|||||||
public int this[string x]
|
public int this[string x]
|
||||||
{
|
{
|
||||||
get => 0;
|
get => 0;
|
||||||
set
|
set { }
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string PublicProperty { get; set; }
|
public string PublicProperty { get; set; }
|
||||||
@@ -159,8 +178,9 @@ internal class AccessorsTestsService : IAccessorsTestsService
|
|||||||
|
|
||||||
public string PropertyWithProtectedGetter { protected get; set; }
|
public string PropertyWithProtectedGetter { protected get; set; }
|
||||||
|
|
||||||
[AutoInterfaceIgnore] public string IgnoredProperty { get; set; }
|
[AutoInterfaceIgnore]
|
||||||
|
public string IgnoredProperty { get; set; }
|
||||||
|
|
||||||
public static string StaticProperty { get; set; }
|
public static string StaticProperty { get; set; }
|
||||||
}
|
}
|
||||||
// ReSharper enable UnusedMember.Local, ValueParameterNotUsed
|
// ReSharper enable UnusedMember.Local, ValueParameterNotUsed
|
||||||
|
|||||||
@@ -18,12 +18,15 @@ public class GenericInterfaceTests
|
|||||||
|
|
||||||
genericArgs[0].IsClass.Should().BeTrue();
|
genericArgs[0].IsClass.Should().BeTrue();
|
||||||
genericArgs[0]
|
genericArgs[0]
|
||||||
.GenericParameterAttributes
|
.GenericParameterAttributes.Should()
|
||||||
.Should()
|
|
||||||
.HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint);
|
.HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint);
|
||||||
|
|
||||||
var iEquatableOfTx = typeof(IEquatable<>).MakeGenericType(genericArgs[0]);
|
var iEquatableOfTx = typeof(IEquatable<>).MakeGenericType(genericArgs[0]);
|
||||||
genericArgs[0].GetGenericParameterConstraints().Should().HaveCount(1).And.Contain(iEquatableOfTx);
|
genericArgs[0]
|
||||||
|
.GetGenericParameterConstraints()
|
||||||
|
.Should()
|
||||||
|
.HaveCount(1)
|
||||||
|
.And.Contain(iEquatableOfTx);
|
||||||
|
|
||||||
genericArgs[1].IsValueType.Should().BeTrue();
|
genericArgs[1].IsValueType.Should().BeTrue();
|
||||||
}
|
}
|
||||||
@@ -33,6 +36,4 @@ public class GenericInterfaceTests
|
|||||||
// ReSharper disable once UnusedType.Global
|
// ReSharper disable once UnusedType.Global
|
||||||
internal class GenericInterfaceTestsService<TX, TY> : IGenericInterfaceTestsService<TX, TY>
|
internal class GenericInterfaceTestsService<TX, TY> : IGenericInterfaceTestsService<TX, TY>
|
||||||
where TX : class, IEquatable<TX>, new()
|
where TX : class, IEquatable<TX>, new()
|
||||||
where TY : struct
|
where TY : struct { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VoidMethod_IsImplemented()
|
public void VoidMethod_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.VoidMethod)) ?? throw new InvalidOperationException();
|
typeof(IMethodsTestService).GetMethod(nameof(MethodsTestService.VoidMethod))
|
||||||
|
?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -34,8 +35,10 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VoidMethodWithKeywordParam_IsImplemented()
|
public void VoidMethodWithKeywordParam_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.VoidMethodWithKeywordParam)) ?? throw new InvalidOperationException();
|
typeof(IMethodsTestService).GetMethod(
|
||||||
|
nameof(MethodsTestService.VoidMethodWithKeywordParam)
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -52,9 +55,11 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VoidMethodWithParams_IsImplemented()
|
public void VoidMethodWithParams_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.VoidMethodWithParams),
|
typeof(IMethodsTestService).GetMethod(
|
||||||
[typeof(string), typeof(string)]) ?? throw new InvalidOperationException();
|
nameof(MethodsTestService.VoidMethodWithParams),
|
||||||
|
[typeof(string), typeof(string)]
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -69,15 +74,20 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VoidMethodWithOutParam_IsImplemented()
|
public void VoidMethodWithOutParam_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.VoidMethodWithOutParam),
|
typeof(IMethodsTestService).GetMethod(
|
||||||
[typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException();
|
nameof(MethodsTestService.VoidMethodWithOutParam),
|
||||||
|
[typeof(string).MakeByRefType()]
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
|
|
||||||
var parameters = method.GetParameters();
|
var parameters = method.GetParameters();
|
||||||
parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType());
|
parameters
|
||||||
|
.Select(x => x.ParameterType)
|
||||||
|
.Should()
|
||||||
|
.AllBeEquivalentTo(typeof(string).MakeByRefType());
|
||||||
parameters.Should().HaveCount(1);
|
parameters.Should().HaveCount(1);
|
||||||
parameters[0].IsOut.Should().BeTrue();
|
parameters[0].IsOut.Should().BeTrue();
|
||||||
|
|
||||||
@@ -87,15 +97,20 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VoidMethodWithInParam_IsImplemented()
|
public void VoidMethodWithInParam_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.VoidMethodWithInParam),
|
typeof(IMethodsTestService).GetMethod(
|
||||||
[typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException();
|
nameof(MethodsTestService.VoidMethodWithInParam),
|
||||||
|
[typeof(string).MakeByRefType()]
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
|
|
||||||
var parameters = method.GetParameters();
|
var parameters = method.GetParameters();
|
||||||
parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType());
|
parameters
|
||||||
|
.Select(x => x.ParameterType)
|
||||||
|
.Should()
|
||||||
|
.AllBeEquivalentTo(typeof(string).MakeByRefType());
|
||||||
parameters.Should().HaveCount(1);
|
parameters.Should().HaveCount(1);
|
||||||
parameters[0].IsIn.Should().BeTrue();
|
parameters[0].IsIn.Should().BeTrue();
|
||||||
|
|
||||||
@@ -106,15 +121,20 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void VoidMethodWithRefParam_IsImplemented()
|
public void VoidMethodWithRefParam_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.VoidMethodWithRefParam),
|
typeof(IMethodsTestService).GetMethod(
|
||||||
[typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException();
|
nameof(MethodsTestService.VoidMethodWithRefParam),
|
||||||
|
[typeof(string).MakeByRefType()]
|
||||||
|
) ?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
|
|
||||||
var parameters = method.GetParameters();
|
var parameters = method.GetParameters();
|
||||||
parameters.Select(x => x.ParameterType).Should().AllBeEquivalentTo(typeof(string).MakeByRefType());
|
parameters
|
||||||
|
.Select(x => x.ParameterType)
|
||||||
|
.Should()
|
||||||
|
.AllBeEquivalentTo(typeof(string).MakeByRefType());
|
||||||
parameters.Should().HaveCount(1);
|
parameters.Should().HaveCount(1);
|
||||||
parameters[0].IsIn.Should().BeFalse();
|
parameters[0].IsIn.Should().BeFalse();
|
||||||
parameters[0].IsOut.Should().BeFalse();
|
parameters[0].IsOut.Should().BeFalse();
|
||||||
@@ -126,8 +146,9 @@ public class MethodGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void StringMethod_IsImplemented()
|
public void StringMethod_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService).GetMethod(
|
var method =
|
||||||
nameof(MethodsTestService.StringMethod)) ?? throw new InvalidOperationException();
|
typeof(IMethodsTestService).GetMethod(nameof(MethodsTestService.StringMethod))
|
||||||
|
?? throw new InvalidOperationException();
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(string));
|
method.ReturnType.Should().Be(typeof(string));
|
||||||
@@ -142,8 +163,8 @@ public class MethodGenerationTests
|
|||||||
public void GenericVoidMethod_IsImplemented()
|
public void GenericVoidMethod_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.First(x => x.Name == nameof(MethodsTestService.GenericVoidMethod));
|
.First(x => x.Name == nameof(MethodsTestService.GenericVoidMethod));
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -160,8 +181,8 @@ public class MethodGenerationTests
|
|||||||
public void GenericVoidMethodWithGenericParam_IsImplemented()
|
public void GenericVoidMethodWithGenericParam_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithGenericParam));
|
.First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithGenericParam));
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -180,8 +201,8 @@ public class MethodGenerationTests
|
|||||||
public void GenericVoidMethodWithConstraints_IsImplemented()
|
public void GenericVoidMethodWithConstraints_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithConstraints));
|
.First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithConstraints));
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -206,8 +227,8 @@ public class MethodGenerationTests
|
|||||||
public void VoidMethodWithOptionalParams_IsImplemented()
|
public void VoidMethodWithOptionalParams_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.First(x => x.Name == nameof(MethodsTestService.VoidMethodWithOptionalParams));
|
.First(x => x.Name == nameof(MethodsTestService.VoidMethodWithOptionalParams));
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -226,7 +247,7 @@ public class MethodGenerationTests
|
|||||||
parameters[7].DefaultValue.Should().Be(true);
|
parameters[7].DefaultValue.Should().Be(true);
|
||||||
parameters[8].DefaultValue.Should().Be(false);
|
parameters[8].DefaultValue.Should().Be(false);
|
||||||
parameters[9].DefaultValue.Should().Be(null);
|
parameters[9].DefaultValue.Should().Be(null);
|
||||||
|
|
||||||
_sut.VoidMethodWithOptionalParams();
|
_sut.VoidMethodWithOptionalParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,8 +255,8 @@ public class MethodGenerationTests
|
|||||||
public void VoidMethodWithExpandingParam_IsImplemented()
|
public void VoidMethodWithExpandingParam_IsImplemented()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.First(x => x.Name == nameof(MethodsTestService.VoidMethodWithExpandingParam));
|
.First(x => x.Name == nameof(MethodsTestService.VoidMethodWithExpandingParam));
|
||||||
|
|
||||||
method.ReturnType.Should().Be(typeof(void));
|
method.ReturnType.Should().Be(typeof(void));
|
||||||
|
|
||||||
@@ -249,8 +270,8 @@ public class MethodGenerationTests
|
|||||||
public void IgnoreMethod_IsOmitted()
|
public void IgnoreMethod_IsOmitted()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.FirstOrDefault(x => x.Name == nameof(MethodsTestService.IgnoredMethod));
|
.FirstOrDefault(x => x.Name == nameof(MethodsTestService.IgnoredMethod));
|
||||||
|
|
||||||
method.Should().BeNull();
|
method.Should().BeNull();
|
||||||
}
|
}
|
||||||
@@ -259,8 +280,8 @@ public class MethodGenerationTests
|
|||||||
public void StaticMethod_IsOmitted()
|
public void StaticMethod_IsOmitted()
|
||||||
{
|
{
|
||||||
var method = typeof(IMethodsTestService)
|
var method = typeof(IMethodsTestService)
|
||||||
.GetMethods()
|
.GetMethods()
|
||||||
.FirstOrDefault(x => x.Name == nameof(MethodsTestService.StaticMethod));
|
.FirstOrDefault(x => x.Name == nameof(MethodsTestService.StaticMethod));
|
||||||
|
|
||||||
method.Should().BeNull();
|
method.Should().BeNull();
|
||||||
}
|
}
|
||||||
@@ -271,49 +292,33 @@ internal class MethodsTestService : IMethodsTestService
|
|||||||
{
|
{
|
||||||
public const string StringConstant = "Const";
|
public const string StringConstant = "Const";
|
||||||
|
|
||||||
public void VoidMethod()
|
public void VoidMethod() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VoidMethodWithParams(string a, string b)
|
public void VoidMethodWithParams(string a, string b) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VoidMethodWithKeywordParam(string @void)
|
public void VoidMethodWithKeywordParam(string @void) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VoidMethodWithOutParam(out string a)
|
public void VoidMethodWithOutParam(out string a)
|
||||||
{
|
{
|
||||||
a = default;
|
a = default;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void VoidMethodWithRefParam(ref string a)
|
public void VoidMethodWithRefParam(ref string a) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VoidMethodWithInParam(in string a)
|
public void VoidMethodWithInParam(in string a) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string StringMethod()
|
public string StringMethod()
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GenericVoidMethod<TX, TY>()
|
public void GenericVoidMethod<TX, TY>() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GenericVoidMethodWithGenericParam<TX, TY>(TX a)
|
public void GenericVoidMethodWithGenericParam<TX, TY>(TX a) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GenericVoidMethodWithConstraints<TX, TY>()
|
public void GenericVoidMethodWithConstraints<TX, TY>()
|
||||||
where TX : class
|
where TX : class
|
||||||
where TY : class, TX, new()
|
where TY : class, TX, new() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void VoidMethodWithOptionalParams(
|
public void VoidMethodWithOptionalParams(
|
||||||
string stringLiteral = "cGFyYW0=",
|
string stringLiteral = "cGFyYW0=",
|
||||||
@@ -325,25 +330,17 @@ internal class MethodsTestService : IMethodsTestService
|
|||||||
bool falseLiteral = false,
|
bool falseLiteral = false,
|
||||||
bool? nullableTrueLiteral = true,
|
bool? nullableTrueLiteral = true,
|
||||||
bool? nullableFalseLiteral = false,
|
bool? nullableFalseLiteral = false,
|
||||||
bool? nullableNullBoolLiteral = null)
|
bool? nullableNullBoolLiteral = null
|
||||||
{
|
) { }
|
||||||
}
|
|
||||||
|
|
||||||
public void VoidMethodWithExpandingParam(params string[] strings)
|
public void VoidMethodWithExpandingParam(params string[] strings) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[AutoInterfaceIgnore]
|
[AutoInterfaceIgnore]
|
||||||
public void IgnoredMethod()
|
public void IgnoredMethod() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void StaticMethod()
|
public static void StaticMethod() { }
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
internal class MethodsTestServiceGeneric<T> : IMethodsTestServiceGeneric<T> where T : class
|
internal class MethodsTestServiceGeneric<T> : IMethodsTestServiceGeneric<T>
|
||||||
{
|
where T : class { }
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
namespace Speckle.InterfaceGenerator.Tests.Partial;
|
namespace Speckle.InterfaceGenerator.Tests.Partial;
|
||||||
|
|
||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
internal partial class PartialClass : IPartialClass
|
internal partial class PartialClass : IPartialClass { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,7 +2,5 @@ namespace Speckle.InterfaceGenerator.Tests.Partial;
|
|||||||
|
|
||||||
internal partial class PartialClass
|
internal partial class PartialClass
|
||||||
{
|
{
|
||||||
public void SomeMethodThatShouldGenerate()
|
public void SomeMethodThatShouldGenerate() { }
|
||||||
{
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ public class PartialClassTests
|
|||||||
public void GeneratesMethodFromOtherParts()
|
public void GeneratesMethodFromOtherParts()
|
||||||
{
|
{
|
||||||
var tInterface = typeof(IPartialClass);
|
var tInterface = typeof(IPartialClass);
|
||||||
tInterface.GetMethods().Should().Contain(x => x.Name == nameof(PartialClass.SomeMethodThatShouldGenerate));
|
tInterface
|
||||||
|
.GetMethods()
|
||||||
|
.Should()
|
||||||
|
.Contain(x => x.Name == nameof(PartialClass.SomeMethodThatShouldGenerate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,17 @@ public class RecordInterfaceGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void RecordProperty_IsGenerated()
|
public void RecordProperty_IsGenerated()
|
||||||
{
|
{
|
||||||
var prop = typeof(ITestRecord)
|
var prop =
|
||||||
.GetProperty(nameof(TestRecord.RecordProperty)) ?? throw new InvalidOperationException();
|
typeof(ITestRecord).GetProperty(nameof(TestRecord.RecordProperty))
|
||||||
|
?? throw new InvalidOperationException();
|
||||||
|
|
||||||
prop.Should().NotBeNull();
|
prop.Should().NotBeNull();
|
||||||
|
|
||||||
prop.GetMethod.Should().NotBeNull();
|
prop.GetMethod.Should().NotBeNull();
|
||||||
prop.SetMethod.Should().NotBeNull();
|
prop.SetMethod.Should().NotBeNull();
|
||||||
prop.SetMethod?.ReturnParameter?.GetRequiredCustomModifiers().Should().Contain(typeof(IsExternalInit));
|
prop.SetMethod?.ReturnParameter?.GetRequiredCustomModifiers()
|
||||||
|
.Should()
|
||||||
|
.Contain(typeof(IsExternalInit));
|
||||||
|
|
||||||
_sut.RecordProperty.Should().Be(420);
|
_sut.RecordProperty.Should().Be(420);
|
||||||
}
|
}
|
||||||
@@ -32,8 +35,7 @@ public class RecordInterfaceGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void RecordMethod_IsGenerated()
|
public void RecordMethod_IsGenerated()
|
||||||
{
|
{
|
||||||
var method = typeof(ITestRecord).GetMethod(
|
var method = typeof(ITestRecord).GetMethod(nameof(TestRecord.RecordMethod));
|
||||||
nameof(TestRecord.RecordMethod));
|
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method?.ReturnType.Should().Be(typeof(void));
|
method?.ReturnType.Should().Be(typeof(void));
|
||||||
@@ -47,13 +49,12 @@ public class RecordInterfaceGenerationTests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void Deconstruct_IsGenerated()
|
public void Deconstruct_IsGenerated()
|
||||||
{
|
{
|
||||||
var method = typeof(ITestRecord).GetMethod(
|
var method = typeof(ITestRecord).GetMethod(nameof(TestRecord.Deconstruct));
|
||||||
nameof(TestRecord.Deconstruct));
|
|
||||||
|
|
||||||
method.Should().NotBeNull();
|
method.Should().NotBeNull();
|
||||||
method?.ReturnType.Should().Be(typeof(void));
|
method?.ReturnType.Should().Be(typeof(void));
|
||||||
|
|
||||||
var parameters = method?.GetParameters() ?? throw new InvalidOperationException();
|
var parameters = method?.GetParameters() ?? throw new InvalidOperationException();
|
||||||
parameters.Length.Should().Be(1);
|
parameters.Length.Should().Be(1);
|
||||||
|
|
||||||
var parameter = parameters[0];
|
var parameter = parameters[0];
|
||||||
@@ -65,7 +66,5 @@ public class RecordInterfaceGenerationTests
|
|||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
internal record TestRecord(int RecordProperty) : ITestRecord
|
internal record TestRecord(int RecordProperty) : ITestRecord
|
||||||
{
|
{
|
||||||
public void RecordMethod()
|
public void RecordMethod() { }
|
||||||
{
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,7 +9,4 @@ namespace InterfaceGenerator.Tests.SameName_1;
|
|||||||
/// qualified names.
|
/// qualified names.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
internal class SameNameClass : ISameNameClass
|
internal class SameNameClass : ISameNameClass { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,7 +5,4 @@ using Speckle.InterfaceGenerator;
|
|||||||
namespace InterfaceGenerator.Tests.SameName_2;
|
namespace InterfaceGenerator.Tests.SameName_2;
|
||||||
|
|
||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
internal class SameNameClass : ISameNameClass
|
internal class SameNameClass : ISameNameClass { }
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="FluentAssertions" Version="5.10.3" />
|
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.8.0" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\InterfaceGenerator\Speckle.InterfaceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
<ProjectReference Include="..\Speckle.InterfaceGenerator\Speckle.InterfaceGenerator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -36,21 +36,13 @@ public class VisibilityModifierTests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[GenerateAutoInterface(VisibilityModifier = "public")]
|
[GenerateAutoInterface(VisibilityModifier = "public")]
|
||||||
internal class ExplicitlyPublicService : IExplicitlyPublicService
|
internal class ExplicitlyPublicService : IExplicitlyPublicService { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[GenerateAutoInterface(VisibilityModifier = "internal")]
|
[GenerateAutoInterface(VisibilityModifier = "internal")]
|
||||||
public class ExplicitlyInternalService : IExplicitlyInternalService
|
public class ExplicitlyInternalService : IExplicitlyInternalService { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
public class ImplicitlyPublicService : IImplicitlyPublicService
|
public class ImplicitlyPublicService : IImplicitlyPublicService { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[GenerateAutoInterface]
|
[GenerateAutoInterface]
|
||||||
internal class ImplicitlyInternalService : IImplicitlyInternalService
|
internal class ImplicitlyInternalService : IImplicitlyInternalService { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ internal static class AttributeDataExtensions
|
|||||||
var pair = attributeData.NamedArguments.FirstOrDefault(x => x.Key == paramName);
|
var pair = attributeData.NamedArguments.FirstOrDefault(x => x.Key == paramName);
|
||||||
return pair.Value.Value?.ToString();
|
return pair.Value.Value?.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ internal class Attributes
|
|||||||
|
|
||||||
public const string VisibilityModifierPropName = "VisibilityModifier";
|
public const string VisibilityModifierPropName = "VisibilityModifier";
|
||||||
public const string InterfaceNamePropName = "Name";
|
public const string InterfaceNamePropName = "Name";
|
||||||
|
|
||||||
public static readonly string AttributesSourceCode = $@"
|
public static readonly string AttributesSourceCode =
|
||||||
|
$@"
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
@@ -38,4 +39,4 @@ namespace {AttributesNamespace}
|
|||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
";
|
";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,10 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RaiseExceptionDiagnostic(GeneratorExecutionContext context, Exception exception)
|
private static void RaiseExceptionDiagnostic(
|
||||||
|
GeneratorExecutionContext context,
|
||||||
|
Exception exception
|
||||||
|
)
|
||||||
{
|
{
|
||||||
var descriptor = new DiagnosticDescriptor(
|
var descriptor = new DiagnosticDescriptor(
|
||||||
"Speckle.InterfaceGenerator.CriticalError",
|
"Speckle.InterfaceGenerator.CriticalError",
|
||||||
@@ -53,13 +56,14 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
"Speckle.InterfaceGenerator",
|
"Speckle.InterfaceGenerator",
|
||||||
DiagnosticSeverity.Error,
|
DiagnosticSeverity.Error,
|
||||||
true,
|
true,
|
||||||
customTags: WellKnownDiagnosticTags.AnalyzerException);
|
customTags: WellKnownDiagnosticTags.AnalyzerException
|
||||||
|
);
|
||||||
|
|
||||||
var diagnostic = Diagnostic.Create(descriptor, null);
|
var diagnostic = Diagnostic.Create(descriptor, null);
|
||||||
|
|
||||||
context.ReportDiagnostic(diagnostic);
|
context.ReportDiagnostic(diagnostic);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ExecuteCore(GeneratorExecutionContext context)
|
private void ExecuteCore(GeneratorExecutionContext context)
|
||||||
{
|
{
|
||||||
// setting the culture to invariant prevents errors such as emitting a decimal comma (0,1) instead of
|
// setting the culture to invariant prevents errors such as emitting a decimal comma (0,1) instead of
|
||||||
@@ -77,7 +81,8 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
{
|
{
|
||||||
context.AddSource(
|
context.AddSource(
|
||||||
Attributes.GenerateAutoInterfaceClassname,
|
Attributes.GenerateAutoInterfaceClassname,
|
||||||
SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8));
|
SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateInterfaces(GeneratorExecutionContext context)
|
private void GenerateInterfaces(GeneratorExecutionContext context)
|
||||||
@@ -96,26 +101,47 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
|
|
||||||
foreach (var implTypeSymbol in classSymbols)
|
foreach (var implTypeSymbol in classSymbols)
|
||||||
{
|
{
|
||||||
if (!implTypeSymbol.TryGetAttribute(_generateAutoInterfaceAttribute ?? throw new NullReferenceException("_generateAutoInterfaceAttribute is null"), out var attributes))
|
if (
|
||||||
|
!implTypeSymbol.TryGetAttribute(
|
||||||
|
_generateAutoInterfaceAttribute
|
||||||
|
?? throw new NullReferenceException(
|
||||||
|
"_generateAutoInterfaceAttribute is null"
|
||||||
|
),
|
||||||
|
out var attributes
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(classSymbolNames.Contains(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)))
|
if (
|
||||||
|
classSymbolNames.Contains(
|
||||||
|
implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
continue; // partial class, already added
|
continue; // partial class, already added
|
||||||
}
|
}
|
||||||
|
|
||||||
classSymbolNames.Add(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true));
|
classSymbolNames.Add(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true));
|
||||||
|
|
||||||
var attribute = attributes.Single();
|
var attribute = attributes.Single();
|
||||||
var source = SourceText.From(GenerateInterfaceCode(implTypeSymbol, attribute), Encoding.UTF8);
|
var source = SourceText.From(
|
||||||
|
GenerateInterfaceCode(implTypeSymbol, attribute),
|
||||||
|
Encoding.UTF8
|
||||||
|
);
|
||||||
|
|
||||||
context.AddSource($"{implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)}_AutoInterface.g.cs", source);
|
context.AddSource(
|
||||||
|
$"{implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)}_AutoInterface.g.cs",
|
||||||
|
source
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string InferVisibilityModifier(ISymbol implTypeSymbol, AttributeData attributeData)
|
private static string InferVisibilityModifier(
|
||||||
|
ISymbol implTypeSymbol,
|
||||||
|
AttributeData attributeData
|
||||||
|
)
|
||||||
{
|
{
|
||||||
string? result = attributeData.GetNamedParamValue(Attributes.VisibilityModifierPropName);
|
string? result = attributeData.GetNamedParamValue(Attributes.VisibilityModifierPropName);
|
||||||
if (!string.IsNullOrEmpty(result))
|
if (!string.IsNullOrEmpty(result))
|
||||||
@@ -126,16 +152,20 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
return implTypeSymbol.DeclaredAccessibility switch
|
return implTypeSymbol.DeclaredAccessibility switch
|
||||||
{
|
{
|
||||||
Accessibility.Public => "public",
|
Accessibility.Public => "public",
|
||||||
_ => "internal",
|
_ => "internal",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string InferInterfaceName(ISymbol implTypeSymbol, AttributeData attributeData)
|
private static string InferInterfaceName(ISymbol implTypeSymbol, AttributeData attributeData)
|
||||||
{
|
{
|
||||||
return attributeData.GetNamedParamValue(Attributes.InterfaceNamePropName) ?? $"I{implTypeSymbol.Name}";
|
return attributeData.GetNamedParamValue(Attributes.InterfaceNamePropName)
|
||||||
|
?? $"I{implTypeSymbol.Name}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeData attributeData)
|
private string GenerateInterfaceCode(
|
||||||
|
INamedTypeSymbol implTypeSymbol,
|
||||||
|
AttributeData attributeData
|
||||||
|
)
|
||||||
{
|
{
|
||||||
using var stream = new MemoryStream();
|
using var stream = new MemoryStream();
|
||||||
var streamWriter = new StreamWriter(stream, Encoding.UTF8);
|
var streamWriter = new StreamWriter(stream, Encoding.UTF8);
|
||||||
@@ -179,7 +209,10 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
return reader.ReadToEnd();
|
return reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteTypeGenericsIfNeeded(TextWriter writer, INamedTypeSymbol implTypeSymbol)
|
private static void WriteTypeGenericsIfNeeded(
|
||||||
|
TextWriter writer,
|
||||||
|
INamedTypeSymbol implTypeSymbol
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (!implTypeSymbol.IsGenericType)
|
if (!implTypeSymbol.IsGenericType)
|
||||||
{
|
{
|
||||||
@@ -193,16 +226,23 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
WriteTypeParameterConstraints(writer, implTypeSymbol.TypeParameters);
|
WriteTypeParameterConstraints(writer, implTypeSymbol.TypeParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenerateInterfaceMemberDefinitions(TextWriter writer, INamespaceOrTypeSymbol implTypeSymbol)
|
private void GenerateInterfaceMemberDefinitions(
|
||||||
|
TextWriter writer,
|
||||||
|
INamespaceOrTypeSymbol implTypeSymbol
|
||||||
|
)
|
||||||
{
|
{
|
||||||
foreach (var member in implTypeSymbol.GetMembers())
|
foreach (var member in implTypeSymbol.GetMembers())
|
||||||
{
|
{
|
||||||
if (member.DeclaredAccessibility != Accessibility.Public ||
|
if (
|
||||||
member.HasAttribute(_ignoreAttribute ?? throw new NullReferenceException("_ignoreAttribute is null")))
|
member.DeclaredAccessibility != Accessibility.Public
|
||||||
|
|| member.HasAttribute(
|
||||||
|
_ignoreAttribute ?? throw new NullReferenceException("_ignoreAttribute is null")
|
||||||
|
)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
GenerateInterfaceMemberDefinition(writer, member);
|
GenerateInterfaceMemberDefinition(writer, member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,10 +269,10 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// omit the fist and last lines to skip the <member> tag
|
// omit the fist and last lines to skip the <member> tag
|
||||||
|
|
||||||
var reader = new StringReader(xml);
|
var reader = new StringReader(xml);
|
||||||
var lines = new List<string>();
|
var lines = new List<string>();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
var line = reader.ReadLine();
|
var line = reader.ReadLine();
|
||||||
@@ -240,7 +280,7 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lines.Add(line);
|
lines.Add(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,18 +296,21 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
return symbol.DeclaredAccessibility is Accessibility.Public or Accessibility.Internal;
|
return symbol.DeclaredAccessibility is Accessibility.Public or Accessibility.Internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GeneratePropertyDefinition(TextWriter writer, IPropertySymbol propertySymbol)
|
private static void GeneratePropertyDefinition(
|
||||||
|
TextWriter writer,
|
||||||
|
IPropertySymbol propertySymbol
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (propertySymbol.IsStatic)
|
if (propertySymbol.IsStatic)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasPublicGetter = propertySymbol.GetMethod is not null &&
|
bool hasPublicGetter =
|
||||||
IsPublicOrInternal(propertySymbol.GetMethod);
|
propertySymbol.GetMethod is not null && IsPublicOrInternal(propertySymbol.GetMethod);
|
||||||
|
|
||||||
bool hasPublicSetter = propertySymbol.SetMethod is not null &&
|
bool hasPublicSetter =
|
||||||
IsPublicOrInternal(propertySymbol.SetMethod);
|
propertySymbol.SetMethod is not null && IsPublicOrInternal(propertySymbol.SetMethod);
|
||||||
|
|
||||||
if (!hasPublicGetter && !hasPublicSetter)
|
if (!hasPublicGetter && !hasPublicSetter)
|
||||||
{
|
{
|
||||||
@@ -275,7 +318,7 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
}
|
}
|
||||||
|
|
||||||
WriteSymbolDocsIfPresent(writer, propertySymbol);
|
WriteSymbolDocsIfPresent(writer, propertySymbol);
|
||||||
|
|
||||||
if (propertySymbol.IsIndexer)
|
if (propertySymbol.IsIndexer)
|
||||||
{
|
{
|
||||||
writer.Write("{0} this[", propertySymbol.Type);
|
writer.Write("{0} this[", propertySymbol.Type);
|
||||||
@@ -316,13 +359,13 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (methodSymbol.IsImplicitlyDeclared && methodSymbol.Name != "Deconstruct")
|
if (methodSymbol.IsImplicitlyDeclared && methodSymbol.Name != "Deconstruct")
|
||||||
{
|
{
|
||||||
// omit methods that are auto generated by the compiler (eg. record's methods),
|
// omit methods that are auto generated by the compiler (eg. record's methods),
|
||||||
// except for the record Deconstruct method
|
// except for the record Deconstruct method
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteSymbolDocsIfPresent(writer, methodSymbol);
|
WriteSymbolDocsIfPresent(writer, methodSymbol);
|
||||||
|
|
||||||
writer.Write("{0} {1}", methodSymbol.ReturnType, methodSymbol.Name); // ex. int Foo
|
writer.Write("{0} {1}", methodSymbol.ReturnType, methodSymbol.Name); // ex. int Foo
|
||||||
@@ -366,7 +409,7 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
writer.Write("in ");
|
writer.Write("in ");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(param.Type);
|
writer.Write(param.Type);
|
||||||
writer.Write(" ");
|
writer.Write(" ");
|
||||||
|
|
||||||
@@ -374,7 +417,7 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
{
|
{
|
||||||
writer.Write("@");
|
writer.Write("@");
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.Write(param.Name);
|
writer.Write(param.Name);
|
||||||
|
|
||||||
if (param.HasExplicitDefaultValue)
|
if (param.HasExplicitDefaultValue)
|
||||||
@@ -420,7 +463,8 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
|
|
||||||
private static void WriteTypeParameterConstraints(
|
private static void WriteTypeParameterConstraints(
|
||||||
TextWriter writer,
|
TextWriter writer,
|
||||||
IEnumerable<ITypeParameterSymbol> typeParameters)
|
IEnumerable<ITypeParameterSymbol> typeParameters
|
||||||
|
)
|
||||||
{
|
{
|
||||||
foreach (var typeParameter in typeParameters)
|
foreach (var typeParameter in typeParameters)
|
||||||
{
|
{
|
||||||
@@ -438,15 +482,23 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
private void InitAttributes(Compilation compilation)
|
private void InitAttributes(Compilation compilation)
|
||||||
{
|
{
|
||||||
_generateAutoInterfaceAttribute = compilation.GetTypeByMetadataName(
|
_generateAutoInterfaceAttribute = compilation.GetTypeByMetadataName(
|
||||||
$"{Attributes.AttributesNamespace}.{Attributes.GenerateAutoInterfaceClassname}");
|
$"{Attributes.AttributesNamespace}.{Attributes.GenerateAutoInterfaceClassname}"
|
||||||
|
);
|
||||||
|
|
||||||
_ignoreAttribute = compilation.GetTypeByMetadataName(
|
_ignoreAttribute = compilation.GetTypeByMetadataName(
|
||||||
$"{Attributes.AttributesNamespace}.{Attributes.AutoInterfaceIgnoreAttributeClassname}");
|
$"{Attributes.AttributesNamespace}.{Attributes.AutoInterfaceIgnoreAttributeClassname}"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<INamedTypeSymbol> GetImplTypeSymbols(Compilation compilation, SyntaxReceiver receiver)
|
private static IEnumerable<INamedTypeSymbol> GetImplTypeSymbols(
|
||||||
|
Compilation compilation,
|
||||||
|
SyntaxReceiver receiver
|
||||||
|
)
|
||||||
{
|
{
|
||||||
return receiver.CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate)).Where(x => x != null).Cast<INamedTypeSymbol>();
|
return receiver
|
||||||
|
.CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate))
|
||||||
|
.Where(x => x != null)
|
||||||
|
.Cast<INamedTypeSymbol>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static INamedTypeSymbol? GetTypeSymbol(Compilation compilation, SyntaxNode type)
|
private static INamedTypeSymbol? GetTypeSymbol(Compilation compilation, SyntaxNode type)
|
||||||
@@ -462,8 +514,11 @@ public class AutoInterfaceGenerator : ISourceGenerator
|
|||||||
|
|
||||||
var compilation = context.Compilation.AddSyntaxTrees(
|
var compilation = context.Compilation.AddSyntaxTrees(
|
||||||
CSharpSyntaxTree.ParseText(
|
CSharpSyntaxTree.ParseText(
|
||||||
SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8), options));
|
SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8),
|
||||||
|
options
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return compilation;
|
return compilation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||||
<NoPackageAnalysis>true</NoPackageAnalysis>
|
<NoPackageAnalysis>true</NoPackageAnalysis>
|
||||||
<RootNamespace>Speckle.InterfaceGenerator</RootNamespace>
|
<RootNamespace>Speckle.InterfaceGenerator</RootNamespace>
|
||||||
|
<EnforoceExtendedAnalyzerRules>true</EnforoceExtendedAnalyzerRules>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
@@ -22,9 +23,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.2.0" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.2.0" PrivateAssets="all" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.3" PrivateAssets="all" >
|
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" PrivateAssets="all">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -121,4 +121,4 @@ internal static class StringExtensions
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,16 +10,19 @@ internal static class SymbolExtensions
|
|||||||
public static bool TryGetAttribute(
|
public static bool TryGetAttribute(
|
||||||
this ISymbol symbol,
|
this ISymbol symbol,
|
||||||
INamedTypeSymbol attributeType,
|
INamedTypeSymbol attributeType,
|
||||||
out IEnumerable<AttributeData> attributes)
|
out IEnumerable<AttributeData> attributes
|
||||||
|
)
|
||||||
{
|
{
|
||||||
attributes = symbol.GetAttributes()
|
attributes = symbol
|
||||||
|
.GetAttributes()
|
||||||
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
|
.Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
|
||||||
return attributes.Any();
|
return attributes.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attributeType)
|
public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attributeType)
|
||||||
{
|
{
|
||||||
return symbol.GetAttributes()
|
return symbol
|
||||||
|
.GetAttributes()
|
||||||
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
|
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +50,12 @@ internal static class SymbolExtensions
|
|||||||
stringBuilder.Insert(0, '.');
|
stringBuilder.Insert(0, '.');
|
||||||
}
|
}
|
||||||
|
|
||||||
stringBuilder.Insert(0, symbol.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat));
|
stringBuilder.Insert(
|
||||||
|
0,
|
||||||
|
symbol.OriginalDefinition.ToDisplayString(
|
||||||
|
SymbolDisplayFormat.MinimallyQualifiedFormat
|
||||||
|
)
|
||||||
|
);
|
||||||
symbol = symbol.ContainingSymbol;
|
symbol = symbol.ContainingSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,4 +72,4 @@ internal static class SymbolExtensions
|
|||||||
{
|
{
|
||||||
return symbol is INamespaceSymbol { IsGlobalNamespace: true };
|
return symbol is INamespaceSymbol { IsGlobalNamespace: true };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,14 @@ namespace Speckle.InterfaceGenerator;
|
|||||||
internal class SyntaxReceiver : ISyntaxReceiver
|
internal class SyntaxReceiver : ISyntaxReceiver
|
||||||
{
|
{
|
||||||
public IList<TypeDeclarationSyntax> CandidateTypes { get; } = new List<TypeDeclarationSyntax>();
|
public IList<TypeDeclarationSyntax> CandidateTypes { get; } = new List<TypeDeclarationSyntax>();
|
||||||
|
|
||||||
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
|
||||||
{
|
{
|
||||||
if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax &&
|
if (
|
||||||
IsClassOrRecord(typeDeclarationSyntax) &&
|
syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax
|
||||||
typeDeclarationSyntax.AttributeLists.Count > 0)
|
&& IsClassOrRecord(typeDeclarationSyntax)
|
||||||
|
&& typeDeclarationSyntax.AttributeLists.Count > 0
|
||||||
|
)
|
||||||
{
|
{
|
||||||
CandidateTypes.Add(typeDeclarationSyntax);
|
CandidateTypes.Add(typeDeclarationSyntax);
|
||||||
}
|
}
|
||||||
@@ -20,6 +22,7 @@ internal class SyntaxReceiver : ISyntaxReceiver
|
|||||||
|
|
||||||
private static bool IsClassOrRecord(TypeDeclarationSyntax typeDeclarationSyntax)
|
private static bool IsClassOrRecord(TypeDeclarationSyntax typeDeclarationSyntax)
|
||||||
{
|
{
|
||||||
return typeDeclarationSyntax is ClassDeclarationSyntax || typeDeclarationSyntax is RecordDeclarationSyntax;
|
return typeDeclarationSyntax is ClassDeclarationSyntax
|
||||||
|
|| typeDeclarationSyntax is RecordDeclarationSyntax;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,20 +6,17 @@ namespace Speckle.InterfaceGenerator;
|
|||||||
|
|
||||||
internal static class TextWriterExtensions
|
internal static class TextWriterExtensions
|
||||||
{
|
{
|
||||||
|
public static void WriteJoin<T>(this TextWriter writer, string separator, IEnumerable<T> values)
|
||||||
public static void WriteJoin<T>(
|
|
||||||
this TextWriter writer,
|
|
||||||
string separator,
|
|
||||||
IEnumerable<T> values)
|
|
||||||
{
|
{
|
||||||
writer.WriteJoin(separator, values, (w, x) => w.Write(x));
|
writer.WriteJoin(separator, values, (w, x) => w.Write(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteJoin<T>(
|
public static void WriteJoin<T>(
|
||||||
this TextWriter writer,
|
this TextWriter writer,
|
||||||
string separator,
|
string separator,
|
||||||
IEnumerable<T> values,
|
IEnumerable<T> values,
|
||||||
Action<TextWriter, T> writeAction)
|
Action<TextWriter, T> writeAction
|
||||||
|
)
|
||||||
{
|
{
|
||||||
using var enumerator = values.GetEnumerator();
|
using var enumerator = values.GetEnumerator();
|
||||||
|
|
||||||
@@ -41,4 +38,4 @@ internal static class TextWriterExtensions
|
|||||||
writeAction(writer, enumerator.Current);
|
writeAction(writer, enumerator.Current);
|
||||||
} while (enumerator.MoveNext());
|
} while (enumerator.MoveNext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,36 +12,35 @@ internal static class TypeParameterSymbolExtensions
|
|||||||
{
|
{
|
||||||
yield return "notnull";
|
yield return "notnull";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol.HasValueTypeConstraint)
|
if (symbol.HasValueTypeConstraint)
|
||||||
{
|
{
|
||||||
yield return "struct";
|
yield return "struct";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol.HasUnmanagedTypeConstraint)
|
if (symbol.HasUnmanagedTypeConstraint)
|
||||||
{
|
{
|
||||||
yield return "unmanaged";
|
yield return "unmanaged";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol.HasReferenceTypeConstraint)
|
if (symbol.HasReferenceTypeConstraint)
|
||||||
{
|
{
|
||||||
yield return symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated
|
yield return symbol.ReferenceTypeConstraintNullableAnnotation
|
||||||
|
== NullableAnnotation.Annotated
|
||||||
? "class?"
|
? "class?"
|
||||||
: "class";
|
: "class";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// types go in the middle
|
// types go in the middle
|
||||||
foreach (var constraintType in symbol.ConstraintTypes)
|
foreach (var constraintType in symbol.ConstraintTypes)
|
||||||
{
|
{
|
||||||
yield return constraintType.ToDisplayString();
|
yield return constraintType.ToDisplayString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// the new() constraint has to be the last
|
// the new() constraint has to be the last
|
||||||
if (symbol.HasConstructorConstraint)
|
if (symbol.HasConstructorConstraint)
|
||||||
{
|
{
|
||||||
yield return "new()";
|
yield return "new()";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user