diff --git a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs index 80b648dfd95803..879b41e23c324a 100644 --- a/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs +++ b/src/libraries/System.Text.Json/gen/JsonSourceGenerator.Emitter.cs @@ -612,7 +612,17 @@ private void GeneratePropMetadataInitFunc(SourceWriter writer, string propInitMe PropertyGenerationSpec property = properties[i]; string propertyName = property.NameSpecifiedInSourceCode; string declaringTypeFQN = property.DeclaringType.FullyQualifiedName; - string propertyTypeFQN = property.PropertyType.FullyQualifiedName; + + // If the property is ignored and its type is not used anywhere else in the type graph, + // emit a JsonPropertyInfo of type 'object' to avoid unnecessarily referencing the type. + // STJ requires that all ignored properties be included so that it can perform + // necessary run-time validations using configuration not known at compile time + // such as the property naming policy and case sensitivity. + bool isIgnoredPropertyOfUnusedType = + property.DefaultIgnoreCondition is JsonIgnoreCondition.Always && + !_typeIndex.ContainsKey(property.PropertyType); + + string propertyTypeFQN = isIgnoredPropertyOfUnusedType ? "object" : property.PropertyType.FullyQualifiedName; string getterValue = property switch { @@ -653,9 +663,12 @@ private void GeneratePropMetadataInitFunc(SourceWriter writer, string propInitMe : $"({JsonConverterTypeRef}<{propertyTypeFQN}>){ExpandConverterMethodName}(typeof({propertyTypeFQN}), new {converterFQN}(), {OptionsLocalVariableName})"; } - string attributeProviderFactoryExpr = property.IsProperty - ? $"typeof({property.DeclaringType.FullyQualifiedName}).GetProperty({FormatStringLiteral(property.MemberName)}, {InstanceMemberBindingFlagsVariableName}, null, typeof({property.PropertyType.FullyQualifiedName}), {EmptyTypeArray}, null)" - : $"typeof({property.DeclaringType.FullyQualifiedName}).GetField({FormatStringLiteral(property.MemberName)}, {InstanceMemberBindingFlagsVariableName})"; + string attributeProviderFactoryExpr = property switch + { + _ when isIgnoredPropertyOfUnusedType => "null", + { IsProperty: true } => $"typeof({property.DeclaringType.FullyQualifiedName}).GetProperty({FormatStringLiteral(property.MemberName)}, {InstanceMemberBindingFlagsVariableName}, null, typeof({propertyTypeFQN}), {EmptyTypeArray}, null)", + _ => $"typeof({property.DeclaringType.FullyQualifiedName}).GetField({FormatStringLiteral(property.MemberName)}, {InstanceMemberBindingFlagsVariableName})", + }; writer.WriteLine($$""" var {{InfoVarName}}{{i}} = new {{JsonPropertyInfoValuesTypeRef}}<{{propertyTypeFQN}}> diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs index c058cf81a3d164..e30fafc95d262c 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/RealWorldContextTests.cs @@ -1122,6 +1122,7 @@ public void NumberHandlingHonoredOnPoco() [InlineData(MemberTypes.Field, nameof(PocoWithMixedVisibilityMembers.FieldWithCustomName), "customField")] [InlineData(MemberTypes.Property, nameof(PocoWithMixedVisibilityMembers.BaseProperty))] [InlineData(MemberTypes.Property, nameof(PocoWithMixedVisibilityMembers.ShadowProperty))] + [InlineData(MemberTypes.Property, nameof(PocoWithMixedVisibilityMembers.ExperimentalProperty))] public void JsonPropertyInfo_PopulatesAttributeProvider(MemberTypes memberType, string propertyName, string? jsonPropertyName = null) { if (DefaultContext.JsonSourceGenerationMode is JsonSourceGenerationMode.Serialization) @@ -1134,7 +1135,17 @@ public void JsonPropertyInfo_PopulatesAttributeProvider(MemberTypes memberType, JsonPropertyInfo prop = typeInfo.Properties.FirstOrDefault(prop => prop.Name == name); Assert.NotNull(prop); - MemberInfo memberInfo = Assert.IsAssignableFrom(prop.AttributeProvider); + MemberInfo memberInfo; + if (prop.AttributeProvider is null) + { + Assert.Equal(typeof(object), prop.PropertyType); + memberInfo = typeof(PocoWithMixedVisibilityMembers).GetMember(propertyName, memberType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(); + Type actualPropertyType = memberInfo is PropertyInfo pInfo ? pInfo.PropertyType : ((FieldInfo)memberInfo).FieldType; + Assert.False(typeInfo.Options.TryGetTypeInfo(actualPropertyType, out _)); + return; + } + + memberInfo = Assert.IsAssignableFrom(prop.AttributeProvider); string? actualJsonPropertyName = memberInfo.GetCustomAttribute()?.Name; Assert.True(memberInfo.DeclaringType.IsAssignableFrom(typeInfo.Type)); diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs index b6f2be9217556e..5f542807d1f2f3 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/TestClasses.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using Microsoft.Extensions.Primitives; @@ -332,8 +333,18 @@ public class PocoWithMixedVisibilityMembers : PocoWithMixedVisibilityMembersBase public string FieldWithCustomName; public new int ShadowProperty { get; set; } + +#pragma warning disable EXP0001 + [JsonIgnore] + public ExperimentalClass ExperimentalProperty { get; set; } +#pragma warning restore EXP0001 } +#if NET + [Experimental("EXP0001")] +#endif + public class ExperimentalClass; + public sealed class ClassWithConflictingIgnoredProperties { [JsonIgnore] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs index 37f6c74e172c0d..9db17588627af5 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/CompilationHelper.cs @@ -14,6 +14,7 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using Xunit; +using Xunit.Abstractions; namespace System.Text.Json.SourceGeneration.UnitTests { @@ -133,7 +134,10 @@ public static CSharpGeneratorDriver CreateJsonSourceGeneratorDriver(Compilation #endif } - public static JsonSourceGeneratorResult RunJsonSourceGenerator(Compilation compilation, bool disableDiagnosticValidation = false) + public static JsonSourceGeneratorResult RunJsonSourceGenerator( + Compilation compilation, + bool disableDiagnosticValidation = false, + ITestOutputHelper? logger = null) { var generatedSpecs = ImmutableArray.Empty; var generator = new JsonSourceGenerator @@ -144,6 +148,19 @@ public static JsonSourceGeneratorResult RunJsonSourceGenerator(Compilation compi CSharpGeneratorDriver driver = CreateJsonSourceGeneratorDriver(compilation, generator); driver.RunGeneratorsAndUpdateCompilation(compilation, out Compilation outCompilation, out ImmutableArray diagnostics); + if (logger is not null) + { + foreach (Diagnostic diagnostic in outCompilation.GetDiagnostics().Concat(diagnostics)) + { + logger.WriteLine(diagnostic.ToString()); + } + + foreach (var tree in outCompilation.SyntaxTrees) + { + LogGeneratedCode(tree, logger); + } + } + if (!disableDiagnosticValidation) { outCompilation.GetDiagnostics().AssertMaxSeverity(DiagnosticSeverity.Info); @@ -831,6 +848,59 @@ internal static void AssertMaxSeverity(this IEnumerable diagnostics, { Assert.DoesNotContain(diagnostics, diagnostic => diagnostic.Severity > maxSeverity); } + + private static void LogGeneratedCode(SyntaxTree tree, ITestOutputHelper logger) + { + logger.WriteLine(FileSeparator); + logger.WriteLine($"{tree.FilePath} content:"); + logger.WriteLine(FileSeparator); + using NumberedSourceFileWriter lineWriter = new(logger); + tree.GetRoot().WriteTo(lineWriter); + lineWriter.WriteLine(string.Empty); + } + + private static readonly string FileSeparator = new string('=', 140); + + private sealed class NumberedSourceFileWriter : TextWriter + { + private readonly ITestOutputHelper _logger; + private readonly StringBuilder _lineBuilder = new StringBuilder(); + private int _lineNumber; + + internal NumberedSourceFileWriter(ITestOutputHelper logger) + { + _logger = logger; + } + + public override Encoding Encoding => Encoding.Unicode; + + public override void WriteLine(string? value) + { + _logger.WriteLine($"{++_lineNumber,6}: {_lineBuilder}{value}"); + _lineBuilder.Clear(); + } + + public override void Write(string? value) + { + if (value is null) + { + return; + } + + if (value.EndsWith("\r\n", StringComparison.Ordinal)) + { + WriteLine(value.Substring(0, value.Length - 2)); + } + else if (value.EndsWith("\n", StringComparison.Ordinal)) + { + WriteLine(value.Substring(0, value.Length - 1)); + } + else + { + _lineBuilder.Append(value); + } + } + } } public record struct DiagnosticData( diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs index 185881ccbcd16c..9faf0472700dd5 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/JsonSourceGeneratorTests.cs @@ -5,6 +5,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; +using Xunit.Abstractions; namespace System.Text.Json.SourceGeneration.UnitTests { @@ -12,7 +13,7 @@ namespace System.Text.Json.SourceGeneration.UnitTests [SkipOnCoreClr("https://github.com/dotnet/runtime/issues/71962", ~RuntimeConfiguration.Release)] [SkipOnMono("https://github.com/dotnet/runtime/issues/92467")] [ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotX86Process))] // https://github.com/dotnet/runtime/issues/71962 - public class GeneratorTests + public class GeneratorTests(ITestOutputHelper logger) { [Fact] public void TypeDiscoveryPrimitivePOCO() @@ -54,7 +55,7 @@ public void UsePrivates() """; Compilation compilation = CompilationHelper.CreateCompilation(source); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(5, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::HelloWorld.MyType"); @@ -109,7 +110,7 @@ public void UsePrivates() Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(6, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::HelloWorld.MyType"); @@ -169,7 +170,7 @@ public void UsePrivates() Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(6, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::HelloWorld.MyType"); @@ -271,7 +272,7 @@ public class WeatherForecastWithPOCOs MetadataReference[] additionalReferences = { MetadataReference.CreateFromImage(referencedImage) }; Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] @@ -312,7 +313,7 @@ public void UsePrivates() Compilation compilation = CompilationHelper.CreateCompilation(source); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(5, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::MyType"); @@ -362,7 +363,7 @@ public record AppRecord(int Id) Compilation compilation = CompilationHelper.CreateCompilation(source); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(3, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::HelloWorld.AppRecord"); @@ -396,7 +397,7 @@ internal partial class JsonContext : JsonSerializerContext MetadataReference[] additionalReferences = { MetadataReference.CreateFromImage(referencedImage) }; Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(3, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::ReferencedAssembly.LibRecord"); @@ -435,7 +436,7 @@ internal record AppRecord : LibRecord Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(3, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::HelloWorld.AppRecord"); @@ -486,7 +487,7 @@ public class MyType MetadataReference[] additionalReferences = { MetadataReference.CreateFromImage(referencedImage) }; Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); // Should find the generated type. Assert.Equal(2, result.AllGeneratedTypes.Count()); @@ -495,7 +496,7 @@ public class MyType } [Fact] - public static void NoWarningsDueToObsoleteMembers() + public void NoWarningsDueToObsoleteMembers() { string source = """ using System; @@ -518,11 +519,11 @@ public class ClassWithObsolete """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] - public static void NoErrorsWhenUsingReservedCSharpKeywords() + public void NoErrorsWhenUsingReservedCSharpKeywords() { string source = """ using System.Text.Json.Serialization; @@ -541,7 +542,7 @@ public class ClassWithPropertiesAndFieldsThatAreReservedKeywords """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] @@ -564,7 +565,7 @@ internal partial class JsonContext : JsonSerializerContext Compilation compilation = CompilationHelper.CreateCompilation(source); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); // Should find the generated type. Assert.Equal(3, result.AllGeneratedTypes.Count()); @@ -574,7 +575,7 @@ internal partial class JsonContext : JsonSerializerContext } [Fact] - public static void NoErrorsWhenUsingTypesWithMultipleEqualsOperators() + public void NoErrorsWhenUsingTypesWithMultipleEqualsOperators() { // Regression test for https://github.com/dotnet/runtime/issues/103515 string source = """ @@ -604,11 +605,11 @@ internal partial class JsonSourceGenerationContext : JsonSerializerContext """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] - public static void NoErrorsWhenUsingIgnoredReservedCSharpKeywords() + public void NoErrorsWhenUsingIgnoredReservedCSharpKeywords() { string source = """ using System.Text.Json.Serialization; @@ -627,7 +628,7 @@ public class ClassWithPropertyNameThatIsAReservedKeyword """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] @@ -678,7 +679,7 @@ public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSeri Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(3, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::Test.Sample"); @@ -724,7 +725,7 @@ public class NestedGenericClass Compilation compilation = CompilationHelper.CreateCompilation(source); - JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation); + JsonSourceGeneratorResult result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); Assert.Equal(5, result.AllGeneratedTypes.Count()); result.AssertContainsType("global::System.Collections.Generic.Dictionary"); @@ -771,7 +772,7 @@ public class MyClass """; Compilation compilation = CompilationHelper.CreateCompilation(source, parseOptions: CompilationHelper.CreateParseOptions(languageVersion)); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] @@ -802,7 +803,7 @@ internal partial class JsonContext : JsonSerializerContext """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } #if ROSLYN4_4_OR_GREATER && NET @@ -828,7 +829,7 @@ public partial class MyContext : JsonSerializerContext """; Compilation compilation = CompilationHelper.CreateCompilation(source, parseOptions: CompilationHelper.CreateParseOptions(LanguageVersion.CSharp11)); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } #endif @@ -856,7 +857,7 @@ internal partial class ModelContext : JsonSerializerContext """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } [Fact] @@ -881,7 +882,88 @@ public partial class MyContext : JsonSerializerContext """; Compilation compilation = CompilationHelper.CreateCompilation(source); - CompilationHelper.RunJsonSourceGenerator(compilation); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); } + +#if ROSLYN4_4_OR_GREATER && NET + [Fact] + public void PropertyWithExperimentalType_JsonIgnore_CompilesSuccessfully() + { + string source = """ + using System.Diagnostics.CodeAnalysis; + using System.Text.Json.Serialization; + + [Experimental("EXP001")] + public class ExperimentalType + { + public int Value { get; set; } + } + + public class MyPoco + { + [JsonIgnore] + #pragma warning disable EXP001 + public ExperimentalType ExpType { get; set; } + #pragma warning restore EXP001 + } + + [JsonSerializable(typeof(MyPoco))] + public partial class MyContext : JsonSerializerContext + { + } + """; + + Compilation compilation = CompilationHelper.CreateCompilation(source); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); + } + + [Fact] + public void PocoWithExperimentalProperty_JsonIgnore_CompilesSuccessfully() + { + string source = """ + using System.Diagnostics.CodeAnalysis; + using System.Text.Json.Serialization; + + public class MyPoco + { + [Experimental("EXP001"), JsonIgnore] + public int ExperimentalProperty { get; set; } + } + + [JsonSerializable(typeof(MyPoco))] + public partial class MyContext : JsonSerializerContext + { + } + """; + + Compilation compilation = CompilationHelper.CreateCompilation(source); + CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger); + } + + [Fact] + public void PocoWithExperimentalProperty_NoJsonIgnore_EmitsDiagnostic() + { + string source = """ + using System.Diagnostics.CodeAnalysis; + using System.Text.Json.Serialization; + + public class MyPoco + { + [Experimental("EXP001")] + public int ExperimentalProperty { get; set; } + } + + [JsonSerializable(typeof(MyPoco))] + public partial class MyContext : JsonSerializerContext + { + } + """; + + Compilation compilation = CompilationHelper.CreateCompilation(source); + var result = CompilationHelper.RunJsonSourceGenerator(compilation, logger: logger, disableDiagnosticValidation: true); + + Assert.NotEmpty(result.NewCompilation.GetDiagnostics().Where(d => d.Id == "EXP001")); + } +#endif } } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Unit.Tests.csproj b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Unit.Tests.csproj index 7886da322004ec..b453e5051e1693 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Unit.Tests.csproj +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Unit.Tests/System.Text.Json.SourceGeneration.Roslyn4.4.Unit.Tests.csproj @@ -1,6 +1,6 @@ - $(MicrosoftCodeAnalysisVersion_4_4) + $(MicrosoftCodeAnalysisVersion_4_8) $(DefineConstants);ROSLYN4_0_OR_GREATER;ROSLYN4_4_OR_GREATER true