diff --git a/src/MapTo/AccessModifier.cs b/src/MapTo/AccessModifier.cs deleted file mode 100644 index 64f557b..0000000 --- a/src/MapTo/AccessModifier.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace MapTo -{ - internal enum AccessModifier - { - Public, - Internal, - Private - } -} \ No newline at end of file diff --git a/src/MapTo/Extensions/RoslynExtensions.cs b/src/MapTo/Extensions/RoslynExtensions.cs index 234b60d..edae4c8 100644 --- a/src/MapTo/Extensions/RoslynExtensions.cs +++ b/src/MapTo/Extensions/RoslynExtensions.cs @@ -116,5 +116,16 @@ namespace MapTo.Extensions public static SyntaxNode? GetSyntaxNode(this ISymbol symbol) => symbol.Locations.FirstOrDefault() is { } location ? location.SourceTree?.GetRoot().FindNode(location.SourceSpan) : null; + + public static IEnumerable GetTypesByMetadataName(this Compilation compilation, string typeMetadataName) + { + return compilation.References + .Select(compilation.GetAssemblyOrModuleSymbol) + .OfType() + .Select(assemblySymbol => assemblySymbol.GetTypeByMetadataName(typeMetadataName)) + .Where(t => t != null)!; + } + + public static bool TypeByMetadataNameExists(this Compilation compilation, string typeMetadataName) => GetTypesByMetadataName(compilation, typeMetadataName).Any(); } } \ No newline at end of file diff --git a/src/MapTo/Models.cs b/src/MapTo/Models.cs index 1ec8e0d..9bda8be 100644 --- a/src/MapTo/Models.cs +++ b/src/MapTo/Models.cs @@ -1,10 +1,25 @@ -using System.Collections.Immutable; +using System; +using System.Collections.Immutable; using MapTo.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; namespace MapTo { + internal enum AccessModifier + { + Public, + Internal, + Private + } + + internal enum NullStaticAnalysisState + { + Default, + Enabled, + Disabled + } + internal record SourceCode(string Text, string HintName); internal record MappedProperty( @@ -42,29 +57,25 @@ namespace MapTo AccessModifier GeneratedMethodsAccessModifier, bool GenerateXmlDocument, bool SupportNullableReferenceTypes, - bool SupportNullableStaticAnalysis, - LanguageVersion LanguageVersion) + bool SupportNullableStaticAnalysis) { internal static SourceGenerationOptions From(GeneratorExecutionContext context) { - var compilation = context.Compilation as CSharpCompilation; - var supportNullableReferenceTypes = false; - var supportNullableStaticAnalysis = false; + const string allowNullAttributeName = "System.Diagnostics.CodeAnalysis.AllowNullAttribute"; + var supportNullableStaticAnalysis = context.GetBuildGlobalOption(propertyName: nameof(SupportNullableStaticAnalysis), NullStaticAnalysisState.Default); + var supportNullableReferenceTypes = context.Compilation.Options.NullableContextOptions is NullableContextOptions.Warnings or NullableContextOptions.Enable; - if (compilation is not null) - { - supportNullableStaticAnalysis = compilation.LanguageVersion >= LanguageVersion.CSharp8; - supportNullableReferenceTypes = compilation.Options.NullableContextOptions == NullableContextOptions.Warnings || - compilation.Options.NullableContextOptions == NullableContextOptions.Enable; - } - return new( - context.GetBuildGlobalOption(nameof(ConstructorAccessModifier), AccessModifier.Public), - context.GetBuildGlobalOption(nameof(GeneratedMethodsAccessModifier), AccessModifier.Public), - context.GetBuildGlobalOption(nameof(GenerateXmlDocument), true), - supportNullableReferenceTypes, - supportNullableStaticAnalysis, - compilation?.LanguageVersion ?? LanguageVersion.Default + ConstructorAccessModifier: context.GetBuildGlobalOption(propertyName: nameof(ConstructorAccessModifier), AccessModifier.Public), + GeneratedMethodsAccessModifier: context.GetBuildGlobalOption(propertyName: nameof(GeneratedMethodsAccessModifier), AccessModifier.Public), + GenerateXmlDocument: context.GetBuildGlobalOption(propertyName: nameof(GenerateXmlDocument), true), + SupportNullableReferenceTypes: supportNullableReferenceTypes, + SupportNullableStaticAnalysis: supportNullableStaticAnalysis switch + { + NullStaticAnalysisState.Enabled => true, + NullStaticAnalysisState.Disabled => false, + _ => context.Compilation is CSharpCompilation { LanguageVersion: >= LanguageVersion.CSharp8 } cs && cs.TypeByMetadataNameExists(allowNullAttributeName) + } ); } diff --git a/test/TestConsoleApp/TestConsoleApp.csproj b/test/TestConsoleApp/TestConsoleApp.csproj index 244c732..989f8e5 100644 --- a/test/TestConsoleApp/TestConsoleApp.csproj +++ b/test/TestConsoleApp/TestConsoleApp.csproj @@ -2,9 +2,9 @@ Exe - net5.0 + net471 latest - disable + enable diff --git a/test/TestConsoleApp/ViewModels/UserViewModel.cs b/test/TestConsoleApp/ViewModels/UserViewModel.cs index 50f3f3e..91b2f77 100644 --- a/test/TestConsoleApp/ViewModels/UserViewModel.cs +++ b/test/TestConsoleApp/ViewModels/UserViewModel.cs @@ -18,7 +18,7 @@ namespace TestConsoleApp.ViewModels private class IdConverter : ITypeConverter { - public string Convert(int source, object[] converterParameters) => $"{source:X}"; + public string Convert(int source, object[]? converterParameters) => $"{source:X}"; } } } \ No newline at end of file