From 2f8a8976764b5a3fb899defb4bb1d881c9257d27 Mon Sep 17 00:00:00 2001 From: Mohammadreza Taikandi Date: Sat, 17 Apr 2021 08:13:08 +0100 Subject: [PATCH] Refactor DiagnosticProvider to DiagnosticsFactory. --- src/MapTo/DiagnosticProvider.cs | 37 ---------------- src/MapTo/DiagnosticsFactory.cs | 42 +++++++++++++++++++ .../GeneratorExecutionContextExtensions.cs | 2 +- .../Extensions/ShouldlyExtensions.cs | 2 +- test/MapTo.Tests/MapToTests.cs | 14 +++---- test/MapTo.Tests/MapTypeConverterTests.cs | 4 +- 6 files changed, 53 insertions(+), 48 deletions(-) delete mode 100644 src/MapTo/DiagnosticProvider.cs create mode 100644 src/MapTo/DiagnosticsFactory.cs diff --git a/src/MapTo/DiagnosticProvider.cs b/src/MapTo/DiagnosticProvider.cs deleted file mode 100644 index a43506b..0000000 --- a/src/MapTo/DiagnosticProvider.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Collections.Immutable; -using System.Linq; -using MapTo.Sources; -using Microsoft.CodeAnalysis; -using static MapTo.Sources.Constants; - -namespace MapTo -{ - internal static class DiagnosticProvider - { - private const string UsageCategory = "Usage"; - private const string ErrorId = "MT0"; - private const string InfoId = "MT1"; - private const string WarningId = "MT2"; - - internal static Diagnostic TypeNotFoundError(Location location, string syntaxName) => - Create($"{ErrorId}010", location, "Type not found.", $"Unable to find '{syntaxName}' type."); - - internal static Diagnostic MapFromAttributeNotFoundError(Location location) => - Create($"{ErrorId}020", location, "Attribute Not Available", $"Unable to find {MapFromAttributeSource.AttributeName} type."); - - internal static Diagnostic NoMatchingPropertyFoundError(Location location, INamedTypeSymbol classType, INamedTypeSymbol sourceType) => - Create($"{ErrorId}030", location, "Type Mismatch", $"No matching properties found between '{classType.ToDisplayString()}' and '{sourceType.ToDisplayString()}' types."); - - internal static Diagnostic NoMatchingPropertyTypeFoundError(IPropertySymbol property) => - Create($"{ErrorId}031", property.Locations.FirstOrDefault(), "Type Mismatch", $"Cannot create a map for '{property.ToDisplayString()}' property because source and destination types are not implicitly convertible. Consider using '{MapTypeConverterAttributeSource.FullyQualifiedName}' to provide a type converter or ignore the property using '{IgnorePropertyAttributeSource.FullyQualifiedName}'."); - - internal static Diagnostic InvalidTypeConverterGenericTypesError(IPropertySymbol property, IPropertySymbol sourceProperty) => - Create($"{ErrorId}032", property.Locations.FirstOrDefault(), "Type Mismatch", $"Cannot map '{property.ToDisplayString()}' property because the annotated converter does not implement '{RootNamespace}.{ITypeConverterSource.InterfaceName}<{sourceProperty.Type.ToDisplayString()}, {property.Type.ToDisplayString()}>'."); - - internal static Diagnostic ConfigurationParseError(string error) => - Create($"{ErrorId}040", Location.None, "Incorrect Configuration", error); - - private static Diagnostic Create(string id, Location? location, string title, string message, DiagnosticSeverity severity = DiagnosticSeverity.Error) => - Diagnostic.Create(new DiagnosticDescriptor(id, title, message, UsageCategory, severity, true), location ?? Location.None); - } -} \ No newline at end of file diff --git a/src/MapTo/DiagnosticsFactory.cs b/src/MapTo/DiagnosticsFactory.cs new file mode 100644 index 0000000..1c0c56f --- /dev/null +++ b/src/MapTo/DiagnosticsFactory.cs @@ -0,0 +1,42 @@ +using System.Collections.Immutable; +using System.Linq; +using MapTo.Sources; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using static MapTo.Sources.Constants; + +namespace MapTo +{ + internal static class DiagnosticsFactory + { + private const string UsageCategory = "Usage"; + private const string CodePrefix = "MT"; + private const string ErrorId = CodePrefix + "0"; + private const string InfoId = CodePrefix + "1"; + private const string WarningId = CodePrefix + "2"; + + internal static Diagnostic TypeNotFoundError(Location location, string syntaxName) => + Create($"{ErrorId}010", location, $"Unable to find '{syntaxName}' type."); + + internal static Diagnostic MapFromAttributeNotFoundError(Location location) => + Create($"{ErrorId}020", location, $"Unable to find {MapFromAttributeSource.AttributeName} type."); + + internal static Diagnostic NoMatchingPropertyFoundError(Location location, INamedTypeSymbol classType, INamedTypeSymbol sourceType) => + Create($"{ErrorId}030", location, $"No matching properties found between '{classType.ToDisplayString()}' and '{sourceType.ToDisplayString()}' types."); + + internal static Diagnostic NoMatchingPropertyTypeFoundError(IPropertySymbol property) => + Create($"{ErrorId}031", property.Locations.FirstOrDefault(), $"Cannot create a map for '{property.ToDisplayString()}' property because source and destination types are not implicitly convertible. Consider using '{MapTypeConverterAttributeSource.FullyQualifiedName}' to provide a type converter or ignore the property using '{IgnorePropertyAttributeSource.FullyQualifiedName}'."); + + internal static Diagnostic InvalidTypeConverterGenericTypesError(IPropertySymbol property, IPropertySymbol sourceProperty) => + Create($"{ErrorId}032", property.Locations.FirstOrDefault(), $"Cannot map '{property.ToDisplayString()}' property because the annotated converter does not implement '{RootNamespace}.{ITypeConverterSource.InterfaceName}<{sourceProperty.Type.ToDisplayString()}, {property.Type.ToDisplayString()}>'."); + + internal static Diagnostic ConfigurationParseError(string error) => + Create($"{ErrorId}040", Location.None, error); + + internal static Diagnostic MissingConstructorArgument(ConstructorDeclarationSyntax constructorSyntax) => + Create($"{ErrorId}050", constructorSyntax.GetLocation(), "There are no argument given that corresponds to the required formal parameter."); + + private static Diagnostic Create(string id, Location? location, string message, DiagnosticSeverity severity = DiagnosticSeverity.Error) => + Diagnostic.Create(new DiagnosticDescriptor(id, null, message, UsageCategory, severity, true), location ?? Location.None); + } +} \ No newline at end of file diff --git a/src/MapTo/Extensions/GeneratorExecutionContextExtensions.cs b/src/MapTo/Extensions/GeneratorExecutionContextExtensions.cs index cb690e4..4b85fc8 100644 --- a/src/MapTo/Extensions/GeneratorExecutionContextExtensions.cs +++ b/src/MapTo/Extensions/GeneratorExecutionContextExtensions.cs @@ -30,7 +30,7 @@ namespace MapTo.Extensions } catch (Exception) { - context.ReportDiagnostic(DiagnosticProvider.ConfigurationParseError($"'{optionValue}' is not a valid value for {PropertyNameSuffix}{propertyName} property.")); + context.ReportDiagnostic(DiagnosticsFactory.ConfigurationParseError($"'{optionValue}' is not a valid value for {PropertyNameSuffix}{propertyName} property.")); return defaultValue; } } diff --git a/test/MapTo.Tests/Extensions/ShouldlyExtensions.cs b/test/MapTo.Tests/Extensions/ShouldlyExtensions.cs index f7aeb57..e080ac9 100644 --- a/test/MapTo.Tests/Extensions/ShouldlyExtensions.cs +++ b/test/MapTo.Tests/Extensions/ShouldlyExtensions.cs @@ -66,7 +66,7 @@ namespace MapTo.Tests.Extensions Assert.False(true, builder.ToString()); } - internal static void ShouldBeUnsuccessful(this ImmutableArray diagnostics, Diagnostic expectedError) + internal static void ShouldNotBeSuccessful(this ImmutableArray diagnostics, Diagnostic expectedError) { var actualDiagnostics = diagnostics.SingleOrDefault(d => d.Id == expectedError.Id); var compilationDiagnostics = actualDiagnostics == null ? diagnostics : diagnostics.Except(new[] { actualDiagnostics }); diff --git a/test/MapTo.Tests/MapToTests.cs b/test/MapTo.Tests/MapToTests.cs index 4aa4988..b3d39f5 100644 --- a/test/MapTo.Tests/MapToTests.cs +++ b/test/MapTo.Tests/MapToTests.cs @@ -56,9 +56,9 @@ namespace MapTo var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions); // Assert - var expectedError = DiagnosticProvider.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("Prop4", compilation)); + var expectedError = DiagnosticsFactory.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("Prop4", compilation)); - diagnostics.ShouldBeUnsuccessful(expectedError); + diagnostics.ShouldNotBeSuccessful(expectedError); } [Fact] @@ -178,7 +178,7 @@ namespace Test var bazType = compilation.GetTypeByMetadataName("Test.Baz"); bazType.ShouldNotBeNull(); - var expectedDiagnostic = DiagnosticProvider.NoMatchingPropertyFoundError(fooType.Locations.Single(), fooType, bazType); + var expectedDiagnostic = DiagnosticsFactory.NoMatchingPropertyFoundError(fooType.Locations.Single(), fooType, bazType); var error = diagnostics.FirstOrDefault(d => d.Id == expectedDiagnostic.Id); error.ShouldNotBeNull(); } @@ -425,8 +425,8 @@ namespace Test var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions); // Assert - var expectedError = DiagnosticProvider.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("InnerProp1", compilation)); - diagnostics.ShouldBeUnsuccessful(expectedError); + var expectedError = DiagnosticsFactory.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("InnerProp1", compilation)); + diagnostics.ShouldNotBeSuccessful(expectedError); } [Fact] @@ -454,8 +454,8 @@ namespace Test var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions); // Assert - var expectedError = DiagnosticProvider.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("InnerProp1", compilation)); - diagnostics.ShouldBeUnsuccessful(expectedError); + var expectedError = DiagnosticsFactory.NoMatchingPropertyTypeFoundError(GetSourcePropertySymbol("InnerProp1", compilation)); + diagnostics.ShouldNotBeSuccessful(expectedError); } [Fact] diff --git a/test/MapTo.Tests/MapTypeConverterTests.cs b/test/MapTo.Tests/MapTypeConverterTests.cs index ec2c456..011cf09 100644 --- a/test/MapTo.Tests/MapTypeConverterTests.cs +++ b/test/MapTo.Tests/MapTypeConverterTests.cs @@ -276,8 +276,8 @@ namespace Test var (compilation, diagnostics) = CSharpGenerator.GetOutputCompilation(source, analyzerConfigOptions: DefaultAnalyzerOptions); // Assert - var expectedError = DiagnosticProvider.InvalidTypeConverterGenericTypesError(GetSourcePropertySymbol("Prop4", compilation), GetSourcePropertySymbol("Prop4", compilation, "Baz")); - diagnostics.ShouldBeUnsuccessful(expectedError); + var expectedError = DiagnosticsFactory.InvalidTypeConverterGenericTypesError(GetSourcePropertySymbol("Prop4", compilation), GetSourcePropertySymbol("Prop4", compilation, "Baz")); + diagnostics.ShouldNotBeSuccessful(expectedError); } } } \ No newline at end of file