From 500c6654bdd9970c06cc448185efe8702769e312 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 28 Feb 2023 10:45:33 +0000 Subject: [PATCH 01/25] add nullable fix --- InterfaceGenerator/AutoInterfaceGenerator.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/InterfaceGenerator/AutoInterfaceGenerator.cs index e4ec264..c74ffc6 100644 --- a/InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/InterfaceGenerator/AutoInterfaceGenerator.cs @@ -145,6 +145,8 @@ private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeD var interfaceName = InferInterfaceName(implTypeSymbol, attributeData); var visibilityModifier = InferVisibilityModifier(implTypeSymbol, attributeData); + //https://stackoverflow.com/questions/55492214/the-annotation-for-nullable-reference-types-should-only-be-used-in-code-within-a fix for nullable + codeWriter.WriteLine("#nullable enable"); codeWriter.WriteLine("namespace {0}", namespaceName); codeWriter.WriteLine("{"); @@ -163,6 +165,7 @@ private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeD --codeWriter.Indent; codeWriter.WriteLine("}"); + codeWriter.WriteLine("#nullable restore"); codeWriter.Flush(); stream.Seek(0, SeekOrigin.Begin); From 74337459d3a87b054a728c6cff43e50823f3acf1 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 28 Feb 2023 10:48:31 +0000 Subject: [PATCH 02/25] test annotation --- InterfaceGenerator/AutoInterfaceGenerator.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/InterfaceGenerator/AutoInterfaceGenerator.cs index c74ffc6..ae04430 100644 --- a/InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/InterfaceGenerator/AutoInterfaceGenerator.cs @@ -146,7 +146,10 @@ private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeD var visibilityModifier = InferVisibilityModifier(implTypeSymbol, attributeData); //https://stackoverflow.com/questions/55492214/the-annotation-for-nullable-reference-types-should-only-be-used-in-code-within-a fix for nullable - codeWriter.WriteLine("#nullable enable"); + if (implTypeSymbol.NullableAnnotation == NullableAnnotation.Annotated) + { + codeWriter.WriteLine("#nullable enable"); + } codeWriter.WriteLine("namespace {0}", namespaceName); codeWriter.WriteLine("{"); @@ -165,7 +168,10 @@ private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeD --codeWriter.Indent; codeWriter.WriteLine("}"); - codeWriter.WriteLine("#nullable restore"); + if (implTypeSymbol.NullableAnnotation == NullableAnnotation.Annotated) + { + codeWriter.WriteLine("#nullable restore"); + } codeWriter.Flush(); stream.Seek(0, SeekOrigin.Begin); From dc5204ac3206ba9ee4d02c0804eaa5201aabf5a8 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 11:43:16 +0100 Subject: [PATCH 03/25] Rename interface generator --- .github/workflows/nuget.yml | 4 +- .../AccessorsGenerationTests.cs | 19 +- .../GenericInterfaceTests.cs | 2 +- .../MethodGenerationTests.cs | 16 +- .../Partial/PartialClass.1.cs | 2 +- .../Partial/PartialClass.2.cs | 2 +- InterfaceGenerator.Tests/PartialClassTests.cs | 5 +- .../RecordInterfaceGenerationTests.cs | 15 +- .../SameName/SameNameClass.1.cs | 3 + .../SameName/SameNameClass.2.cs | 3 + ...> Speckle.InterfaceGenerator.Tests.csproj} | 6 +- .../VisibilityModifierTests.cs | 2 +- InterfaceGenerator/AttributeDataExtensions.cs | 13 +- InterfaceGenerator/Attributes.cs | 20 +- InterfaceGenerator/AutoInterfaceGenerator.cs | 669 +++++++++--------- ...proj => Speckle.InterfaceGenerator.csproj} | 14 +- InterfaceGenerator/StringExtensions.cs | 237 +++---- InterfaceGenerator/SymbolExtensions.cs | 87 ++- InterfaceGenerator/SyntaxReceiver.cs | 29 +- InterfaceGenerator/TextWriterExtensions.cs | 61 +- .../TypeParameterSymbolExtensions.cs | 63 +- ...ator.sln => Speckle.InterfaceGenerator.sln | 4 +- 22 files changed, 637 insertions(+), 639 deletions(-) rename InterfaceGenerator.Tests/{InterfaceGenerator.Tests.csproj => Speckle.InterfaceGenerator.Tests.csproj} (64%) rename InterfaceGenerator/{InterfaceGenerator.csproj => Speckle.InterfaceGenerator.csproj} (70%) rename InterfaceGenerator.sln => Speckle.InterfaceGenerator.sln (72%) diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index f18e6f2..b096c53 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -16,7 +16,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - name: Restore dependencies run: dotnet restore @@ -31,4 +31,4 @@ jobs: run: dotnet pack --no-build --configuration Release InterfaceGenerator/InterfaceGenerator.csproj --output . - name: Push to nuget.org - run: dotnet nuget push *.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.NUGET_API_KEY}} --skip-duplicate \ No newline at end of file + run: dotnet nuget push *.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.NUGET_KEY}} --skip-duplicate \ No newline at end of file diff --git a/InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/InterfaceGenerator.Tests/AccessorsGenerationTests.cs index 7e61ee2..593016d 100644 --- a/InterfaceGenerator.Tests/AccessorsGenerationTests.cs +++ b/InterfaceGenerator.Tests/AccessorsGenerationTests.cs @@ -1,9 +1,10 @@ -using System.Runtime.CompilerServices; +using System; +using System.Runtime.CompilerServices; using FluentAssertions; using FluentAssertions.Common; using Xunit; -namespace InterfaceGenerator.Tests; +namespace Speckle.InterfaceGenerator.Tests; public class AccessorsGenerationTests { @@ -32,7 +33,7 @@ public void GetSetIndexer_IsImplemented() public void PublicProperty_IsImplemented() { var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PublicProperty))!; + .GetProperty(nameof(IAccessorsTestsService.PublicProperty)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -47,14 +48,14 @@ public void PublicProperty_IsImplemented() public void InitProperty_IsImplemented() { var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.InitOnlyProperty))!; + .GetProperty(nameof(IAccessorsTestsService.InitOnlyProperty)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); prop.GetMethod.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; } @@ -63,7 +64,7 @@ public void InitProperty_IsImplemented() public void PrivateSetter_IsOmitted() { var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateSetter))!; + .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateSetter)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -77,7 +78,7 @@ public void PrivateSetter_IsOmitted() public void PrivateGetter_IsOmitted() { var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateGetter))!; + .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateGetter)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -91,7 +92,7 @@ public void PrivateGetter_IsOmitted() public void ProtectedSetter_IsOmitted() { var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedSetter))!; + .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedSetter)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -105,7 +106,7 @@ public void ProtectedSetter_IsOmitted() public void ProtectedGetter_IsOmitted() { var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedGetter))!; + .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedGetter)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); diff --git a/InterfaceGenerator.Tests/GenericInterfaceTests.cs b/InterfaceGenerator.Tests/GenericInterfaceTests.cs index 8642e3b..d58fab8 100644 --- a/InterfaceGenerator.Tests/GenericInterfaceTests.cs +++ b/InterfaceGenerator.Tests/GenericInterfaceTests.cs @@ -3,7 +3,7 @@ using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests; +namespace Speckle.InterfaceGenerator.Tests; public class GenericInterfaceTests { diff --git a/InterfaceGenerator.Tests/MethodGenerationTests.cs b/InterfaceGenerator.Tests/MethodGenerationTests.cs index fb9a748..4c6ae1e 100644 --- a/InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -5,7 +5,7 @@ using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests; +namespace Speckle.InterfaceGenerator.Tests; public class MethodGenerationTests { @@ -20,7 +20,7 @@ public MethodGenerationTests() public void VoidMethod_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethod))!; + nameof(MethodsTestService.VoidMethod)) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -35,7 +35,7 @@ public void VoidMethod_IsImplemented() public void VoidMethodWithKeywordParam_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithKeywordParam))!; + nameof(MethodsTestService.VoidMethodWithKeywordParam)) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -54,7 +54,7 @@ public void VoidMethodWithParams_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( nameof(MethodsTestService.VoidMethodWithParams), - new[] { typeof(string), typeof(string) })!; + [typeof(string), typeof(string)]) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -71,7 +71,7 @@ public void VoidMethodWithOutParam_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( nameof(MethodsTestService.VoidMethodWithOutParam), - new[] { typeof(string).MakeByRefType() })!; + [typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -89,7 +89,7 @@ public void VoidMethodWithInParam_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( nameof(MethodsTestService.VoidMethodWithInParam), - new[] { typeof(string).MakeByRefType() })!; + [typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -108,7 +108,7 @@ public void VoidMethodWithRefParam_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( nameof(MethodsTestService.VoidMethodWithRefParam), - new[] { typeof(string).MakeByRefType() })!; + [typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -127,7 +127,7 @@ public void VoidMethodWithRefParam_IsImplemented() public void StringMethod_IsImplemented() { var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.StringMethod))!; + nameof(MethodsTestService.StringMethod)) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(string)); diff --git a/InterfaceGenerator.Tests/Partial/PartialClass.1.cs b/InterfaceGenerator.Tests/Partial/PartialClass.1.cs index 02ff0de..bbb9788 100644 --- a/InterfaceGenerator.Tests/Partial/PartialClass.1.cs +++ b/InterfaceGenerator.Tests/Partial/PartialClass.1.cs @@ -1,4 +1,4 @@ -namespace InterfaceGenerator.Tests.Partial; +namespace Speckle.InterfaceGenerator.Tests.Partial; [GenerateAutoInterface] internal partial class PartialClass : IPartialClass diff --git a/InterfaceGenerator.Tests/Partial/PartialClass.2.cs b/InterfaceGenerator.Tests/Partial/PartialClass.2.cs index 9bcf3b9..fd52e37 100644 --- a/InterfaceGenerator.Tests/Partial/PartialClass.2.cs +++ b/InterfaceGenerator.Tests/Partial/PartialClass.2.cs @@ -1,4 +1,4 @@ -namespace InterfaceGenerator.Tests.Partial; +namespace Speckle.InterfaceGenerator.Tests.Partial; internal partial class PartialClass { diff --git a/InterfaceGenerator.Tests/PartialClassTests.cs b/InterfaceGenerator.Tests/PartialClassTests.cs index a290724..3befa71 100644 --- a/InterfaceGenerator.Tests/PartialClassTests.cs +++ b/InterfaceGenerator.Tests/PartialClassTests.cs @@ -1,9 +1,8 @@ -using System; using FluentAssertions; -using InterfaceGenerator.Tests.Partial; +using Speckle.InterfaceGenerator.Tests.Partial; using Xunit; -namespace InterfaceGenerator.Tests; +namespace Speckle.InterfaceGenerator.Tests; public class PartialClassTests { diff --git a/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs b/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs index 8274723..1cb38bc 100644 --- a/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs +++ b/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs @@ -1,8 +1,9 @@ +using System; using System.Runtime.CompilerServices; using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests; +namespace Speckle.InterfaceGenerator.Tests; public class RecordInterfaceGenerationTests { @@ -17,13 +18,13 @@ public RecordInterfaceGenerationTests() public void RecordProperty_IsGenerated() { var prop = typeof(ITestRecord) - .GetProperty(nameof(TestRecord.RecordProperty))!; + .GetProperty(nameof(TestRecord.RecordProperty)) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); prop.GetMethod.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); } @@ -35,9 +36,9 @@ public void RecordMethod_IsGenerated() nameof(TestRecord.RecordMethod)); method.Should().NotBeNull(); - method!.ReturnType.Should().Be(typeof(void)); + method?.ReturnType.Should().Be(typeof(void)); - var parameters = method.GetParameters(); + var parameters = method?.GetParameters(); parameters.Should().BeEmpty(); _sut.RecordMethod(); @@ -50,9 +51,9 @@ public void Deconstruct_IsGenerated() nameof(TestRecord.Deconstruct)); method.Should().NotBeNull(); - method!.ReturnType.Should().Be(typeof(void)); + method?.ReturnType.Should().Be(typeof(void)); - var parameters = method.GetParameters(); + var parameters = method?.GetParameters() ?? throw new InvalidOperationException(); parameters.Length.Should().Be(1); var parameter = parameters[0]; diff --git a/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs index e3906f2..cb72fdf 100644 --- a/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs +++ b/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs @@ -1,4 +1,7 @@ // ReSharper disable CheckNamespace + +using Speckle.InterfaceGenerator; + namespace InterfaceGenerator.Tests.SameName_1; /// diff --git a/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs b/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs index 9147b4f..67a87c1 100644 --- a/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs +++ b/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs @@ -1,4 +1,7 @@ // ReSharper disable CheckNamespace + +using Speckle.InterfaceGenerator; + namespace InterfaceGenerator.Tests.SameName_2; [GenerateAutoInterface] diff --git a/InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj b/InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj similarity index 64% rename from InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj rename to InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj index db3e2fe..0c30220 100644 --- a/InterfaceGenerator.Tests/InterfaceGenerator.Tests.csproj +++ b/InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj @@ -1,9 +1,9 @@ - net6.0 - + net8.0 false + Speckle.InterfaceGenerator.Tests @@ -14,7 +14,7 @@ - + diff --git a/InterfaceGenerator.Tests/VisibilityModifierTests.cs b/InterfaceGenerator.Tests/VisibilityModifierTests.cs index 33c9e08..951f472 100644 --- a/InterfaceGenerator.Tests/VisibilityModifierTests.cs +++ b/InterfaceGenerator.Tests/VisibilityModifierTests.cs @@ -2,7 +2,7 @@ using FluentAssertions; using Xunit; -namespace InterfaceGenerator.Tests; +namespace Speckle.InterfaceGenerator.Tests; public class VisibilityModifierTests { diff --git a/InterfaceGenerator/AttributeDataExtensions.cs b/InterfaceGenerator/AttributeDataExtensions.cs index 084842a..10671cb 100644 --- a/InterfaceGenerator/AttributeDataExtensions.cs +++ b/InterfaceGenerator/AttributeDataExtensions.cs @@ -1,14 +1,13 @@ using System.Linq; using Microsoft.CodeAnalysis; -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal static class AttributeDataExtensions { - internal static class AttributeDataExtensions + public static string? GetNamedParamValue(this AttributeData attributeData, string paramName) { - public static string? GetNamedParamValue(this AttributeData attributeData, string paramName) - { - var pair = attributeData.NamedArguments.FirstOrDefault(x => x.Key == paramName); - return pair.Value.Value?.ToString(); - } + var pair = attributeData.NamedArguments.FirstOrDefault(x => x.Key == paramName); + return pair.Value.Value?.ToString(); } } \ No newline at end of file diff --git a/InterfaceGenerator/Attributes.cs b/InterfaceGenerator/Attributes.cs index 754b8ec..c600554 100644 --- a/InterfaceGenerator/Attributes.cs +++ b/InterfaceGenerator/Attributes.cs @@ -1,17 +1,16 @@ -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal class Attributes { - - internal class Attributes - { - public const string AttributesNamespace = nameof(InterfaceGenerator); + public const string AttributesNamespace = "Speckle.InterfaceGenerator"; - public const string GenerateAutoInterfaceClassname = "GenerateAutoInterfaceAttribute"; - public const string AutoInterfaceIgnoreAttributeClassname = "AutoInterfaceIgnoreAttribute"; + public const string GenerateAutoInterfaceClassname = "GenerateAutoInterfaceAttribute"; + public const string AutoInterfaceIgnoreAttributeClassname = "AutoInterfaceIgnoreAttribute"; - public const string VisibilityModifierPropName = "VisibilityModifier"; - public const string InterfaceNamePropName = "Name"; + public const string VisibilityModifierPropName = "VisibilityModifier"; + public const string InterfaceNamePropName = "Name"; - public static readonly string AttributesSourceCode = $@" + public static readonly string AttributesSourceCode = $@" using System; using System.Diagnostics; @@ -39,5 +38,4 @@ internal sealed class {AutoInterfaceIgnoreAttributeClassname} : Attribute }} }} "; - } } \ No newline at end of file diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/InterfaceGenerator/AutoInterfaceGenerator.cs index e4ec264..818cb7c 100644 --- a/InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/InterfaceGenerator/AutoInterfaceGenerator.cs @@ -11,451 +11,450 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +[Generator] +public class AutoInterfaceGenerator : ISourceGenerator { - [Generator] - public class AutoInterfaceGenerator : ISourceGenerator + private INamedTypeSymbol? _generateAutoInterfaceAttribute; + private INamedTypeSymbol? _ignoreAttribute; + + public void Initialize(GeneratorInitializationContext context) { - private INamedTypeSymbol _generateAutoInterfaceAttribute = null!; - private INamedTypeSymbol _ignoreAttribute = null!; + context.RegisterForSyntaxNotifications(() => new SyntaxReceiver()); - public void Initialize(GeneratorInitializationContext context) +#if DEBUG + if (!Debugger.IsAttached) { - context.RegisterForSyntaxNotifications(() => new SyntaxReceiver()); - - #if DEBUG - if (!Debugger.IsAttached) - { - // sadly this is Windows only so as of now :( - Debugger.Launch(); - } - #endif + // sadly this is Windows only so as of now :( + Debugger.Launch(); } +#endif + } - public void Execute(GeneratorExecutionContext context) + public void Execute(GeneratorExecutionContext context) + { + try { - try - { - ExecuteCore(context); - } - catch (Exception exception) - { - RaiseExceptionDiagnostic(context, exception); - } + ExecuteCore(context); } - - private static void RaiseExceptionDiagnostic(GeneratorExecutionContext context, Exception exception) + catch (Exception exception) { - var descriptor = new DiagnosticDescriptor( - "InterfaceGenerator.CriticalError", - $"Exception thrown in InterfaceGenerator", - $"{exception.GetType().FullName} {exception.Message} {exception.StackTrace.Trim()}", - "InterfaceGenerator", - DiagnosticSeverity.Error, - true, - customTags: WellKnownDiagnosticTags.AnalyzerException); - - var diagnostic = Diagnostic.Create(descriptor, null); - - context.ReportDiagnostic(diagnostic); + RaiseExceptionDiagnostic(context, exception); } + } + + private static void RaiseExceptionDiagnostic(GeneratorExecutionContext context, Exception exception) + { + var descriptor = new DiagnosticDescriptor( + "Speckle.InterfaceGenerator.CriticalError", + "Exception thrown in InterfaceGenerator", + $"{exception.GetType().FullName} {exception.Message} {exception.StackTrace.Trim()}", + "Speckle.InterfaceGenerator", + DiagnosticSeverity.Error, + true, + customTags: WellKnownDiagnosticTags.AnalyzerException); + + var diagnostic = Diagnostic.Create(descriptor, null); + + context.ReportDiagnostic(diagnostic); + } - private void ExecuteCore(GeneratorExecutionContext context) - { - // setting the culture to invariant prevents errors such as emitting a decimal comma (0,1) instead of - // a decimal point (0.1) in certain cultures - var prevCulture = Thread.CurrentThread.CurrentCulture; - Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; + private void ExecuteCore(GeneratorExecutionContext context) + { + // setting the culture to invariant prevents errors such as emitting a decimal comma (0,1) instead of + // a decimal point (0.1) in certain cultures + var prevCulture = Thread.CurrentThread.CurrentCulture; + Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; - GenerateAttributes(context); - GenerateInterfaces(context); + GenerateAttributes(context); + GenerateInterfaces(context); - Thread.CurrentThread.CurrentCulture = prevCulture; - } + Thread.CurrentThread.CurrentCulture = prevCulture; + } - private static void GenerateAttributes(GeneratorExecutionContext context) - { - context.AddSource( - Attributes.GenerateAutoInterfaceClassname, - SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8)); - } + private static void GenerateAttributes(GeneratorExecutionContext context) + { + context.AddSource( + Attributes.GenerateAutoInterfaceClassname, + SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8)); + } - private void GenerateInterfaces(GeneratorExecutionContext context) + private void GenerateInterfaces(GeneratorExecutionContext context) + { + if (context.SyntaxReceiver is not SyntaxReceiver receiver) { - if (context.SyntaxReceiver is not SyntaxReceiver receiver) - { - return; - } + return; + } - var compilation = GetCompilation(context); - InitAttributes(compilation); + var compilation = GetCompilation(context); + InitAttributes(compilation); - var classSymbols = GetImplTypeSymbols(compilation, receiver); + var classSymbols = GetImplTypeSymbols(compilation, receiver); - List classSymbolNames = new List(); + List classSymbolNames = []; - 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, out var attributes)) - { - continue; - } - - if(classSymbolNames.Contains(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true))) - { - continue; // partial class, already added - } - - classSymbolNames.Add(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)); - - var attribute = attributes.Single(); - var source = SourceText.From(GenerateInterfaceCode(implTypeSymbol, attribute), Encoding.UTF8); - - context.AddSource($"{implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)}_AutoInterface.g.cs", source); + continue; } - } - private static string InferVisibilityModifier(ISymbol implTypeSymbol, AttributeData attributeData) - { - string? result = attributeData.GetNamedParamValue(Attributes.VisibilityModifierPropName); - if (!string.IsNullOrEmpty(result)) + if(classSymbolNames.Contains(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true))) { - return result!; + continue; // partial class, already added } - return implTypeSymbol.DeclaredAccessibility switch - { - Accessibility.Public => "public", - _ => "internal", - }; + classSymbolNames.Add(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)); + + var attribute = attributes.Single(); + var source = SourceText.From(GenerateInterfaceCode(implTypeSymbol, attribute), Encoding.UTF8); + + context.AddSource($"{implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)}_AutoInterface.g.cs", source); } + } - private static string InferInterfaceName(ISymbol implTypeSymbol, AttributeData attributeData) + private static string InferVisibilityModifier(ISymbol implTypeSymbol, AttributeData attributeData) + { + string? result = attributeData.GetNamedParamValue(Attributes.VisibilityModifierPropName); + if (!string.IsNullOrEmpty(result)) { - return attributeData.GetNamedParamValue(Attributes.InterfaceNamePropName) ?? $"I{implTypeSymbol.Name}"; + return result ?? throw new NullReferenceException("result is null"); } - private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeData attributeData) + return implTypeSymbol.DeclaredAccessibility switch { - using var stream = new MemoryStream(); - var streamWriter = new StreamWriter(stream, Encoding.UTF8); - var codeWriter = new IndentedTextWriter(streamWriter, " "); + Accessibility.Public => "public", + _ => "internal", + }; + } - var namespaceName = implTypeSymbol.ContainingNamespace.ToDisplayString(); - var interfaceName = InferInterfaceName(implTypeSymbol, attributeData); - var visibilityModifier = InferVisibilityModifier(implTypeSymbol, attributeData); + private static string InferInterfaceName(ISymbol implTypeSymbol, AttributeData attributeData) + { + return attributeData.GetNamedParamValue(Attributes.InterfaceNamePropName) ?? $"I{implTypeSymbol.Name}"; + } - codeWriter.WriteLine("namespace {0}", namespaceName); - codeWriter.WriteLine("{"); + private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeData attributeData) + { + using var stream = new MemoryStream(); + var streamWriter = new StreamWriter(stream, Encoding.UTF8); + var codeWriter = new IndentedTextWriter(streamWriter, " "); - ++codeWriter.Indent; - WriteSymbolDocsIfPresent(codeWriter, implTypeSymbol); - codeWriter.Write("{0} partial interface {1}", visibilityModifier, interfaceName); - WriteTypeGenericsIfNeeded(codeWriter, implTypeSymbol); - codeWriter.WriteLine(); - codeWriter.WriteLine("{"); + var namespaceName = implTypeSymbol.ContainingNamespace.ToDisplayString(); + var interfaceName = InferInterfaceName(implTypeSymbol, attributeData); + var visibilityModifier = InferVisibilityModifier(implTypeSymbol, attributeData); - ++codeWriter.Indent; - GenerateInterfaceMemberDefinitions(codeWriter, implTypeSymbol); - --codeWriter.Indent; + codeWriter.WriteLine("namespace {0}", namespaceName); + codeWriter.WriteLine("{"); - codeWriter.WriteLine("}"); - --codeWriter.Indent; + ++codeWriter.Indent; + WriteSymbolDocsIfPresent(codeWriter, implTypeSymbol); + codeWriter.Write("{0} partial interface {1}", visibilityModifier, interfaceName); + WriteTypeGenericsIfNeeded(codeWriter, implTypeSymbol); + codeWriter.WriteLine(); + codeWriter.WriteLine("{"); - codeWriter.WriteLine("}"); + ++codeWriter.Indent; + GenerateInterfaceMemberDefinitions(codeWriter, implTypeSymbol); + --codeWriter.Indent; - codeWriter.Flush(); - stream.Seek(0, SeekOrigin.Begin); - using var reader = new StreamReader(stream, Encoding.UTF8, true); - return reader.ReadToEnd(); - } + codeWriter.WriteLine("}"); + --codeWriter.Indent; - private static void WriteTypeGenericsIfNeeded(TextWriter writer, INamedTypeSymbol implTypeSymbol) - { - if (!implTypeSymbol.IsGenericType) - { - return; - } + codeWriter.WriteLine("}"); - writer.Write("<"); - writer.WriteJoin(", ", implTypeSymbol.TypeParameters.Select(x => x.Name)); - writer.Write(">"); + codeWriter.Flush(); + stream.Seek(0, SeekOrigin.Begin); + using var reader = new StreamReader(stream, Encoding.UTF8, true); + return reader.ReadToEnd(); + } - WriteTypeParameterConstraints(writer, implTypeSymbol.TypeParameters); + private static void WriteTypeGenericsIfNeeded(TextWriter writer, INamedTypeSymbol implTypeSymbol) + { + if (!implTypeSymbol.IsGenericType) + { + return; } - private void GenerateInterfaceMemberDefinitions(TextWriter writer, INamespaceOrTypeSymbol implTypeSymbol) + writer.Write("<"); + writer.WriteJoin(", ", implTypeSymbol.TypeParameters.Select(x => x.Name)); + writer.Write(">"); + + WriteTypeParameterConstraints(writer, implTypeSymbol.TypeParameters); + } + + private void GenerateInterfaceMemberDefinitions(TextWriter writer, INamespaceOrTypeSymbol implTypeSymbol) + { + foreach (var member in implTypeSymbol.GetMembers()) { - foreach (var member in implTypeSymbol.GetMembers()) + if (member.DeclaredAccessibility != Accessibility.Public || + member.HasAttribute(_ignoreAttribute ?? throw new NullReferenceException("_ignoreAttribute is null"))) { - if (member.DeclaredAccessibility != Accessibility.Public || - member.HasAttribute(_ignoreAttribute)) - { - continue; - } - - GenerateInterfaceMemberDefinition(writer, member); + continue; } + + GenerateInterfaceMemberDefinition(writer, member); } + } - private static void GenerateInterfaceMemberDefinition(TextWriter writer, ISymbol member) + private static void GenerateInterfaceMemberDefinition(TextWriter writer, ISymbol member) + { + switch (member) { - switch (member) - { - case IPropertySymbol propertySymbol: - GeneratePropertyDefinition(writer, propertySymbol); - break; - case IMethodSymbol methodSymbol: - GenerateMethodDefinition(writer, methodSymbol); - break; - } + case IPropertySymbol propertySymbol: + GeneratePropertyDefinition(writer, propertySymbol); + break; + case IMethodSymbol methodSymbol: + GenerateMethodDefinition(writer, methodSymbol); + break; } + } - private static void WriteSymbolDocsIfPresent(TextWriter writer, ISymbol symbol) + private static void WriteSymbolDocsIfPresent(TextWriter writer, ISymbol symbol) + { + var xml = symbol.GetDocumentationCommentXml(); + if (string.IsNullOrWhiteSpace(xml)) { - var xml = symbol.GetDocumentationCommentXml(); - if (string.IsNullOrWhiteSpace(xml)) - { - return; - } + return; + } - // omit the fist and last lines to skip the tag + // omit the fist and last lines to skip the tag - var reader = new StringReader(xml); - var lines = new List(); + var reader = new StringReader(xml); + var lines = new List(); - while (true) - { - var line = reader.ReadLine(); - if (line is null) - { - break; - } - - lines.Add(line); - } - - for (int i = 1; i < lines.Count - 1; i++) + while (true) + { + var line = reader.ReadLine(); + if (line is null) { - var line = lines[i].TrimStart(); // for some reason, 4 spaces are inserted to the beginning of the line - writer.WriteLine("/// {0}", line); + break; } + + lines.Add(line); } - private static bool IsPublicOrInternal(ISymbol symbol) + for (int i = 1; i < lines.Count - 1; i++) { - return symbol.DeclaredAccessibility is Accessibility.Public or Accessibility.Internal; + var line = lines[i].TrimStart(); // for some reason, 4 spaces are inserted to the beginning of the line + writer.WriteLine("/// {0}", line); } + } - private static void GeneratePropertyDefinition(TextWriter writer, IPropertySymbol propertySymbol) + private static bool IsPublicOrInternal(ISymbol symbol) + { + return symbol.DeclaredAccessibility is Accessibility.Public or Accessibility.Internal; + } + + private static void GeneratePropertyDefinition(TextWriter writer, IPropertySymbol propertySymbol) + { + if (propertySymbol.IsStatic) { - if (propertySymbol.IsStatic) - { - return; - } + return; + } - bool hasPublicGetter = propertySymbol.GetMethod is not null && - IsPublicOrInternal(propertySymbol.GetMethod); + bool hasPublicGetter = propertySymbol.GetMethod is not null && + IsPublicOrInternal(propertySymbol.GetMethod); - bool hasPublicSetter = propertySymbol.SetMethod is not null && - IsPublicOrInternal(propertySymbol.SetMethod); + bool hasPublicSetter = propertySymbol.SetMethod is not null && + IsPublicOrInternal(propertySymbol.SetMethod); - if (!hasPublicGetter && !hasPublicSetter) - { - return; - } + if (!hasPublicGetter && !hasPublicSetter) + { + return; + } - WriteSymbolDocsIfPresent(writer, propertySymbol); + WriteSymbolDocsIfPresent(writer, propertySymbol); - if (propertySymbol.IsIndexer) - { - writer.Write("{0} this[", propertySymbol.Type); - writer.WriteJoin(", ", propertySymbol.Parameters, WriteMethodParam); - writer.Write("] "); - } - else - { - writer.Write("{0} {1} ", propertySymbol.Type, propertySymbol.Name); // ex. int Foo - } + if (propertySymbol.IsIndexer) + { + writer.Write("{0} this[", propertySymbol.Type); + writer.WriteJoin(", ", propertySymbol.Parameters, WriteMethodParam); + writer.Write("] "); + } + else + { + writer.Write("{0} {1} ", propertySymbol.Type, propertySymbol.Name); // ex. int Foo + } - writer.Write("{ "); + writer.Write("{ "); + + if (hasPublicGetter) + { + writer.Write("get; "); + } - if (hasPublicGetter) + if (hasPublicSetter) + { + if (propertySymbol.SetMethod?.IsInitOnly ?? false) { - writer.Write("get; "); + writer.Write("init; "); } - - if (hasPublicSetter) + else { - if (propertySymbol.SetMethod!.IsInitOnly) - { - writer.Write("init; "); - } - else - { - writer.Write("set; "); - } + writer.Write("set; "); } - - writer.WriteLine("}"); } - private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol methodSymbol) + writer.WriteLine("}"); + } + + private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol methodSymbol) + { + if (methodSymbol.MethodKind != MethodKind.Ordinary || methodSymbol.IsStatic) { - if (methodSymbol.MethodKind != MethodKind.Ordinary || methodSymbol.IsStatic) - { - return; - } + return; + } - if (methodSymbol.IsImplicitlyDeclared && methodSymbol.Name != "Deconstruct") - { - // omit methods that are auto generated by the compiler (eg. record's methods), - // except for the record Deconstruct method - return; - } + if (methodSymbol.IsImplicitlyDeclared && methodSymbol.Name != "Deconstruct") + { + // omit methods that are auto generated by the compiler (eg. record's methods), + // except for the record Deconstruct method + return; + } - WriteSymbolDocsIfPresent(writer, methodSymbol); + WriteSymbolDocsIfPresent(writer, methodSymbol); - writer.Write("{0} {1}", methodSymbol.ReturnType, methodSymbol.Name); // ex. int Foo - - if (methodSymbol.IsGenericMethod) - { - writer.Write("<"); - writer.WriteJoin(", ", methodSymbol.TypeParameters.Select(x => x.Name)); - writer.Write(">"); - } + writer.Write("{0} {1}", methodSymbol.ReturnType, methodSymbol.Name); // ex. int Foo - writer.Write("("); - writer.WriteJoin(", ", methodSymbol.Parameters, WriteMethodParam); + if (methodSymbol.IsGenericMethod) + { + writer.Write("<"); + writer.WriteJoin(", ", methodSymbol.TypeParameters.Select(x => x.Name)); + writer.Write(">"); + } - writer.Write(")"); + writer.Write("("); + writer.WriteJoin(", ", methodSymbol.Parameters, WriteMethodParam); - if (methodSymbol.IsGenericMethod) - { - WriteTypeParameterConstraints(writer, methodSymbol.TypeParameters); - } + writer.Write(")"); - writer.WriteLine(";"); + if (methodSymbol.IsGenericMethod) + { + WriteTypeParameterConstraints(writer, methodSymbol.TypeParameters); } - private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) + writer.WriteLine(";"); + } + + private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) + { + if (param.IsParams) { - if (param.IsParams) - { - writer.Write("params "); - } + writer.Write("params "); + } - switch (param.RefKind) - { - case RefKind.Ref: - writer.Write("ref "); - break; - case RefKind.Out: - writer.Write("out "); - break; - case RefKind.In: - writer.Write("in "); - break; - } + switch (param.RefKind) + { + case RefKind.Ref: + writer.Write("ref "); + break; + case RefKind.Out: + writer.Write("out "); + break; + case RefKind.In: + writer.Write("in "); + break; + } - writer.Write(param.Type); - writer.Write(" "); + writer.Write(param.Type); + writer.Write(" "); - if (StringExtensions.IsCSharpKeyword(param.Name)) - { - writer.Write("@"); - } + if (StringExtensions.IsCSharpKeyword(param.Name)) + { + writer.Write("@"); + } - writer.Write(param.Name); + writer.Write(param.Name); - if (param.HasExplicitDefaultValue) - { - WriteParamExplicitDefaultValue(writer, param); - } + if (param.HasExplicitDefaultValue) + { + WriteParamExplicitDefaultValue(writer, param); } + } - private static void WriteParamExplicitDefaultValue(TextWriter writer, IParameterSymbol param) + private static void WriteParamExplicitDefaultValue(TextWriter writer, IParameterSymbol param) + { + if (param.ExplicitDefaultValue is null) { - if (param.ExplicitDefaultValue is null) - { - writer.Write(" = default"); - } - else + writer.Write(" = default"); + } + else + { + switch (param.Type.Name) { - switch (param.Type.Name) - { - case nameof(String): - writer.Write(" = \"{0}\"", param.ExplicitDefaultValue); - break; - case nameof(Single): - writer.Write(" = {0}f", param.ExplicitDefaultValue); - break; - case nameof(Double): - writer.Write(" = {0}d", param.ExplicitDefaultValue); - break; - case nameof(Decimal): - writer.Write(" = {0}m", param.ExplicitDefaultValue); - break; - case nameof(Boolean): - writer.Write(" = {0}", param.ExplicitDefaultValue.ToString().ToLower()); - break; - case nameof(Nullable): - writer.Write(" = {0}", param.ExplicitDefaultValue.ToString().ToLower()); - break; - default: - writer.Write(" = {0}", param.ExplicitDefaultValue); - break; - } + case nameof(String): + writer.Write(" = \"{0}\"", param.ExplicitDefaultValue); + break; + case nameof(Single): + writer.Write(" = {0}f", param.ExplicitDefaultValue); + break; + case nameof(Double): + writer.Write(" = {0}d", param.ExplicitDefaultValue); + break; + case nameof(Decimal): + writer.Write(" = {0}m", param.ExplicitDefaultValue); + break; + case nameof(Boolean): + writer.Write(" = {0}", param.ExplicitDefaultValue.ToString().ToLower()); + break; + case nameof(Nullable): + writer.Write(" = {0}", param.ExplicitDefaultValue.ToString().ToLower()); + break; + default: + writer.Write(" = {0}", param.ExplicitDefaultValue); + break; } } + } - private static void WriteTypeParameterConstraints( - TextWriter writer, - IEnumerable typeParameters) + private static void WriteTypeParameterConstraints( + TextWriter writer, + IEnumerable typeParameters) + { + foreach (var typeParameter in typeParameters) { - foreach (var typeParameter in typeParameters) + var constraints = typeParameter.EnumGenericConstraints().ToList(); + if (constraints.Count == 0) { - var constraints = typeParameter.EnumGenericConstraints().ToList(); - if (constraints.Count == 0) - { - break; - } - - writer.Write(" where {0} : ", typeParameter.Name); - writer.WriteJoin(", ", constraints); + break; } + + writer.Write(" where {0} : ", typeParameter.Name); + writer.WriteJoin(", ", constraints); } + } - private void InitAttributes(Compilation compilation) - { - _generateAutoInterfaceAttribute = compilation.GetTypeByMetadataName( - $"{Attributes.AttributesNamespace}.{Attributes.GenerateAutoInterfaceClassname}")!; + private void InitAttributes(Compilation compilation) + { + _generateAutoInterfaceAttribute = compilation.GetTypeByMetadataName( + $"{Attributes.AttributesNamespace}.{Attributes.GenerateAutoInterfaceClassname}"); - _ignoreAttribute = compilation.GetTypeByMetadataName( - $"{Attributes.AttributesNamespace}.{Attributes.AutoInterfaceIgnoreAttributeClassname}")!; - } + _ignoreAttribute = compilation.GetTypeByMetadataName( + $"{Attributes.AttributesNamespace}.{Attributes.AutoInterfaceIgnoreAttributeClassname}"); + } - private static IEnumerable GetImplTypeSymbols(Compilation compilation, SyntaxReceiver receiver) - { - return receiver.CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate)); - } + private static IEnumerable GetImplTypeSymbols(Compilation compilation, SyntaxReceiver receiver) + { + return receiver.CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate)).Where(x => x != null).Cast(); + } - private static INamedTypeSymbol GetTypeSymbol(Compilation compilation, SyntaxNode type) - { - var model = compilation.GetSemanticModel(type.SyntaxTree); - var typeSymbol = model.GetDeclaredSymbol(type)!; - return (INamedTypeSymbol)typeSymbol; - } + private static INamedTypeSymbol? GetTypeSymbol(Compilation compilation, SyntaxNode type) + { + var model = compilation.GetSemanticModel(type.SyntaxTree); + var typeSymbol = model.GetDeclaredSymbol(type); + return typeSymbol as INamedTypeSymbol; + } - private static Compilation GetCompilation(GeneratorExecutionContext context) - { - var options = context.Compilation.SyntaxTrees.First().Options as CSharpParseOptions; + private static Compilation GetCompilation(GeneratorExecutionContext context) + { + var options = context.Compilation.SyntaxTrees.First().Options as CSharpParseOptions; - var compilation = context.Compilation.AddSyntaxTrees( - CSharpSyntaxTree.ParseText( - SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8), options)); + var compilation = context.Compilation.AddSyntaxTrees( + CSharpSyntaxTree.ParseText( + SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8), options)); - return compilation; - } + return compilation; } } \ No newline at end of file diff --git a/InterfaceGenerator/InterfaceGenerator.csproj b/InterfaceGenerator/Speckle.InterfaceGenerator.csproj similarity index 70% rename from InterfaceGenerator/InterfaceGenerator.csproj rename to InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 9da3776..5da3d0f 100644 --- a/InterfaceGenerator/InterfaceGenerator.csproj +++ b/InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -1,23 +1,23 @@ netstandard2 - 9.0 + Latest enable - 1.0.14 + 0.9.0 true false false true + Speckle.InterfaceGenerator - R. David - InterfaceGenerator + Speckle.InterfaceGenerator A source generator that creates interfaces from implementations - https://github.com/daver32/InterfaceGenerator - https://github.com/daver32/InterfaceGenerator/blob/master/LICENSE - https://github.com/daver32/InterfaceGenerator + https://github.com/specklesystems/InterfaceGenerator + https://github.com/specklesystems/InterfaceGenerator/blob/master/LICENSE + https://github.com/specklesystems/InterfaceGenerator git diff --git a/InterfaceGenerator/StringExtensions.cs b/InterfaceGenerator/StringExtensions.cs index 8859a69..1240040 100644 --- a/InterfaceGenerator/StringExtensions.cs +++ b/InterfaceGenerator/StringExtensions.cs @@ -1,125 +1,124 @@ -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal static class StringExtensions { - internal static class StringExtensions + public static bool IsCSharpKeyword(string? name) { - public static bool IsCSharpKeyword(string? name) + switch (name) { - switch (name) - { - case "abstract": - case "add": - case "alias": - case "as": - case "ascending": - case "async": - case "await": - case "base": - case "bool": - case "break": - case "by": - case "byte": - case "case": - case "catch": - case "char": - case "checked": - case "class": - case "const": - case "continue": - case "decimal": - case "default": - case "delegate": - case "descending": - case "do": - case "double": - case "dynamic": - case "else": - case "enum": - case "equals": - case "event": - case "explicit": - case "extern": - case "false": - case "finally": - case "fixed": - case "float": - case "for": - case "foreach": - case "from": - case "get": - case "global": - case "goto": - // `group` is a contextual to linq queries that we don't generate - //case "group": - case "if": - case "implicit": - case "in": - case "int": - case "interface": - case "internal": - case "into": - case "is": - case "join": - case "let": - case "lock": - case "long": - case "nameof": - case "namespace": - case "new": - case "null": - case "object": - case "on": - case "operator": - // `orderby` is a contextual to linq queries that we don't generate - //case "orderby": - case "out": - case "override": - case "params": - case "partial": - case "private": - case "protected": - case "public": - case "readonly": - case "ref": - case "remove": - case "return": - case "sbyte": - case "sealed": - // `select` is a contextual to linq queries that we don't generate - // case "select": - case "set": - case "short": - case "sizeof": - case "stackalloc": - case "static": - case "string": - case "struct": - case "switch": - case "this": - case "throw": - case "true": - case "try": - case "typeof": - case "uint": - case "ulong": - case "unchecked": - case "unmanaged": - case "unsafe": - case "ushort": - case "using": - // `value` is a contextual to getters that we don't generate - // case "value": - case "var": - case "virtual": - case "void": - case "volatile": - case "when": - case "where": - case "while": - case "yield": - return true; - default: - return false; - } + case "abstract": + case "add": + case "alias": + case "as": + case "ascending": + case "async": + case "await": + case "base": + case "bool": + case "break": + case "by": + case "byte": + case "case": + case "catch": + case "char": + case "checked": + case "class": + case "const": + case "continue": + case "decimal": + case "default": + case "delegate": + case "descending": + case "do": + case "double": + case "dynamic": + case "else": + case "enum": + case "equals": + case "event": + case "explicit": + case "extern": + case "false": + case "finally": + case "fixed": + case "float": + case "for": + case "foreach": + case "from": + case "get": + case "global": + case "goto": + // `group` is a contextual to linq queries that we don't generate + //case "group": + case "if": + case "implicit": + case "in": + case "int": + case "interface": + case "internal": + case "into": + case "is": + case "join": + case "let": + case "lock": + case "long": + case "nameof": + case "namespace": + case "new": + case "null": + case "object": + case "on": + case "operator": + // `orderby` is a contextual to linq queries that we don't generate + //case "orderby": + case "out": + case "override": + case "params": + case "partial": + case "private": + case "protected": + case "public": + case "readonly": + case "ref": + case "remove": + case "return": + case "sbyte": + case "sealed": + // `select` is a contextual to linq queries that we don't generate + // case "select": + case "set": + case "short": + case "sizeof": + case "stackalloc": + case "static": + case "string": + case "struct": + case "switch": + case "this": + case "throw": + case "true": + case "try": + case "typeof": + case "uint": + case "ulong": + case "unchecked": + case "unmanaged": + case "unsafe": + case "ushort": + case "using": + // `value` is a contextual to getters that we don't generate + // case "value": + case "var": + case "virtual": + case "void": + case "volatile": + case "when": + case "where": + case "while": + case "yield": + return true; + default: + return false; } } } \ No newline at end of file diff --git a/InterfaceGenerator/SymbolExtensions.cs b/InterfaceGenerator/SymbolExtensions.cs index 5f309ae..fc7adc8 100644 --- a/InterfaceGenerator/SymbolExtensions.cs +++ b/InterfaceGenerator/SymbolExtensions.cs @@ -3,66 +3,65 @@ using System.Text; using Microsoft.CodeAnalysis; -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal static class SymbolExtensions { - internal static class SymbolExtensions + public static bool TryGetAttribute( + this ISymbol symbol, + INamedTypeSymbol attributeType, + out IEnumerable attributes) { - public static bool TryGetAttribute( - this ISymbol symbol, - INamedTypeSymbol attributeType, - out IEnumerable attributes) - { - attributes = symbol.GetAttributes() - .Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType)); - return attributes.Any(); - } + attributes = symbol.GetAttributes() + .Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType)); + return attributes.Any(); + } - public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attributeType) - { - return symbol.GetAttributes() - .Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType)); - } + public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attributeType) + { + return symbol.GetAttributes() + .Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType)); + } - //Ref: https://stackoverflow.com/questions/27105909/get-fully-qualified-metadata-name-in-roslyn - public static string GetFullMetadataName(this ISymbol symbol, bool useNameWhenNotFound = false) + //Ref: https://stackoverflow.com/questions/27105909/get-fully-qualified-metadata-name-in-roslyn + public static string GetFullMetadataName(this ISymbol symbol, bool useNameWhenNotFound = false) + { + if (IsRootNamespace(symbol)) { - if (IsRootNamespace(symbol)) - { - return useNameWhenNotFound ? symbol.Name : string.Empty; - } + return useNameWhenNotFound ? symbol.Name : string.Empty; + } - var stringBuilder = new StringBuilder(symbol.MetadataName); - var last = symbol; + var stringBuilder = new StringBuilder(symbol.MetadataName); + var last = symbol; - symbol = symbol.ContainingSymbol; + symbol = symbol.ContainingSymbol; - while (!IsRootNamespace(symbol)) + while (!IsRootNamespace(symbol)) + { + if (symbol is ITypeSymbol && last is ITypeSymbol) { - if (symbol is ITypeSymbol && last is ITypeSymbol) - { - stringBuilder.Insert(0, '+'); - } - else - { - stringBuilder.Insert(0, '.'); - } - - stringBuilder.Insert(0, symbol.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); - symbol = symbol.ContainingSymbol; + stringBuilder.Insert(0, '+'); } - - var retVal = stringBuilder.ToString(); - if (string.IsNullOrWhiteSpace(retVal) && useNameWhenNotFound) + else { - return symbol.Name; + stringBuilder.Insert(0, '.'); } - return retVal; + stringBuilder.Insert(0, symbol.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); + symbol = symbol.ContainingSymbol; } - private static bool IsRootNamespace(ISymbol symbol) + var retVal = stringBuilder.ToString(); + if (string.IsNullOrWhiteSpace(retVal) && useNameWhenNotFound) { - return symbol is INamespaceSymbol { IsGlobalNamespace: true }; + return symbol.Name; } + + return retVal; + } + + private static bool IsRootNamespace(ISymbol symbol) + { + return symbol is INamespaceSymbol { IsGlobalNamespace: true }; } } \ No newline at end of file diff --git a/InterfaceGenerator/SyntaxReceiver.cs b/InterfaceGenerator/SyntaxReceiver.cs index 570b42b..742630f 100644 --- a/InterfaceGenerator/SyntaxReceiver.cs +++ b/InterfaceGenerator/SyntaxReceiver.cs @@ -2,25 +2,24 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal class SyntaxReceiver : ISyntaxReceiver { - internal class SyntaxReceiver : ISyntaxReceiver - { - public IList CandidateTypes { get; } = new List(); + public IList CandidateTypes { get; } = new List(); - public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + public void OnVisitSyntaxNode(SyntaxNode syntaxNode) + { + if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax && + IsClassOrRecord(typeDeclarationSyntax) && + typeDeclarationSyntax.AttributeLists.Count > 0) { - if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax && - IsClassOrRecord(typeDeclarationSyntax) && - typeDeclarationSyntax.AttributeLists.Count > 0) - { - CandidateTypes.Add(typeDeclarationSyntax); - } + CandidateTypes.Add(typeDeclarationSyntax); } + } - private static bool IsClassOrRecord(TypeDeclarationSyntax typeDeclarationSyntax) - { - return typeDeclarationSyntax is ClassDeclarationSyntax || typeDeclarationSyntax is RecordDeclarationSyntax; - } + private static bool IsClassOrRecord(TypeDeclarationSyntax typeDeclarationSyntax) + { + return typeDeclarationSyntax is ClassDeclarationSyntax || typeDeclarationSyntax is RecordDeclarationSyntax; } } \ No newline at end of file diff --git a/InterfaceGenerator/TextWriterExtensions.cs b/InterfaceGenerator/TextWriterExtensions.cs index 2c25a61..4120d99 100644 --- a/InterfaceGenerator/TextWriterExtensions.cs +++ b/InterfaceGenerator/TextWriterExtensions.cs @@ -2,44 +2,43 @@ using System.Collections.Generic; using System.IO; -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal static class TextWriterExtensions { - internal static class TextWriterExtensions + + public static void WriteJoin( + this TextWriter writer, + string separator, + IEnumerable values) { + writer.WriteJoin(separator, values, (w, x) => w.Write(x)); + } - public static void WriteJoin( - this TextWriter writer, - string separator, - IEnumerable values) + public static void WriteJoin( + this TextWriter writer, + string separator, + IEnumerable values, + Action writeAction) + { + using var enumerator = values.GetEnumerator(); + + if (!enumerator.MoveNext()) { - writer.WriteJoin(separator, values, (w, x) => w.Write(x)); + return; } - - public static void WriteJoin( - this TextWriter writer, - string separator, - IEnumerable values, - Action writeAction) - { - using var enumerator = values.GetEnumerator(); - if (!enumerator.MoveNext()) - { - return; - } + writeAction(writer, enumerator.Current); - writeAction(writer, enumerator.Current); - - if (!enumerator.MoveNext()) - { - return; - } - - do - { - writer.Write(separator); - writeAction(writer, enumerator.Current); - } while (enumerator.MoveNext()); + if (!enumerator.MoveNext()) + { + return; } + + do + { + writer.Write(separator); + writeAction(writer, enumerator.Current); + } while (enumerator.MoveNext()); } } \ No newline at end of file diff --git a/InterfaceGenerator/TypeParameterSymbolExtensions.cs b/InterfaceGenerator/TypeParameterSymbolExtensions.cs index bfaa883..ebc4388 100644 --- a/InterfaceGenerator/TypeParameterSymbolExtensions.cs +++ b/InterfaceGenerator/TypeParameterSymbolExtensions.cs @@ -1,48 +1,47 @@ using System.Collections.Generic; using Microsoft.CodeAnalysis; -namespace InterfaceGenerator +namespace Speckle.InterfaceGenerator; + +internal static class TypeParameterSymbolExtensions { - internal static class TypeParameterSymbolExtensions + public static IEnumerable EnumGenericConstraints(this ITypeParameterSymbol symbol) { - public static IEnumerable EnumGenericConstraints(this ITypeParameterSymbol symbol) + // the class/struct/unmanaged/notnull constraint has to be the last + if (symbol.HasNotNullConstraint) { - // the class/struct/unmanaged/notnull constraint has to be the last - if (symbol.HasNotNullConstraint) - { - yield return "notnull"; - } + yield return "notnull"; + } - if (symbol.HasValueTypeConstraint) - { - yield return "struct"; - } + if (symbol.HasValueTypeConstraint) + { + yield return "struct"; + } - if (symbol.HasUnmanagedTypeConstraint) - { - yield return "unmanaged"; - } + if (symbol.HasUnmanagedTypeConstraint) + { + yield return "unmanaged"; + } - if (symbol.HasReferenceTypeConstraint) - { - yield return symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated - ? "class?" - : "class"; - } + if (symbol.HasReferenceTypeConstraint) + { + yield return symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated + ? "class?" + : "class"; + } - // types go in the middle - foreach (var constraintType in symbol.ConstraintTypes) - { - yield return constraintType.ToDisplayString(); - } + // types go in the middle + foreach (var constraintType in symbol.ConstraintTypes) + { + yield return constraintType.ToDisplayString(); + } - // the new() constraint has to be the last - if (symbol.HasConstructorConstraint) - { - yield return "new()"; - } + // the new() constraint has to be the last + if (symbol.HasConstructorConstraint) + { + yield return "new()"; } } } \ No newline at end of file diff --git a/InterfaceGenerator.sln b/Speckle.InterfaceGenerator.sln similarity index 72% rename from InterfaceGenerator.sln rename to Speckle.InterfaceGenerator.sln index 3cae7ca..e52c24d 100644 --- a/InterfaceGenerator.sln +++ b/Speckle.InterfaceGenerator.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterfaceGenerator", "InterfaceGenerator\InterfaceGenerator.csproj", "{D40E2D60-5580-42D2-8316-F5AAA42CFBF6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator", "InterfaceGenerator\Speckle.InterfaceGenerator.csproj", "{D40E2D60-5580-42D2-8316-F5AAA42CFBF6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterfaceGenerator.Tests", "InterfaceGenerator.Tests\InterfaceGenerator.Tests.csproj", "{D39C541E-9EDC-41E9-BBD8-FAA9DA602CC0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator.Tests", "InterfaceGenerator.Tests\Speckle.InterfaceGenerator.Tests.csproj", "{D39C541E-9EDC-41E9-BBD8-FAA9DA602CC0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 1920ade85556599983e7368998bf2e1f2ebb3736 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 11:49:54 +0100 Subject: [PATCH 04/25] folder rename --- .../AccessorsGenerationTests.cs | 0 .../GenericInterfaceTests.cs | 0 .../MethodGenerationTests.cs | 0 .../Partial/PartialClass.1.cs | 0 .../Partial/PartialClass.2.cs | 0 .../PartialClassTests.cs | 0 .../RecordInterfaceGenerationTests.cs | 0 .../SameName/SameNameClass.1.cs | 0 .../SameName/SameNameClass.2.cs | 0 .../Speckle.InterfaceGenerator.Tests.csproj | 0 .../VisibilityModifierTests.cs | 0 Speckle.InterfaceGenerator.sln | 4 ++-- .../.gitattributes | 0 .../AttributeDataExtensions.cs | 0 .../Attributes.cs | 0 .../AutoInterfaceGenerator.cs | 0 .../Speckle.InterfaceGenerator.csproj | 0 .../StringExtensions.cs | 0 .../SymbolExtensions.cs | 0 .../SyntaxReceiver.cs | 0 .../TextWriterExtensions.cs | 0 .../TypeParameterSymbolExtensions.cs | 0 22 files changed, 2 insertions(+), 2 deletions(-) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/AccessorsGenerationTests.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/GenericInterfaceTests.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/MethodGenerationTests.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/Partial/PartialClass.1.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/Partial/PartialClass.2.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/PartialClassTests.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/RecordInterfaceGenerationTests.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/SameName/SameNameClass.1.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/SameName/SameNameClass.2.cs (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/Speckle.InterfaceGenerator.Tests.csproj (100%) rename {InterfaceGenerator.Tests => Speckle.InterfaceGenerator.Tests}/VisibilityModifierTests.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/.gitattributes (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/AttributeDataExtensions.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/Attributes.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/AutoInterfaceGenerator.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/Speckle.InterfaceGenerator.csproj (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/StringExtensions.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/SymbolExtensions.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/SyntaxReceiver.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/TextWriterExtensions.cs (100%) rename {InterfaceGenerator => Speckle.InterfaceGenerator}/TypeParameterSymbolExtensions.cs (100%) diff --git a/InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs similarity index 100% rename from InterfaceGenerator.Tests/AccessorsGenerationTests.cs rename to Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs diff --git a/InterfaceGenerator.Tests/GenericInterfaceTests.cs b/Speckle.InterfaceGenerator.Tests/GenericInterfaceTests.cs similarity index 100% rename from InterfaceGenerator.Tests/GenericInterfaceTests.cs rename to Speckle.InterfaceGenerator.Tests/GenericInterfaceTests.cs diff --git a/InterfaceGenerator.Tests/MethodGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs similarity index 100% rename from InterfaceGenerator.Tests/MethodGenerationTests.cs rename to Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs diff --git a/InterfaceGenerator.Tests/Partial/PartialClass.1.cs b/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.1.cs similarity index 100% rename from InterfaceGenerator.Tests/Partial/PartialClass.1.cs rename to Speckle.InterfaceGenerator.Tests/Partial/PartialClass.1.cs diff --git a/InterfaceGenerator.Tests/Partial/PartialClass.2.cs b/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.2.cs similarity index 100% rename from InterfaceGenerator.Tests/Partial/PartialClass.2.cs rename to Speckle.InterfaceGenerator.Tests/Partial/PartialClass.2.cs diff --git a/InterfaceGenerator.Tests/PartialClassTests.cs b/Speckle.InterfaceGenerator.Tests/PartialClassTests.cs similarity index 100% rename from InterfaceGenerator.Tests/PartialClassTests.cs rename to Speckle.InterfaceGenerator.Tests/PartialClassTests.cs diff --git a/InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs similarity index 100% rename from InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs rename to Speckle.InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs diff --git a/InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs similarity index 100% rename from InterfaceGenerator.Tests/SameName/SameNameClass.1.cs rename to Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs diff --git a/InterfaceGenerator.Tests/SameName/SameNameClass.2.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.2.cs similarity index 100% rename from InterfaceGenerator.Tests/SameName/SameNameClass.2.cs rename to Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.2.cs diff --git a/InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj b/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj similarity index 100% rename from InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj rename to Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj diff --git a/InterfaceGenerator.Tests/VisibilityModifierTests.cs b/Speckle.InterfaceGenerator.Tests/VisibilityModifierTests.cs similarity index 100% rename from InterfaceGenerator.Tests/VisibilityModifierTests.cs rename to Speckle.InterfaceGenerator.Tests/VisibilityModifierTests.cs diff --git a/Speckle.InterfaceGenerator.sln b/Speckle.InterfaceGenerator.sln index e52c24d..62b8552 100644 --- a/Speckle.InterfaceGenerator.sln +++ b/Speckle.InterfaceGenerator.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator", "InterfaceGenerator\Speckle.InterfaceGenerator.csproj", "{D40E2D60-5580-42D2-8316-F5AAA42CFBF6}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator", "Speckle.InterfaceGenerator\Speckle.InterfaceGenerator.csproj", "{D40E2D60-5580-42D2-8316-F5AAA42CFBF6}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator.Tests", "InterfaceGenerator.Tests\Speckle.InterfaceGenerator.Tests.csproj", "{D39C541E-9EDC-41E9-BBD8-FAA9DA602CC0}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator.Tests", "Speckle.InterfaceGenerator.Tests\Speckle.InterfaceGenerator.Tests.csproj", "{D39C541E-9EDC-41E9-BBD8-FAA9DA602CC0}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/InterfaceGenerator/.gitattributes b/Speckle.InterfaceGenerator/.gitattributes similarity index 100% rename from InterfaceGenerator/.gitattributes rename to Speckle.InterfaceGenerator/.gitattributes diff --git a/InterfaceGenerator/AttributeDataExtensions.cs b/Speckle.InterfaceGenerator/AttributeDataExtensions.cs similarity index 100% rename from InterfaceGenerator/AttributeDataExtensions.cs rename to Speckle.InterfaceGenerator/AttributeDataExtensions.cs diff --git a/InterfaceGenerator/Attributes.cs b/Speckle.InterfaceGenerator/Attributes.cs similarity index 100% rename from InterfaceGenerator/Attributes.cs rename to Speckle.InterfaceGenerator/Attributes.cs diff --git a/InterfaceGenerator/AutoInterfaceGenerator.cs b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs similarity index 100% rename from InterfaceGenerator/AutoInterfaceGenerator.cs rename to Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs diff --git a/InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj similarity index 100% rename from InterfaceGenerator/Speckle.InterfaceGenerator.csproj rename to Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj diff --git a/InterfaceGenerator/StringExtensions.cs b/Speckle.InterfaceGenerator/StringExtensions.cs similarity index 100% rename from InterfaceGenerator/StringExtensions.cs rename to Speckle.InterfaceGenerator/StringExtensions.cs diff --git a/InterfaceGenerator/SymbolExtensions.cs b/Speckle.InterfaceGenerator/SymbolExtensions.cs similarity index 100% rename from InterfaceGenerator/SymbolExtensions.cs rename to Speckle.InterfaceGenerator/SymbolExtensions.cs diff --git a/InterfaceGenerator/SyntaxReceiver.cs b/Speckle.InterfaceGenerator/SyntaxReceiver.cs similarity index 100% rename from InterfaceGenerator/SyntaxReceiver.cs rename to Speckle.InterfaceGenerator/SyntaxReceiver.cs diff --git a/InterfaceGenerator/TextWriterExtensions.cs b/Speckle.InterfaceGenerator/TextWriterExtensions.cs similarity index 100% rename from InterfaceGenerator/TextWriterExtensions.cs rename to Speckle.InterfaceGenerator/TextWriterExtensions.cs diff --git a/InterfaceGenerator/TypeParameterSymbolExtensions.cs b/Speckle.InterfaceGenerator/TypeParameterSymbolExtensions.cs similarity index 100% rename from InterfaceGenerator/TypeParameterSymbolExtensions.cs rename to Speckle.InterfaceGenerator/TypeParameterSymbolExtensions.cs From 6945bae955559f80545bf05f3af7e0fd05bedf71 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 11:58:54 +0100 Subject: [PATCH 05/25] update and format --- .config/dotnet-tools.json | 12 ++ .../AccessorsGenerationTests.cs | 66 +++++--- .../GenericInterfaceTests.cs | 13 +- .../MethodGenerationTests.cs | 147 +++++++++--------- .../Partial/PartialClass.1.cs | 5 +- .../Partial/PartialClass.2.cs | 6 +- .../PartialClassTests.cs | 7 +- .../RecordInterfaceGenerationTests.cs | 23 ++- .../SameName/SameNameClass.1.cs | 5 +- .../SameName/SameNameClass.2.cs | 5 +- .../Speckle.InterfaceGenerator.Tests.csproj | 10 +- .../VisibilityModifierTests.cs | 16 +- .../AttributeDataExtensions.cs | 2 +- Speckle.InterfaceGenerator/Attributes.cs | 7 +- .../AutoInterfaceGenerator.cs | 139 ++++++++++++----- .../Speckle.InterfaceGenerator.csproj | 7 +- .../StringExtensions.cs | 2 +- .../SymbolExtensions.cs | 18 ++- Speckle.InterfaceGenerator/SyntaxReceiver.cs | 15 +- .../TextWriterExtensions.cs | 13 +- .../TypeParameterSymbolExtensions.cs | 15 +- 21 files changed, 305 insertions(+), 228 deletions(-) create mode 100644 .config/dotnet-tools.json diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000..a271784 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "csharpier": { + "version": "0.28.2", + "commands": [ + "dotnet-csharpier" + ] + } + } +} \ No newline at end of file diff --git a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs index 593016d..3baf4c7 100644 --- a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Runtime.CompilerServices; using FluentAssertions; using FluentAssertions.Common; @@ -18,7 +19,11 @@ public AccessorsGenerationTests() [Fact] 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(); @@ -32,8 +37,10 @@ public void GetSetIndexer_IsImplemented() [Fact] public void PublicProperty_IsImplemented() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PublicProperty)) ?? throw new InvalidOperationException(); + var prop = + typeof(IAccessorsTestsService).GetProperty( + nameof(IAccessorsTestsService.PublicProperty) + ) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -47,15 +54,19 @@ public void PublicProperty_IsImplemented() [Fact] public void InitProperty_IsImplemented() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.InitOnlyProperty)) ?? throw new InvalidOperationException(); + var prop = + typeof(IAccessorsTestsService).GetProperty( + nameof(IAccessorsTestsService.InitOnlyProperty) + ) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); prop.GetMethod.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; } @@ -63,8 +74,10 @@ public void InitProperty_IsImplemented() [Fact] public void PrivateSetter_IsOmitted() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateSetter)) ?? throw new InvalidOperationException(); + var prop = + typeof(IAccessorsTestsService).GetProperty( + nameof(IAccessorsTestsService.PropertyWithPrivateSetter) + ) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -77,8 +90,10 @@ public void PrivateSetter_IsOmitted() [Fact] public void PrivateGetter_IsOmitted() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithPrivateGetter)) ?? throw new InvalidOperationException(); + var prop = + typeof(IAccessorsTestsService).GetProperty( + nameof(IAccessorsTestsService.PropertyWithPrivateGetter) + ) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -91,8 +106,10 @@ public void PrivateGetter_IsOmitted() [Fact] public void ProtectedSetter_IsOmitted() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedSetter)) ?? throw new InvalidOperationException(); + var prop = + typeof(IAccessorsTestsService).GetProperty( + nameof(IAccessorsTestsService.PropertyWithProtectedSetter) + ) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -105,8 +122,10 @@ public void ProtectedSetter_IsOmitted() [Fact] public void ProtectedGetter_IsOmitted() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(IAccessorsTestsService.PropertyWithProtectedGetter)) ?? throw new InvalidOperationException(); + var prop = + typeof(IAccessorsTestsService).GetProperty( + nameof(IAccessorsTestsService.PropertyWithProtectedGetter) + ) ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); @@ -119,8 +138,9 @@ public void ProtectedGetter_IsOmitted() [Fact] public void IgnoredProperty_IsOmitted() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(AccessorsTestsService.IgnoredProperty)); + var prop = typeof(IAccessorsTestsService).GetProperty( + nameof(AccessorsTestsService.IgnoredProperty) + ); prop.Should().BeNull(); } @@ -128,8 +148,9 @@ public void IgnoredProperty_IsOmitted() [Fact] public void StaticProperty_IsOmitted() { - var prop = typeof(IAccessorsTestsService) - .GetProperty(nameof(AccessorsTestsService.StaticProperty)); + var prop = typeof(IAccessorsTestsService).GetProperty( + nameof(AccessorsTestsService.StaticProperty) + ); prop.Should().BeNull(); } @@ -142,9 +163,7 @@ internal class AccessorsTestsService : IAccessorsTestsService public int this[string x] { get => 0; - set - { - } + set { } } public string PublicProperty { get; set; } @@ -159,8 +178,9 @@ public int this[string x] public string PropertyWithProtectedGetter { protected get; set; } - [AutoInterfaceIgnore] public string IgnoredProperty { get; set; } + [AutoInterfaceIgnore] + public string IgnoredProperty { get; set; } public static string StaticProperty { get; set; } } -// ReSharper enable UnusedMember.Local, ValueParameterNotUsed \ No newline at end of file +// ReSharper enable UnusedMember.Local, ValueParameterNotUsed diff --git a/Speckle.InterfaceGenerator.Tests/GenericInterfaceTests.cs b/Speckle.InterfaceGenerator.Tests/GenericInterfaceTests.cs index d58fab8..ca1255d 100644 --- a/Speckle.InterfaceGenerator.Tests/GenericInterfaceTests.cs +++ b/Speckle.InterfaceGenerator.Tests/GenericInterfaceTests.cs @@ -18,12 +18,15 @@ public void GenericParametersGeneratedCorrectly() genericArgs[0].IsClass.Should().BeTrue(); genericArgs[0] - .GenericParameterAttributes - .Should() + .GenericParameterAttributes.Should() .HaveFlag(GenericParameterAttributes.DefaultConstructorConstraint); 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(); } @@ -33,6 +36,4 @@ public void GenericParametersGeneratedCorrectly() // ReSharper disable once UnusedType.Global internal class GenericInterfaceTestsService : IGenericInterfaceTestsService where TX : class, IEquatable, new() - where TY : struct -{ -} \ No newline at end of file + where TY : struct { } diff --git a/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs index 4c6ae1e..a860f1f 100644 --- a/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -19,8 +19,9 @@ public MethodGenerationTests() [Fact] public void VoidMethod_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethod)) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod(nameof(MethodsTestService.VoidMethod)) + ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -34,8 +35,10 @@ public void VoidMethod_IsImplemented() [Fact] public void VoidMethodWithKeywordParam_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithKeywordParam)) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithKeywordParam) + ) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -52,9 +55,11 @@ public void VoidMethodWithKeywordParam_IsImplemented() [Fact] public void VoidMethodWithParams_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithParams), - [typeof(string), typeof(string)]) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithParams), + [typeof(string), typeof(string)] + ) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -69,15 +74,20 @@ public void VoidMethodWithParams_IsImplemented() [Fact] public void VoidMethodWithOutParam_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithOutParam), - [typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithOutParam), + [typeof(string).MakeByRefType()] + ) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); 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[0].IsOut.Should().BeTrue(); @@ -87,15 +97,20 @@ public void VoidMethodWithOutParam_IsImplemented() [Fact] public void VoidMethodWithInParam_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithInParam), - [typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithInParam), + [typeof(string).MakeByRefType()] + ) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); 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[0].IsIn.Should().BeTrue(); @@ -106,15 +121,20 @@ public void VoidMethodWithInParam_IsImplemented() [Fact] public void VoidMethodWithRefParam_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.VoidMethodWithRefParam), - [typeof(string).MakeByRefType()]) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod( + nameof(MethodsTestService.VoidMethodWithRefParam), + [typeof(string).MakeByRefType()] + ) ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); 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[0].IsIn.Should().BeFalse(); parameters[0].IsOut.Should().BeFalse(); @@ -126,8 +146,9 @@ public void VoidMethodWithRefParam_IsImplemented() [Fact] public void StringMethod_IsImplemented() { - var method = typeof(IMethodsTestService).GetMethod( - nameof(MethodsTestService.StringMethod)) ?? throw new InvalidOperationException(); + var method = + typeof(IMethodsTestService).GetMethod(nameof(MethodsTestService.StringMethod)) + ?? throw new InvalidOperationException(); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(string)); @@ -142,8 +163,8 @@ public void StringMethod_IsImplemented() public void GenericVoidMethod_IsImplemented() { var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethod)); + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethod)); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -160,8 +181,8 @@ public void GenericVoidMethod_IsImplemented() public void GenericVoidMethodWithGenericParam_IsImplemented() { var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithGenericParam)); + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithGenericParam)); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -180,8 +201,8 @@ public void GenericVoidMethodWithGenericParam_IsImplemented() public void GenericVoidMethodWithConstraints_IsImplemented() { var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithConstraints)); + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.GenericVoidMethodWithConstraints)); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -206,8 +227,8 @@ public void GenericVoidMethodWithConstraints_IsImplemented() public void VoidMethodWithOptionalParams_IsImplemented() { var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithOptionalParams)); + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithOptionalParams)); method.Should().NotBeNull(); method.ReturnType.Should().Be(typeof(void)); @@ -226,7 +247,7 @@ public void VoidMethodWithOptionalParams_IsImplemented() parameters[7].DefaultValue.Should().Be(true); parameters[8].DefaultValue.Should().Be(false); parameters[9].DefaultValue.Should().Be(null); - + _sut.VoidMethodWithOptionalParams(); } @@ -234,8 +255,8 @@ public void VoidMethodWithOptionalParams_IsImplemented() public void VoidMethodWithExpandingParam_IsImplemented() { var method = typeof(IMethodsTestService) - .GetMethods() - .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithExpandingParam)); + .GetMethods() + .First(x => x.Name == nameof(MethodsTestService.VoidMethodWithExpandingParam)); method.ReturnType.Should().Be(typeof(void)); @@ -249,8 +270,8 @@ public void VoidMethodWithExpandingParam_IsImplemented() public void IgnoreMethod_IsOmitted() { var method = typeof(IMethodsTestService) - .GetMethods() - .FirstOrDefault(x => x.Name == nameof(MethodsTestService.IgnoredMethod)); + .GetMethods() + .FirstOrDefault(x => x.Name == nameof(MethodsTestService.IgnoredMethod)); method.Should().BeNull(); } @@ -259,8 +280,8 @@ public void IgnoreMethod_IsOmitted() public void StaticMethod_IsOmitted() { var method = typeof(IMethodsTestService) - .GetMethods() - .FirstOrDefault(x => x.Name == nameof(MethodsTestService.StaticMethod)); + .GetMethods() + .FirstOrDefault(x => x.Name == nameof(MethodsTestService.StaticMethod)); method.Should().BeNull(); } @@ -271,49 +292,33 @@ internal class MethodsTestService : IMethodsTestService { 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) { 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() { return string.Empty; } - public void GenericVoidMethod() - { - } + public void GenericVoidMethod() { } - public void GenericVoidMethodWithGenericParam(TX a) - { - } + public void GenericVoidMethodWithGenericParam(TX a) { } public void GenericVoidMethodWithConstraints() where TX : class - where TY : class, TX, new() - { - } + where TY : class, TX, new() { } public void VoidMethodWithOptionalParams( string stringLiteral = "cGFyYW0=", @@ -325,25 +330,17 @@ public void VoidMethodWithOptionalParams( bool falseLiteral = false, bool? nullableTrueLiteral = true, bool? nullableFalseLiteral = false, - bool? nullableNullBoolLiteral = null) - { - } + bool? nullableNullBoolLiteral = null + ) { } - public void VoidMethodWithExpandingParam(params string[] strings) - { - } + public void VoidMethodWithExpandingParam(params string[] strings) { } [AutoInterfaceIgnore] - public void IgnoredMethod() - { - } + public void IgnoredMethod() { } - public static void StaticMethod() - { - } + public static void StaticMethod() { } } [GenerateAutoInterface] -internal class MethodsTestServiceGeneric : IMethodsTestServiceGeneric where T : class -{ -} \ No newline at end of file +internal class MethodsTestServiceGeneric : IMethodsTestServiceGeneric + where T : class { } diff --git a/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.1.cs b/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.1.cs index bbb9788..e965d62 100644 --- a/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.1.cs +++ b/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.1.cs @@ -1,7 +1,4 @@ namespace Speckle.InterfaceGenerator.Tests.Partial; [GenerateAutoInterface] -internal partial class PartialClass : IPartialClass -{ - -} \ No newline at end of file +internal partial class PartialClass : IPartialClass { } diff --git a/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.2.cs b/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.2.cs index fd52e37..caa08b1 100644 --- a/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.2.cs +++ b/Speckle.InterfaceGenerator.Tests/Partial/PartialClass.2.cs @@ -2,7 +2,5 @@ namespace Speckle.InterfaceGenerator.Tests.Partial; internal partial class PartialClass { - public void SomeMethodThatShouldGenerate() - { - } -} \ No newline at end of file + public void SomeMethodThatShouldGenerate() { } +} diff --git a/Speckle.InterfaceGenerator.Tests/PartialClassTests.cs b/Speckle.InterfaceGenerator.Tests/PartialClassTests.cs index 3befa71..ab64e34 100644 --- a/Speckle.InterfaceGenerator.Tests/PartialClassTests.cs +++ b/Speckle.InterfaceGenerator.Tests/PartialClassTests.cs @@ -10,6 +10,9 @@ public class PartialClassTests public void GeneratesMethodFromOtherParts() { var tInterface = typeof(IPartialClass); - tInterface.GetMethods().Should().Contain(x => x.Name == nameof(PartialClass.SomeMethodThatShouldGenerate)); + tInterface + .GetMethods() + .Should() + .Contain(x => x.Name == nameof(PartialClass.SomeMethodThatShouldGenerate)); } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs index 1cb38bc..90e74fa 100644 --- a/Speckle.InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/RecordInterfaceGenerationTests.cs @@ -17,14 +17,17 @@ public RecordInterfaceGenerationTests() [Fact] public void RecordProperty_IsGenerated() { - var prop = typeof(ITestRecord) - .GetProperty(nameof(TestRecord.RecordProperty)) ?? throw new InvalidOperationException(); + var prop = + typeof(ITestRecord).GetProperty(nameof(TestRecord.RecordProperty)) + ?? throw new InvalidOperationException(); prop.Should().NotBeNull(); prop.GetMethod.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); } @@ -32,8 +35,7 @@ public void RecordProperty_IsGenerated() [Fact] public void RecordMethod_IsGenerated() { - var method = typeof(ITestRecord).GetMethod( - nameof(TestRecord.RecordMethod)); + var method = typeof(ITestRecord).GetMethod(nameof(TestRecord.RecordMethod)); method.Should().NotBeNull(); method?.ReturnType.Should().Be(typeof(void)); @@ -47,13 +49,12 @@ public void RecordMethod_IsGenerated() [Fact] public void Deconstruct_IsGenerated() { - var method = typeof(ITestRecord).GetMethod( - nameof(TestRecord.Deconstruct)); + var method = typeof(ITestRecord).GetMethod(nameof(TestRecord.Deconstruct)); method.Should().NotBeNull(); 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); var parameter = parameters[0]; @@ -65,7 +66,5 @@ public void Deconstruct_IsGenerated() [GenerateAutoInterface] internal record TestRecord(int RecordProperty) : ITestRecord { - public void RecordMethod() - { - } -} \ No newline at end of file + public void RecordMethod() { } +} diff --git a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs index cb72fdf..bba5998 100644 --- a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs +++ b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs @@ -9,7 +9,4 @@ namespace InterfaceGenerator.Tests.SameName_1; /// qualified names. /// [GenerateAutoInterface] -internal class SameNameClass : ISameNameClass -{ - -} \ No newline at end of file +internal class SameNameClass : ISameNameClass { } diff --git a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.2.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.2.cs index 67a87c1..b1b2764 100644 --- a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.2.cs +++ b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.2.cs @@ -5,7 +5,4 @@ namespace InterfaceGenerator.Tests.SameName_2; [GenerateAutoInterface] -internal class SameNameClass : ISameNameClass -{ - -} \ No newline at end of file +internal class SameNameClass : ISameNameClass { } diff --git a/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj b/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj index 0c30220..d3121c9 100644 --- a/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj +++ b/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj @@ -7,14 +7,14 @@ - - - - + + + + - + diff --git a/Speckle.InterfaceGenerator.Tests/VisibilityModifierTests.cs b/Speckle.InterfaceGenerator.Tests/VisibilityModifierTests.cs index 951f472..04cc2a2 100644 --- a/Speckle.InterfaceGenerator.Tests/VisibilityModifierTests.cs +++ b/Speckle.InterfaceGenerator.Tests/VisibilityModifierTests.cs @@ -36,21 +36,13 @@ public void IImplicitlyInternalService_IsInternal() } [GenerateAutoInterface(VisibilityModifier = "public")] -internal class ExplicitlyPublicService : IExplicitlyPublicService -{ -} +internal class ExplicitlyPublicService : IExplicitlyPublicService { } [GenerateAutoInterface(VisibilityModifier = "internal")] -public class ExplicitlyInternalService : IExplicitlyInternalService -{ -} +public class ExplicitlyInternalService : IExplicitlyInternalService { } [GenerateAutoInterface] -public class ImplicitlyPublicService : IImplicitlyPublicService -{ -} +public class ImplicitlyPublicService : IImplicitlyPublicService { } [GenerateAutoInterface] -internal class ImplicitlyInternalService : IImplicitlyInternalService -{ -} \ No newline at end of file +internal class ImplicitlyInternalService : IImplicitlyInternalService { } diff --git a/Speckle.InterfaceGenerator/AttributeDataExtensions.cs b/Speckle.InterfaceGenerator/AttributeDataExtensions.cs index 10671cb..3d7c0ec 100644 --- a/Speckle.InterfaceGenerator/AttributeDataExtensions.cs +++ b/Speckle.InterfaceGenerator/AttributeDataExtensions.cs @@ -10,4 +10,4 @@ internal static class AttributeDataExtensions var pair = attributeData.NamedArguments.FirstOrDefault(x => x.Key == paramName); return pair.Value.Value?.ToString(); } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/Attributes.cs b/Speckle.InterfaceGenerator/Attributes.cs index c600554..04200ef 100644 --- a/Speckle.InterfaceGenerator/Attributes.cs +++ b/Speckle.InterfaceGenerator/Attributes.cs @@ -9,8 +9,9 @@ internal class Attributes public const string VisibilityModifierPropName = "VisibilityModifier"; public const string InterfaceNamePropName = "Name"; - - public static readonly string AttributesSourceCode = $@" + + public static readonly string AttributesSourceCode = + $@" using System; using System.Diagnostics; @@ -38,4 +39,4 @@ internal sealed class {AutoInterfaceIgnoreAttributeClassname} : Attribute }} }} "; -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs index 30cdfba..4c2d29d 100644 --- a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs @@ -44,7 +44,10 @@ public void Execute(GeneratorExecutionContext context) } } - private static void RaiseExceptionDiagnostic(GeneratorExecutionContext context, Exception exception) + private static void RaiseExceptionDiagnostic( + GeneratorExecutionContext context, + Exception exception + ) { var descriptor = new DiagnosticDescriptor( "Speckle.InterfaceGenerator.CriticalError", @@ -53,13 +56,14 @@ private static void RaiseExceptionDiagnostic(GeneratorExecutionContext context, "Speckle.InterfaceGenerator", DiagnosticSeverity.Error, true, - customTags: WellKnownDiagnosticTags.AnalyzerException); + customTags: WellKnownDiagnosticTags.AnalyzerException + ); var diagnostic = Diagnostic.Create(descriptor, null); - + context.ReportDiagnostic(diagnostic); } - + private void ExecuteCore(GeneratorExecutionContext context) { // setting the culture to invariant prevents errors such as emitting a decimal comma (0,1) instead of @@ -77,7 +81,8 @@ private static void GenerateAttributes(GeneratorExecutionContext context) { context.AddSource( Attributes.GenerateAutoInterfaceClassname, - SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8)); + SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8) + ); } private void GenerateInterfaces(GeneratorExecutionContext context) @@ -96,26 +101,47 @@ private void GenerateInterfaces(GeneratorExecutionContext context) 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; } - if(classSymbolNames.Contains(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true))) + if ( + classSymbolNames.Contains( + implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true) + ) + ) { continue; // partial class, already added } classSymbolNames.Add(implTypeSymbol.GetFullMetadataName(useNameWhenNotFound: true)); - var attribute = attributes.Single(); - var source = SourceText.From(GenerateInterfaceCode(implTypeSymbol, attribute), Encoding.UTF8); + var attribute = attributes.Single(); + 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); if (!string.IsNullOrEmpty(result)) @@ -126,16 +152,20 @@ private static string InferVisibilityModifier(ISymbol implTypeSymbol, AttributeD return implTypeSymbol.DeclaredAccessibility switch { Accessibility.Public => "public", - _ => "internal", + _ => "internal", }; } 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(); var streamWriter = new StreamWriter(stream, Encoding.UTF8); @@ -179,7 +209,10 @@ private string GenerateInterfaceCode(INamedTypeSymbol implTypeSymbol, AttributeD return reader.ReadToEnd(); } - private static void WriteTypeGenericsIfNeeded(TextWriter writer, INamedTypeSymbol implTypeSymbol) + private static void WriteTypeGenericsIfNeeded( + TextWriter writer, + INamedTypeSymbol implTypeSymbol + ) { if (!implTypeSymbol.IsGenericType) { @@ -193,16 +226,23 @@ private static void WriteTypeGenericsIfNeeded(TextWriter writer, INamedTypeSymbo WriteTypeParameterConstraints(writer, implTypeSymbol.TypeParameters); } - private void GenerateInterfaceMemberDefinitions(TextWriter writer, INamespaceOrTypeSymbol implTypeSymbol) + private void GenerateInterfaceMemberDefinitions( + TextWriter writer, + INamespaceOrTypeSymbol implTypeSymbol + ) { foreach (var member in implTypeSymbol.GetMembers()) { - if (member.DeclaredAccessibility != Accessibility.Public || - member.HasAttribute(_ignoreAttribute ?? throw new NullReferenceException("_ignoreAttribute is null"))) + if ( + member.DeclaredAccessibility != Accessibility.Public + || member.HasAttribute( + _ignoreAttribute ?? throw new NullReferenceException("_ignoreAttribute is null") + ) + ) { continue; } - + GenerateInterfaceMemberDefinition(writer, member); } } @@ -229,10 +269,10 @@ private static void WriteSymbolDocsIfPresent(TextWriter writer, ISymbol symbol) } // omit the fist and last lines to skip the tag - + var reader = new StringReader(xml); var lines = new List(); - + while (true) { var line = reader.ReadLine(); @@ -240,7 +280,7 @@ private static void WriteSymbolDocsIfPresent(TextWriter writer, ISymbol symbol) { break; } - + lines.Add(line); } @@ -256,18 +296,21 @@ private static bool IsPublicOrInternal(ISymbol symbol) 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) { return; } - - bool hasPublicGetter = propertySymbol.GetMethod is not null && - IsPublicOrInternal(propertySymbol.GetMethod); - - bool hasPublicSetter = propertySymbol.SetMethod is not null && - IsPublicOrInternal(propertySymbol.SetMethod); + + bool hasPublicGetter = + propertySymbol.GetMethod is not null && IsPublicOrInternal(propertySymbol.GetMethod); + + bool hasPublicSetter = + propertySymbol.SetMethod is not null && IsPublicOrInternal(propertySymbol.SetMethod); if (!hasPublicGetter && !hasPublicSetter) { @@ -275,7 +318,7 @@ private static void GeneratePropertyDefinition(TextWriter writer, IPropertySymbo } WriteSymbolDocsIfPresent(writer, propertySymbol); - + if (propertySymbol.IsIndexer) { writer.Write("{0} this[", propertySymbol.Type); @@ -316,13 +359,13 @@ private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol me 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), // except for the record Deconstruct method return; } - + WriteSymbolDocsIfPresent(writer, methodSymbol); writer.Write("{0} {1}", methodSymbol.ReturnType, methodSymbol.Name); // ex. int Foo @@ -366,7 +409,7 @@ private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) writer.Write("in "); break; } - + writer.Write(param.Type); writer.Write(" "); @@ -374,7 +417,7 @@ private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) { writer.Write("@"); } - + writer.Write(param.Name); if (param.HasExplicitDefaultValue) @@ -420,7 +463,8 @@ private static void WriteParamExplicitDefaultValue(TextWriter writer, IParameter private static void WriteTypeParameterConstraints( TextWriter writer, - IEnumerable typeParameters) + IEnumerable typeParameters + ) { foreach (var typeParameter in typeParameters) { @@ -438,15 +482,23 @@ private static void WriteTypeParameterConstraints( private void InitAttributes(Compilation compilation) { _generateAutoInterfaceAttribute = compilation.GetTypeByMetadataName( - $"{Attributes.AttributesNamespace}.{Attributes.GenerateAutoInterfaceClassname}"); - + $"{Attributes.AttributesNamespace}.{Attributes.GenerateAutoInterfaceClassname}" + ); + _ignoreAttribute = compilation.GetTypeByMetadataName( - $"{Attributes.AttributesNamespace}.{Attributes.AutoInterfaceIgnoreAttributeClassname}"); + $"{Attributes.AttributesNamespace}.{Attributes.AutoInterfaceIgnoreAttributeClassname}" + ); } - private static IEnumerable GetImplTypeSymbols(Compilation compilation, SyntaxReceiver receiver) + private static IEnumerable GetImplTypeSymbols( + Compilation compilation, + SyntaxReceiver receiver + ) { - return receiver.CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate)).Where(x => x != null).Cast(); + return receiver + .CandidateTypes.Select(candidate => GetTypeSymbol(compilation, candidate)) + .Where(x => x != null) + .Cast(); } private static INamedTypeSymbol? GetTypeSymbol(Compilation compilation, SyntaxNode type) @@ -462,8 +514,11 @@ private static Compilation GetCompilation(GeneratorExecutionContext context) var compilation = context.Compilation.AddSyntaxTrees( CSharpSyntaxTree.ParseText( - SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8), options)); + SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8), + options + ) + ); return compilation; } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 5da3d0f..374f0f9 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -10,6 +10,7 @@ false true Speckle.InterfaceGenerator + true @@ -22,9 +23,9 @@ - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Speckle.InterfaceGenerator/StringExtensions.cs b/Speckle.InterfaceGenerator/StringExtensions.cs index 1240040..02a2522 100644 --- a/Speckle.InterfaceGenerator/StringExtensions.cs +++ b/Speckle.InterfaceGenerator/StringExtensions.cs @@ -121,4 +121,4 @@ public static bool IsCSharpKeyword(string? name) return false; } } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/SymbolExtensions.cs b/Speckle.InterfaceGenerator/SymbolExtensions.cs index fc7adc8..0c65890 100644 --- a/Speckle.InterfaceGenerator/SymbolExtensions.cs +++ b/Speckle.InterfaceGenerator/SymbolExtensions.cs @@ -10,16 +10,19 @@ internal static class SymbolExtensions public static bool TryGetAttribute( this ISymbol symbol, INamedTypeSymbol attributeType, - out IEnumerable attributes) + out IEnumerable attributes + ) { - attributes = symbol.GetAttributes() + attributes = symbol + .GetAttributes() .Where(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType)); return attributes.Any(); } public static bool HasAttribute(this ISymbol symbol, INamedTypeSymbol attributeType) { - return symbol.GetAttributes() + return symbol + .GetAttributes() .Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attributeType)); } @@ -47,7 +50,12 @@ public static string GetFullMetadataName(this ISymbol symbol, bool useNameWhenNo stringBuilder.Insert(0, '.'); } - stringBuilder.Insert(0, symbol.OriginalDefinition.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)); + stringBuilder.Insert( + 0, + symbol.OriginalDefinition.ToDisplayString( + SymbolDisplayFormat.MinimallyQualifiedFormat + ) + ); symbol = symbol.ContainingSymbol; } @@ -64,4 +72,4 @@ private static bool IsRootNamespace(ISymbol symbol) { return symbol is INamespaceSymbol { IsGlobalNamespace: true }; } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/SyntaxReceiver.cs b/Speckle.InterfaceGenerator/SyntaxReceiver.cs index 742630f..7651dee 100644 --- a/Speckle.InterfaceGenerator/SyntaxReceiver.cs +++ b/Speckle.InterfaceGenerator/SyntaxReceiver.cs @@ -7,12 +7,14 @@ namespace Speckle.InterfaceGenerator; internal class SyntaxReceiver : ISyntaxReceiver { public IList CandidateTypes { get; } = new List(); - + public void OnVisitSyntaxNode(SyntaxNode syntaxNode) { - if (syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax && - IsClassOrRecord(typeDeclarationSyntax) && - typeDeclarationSyntax.AttributeLists.Count > 0) + if ( + syntaxNode is TypeDeclarationSyntax typeDeclarationSyntax + && IsClassOrRecord(typeDeclarationSyntax) + && typeDeclarationSyntax.AttributeLists.Count > 0 + ) { CandidateTypes.Add(typeDeclarationSyntax); } @@ -20,6 +22,7 @@ public void OnVisitSyntaxNode(SyntaxNode syntaxNode) private static bool IsClassOrRecord(TypeDeclarationSyntax typeDeclarationSyntax) { - return typeDeclarationSyntax is ClassDeclarationSyntax || typeDeclarationSyntax is RecordDeclarationSyntax; + return typeDeclarationSyntax is ClassDeclarationSyntax + || typeDeclarationSyntax is RecordDeclarationSyntax; } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/TextWriterExtensions.cs b/Speckle.InterfaceGenerator/TextWriterExtensions.cs index 4120d99..c2c5d94 100644 --- a/Speckle.InterfaceGenerator/TextWriterExtensions.cs +++ b/Speckle.InterfaceGenerator/TextWriterExtensions.cs @@ -6,20 +6,17 @@ namespace Speckle.InterfaceGenerator; internal static class TextWriterExtensions { - - public static void WriteJoin( - this TextWriter writer, - string separator, - IEnumerable values) + public static void WriteJoin(this TextWriter writer, string separator, IEnumerable values) { writer.WriteJoin(separator, values, (w, x) => w.Write(x)); } - + public static void WriteJoin( this TextWriter writer, string separator, IEnumerable values, - Action writeAction) + Action writeAction + ) { using var enumerator = values.GetEnumerator(); @@ -41,4 +38,4 @@ public static void WriteJoin( writeAction(writer, enumerator.Current); } while (enumerator.MoveNext()); } -} \ No newline at end of file +} diff --git a/Speckle.InterfaceGenerator/TypeParameterSymbolExtensions.cs b/Speckle.InterfaceGenerator/TypeParameterSymbolExtensions.cs index ebc4388..d33a8ba 100644 --- a/Speckle.InterfaceGenerator/TypeParameterSymbolExtensions.cs +++ b/Speckle.InterfaceGenerator/TypeParameterSymbolExtensions.cs @@ -12,36 +12,35 @@ public static IEnumerable EnumGenericConstraints(this ITypeParameterSymb { yield return "notnull"; } - + if (symbol.HasValueTypeConstraint) { yield return "struct"; } - + if (symbol.HasUnmanagedTypeConstraint) { yield return "unmanaged"; } - + if (symbol.HasReferenceTypeConstraint) { - yield return symbol.ReferenceTypeConstraintNullableAnnotation == NullableAnnotation.Annotated + yield return symbol.ReferenceTypeConstraintNullableAnnotation + == NullableAnnotation.Annotated ? "class?" : "class"; } - // types go in the middle foreach (var constraintType in symbol.ConstraintTypes) { yield return constraintType.ToDisplayString(); } - - + // the new() constraint has to be the last if (symbol.HasConstructorConstraint) { yield return "new()"; } } -} \ No newline at end of file +} From 47b3d45a390afd0659b94087f82a6b58750975d5 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 12:01:09 +0100 Subject: [PATCH 06/25] fixes --- .github/workflows/nuget.yml | 2 +- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index b096c53..82a3ca4 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -28,7 +28,7 @@ jobs: run: dotnet test --no-build --configuration Release --verbosity normal - name: Pack - run: dotnet pack --no-build --configuration Release InterfaceGenerator/InterfaceGenerator.csproj --output . + run: dotnet pack --no-build --configuration Release Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj --output . - name: Push to nuget.org run: dotnet nuget push *.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.NUGET_KEY}} --skip-duplicate \ No newline at end of file diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 374f0f9..8d02ea3 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -10,7 +10,7 @@ false true Speckle.InterfaceGenerator - true + true From d1477d88cc48eb4fb4f9b1f8bbb251a48552d932 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 15:34:14 +0100 Subject: [PATCH 07/25] add correct nuget token --- .github/workflows/nuget.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index 82a3ca4..2de3d2b 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -31,4 +31,4 @@ jobs: run: dotnet pack --no-build --configuration Release Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj --output . - name: Push to nuget.org - run: dotnet nuget push *.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.NUGET_KEY}} --skip-duplicate \ No newline at end of file + run: dotnet nuget push *.nupkg --source "https://api.nuget.org/v3/index.json" --api-key ${{secrets.CONNECTORS_NUGET_TOKEN }} --skip-duplicate \ No newline at end of file From 40d725ffaca04f0e74af58ffa03db3856eee86f6 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 15:35:34 +0100 Subject: [PATCH 08/25] update actions more --- .github/dependabot.yml | 6 ++++++ .github/workflows/nuget.yml | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..3413224 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" # search for actions - there are other options available + directory: "/" # search in .github/workflows under root `/` + schedule: + interval: "weekly" # check for action update every week \ No newline at end of file diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index 2de3d2b..f5e8b3d 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -11,10 +11,10 @@ jobs: steps: - name: Checkout Project - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v4 with: dotnet-version: 8.0.x From e1a345aafe386d2379f857fcba44aae1f1f2b65d Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 17:00:10 +0100 Subject: [PATCH 09/25] retarget to not have conflicts --- .../Speckle.InterfaceGenerator.csproj | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 8d02ea3..c7d89dd 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -1,18 +1,18 @@ - netstandard2 + netstandard2.0 Latest enable - 0.9.0 + 0.9.1 - true - false - false - true - Speckle.InterfaceGenerator + true + false + false + true + Speckle.InterfaceGenerator true - + Speckle.InterfaceGenerator A source generator that creates interfaces from implementations @@ -23,11 +23,11 @@ - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + From bcaf476ae54f0e13baaa225ee36c4723fd7b13fc Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 17 May 2024 17:48:56 +0100 Subject: [PATCH 10/25] always write nullable context --- .../MethodGenerationTests.cs | 36 +++++++++++++++++++ .../AutoInterfaceGenerator.cs | 11 ++---- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs index a860f1f..36ea1e7 100644 --- a/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Text; using FluentAssertions; using Xunit; @@ -159,6 +160,36 @@ public void StringMethod_IsImplemented() var _ = _sut.StringMethod(); } + [Fact] + public void StringMethodNullable_IsImplemented() + { + var method = + typeof(IMethodsTestService).GetMethod(nameof(MethodsTestService.StringMethodNullable)) + ?? throw new InvalidOperationException(); + + method.Should().NotBeNull(); + method.ReturnType.Should().Be(typeof(string)); + IsNullable(method.ReturnType).Should().BeTrue(); + + var parameters = method.GetParameters(); + parameters.Should().BeEmpty(); + + var _ = _sut.StringMethod(); + } + + private static bool IsNullable(Type type) + { + var nullableContextAttribute = type.GetCustomAttribute(); + + // NullableContextAttribute exists and has a flag indicating nullable annotations + if (nullableContextAttribute != null && nullableContextAttribute.Flag == 1) + { + return true; + } + + return false; + } + [Fact] public void GenericVoidMethod_IsImplemented() { @@ -312,6 +343,11 @@ public string StringMethod() return string.Empty; } + public string? StringMethodNullable() + { + return null; + } + public void GenericVoidMethod() { } public void GenericVoidMethodWithGenericParam(TX a) { } diff --git a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs index 4c2d29d..40771e4 100644 --- a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs @@ -176,10 +176,8 @@ AttributeData attributeData var visibilityModifier = InferVisibilityModifier(implTypeSymbol, attributeData); //https://stackoverflow.com/questions/55492214/the-annotation-for-nullable-reference-types-should-only-be-used-in-code-within-a fix for nullable - if (implTypeSymbol.NullableAnnotation == NullableAnnotation.Annotated) - { - codeWriter.WriteLine("#nullable enable"); - } + + codeWriter.WriteLine("#nullable enable"); codeWriter.WriteLine("namespace {0}", namespaceName); codeWriter.WriteLine("{"); @@ -198,10 +196,7 @@ AttributeData attributeData --codeWriter.Indent; codeWriter.WriteLine("}"); - if (implTypeSymbol.NullableAnnotation == NullableAnnotation.Annotated) - { - codeWriter.WriteLine("#nullable restore"); - } + codeWriter.WriteLine("#nullable restore"); codeWriter.Flush(); stream.Seek(0, SeekOrigin.Begin); From b4188aae626c85123af44c5adc223e110c54d63a Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sat, 18 May 2024 09:26:26 +0100 Subject: [PATCH 11/25] bump version --- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index c7d89dd..e6f5c93 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2.0 Latest enable - 0.9.1 + 0.9.2 true false From 6309adfde61818efd365cd62c7b7634d383fe26c Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Sat, 18 May 2024 09:33:36 +0100 Subject: [PATCH 12/25] warnings as errors --- .../AccessorsGenerationTests.cs | 16 ++++++++-------- .../MethodGenerationTests.cs | 2 +- .../Speckle.InterfaceGenerator.Tests.csproj | 2 ++ .../Speckle.InterfaceGenerator.csproj | 1 + 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs index 3baf4c7..ebdeb51 100644 --- a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs @@ -166,21 +166,21 @@ public int this[string x] set { } } - public string PublicProperty { get; set; } + public string PublicProperty { get; set; } = string.Empty; - public string InitOnlyProperty { get; init; } + public string InitOnlyProperty { get; init; } = string.Empty; - public string PropertyWithPrivateSetter { get; private set; } + public string PropertyWithPrivateSetter { get; private set; } = string.Empty; - public string PropertyWithPrivateGetter { private get; set; } + public string PropertyWithPrivateGetter { private get; set; } = string.Empty; - public string PropertyWithProtectedSetter { get; protected set; } + public string PropertyWithProtectedSetter { get; protected set; } = string.Empty; - public string PropertyWithProtectedGetter { protected get; set; } + public string PropertyWithProtectedGetter { protected get; set; } = string.Empty; [AutoInterfaceIgnore] - public string IgnoredProperty { get; set; } + public string IgnoredProperty { get; set; } = string.Empty; - public static string StaticProperty { get; set; } + public static string StaticProperty { get; set; } = string.Empty; } // ReSharper enable UnusedMember.Local, ValueParameterNotUsed diff --git a/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs index 36ea1e7..263766b 100644 --- a/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/MethodGenerationTests.cs @@ -331,7 +331,7 @@ public void VoidMethodWithKeywordParam(string @void) { } public void VoidMethodWithOutParam(out string a) { - a = default; + a = string.Empty; } public void VoidMethodWithRefParam(ref string a) { } diff --git a/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj b/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj index d3121c9..1115338 100644 --- a/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj +++ b/Speckle.InterfaceGenerator.Tests/Speckle.InterfaceGenerator.Tests.csproj @@ -4,6 +4,8 @@ net8.0 false Speckle.InterfaceGenerator.Tests + enable + true diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index e6f5c93..af9c35d 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -11,6 +11,7 @@ true Speckle.InterfaceGenerator true + true From 065d6c75f7a154cee6d1a0da327f6ac3af7dce8a Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 20 May 2024 08:41:27 +0100 Subject: [PATCH 13/25] trying to fix build error --- .editorconfig | 568 ++++++++++++++++++ Speckle.InterfaceGenerator.sln | 8 + Speckle.InterfaceGenerator/Attributes.cs | 9 +- .../Speckle.InterfaceGenerator.csproj | 5 - global.json | 7 + 5 files changed, 589 insertions(+), 8 deletions(-) create mode 100644 .editorconfig create mode 100644 global.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1bab644 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,568 @@ +# Version: 2.0.1 (Using https://semver.org/) +# Updated: 2020-12-11 +# See https://github.com/RehanSaeed/EditorConfig/releases for release notes. +# See https://github.com/RehanSaeed/EditorConfig for updates to this file. +# See http://EditorConfig.org for more information about .editorconfig files. + +########################################## +# Common Settings +########################################## + +# This file is the top-most EditorConfig file +root = true + +# All Files +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = true +trim_trailing_whitespace = true + +########################################## +# File Extension Settings +########################################## + +# Visual Studio Solution Files +[*.sln] +indent_style = tab + +# Visual Studio XML Project Files +[*.{csproj,vbproj,vcxproj.filters,proj,projitems,shproj}] +indent_size = 2 + +# XML Configuration Files +[*.{xml,config,props,targets,nuspec,resx,ruleset,vsixmanifest,vsct}] +indent_size = 2 + +# JSON Files +[*.{json,json5,webmanifest}] +indent_size = 2 + +# YAML Files +[*.{yml,yaml}] +indent_size = 2 + +# Markdown Files +[*.md] +trim_trailing_whitespace = false + +# Web Files +[*.{htm,html,js,jsm,ts,tsx,css,sass,scss,less,svg,vue}] +indent_size = 2 + +# Batch Files +[*.{cmd,bat}] +end_of_line = crlf + +# Bash Files +[*.sh] +end_of_line = lf + +# Makefiles +[Makefile] +indent_style = tab + +########################################## +# Default .NET Code Style Severities +# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/configuration-options#scope +########################################## + +[*.{cs,csx,cake,vb,vbx}] +# Default Severity for all .NET Code Style rules below +dotnet_analyzer_diagnostic.severity = silent + +########################################## +# File Header (Uncomment to support file headers) +# https://docs.microsoft.com/visualstudio/ide/reference/add-file-header +########################################## + +# [*.{cs,csx,cake,vb,vbx}] +# file_header_template = \n© PROJECT-AUTHOR\n + +# SA1636: File header copyright text should match +# Justification: .editorconfig supports file headers. If this is changed to a value other than "none", a stylecop.json file will need to added to the project. +# dotnet_diagnostic.SA1636.severity = none + +########################################## +# .NET Language Conventions +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions +########################################## + +# .NET Code Style Settings +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#net-code-style-settings +[*.{cs,csx,cake,vb,vbx}] +# "this." and "Me." qualifiers +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#this-and-me +#dotnet_style_qualification_for_field = true:warning +#dotnet_style_qualification_for_property = true:warning +#dotnet_style_qualification_for_method = true:warning +#dotnet_style_qualification_for_event = true:warning +# Language keywords instead of framework type names for type references +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#language-keywords +dotnet_style_predefined_type_for_locals_parameters_members = true:warning +dotnet_style_predefined_type_for_member_access = true:warning +# Modifier preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#normalize-modifiers +dotnet_style_require_accessibility_modifiers = always:warning +csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning +visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:warning +dotnet_style_readonly_field = true:warning +# Parentheses preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parentheses-preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning +dotnet_style_parentheses_in_other_operators = always_for_clarity:suggestion +# Expression-level preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences +dotnet_style_object_initializer = true:warning +dotnet_style_collection_initializer = true:warning +dotnet_style_explicit_tuple_names = true:warning +dotnet_style_prefer_inferred_tuple_names = true:warning +dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning +dotnet_style_prefer_auto_properties = true:warning +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:warning +dotnet_style_prefer_conditional_expression_over_assignment = false:suggestion +dotnet_diagnostic.IDE0045.severity = suggestion +dotnet_style_prefer_conditional_expression_over_return = false:suggestion +dotnet_diagnostic.IDE0046.severity = suggestion +dotnet_style_prefer_compound_assignment = true:warning +# Null-checking preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#null-checking-preferences +dotnet_style_coalesce_expression = true:warning +dotnet_style_null_propagation = true:warning +# Parameter preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#parameter-preferences +dotnet_code_quality_unused_parameters = all:warning +# More style options (Undocumented) +# https://github.com/MicrosoftDocs/visualstudio-docs/issues/3641 +dotnet_style_operator_placement_when_wrapping = end_of_line +# https://github.com/dotnet/roslyn/pull/40070 +dotnet_style_prefer_simplified_interpolation = true:warning + +# C# Code Style Settings +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-code-style-settings +[*.{cs,csx,cake}] +# Implicit and explicit types +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#implicit-and-explicit-types +csharp_style_var_for_built_in_types = true:warning +csharp_style_var_when_type_is_apparent = true:warning +csharp_style_var_elsewhere = true:warning +# Expression-bodied members +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-bodied-members +csharp_style_expression_bodied_methods = true:warning +csharp_style_expression_bodied_constructors = true:warning +csharp_style_expression_bodied_operators = true:warning +csharp_style_expression_bodied_properties = true:warning +csharp_style_expression_bodied_indexers = true:warning +csharp_style_expression_bodied_accessors = true:warning +csharp_style_expression_bodied_lambdas = true:warning +csharp_style_expression_bodied_local_functions = true:warning +# Pattern matching +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#pattern-matching +csharp_style_pattern_matching_over_is_with_cast_check = true:warning +csharp_style_pattern_matching_over_as_with_null_check = true:warning +# Inlined variable declarations +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#inlined-variable-declarations +csharp_style_inlined_variable_declaration = true:warning +# Expression-level preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#expression-level-preferences +csharp_prefer_simple_default_expression = true:warning +# "Null" checking preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#c-null-checking-preferences +csharp_style_throw_expression = true:warning +csharp_style_conditional_delegate_call = true:warning +# Code block preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#code-block-preferences +csharp_prefer_braces = true:warning +# Unused value preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#unused-value-preferences +csharp_style_unused_value_expression_statement_preference = discard_variable:suggestion +dotnet_diagnostic.IDE0058.severity = suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +dotnet_diagnostic.IDE0059.severity = suggestion +# Index and range preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#index-and-range-preferences +csharp_style_prefer_index_operator = true:warning +csharp_style_prefer_range_operator = true:warning +# Miscellaneous preferences +# https://docs.microsoft.com/visualstudio/ide/editorconfig-language-conventions#miscellaneous-preferences +csharp_style_deconstructed_variable_declaration = true:warning +csharp_style_pattern_local_over_anonymous_function = true:warning +csharp_using_directive_placement = outside_namespace:warning +csharp_prefer_static_local_function = true:warning +csharp_prefer_simple_using_statement = true:suggestion +dotnet_diagnostic.IDE0063.severity = suggestion + +########################################## +# .NET Formatting Conventions +# https://docs.microsoft.com/visualstudio/ide/editorconfig-code-style-settings-reference#formatting-conventions +########################################## + +# Organize usings +# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#organize-using-directives +dotnet_sort_system_directives_first = true +# Newline options +# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#new-line-options +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_between_query_expression_clauses = true +# Indentation options +# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#indentation-options +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_indent_labels = no_change +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents_when_block = false +# Spacing options +# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#spacing-options +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_between_parentheses = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_around_binary_operators = before_and_after +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_after_comma = true +csharp_space_before_comma = false +csharp_space_after_dot = false +csharp_space_before_dot = false +csharp_space_after_semicolon_in_for_statement = true +csharp_space_before_semicolon_in_for_statement = false +csharp_space_around_declaration_statements = false +csharp_space_before_open_square_brackets = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_square_brackets = false +# Wrapping options +# https://docs.microsoft.com/visualstudio/ide/editorconfig-formatting-conventions#wrap-options +csharp_preserve_single_line_statements = false +csharp_preserve_single_line_blocks = true + +csharp_style_namespace_declarations = file_scoped + +########################################## +# .NET Naming Conventions +# https://docs.microsoft.com/visualstudio/ide/editorconfig-naming-conventions +########################################## + +[*.{cs,csx,cake,vb,vbx}] +dotnet_diagnostic.CA1000.severity = suggestion +dotnet_diagnostic.CA1001.severity = error +dotnet_diagnostic.CA1018.severity = error +dotnet_diagnostic.CA1036.severity = silent +dotnet_diagnostic.CA1051.severity = suggestion +dotnet_diagnostic.CA1068.severity = error +dotnet_diagnostic.CA1069.severity = error +dotnet_diagnostic.CA1304.severity = error +dotnet_diagnostic.CA1305.severity = suggestion +dotnet_diagnostic.CA1307.severity = suggestion +dotnet_diagnostic.CA1309.severity = suggestion +dotnet_diagnostic.CA1310.severity = error +dotnet_diagnostic.CA1507.severity = suggestion +dotnet_diagnostic.CA1513.severity = suggestion +dotnet_diagnostic.CA1707.severity = suggestion +dotnet_diagnostic.CA1708.severity = suggestion +dotnet_diagnostic.CA1711.severity = suggestion +dotnet_diagnostic.CA1716.severity = suggestion +dotnet_diagnostic.CA1720.severity = suggestion +dotnet_diagnostic.CA1725.severity = suggestion +dotnet_diagnostic.CA1805.severity = suggestion +dotnet_diagnostic.CA1816.severity = suggestion +dotnet_diagnostic.CA1822.severity = suggestion +dotnet_diagnostic.CA1825.severity = error +dotnet_diagnostic.CA1826.severity = silent +dotnet_diagnostic.CA1827.severity = error +dotnet_diagnostic.CA1829.severity = suggestion +dotnet_diagnostic.CA1834.severity = error +dotnet_diagnostic.CA1845.severity = suggestion +dotnet_diagnostic.CA1848.severity = suggestion +dotnet_diagnostic.CA1852.severity = suggestion +dotnet_diagnostic.CA1860.severity = silent +dotnet_diagnostic.CA2016.severity = suggestion +dotnet_diagnostic.CA2201.severity = error +dotnet_diagnostic.CA2206.severity = error +dotnet_diagnostic.CA2208.severity = error +dotnet_diagnostic.CA2211.severity = error +dotnet_diagnostic.CA2249.severity = error +dotnet_diagnostic.CA2251.severity = error +dotnet_diagnostic.CA2252.severity = none +dotnet_diagnostic.CA2254.severity = suggestion + +dotnet_diagnostic.CS0169.severity = error +dotnet_diagnostic.CS0219.severity = error +dotnet_diagnostic.CS0649.severity = suggestion +dotnet_diagnostic.CS1998.severity = error +dotnet_diagnostic.CS8602.severity = error +dotnet_diagnostic.CS8604.severity = error +dotnet_diagnostic.CS8618.severity = error +dotnet_diagnostic.CS0618.severity = suggestion +dotnet_diagnostic.CS1998.severity = error +dotnet_diagnostic.CS4014.severity = error +dotnet_diagnostic.CS8600.severity = error +dotnet_diagnostic.CS8603.severity = error +dotnet_diagnostic.CS8625.severity = error + +dotnet_diagnostic.BL0005.severity = suggestion + +dotnet_diagnostic.MVC1000.severity = suggestion + +dotnet_diagnostic.RZ10012.severity = error + +dotnet_diagnostic.IDE0004.severity = error # redundant cast +dotnet_diagnostic.IDE0005.severity = error +dotnet_diagnostic.IDE0007.severity = error # Use var +dotnet_diagnostic.IDE0011.severity = error # Use braces on if statements +dotnet_diagnostic.IDE0010.severity = silent # populate switch +dotnet_diagnostic.IDE0017.severity = suggestion # initialization can be simplified +dotnet_diagnostic.IDE0021.severity = silent # expression body for constructors +dotnet_diagnostic.IDE0022.severity = silent # expression body for methods +dotnet_diagnostic.IDE0023.severity = suggestion # use expression body for operators +dotnet_diagnostic.IDE0024.severity = silent # expression body for operators +dotnet_diagnostic.IDE0025.severity = suggestion # use expression body for properties +dotnet_diagnostic.IDE0027.severity = suggestion # Use expression body for accessors +dotnet_diagnostic.IDE0028.severity = silent # expression body for accessors +dotnet_diagnostic.IDE0032.severity = suggestion # Use auto property +dotnet_diagnostic.IDE0033.severity = error # prefer tuple name +dotnet_diagnostic.IDE0037.severity = suggestion # simplify anonymous type +dotnet_diagnostic.IDE0040.severity = error # modifiers required +dotnet_diagnostic.IDE0041.severity = error # simplify null +dotnet_diagnostic.IDE0042.severity = error # deconstruct variable +dotnet_diagnostic.IDE0044.severity = suggestion # make field only when possible +dotnet_diagnostic.IDE0047.severity = suggestion # parameter name +dotnet_diagnostic.IDE0051.severity = error # unused field +dotnet_diagnostic.IDE0052.severity = error # unused member +dotnet_diagnostic.IDE0053.severity = suggestion # lambda not needed +dotnet_diagnostic.IDE0055.severity = suggestion # Fix formatting +dotnet_diagnostic.IDE0057.severity = suggestion # substring can be simplified +dotnet_diagnostic.IDE0060.severity = suggestion # unused parameters +dotnet_diagnostic.IDE0061.severity = suggestion # local expression body +dotnet_diagnostic.IDE0062.severity = suggestion # local to static +dotnet_diagnostic.IDE0063.severity = error # simplify using +dotnet_diagnostic.IDE0066.severity = suggestion # switch expression +dotnet_diagnostic.IDE0072.severity = suggestion # Populate switch - forces population of all cases even when default specified +dotnet_diagnostic.IDE0078.severity = suggestion # use pattern matching +dotnet_diagnostic.IDE0090.severity = suggestion # new can be simplified +dotnet_diagnostic.IDE0130.severity = suggestion # namespace folder structure +dotnet_diagnostic.IDE0160.severity = silent # Use block namespaces ARE NOT required +dotnet_diagnostic.IDE0161.severity = error # Please use file namespaces +dotnet_diagnostic.IDE0200.severity = suggestion # lambda not needed +dotnet_diagnostic.IDE1006.severity = suggestion # Naming rule violation: These words cannot contain lower case characters +dotnet_diagnostic.IDE0260.severity = suggestion # Use pattern matching +dotnet_diagnostic.IDE0270.severity = suggestion # Null check simplifcation +dotnet_diagnostic.IDE0290.severity = error # Primary Constructor +dotnet_diagnostic.IDE0300.severity = suggestion # Collection +dotnet_diagnostic.IDE0305.severity = suggestion # Collection ToList + +dotnet_diagnostic.NX0001.severity = error +dotnet_diagnostic.NX0002.severity = silent +dotnet_diagnostic.NX0003.severity = silent + +########################################## +# Styles +########################################## + +# camel_case_style - Define the camelCase style +dotnet_naming_style.camel_case_style.capitalization = camel_case +# pascal_case_style - Define the PascalCase style +dotnet_naming_style.pascal_case_style.capitalization = pascal_case +# constant_case - Define the CONSTANT_CASE style +dotnet_naming_style.constant_case.capitalization = all_upper +dotnet_naming_style.constant_case.word_separator = _ +# first_upper_style - The first character must start with an upper-case character +dotnet_naming_style.first_upper_style.capitalization = first_word_upper +# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I' +dotnet_naming_style.prefix_interface_with_i_style.capitalization = pascal_case +dotnet_naming_style.prefix_interface_with_i_style.required_prefix = I +# prefix_type_parameters_with_t_style - Generic Type Parameters must be PascalCase and the first character must be a 'T' +dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_case +dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T +# disallowed_style - Anything that has this style applied is marked as disallowed +dotnet_naming_style.disallowed_style.capitalization = pascal_case +dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____ +dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____ +# internal_error_style - This style should never occur... if it does, it indicates a bug in file or in the parser using the file +dotnet_naming_style.internal_error_style.capitalization = pascal_case +dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____ +dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR____ + +# prefix_interface_with_i_style - Interfaces must be PascalCase and the first character of an interface must be an 'I' +dotnet_naming_style.underscore_camel_case_style.capitalization = camel_case +dotnet_naming_style.underscore_camel_case_style.required_prefix = _ + +########################################## +# .NET Design Guideline Field Naming Rules +# Naming rules for fields follow the .NET Framework design guidelines +# https://docs.microsoft.com/dotnet/standard/design-guidelines/index +########################################## + +# All public/protected/protected_internal constant fields must be constant_case +# https://docs.microsoft.com/dotnet/standard/design-guidelines/field +dotnet_naming_symbols.public_protected_constant_fields_group.applicable_accessibilities = public, protected, protected_internal +dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const +dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field +dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group +dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = constant_case +dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning + +# All public/protected/protected_internal static readonly fields must be constant_case +# https://docs.microsoft.com/dotnet/standard/design-guidelines/field +dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_accessibilities = public, protected, protected_internal +dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly +dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field +dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group +dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = constant_case +dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning + +# No other public/protected/protected_internal fields are allowed +# https://docs.microsoft.com/dotnet/standard/design-guidelines/field +dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibilities = public, protected, protected_internal +dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error + +########################################## +# StyleCop Field Naming Rules +# Naming rules for fields follow the StyleCop analyzers +# This does not override any rules using disallowed_style above +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers +########################################## + +# All constant fields must be constant_case +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1303.md +dotnet_naming_symbols.stylecop_constant_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private +dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const +dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field +dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group +dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = constant_case +dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning + +# All static readonly fields must be constant_case +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1311.md +dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private +dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly +dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field +dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group +dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = constant_case +dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning + +# No non-private instance fields are allowed +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1401.md +dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected +dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field +dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group +dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style +dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error + +# Private fields must be camelCase +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1306.md +dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = private +dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field +dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group +dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = underscore_camel_case_style +dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning + +# Local variables must be camelCase +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md +dotnet_naming_symbols.stylecop_local_fields_group.applicable_accessibilities = local +dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local +dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group +dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style +dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = warning + +# This rule should never fire. However, it's included for at least two purposes: +# First, it helps to understand, reason about, and root-case certain types of issues, such as bugs in .editorconfig parsers. +# Second, it helps to raise immediate awareness if a new field type is added (as occurred recently in C#). +dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_accessibilities = * +dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field +dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group +dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style +dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error + + +########################################## +# Other Naming Rules +########################################## + +# All of the following must be PascalCase: +# - Namespaces +# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-namespaces +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md +# - Classes and Enumerations +# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces +# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md +# - Delegates +# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces#names-of-common-types +# - Constructors, Properties, Events, Methods +# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-type-members +dotnet_naming_symbols.element_group.applicable_kinds = namespace, class, enum, struct, delegate, event, method, property +dotnet_naming_rule.element_rule.symbols = element_group +dotnet_naming_rule.element_rule.style = pascal_case_style +dotnet_naming_rule.element_rule.severity = warning + +# Interfaces use PascalCase and are prefixed with uppercase 'I' +# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces +dotnet_naming_symbols.interface_group.applicable_kinds = interface +dotnet_naming_rule.interface_rule.symbols = interface_group +dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style +dotnet_naming_rule.interface_rule.severity = warning + +# Generics Type Parameters use PascalCase and are prefixed with uppercase 'T' +# https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces +dotnet_naming_symbols.type_parameter_group.applicable_kinds = type_parameter +dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group +dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style +dotnet_naming_rule.type_parameter_rule.severity = warning + +# Function parameters use camelCase +# https://docs.microsoft.com/dotnet/standard/design-guidelines/naming-parameters +dotnet_naming_symbols.parameters_group.applicable_kinds = parameter +dotnet_naming_rule.parameters_rule.symbols = parameters_group +dotnet_naming_rule.parameters_rule.style = camel_case_style +dotnet_naming_rule.parameters_rule.severity = warning + +########################################## +# License +########################################## +# The following applies as to the .editorconfig file ONLY, and is +# included below for reference, per the requirements of the license +# corresponding to this .editorconfig file. +# See: https://github.com/RehanSaeed/EditorConfig +# +# MIT License +# +# Copyright (c) 2017-2019 Muhammad Rehan Saeed +# Copyright (c) 2019 Henry Gabryjelski +# +# Permission is hereby granted, free of charge, to any +# person obtaining a copy of this software and associated +# documentation files (the "Software"), to deal in the +# Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, +# sublicense, and/or sell copies of the Software, and to permit +# persons to whom the Software is furnished to do so, subject +# to the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +########################################## diff --git a/Speckle.InterfaceGenerator.sln b/Speckle.InterfaceGenerator.sln index 62b8552..e4ead48 100644 --- a/Speckle.InterfaceGenerator.sln +++ b/Speckle.InterfaceGenerator.sln @@ -4,6 +4,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Speckle.InterfaceGenerator.Tests", "Speckle.InterfaceGenerator.Tests\Speckle.InterfaceGenerator.Tests.csproj", "{D39C541E-9EDC-41E9-BBD8-FAA9DA602CC0}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{47654DE0-162F-4045-B5EB-151C3678430C}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + .gitignore = .gitignore + global.json = global.json + .github\workflows\nuget.yml = .github\workflows\nuget.yml + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/Speckle.InterfaceGenerator/Attributes.cs b/Speckle.InterfaceGenerator/Attributes.cs index 04200ef..b803e36 100644 --- a/Speckle.InterfaceGenerator/Attributes.cs +++ b/Speckle.InterfaceGenerator/Attributes.cs @@ -13,19 +13,20 @@ internal class Attributes public static readonly string AttributesSourceCode = $@" +#pragma warning disable IDE0005 using System; using System.Diagnostics; #nullable enable -namespace {AttributesNamespace} +namespace {AttributesNamespace} {{ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false)] [Conditional(""CodeGeneration"")] internal sealed class {GenerateAutoInterfaceClassname} : Attribute {{ - public string? {VisibilityModifierPropName} {{ get; init; }} - public string? {InterfaceNamePropName} {{ get; init; }} + public string? {VisibilityModifierPropName} {{ get; init; }} + public string? {InterfaceNamePropName} {{ get; init; }} public {GenerateAutoInterfaceClassname}() {{ @@ -38,5 +39,7 @@ internal sealed class {AutoInterfaceIgnoreAttributeClassname} : Attribute {{ }} }} + +#pragma warning enable IDE0005 "; } diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index af9c35d..7eae8ee 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -4,11 +4,6 @@ Latest enable 0.9.2 - - true - false - false - true Speckle.InterfaceGenerator true true diff --git a/global.json b/global.json new file mode 100644 index 0000000..18b689d --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMinor", + "allowPrerelease": false + } +} From dc132d25159a31ee9449a32e7145e76ffc0bb413 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 20 May 2024 08:42:46 +0100 Subject: [PATCH 14/25] mark for 0.9.3 --- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 7eae8ee..800f0c4 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2.0 Latest enable - 0.9.2 + 0.9.3 Speckle.InterfaceGenerator true true From da4a8a0c50474ba737922486ef0c38954ebc0f65 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 20 May 2024 08:43:35 +0100 Subject: [PATCH 15/25] proper naming --- Speckle.InterfaceGenerator/Attributes.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Speckle.InterfaceGenerator/Attributes.cs b/Speckle.InterfaceGenerator/Attributes.cs index b803e36..3d70ea1 100644 --- a/Speckle.InterfaceGenerator/Attributes.cs +++ b/Speckle.InterfaceGenerator/Attributes.cs @@ -40,6 +40,6 @@ internal sealed class {AutoInterfaceIgnoreAttributeClassname} : Attribute }} }} -#pragma warning enable IDE0005 +#pragma warning restore IDE0005 "; } From 3e620eefedb587526369f4d647def72f4d0e6e2d Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 20 May 2024 08:52:45 +0100 Subject: [PATCH 16/25] fix more strict nuget guidelines --- .../Speckle.InterfaceGenerator.csproj | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 800f0c4..b36c93c 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -13,9 +13,10 @@ Speckle.InterfaceGenerator A source generator that creates interfaces from implementations https://github.com/specklesystems/InterfaceGenerator - https://github.com/specklesystems/InterfaceGenerator/blob/master/LICENSE + https://github.com/specklesystems/InterfaceGenerator/blob/master/LICENSE https://github.com/specklesystems/InterfaceGenerator git + readme.md @@ -24,9 +25,6 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - - - - + From f60ee5318c429de77418aa52bc3f24c6fdac327e Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 20 May 2024 09:12:41 +0100 Subject: [PATCH 17/25] put back some options and mark for 0.9.4 --- .../Speckle.InterfaceGenerator.csproj | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index b36c93c..06cbccb 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,12 @@ netstandard2.0 Latest enable - 0.9.3 + 0.9.4 + true + false + false + true + Speckle.InterfaceGenerator true true @@ -25,6 +30,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + From 88dc7fcc43cc6ea230636ce8f86fdfe55f051c05 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Mon, 3 Jun 2024 10:06:09 +0100 Subject: [PATCH 18/25] fix up actions --- .github/workflows/ci.yml | 26 ++++++++++++++++++++++++++ .github/workflows/nuget.yml | 7 +------ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..1da29ee --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,26 @@ +name: "Check Build" + +on: + pull_request: + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout Project + uses: actions/checkout@v4 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Restore dependencies + run: dotnet restore + + - name: Build + run: dotnet build --configuration Debug --no-restore + + - name: Test + run: dotnet test --no-build --configuration Debug --verbosity normal \ No newline at end of file diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml index f5e8b3d..3350d1e 100644 --- a/.github/workflows/nuget.yml +++ b/.github/workflows/nuget.yml @@ -6,8 +6,6 @@ on: jobs: deploy: runs-on: ubuntu-latest - env: - DOTNET_CLI_TELEMETRY_OPTOUT: true steps: - name: Checkout Project @@ -22,10 +20,7 @@ jobs: run: dotnet restore - name: Build - run: dotnet build --configuration Release --no-restore - - - name: Test - run: dotnet test --no-build --configuration Release --verbosity normal + run: dotnet build --configuration Release --no-restore Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj - name: Pack run: dotnet pack --no-build --configuration Release Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj --output . From e6b909e64224b4ae1618b5577425529cbb7f5c21 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 7 Jun 2024 15:08:21 +0100 Subject: [PATCH 19/25] generate attribute as g.cs and 0.9.5 --- Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs | 2 +- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs index 40771e4..deb577f 100644 --- a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs @@ -80,7 +80,7 @@ private void ExecuteCore(GeneratorExecutionContext context) private static void GenerateAttributes(GeneratorExecutionContext context) { context.AddSource( - Attributes.GenerateAutoInterfaceClassname, + $"{Attributes.GenerateAutoInterfaceClassname}.g.cs", SourceText.From(Attributes.AttributesSourceCode, Encoding.UTF8) ); } diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 06cbccb..69ec099 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2.0 Latest enable - 0.9.4 + 0.9.5 true false false @@ -30,7 +30,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + From 3c592151787c9f2ccc8c55c86107c4d68371999f Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 Jul 2024 15:00:48 +0100 Subject: [PATCH 20/25] Use Global namespaces for some types --- .../AccessorsGenerationTests.cs | 5 ++ .../SameName/SameNameClass.1.cs | 12 ++++- .../AutoInterfaceGenerator.cs | 52 ++++++++++++------- .../SymbolExtensions.cs | 36 +++++++++++++ 4 files changed, 85 insertions(+), 20 deletions(-) diff --git a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs index ebdeb51..ccc2476 100644 --- a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Diagnostics.SymbolStore; using System.Linq; using System.Runtime.CompilerServices; using FluentAssertions; @@ -165,6 +167,9 @@ public int this[string x] get => 0; set { } } + public FtpStyleUriParser? SymbolBinder { get; set; } + public FtpStyleUriParser SymbolBinder2 { get; set; } = default!; + public IEnumerable SymbolBinder3 { get; set; }= default!; public string PublicProperty { get; set; } = string.Empty; diff --git a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs index bba5998..2a751d8 100644 --- a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs +++ b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs @@ -1,5 +1,7 @@ // ReSharper disable CheckNamespace +using System; +using System.Diagnostics.SymbolStore; using Speckle.InterfaceGenerator; namespace InterfaceGenerator.Tests.SameName_1; @@ -9,4 +11,12 @@ namespace InterfaceGenerator.Tests.SameName_1; /// qualified names. /// [GenerateAutoInterface] -internal class SameNameClass : ISameNameClass { } +public class SameNameClass : ISameNameClass { } + +[GenerateAutoInterface] +public class SameNameClass2 : ISameNameClass2 +{ + public ISameNameClass Return() => throw new InvalidOperationException(); + public SymbolToken Return2() => throw new InvalidOperationException(); + +} diff --git a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs index deb577f..5152cca 100644 --- a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs @@ -22,14 +22,6 @@ public class AutoInterfaceGenerator : ISourceGenerator public void Initialize(GeneratorInitializationContext context) { context.RegisterForSyntaxNotifications(() => new SyntaxReceiver()); - -#if DEBUG - if (!Debugger.IsAttached) - { - // sadly this is Windows only so as of now :( - Debugger.Launch(); - } -#endif } public void Execute(GeneratorExecutionContext context) @@ -223,7 +215,7 @@ INamedTypeSymbol implTypeSymbol private void GenerateInterfaceMemberDefinitions( TextWriter writer, - INamespaceOrTypeSymbol implTypeSymbol + INamedTypeSymbol implTypeSymbol ) { foreach (var member in implTypeSymbol.GetMembers()) @@ -238,11 +230,15 @@ INamespaceOrTypeSymbol implTypeSymbol continue; } - GenerateInterfaceMemberDefinition(writer, member); + GenerateInterfaceMemberDefinition(writer, implTypeSymbol, member); } } - private static void GenerateInterfaceMemberDefinition(TextWriter writer, ISymbol member) + private static void GenerateInterfaceMemberDefinition( + TextWriter writer, + INamedTypeSymbol owner, + ISymbol member + ) { switch (member) { @@ -250,7 +246,7 @@ private static void GenerateInterfaceMemberDefinition(TextWriter writer, ISymbol GeneratePropertyDefinition(writer, propertySymbol); break; case IMethodSymbol methodSymbol: - GenerateMethodDefinition(writer, methodSymbol); + GenerateMethodDefinition(writer, owner, methodSymbol); break; } } @@ -316,8 +312,12 @@ IPropertySymbol propertySymbol if (propertySymbol.IsIndexer) { - writer.Write("{0} this[", propertySymbol.Type); - writer.WriteJoin(", ", propertySymbol.Parameters, WriteMethodParam); + writer.Write("{0} this[", propertySymbol.Type.GetNamespaceAndType()); + writer.WriteJoin( + ", ", + propertySymbol.Parameters, + (x, p) => WriteMethodParam(x, p, false) + ); writer.Write("] "); } else @@ -347,7 +347,11 @@ IPropertySymbol propertySymbol writer.WriteLine("}"); } - private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol methodSymbol) + private static void GenerateMethodDefinition( + TextWriter writer, + INamedTypeSymbol owner, + IMethodSymbol methodSymbol + ) { if (methodSymbol.MethodKind != MethodKind.Ordinary || methodSymbol.IsStatic) { @@ -363,7 +367,7 @@ private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol me WriteSymbolDocsIfPresent(writer, methodSymbol); - writer.Write("{0} {1}", methodSymbol.ReturnType, methodSymbol.Name); // ex. int Foo + writer.Write("{0} {1}", methodSymbol.ReturnType.GetNamespaceAndType(), methodSymbol.Name); // ex. int Foo if (methodSymbol.IsGenericMethod) { @@ -373,7 +377,17 @@ private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol me } writer.Write("("); - writer.WriteJoin(", ", methodSymbol.Parameters, WriteMethodParam); + writer.WriteJoin( + ", ", + methodSymbol.Parameters, + (x, p) => + WriteMethodParam( + x, + p, + owner.TypeParameters.Any(t => t.Name == p.Type.Name) + || methodSymbol.TypeParameters.Any(t => t.Name == p.Type.Name) + ) + ); writer.Write(")"); @@ -385,7 +399,7 @@ private static void GenerateMethodDefinition(TextWriter writer, IMethodSymbol me writer.WriteLine(";"); } - private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) + private static void WriteMethodParam(TextWriter writer, IParameterSymbol param, bool isGeneric) { if (param.IsParams) { @@ -405,7 +419,7 @@ private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) break; } - writer.Write(param.Type); + writer.Write(isGeneric ? param.Type : param.Type.GetNamespaceAndType()); writer.Write(" "); if (StringExtensions.IsCSharpKeyword(param.Name)) diff --git a/Speckle.InterfaceGenerator/SymbolExtensions.cs b/Speckle.InterfaceGenerator/SymbolExtensions.cs index 0c65890..5518ff8 100644 --- a/Speckle.InterfaceGenerator/SymbolExtensions.cs +++ b/Speckle.InterfaceGenerator/SymbolExtensions.cs @@ -7,6 +7,42 @@ namespace Speckle.InterfaceGenerator; internal static class SymbolExtensions { + private static readonly HashSet _defaults = new() { "System", "Microsoft" }; + public static string GetNamespaceAndType(this ITypeSymbol typeSymbol) + { + if (typeSymbol.SpecialType != SpecialType.None) + { + return typeSymbol.ToString(); + } + + if (typeSymbol.NullableAnnotation == NullableAnnotation.Annotated) + { + return typeSymbol.ToString(); + } + var namespacez = new List(); + var ns = typeSymbol.ContainingNamespace; + while (ns is not null && !ns.IsGlobalNamespace) + { + namespacez.Insert(0, ns.Name); + ns = ns.ContainingNamespace; + } + + if (namespacez.Any()) + { + if (!_defaults.Contains(namespacez.First())) + { + var candidate = string.Join(".", namespacez); + var name = typeSymbol.ToString(); + if (!name.StartsWith(candidate)) + { + name += candidate + "." + name; + } + return "global::" + name; + } + } + + return typeSymbol.ToString(); + } public static bool TryGetAttribute( this ISymbol symbol, INamedTypeSymbol attributeType, From f6688fa5a3c8ba8d91aa5faae195308cec334652 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 30 Jul 2024 15:01:19 +0100 Subject: [PATCH 21/25] 0.9.6 --- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 69ec099..d49b068 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2.0 Latest enable - 0.9.5 + 0.9.6 true false false From 210276406b26167c530abc584f39c94a78e49207 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 22 Aug 2024 16:02:01 +0100 Subject: [PATCH 22/25] Return a generic value --- Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs | 1 + Speckle.InterfaceGenerator/SymbolExtensions.cs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs index 2a751d8..9c855f5 100644 --- a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs +++ b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs @@ -18,5 +18,6 @@ public class SameNameClass2 : ISameNameClass2 { public ISameNameClass Return() => throw new InvalidOperationException(); public SymbolToken Return2() => throw new InvalidOperationException(); + public T GetRequiredService() where T : class => throw new InvalidOperationException(); } diff --git a/Speckle.InterfaceGenerator/SymbolExtensions.cs b/Speckle.InterfaceGenerator/SymbolExtensions.cs index 5518ff8..889d8bd 100644 --- a/Speckle.InterfaceGenerator/SymbolExtensions.cs +++ b/Speckle.InterfaceGenerator/SymbolExtensions.cs @@ -10,6 +10,10 @@ internal static class SymbolExtensions private static readonly HashSet _defaults = new() { "System", "Microsoft" }; public static string GetNamespaceAndType(this ITypeSymbol typeSymbol) { + if (typeSymbol is ITypeParameterSymbol t) + { + return t.Name; + } if (typeSymbol.SpecialType != SpecialType.None) { return typeSymbol.ToString(); From 42a1a3ca156666d7fc513a0837c213c70bd9bc98 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Thu, 22 Aug 2024 16:02:28 +0100 Subject: [PATCH 23/25] 0.9.7 --- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index d49b068..0542471 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2.0 Latest enable - 0.9.6 + 0.9.7 true false false From 657fb078a81985ecc7fac2bbb8073c5adfe14362 Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 3 Sep 2024 09:19:40 +0100 Subject: [PATCH 24/25] Properly convert type to globals with namespace --- .../AccessorsGenerationTests.cs | 2 +- .../SameName/SameNameClass.1.cs | 8 +++- .../AutoInterfaceGenerator.cs | 27 ++++--------- .../SymbolExtensions.cs | 38 ++----------------- 4 files changed, 20 insertions(+), 55 deletions(-) diff --git a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs index ccc2476..f3bca43 100644 --- a/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs +++ b/Speckle.InterfaceGenerator.Tests/AccessorsGenerationTests.cs @@ -169,7 +169,7 @@ public int this[string x] } public FtpStyleUriParser? SymbolBinder { get; set; } public FtpStyleUriParser SymbolBinder2 { get; set; } = default!; - public IEnumerable SymbolBinder3 { get; set; }= default!; + public IEnumerable SymbolBinder3 { get; set; } = default!; public string PublicProperty { get; set; } = string.Empty; diff --git a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs index 9c855f5..e134043 100644 --- a/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs +++ b/Speckle.InterfaceGenerator.Tests/SameName/SameNameClass.1.cs @@ -1,6 +1,7 @@ // ReSharper disable CheckNamespace using System; +using System.Collections.Generic; using System.Diagnostics.SymbolStore; using Speckle.InterfaceGenerator; @@ -17,7 +18,12 @@ public class SameNameClass : ISameNameClass { } public class SameNameClass2 : ISameNameClass2 { public ISameNameClass Return() => throw new InvalidOperationException(); + public SymbolToken Return2() => throw new InvalidOperationException(); - public T GetRequiredService() where T : class => throw new InvalidOperationException(); + public T GetRequiredService() + where T : class => throw new InvalidOperationException(); + + public void TestGenericParameter(List x) => + throw new InvalidOperationException(); } diff --git a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs index 5152cca..2fc3394 100644 --- a/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs +++ b/Speckle.InterfaceGenerator/AutoInterfaceGenerator.cs @@ -313,11 +313,7 @@ IPropertySymbol propertySymbol if (propertySymbol.IsIndexer) { writer.Write("{0} this[", propertySymbol.Type.GetNamespaceAndType()); - writer.WriteJoin( - ", ", - propertySymbol.Parameters, - (x, p) => WriteMethodParam(x, p, false) - ); + writer.WriteJoin(", ", propertySymbol.Parameters, WriteMethodParam); writer.Write("] "); } else @@ -372,22 +368,15 @@ IMethodSymbol methodSymbol if (methodSymbol.IsGenericMethod) { writer.Write("<"); - writer.WriteJoin(", ", methodSymbol.TypeParameters.Select(x => x.Name)); + writer.WriteJoin( + ", ", + methodSymbol.TypeParameters.Select(x => x.GetNamespaceAndType()) + ); writer.Write(">"); } writer.Write("("); - writer.WriteJoin( - ", ", - methodSymbol.Parameters, - (x, p) => - WriteMethodParam( - x, - p, - owner.TypeParameters.Any(t => t.Name == p.Type.Name) - || methodSymbol.TypeParameters.Any(t => t.Name == p.Type.Name) - ) - ); + writer.WriteJoin(", ", methodSymbol.Parameters, WriteMethodParam); writer.Write(")"); @@ -399,7 +388,7 @@ IMethodSymbol methodSymbol writer.WriteLine(";"); } - private static void WriteMethodParam(TextWriter writer, IParameterSymbol param, bool isGeneric) + private static void WriteMethodParam(TextWriter writer, IParameterSymbol param) { if (param.IsParams) { @@ -419,7 +408,7 @@ private static void WriteMethodParam(TextWriter writer, IParameterSymbol param, break; } - writer.Write(isGeneric ? param.Type : param.Type.GetNamespaceAndType()); + writer.Write(param.Type.GetNamespaceAndType()); writer.Write(" "); if (StringExtensions.IsCSharpKeyword(param.Name)) diff --git a/Speckle.InterfaceGenerator/SymbolExtensions.cs b/Speckle.InterfaceGenerator/SymbolExtensions.cs index 889d8bd..dc733ea 100644 --- a/Speckle.InterfaceGenerator/SymbolExtensions.cs +++ b/Speckle.InterfaceGenerator/SymbolExtensions.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -7,46 +8,15 @@ namespace Speckle.InterfaceGenerator; internal static class SymbolExtensions { - private static readonly HashSet _defaults = new() { "System", "Microsoft" }; public static string GetNamespaceAndType(this ITypeSymbol typeSymbol) { if (typeSymbol is ITypeParameterSymbol t) { return t.Name; } - if (typeSymbol.SpecialType != SpecialType.None) - { - return typeSymbol.ToString(); - } - - if (typeSymbol.NullableAnnotation == NullableAnnotation.Annotated) - { - return typeSymbol.ToString(); - } - var namespacez = new List(); - var ns = typeSymbol.ContainingNamespace; - while (ns is not null && !ns.IsGlobalNamespace) - { - namespacez.Insert(0, ns.Name); - ns = ns.ContainingNamespace; - } - - if (namespacez.Any()) - { - if (!_defaults.Contains(namespacez.First())) - { - var candidate = string.Join(".", namespacez); - var name = typeSymbol.ToString(); - if (!name.StartsWith(candidate)) - { - name += candidate + "." + name; - } - return "global::" + name; - } - } - - return typeSymbol.ToString(); + return typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); } + public static bool TryGetAttribute( this ISymbol symbol, INamedTypeSymbol attributeType, From 26d8506cd72a2c4de17159e56a9be2ef4e59ddec Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Tue, 3 Sep 2024 09:20:04 +0100 Subject: [PATCH 25/25] 0.9.8 --- Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj index 0542471..9577c28 100644 --- a/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj +++ b/Speckle.InterfaceGenerator/Speckle.InterfaceGenerator.csproj @@ -3,7 +3,7 @@ netstandard2.0 Latest enable - 0.9.7 + 0.9.8 true false false