Exemple #1
0
        public static void NoWarningsDueToObsoleteMembers()
        {
            string source = @"using System;
using System.Text.Json.Serialization;

namespace Test
{
    [JsonSerializable(typeof(ClassWithObsolete))]
    public partial class JsonContext : JsonSerializerContext { }

    public class ClassWithObsolete
    {
        [Obsolete(""This is a test"")]
        public bool Test { get; set; }
    }
}
";

            Compilation         compilation = CompilationHelper.CreateCompilation(source);
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            Compilation newCompilation = CompilationHelper.RunGenerators(compilation, out _, generator);
            ImmutableArray <Diagnostic> generatorDiags = newCompilation.GetDiagnostics();

            // No diagnostics expected.
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Info, generatorDiags, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Warning, generatorDiags, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Error, generatorDiags, Array.Empty <(Location, string)>());
        }
        public static void LocalJsonSerializableAttributeUnexpectedShape(string assemblyName, bool includeSTJ)
        {
            string source = @"using System;
using System.Text.Json.Serialization;

[assembly: JsonSerializable(typeof(int))]

namespace System.Text.Json.Serialization
{
    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    public sealed class JsonSerializableAttribute : JsonAttribute
    {
        public JsonSerializableAttribute(string typeInfoPropertyName, Type type) { }
    }
}";

            Compilation         compilation = CompilationHelper.CreateCompilation(source, additionalReferences: null, assemblyName, includeSTJ);
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out ImmutableArray <Diagnostic> generatorDiags, generator);
            Assert.Null(generator.GetSerializableTypes());

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());
        }
        public static void NoErrorsWhenUsingIgnoredReservedCSharpKeywords()
        {
            string              source      = @"using System;
using System.Text.Json.Serialization;

namespace Test
{
    [JsonSerializable(typeof(ClassWithPropertyNameThatIsAReservedKeyword))]
    public partial class JsonContext : JsonSerializerContext { }

    public class ClassWithPropertyNameThatIsAReservedKeyword
    {
        [JsonIgnore]
        public string @event { get; set; }
    }
}
";
            Compilation         compilation = CompilationHelper.CreateCompilation(source);
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            Compilation newCompilation = CompilationHelper.RunGenerators(compilation, out _, generator);
            ImmutableArray <Diagnostic> generatorDiags = newCompilation.GetDiagnostics();

            // No diagnostics expected.
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Info, generatorDiags, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Warning, generatorDiags, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Error, generatorDiags, Array.Empty <(Location, string)>());
        }
Exemple #4
0
        public void SuccessfulSourceGeneration()
        {
            // Compile the referenced assembly first.
            Compilation campaignCompilation = CompilationHelper.CreateCampaignSummaryViewModelCompilation();
            Compilation eventCompilation    = CompilationHelper.CreateActiveOrUpcomingEventCompilation();

            // Emit the image of the referenced assembly.
            byte[] campaignImage = CompilationHelper.CreateAssemblyImage(campaignCompilation);
            byte[] eventImage    = CompilationHelper.CreateAssemblyImage(eventCompilation);

            // Main source for current compilation.
            string source = @"
            using System.Collections.Generic;
            using System.Text.Json.Serialization;
            using ReferencedAssembly;

            [assembly: JsonSerializable(typeof(JsonSourceGenerator.IndexViewModel)]

            namespace JsonSourceGenerator
            {
                public class IndexViewModel
                {
                    public List<ActiveOrUpcomingEvent> ActiveOrUpcomingEvents { get; set; }
                    public CampaignSummaryViewModel FeaturedCampaign { get; set; }
                    public bool IsNewAccount { get; set; }
                    public bool HasFeaturedCampaign => FeaturedCampaign != null;
                }
            }";

            MetadataReference[] additionalReferences =
            {
                MetadataReference.CreateFromImage(campaignImage),
                MetadataReference.CreateFromImage(eventImage),
            };

            Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences);

            JsonSourceGenerator generator = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out var generatorDiags, generator);

            // Expected info logs.
            string[] expectedInfoDiagnostics = new string[] {
                "Generated serialization metadata for type System.Collections.Generic.List<ReferencedAssembly.ActiveOrUpcomingEvent>",
                "Generated serialization metadata for type System.Int32",
                "Generated serialization metadata for type System.String",
                "Generated serialization metadata for type System.DateTimeOffset",
                "Generated serialization metadata for type System.Boolean",
                "Generated serialization metadata for type ReferencedAssembly.ActiveOrUpcomingEvent",
                "Generated serialization metadata for type ReferencedAssembly.CampaignSummaryViewModel",
                "Generated serialization metadata for type JsonSourceGenerator.IndexViewModel",
            };

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, expectedInfoDiagnostics);
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, new string[] { });
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, new string[] { });
        }
Exemple #5
0
        public void WarnOnClassesWithInitOnlyProperties()
        {
            Compilation         compilation = CompilationHelper.CreateCompilationWithInitOnlyProperties();
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out var generatorDiags, generator);

            string[] expectedWarningDiagnostics = new string[] { "The type 'Location' defines init-only properties, deserialization of which is currently not supported in source generation mode." };

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, expectedWarningDiagnostics);
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());
        }
Exemple #6
0
        public void SuccessfulSourceGeneration()
        {
            // Compile the referenced assembly first.
            Compilation campaignCompilation = CompilationHelper.CreateCampaignSummaryViewModelCompilation();
            Compilation eventCompilation    = CompilationHelper.CreateActiveOrUpcomingEventCompilation();

            // Emit the image of the referenced assembly.
            byte[] campaignImage = CompilationHelper.CreateAssemblyImage(campaignCompilation);
            byte[] eventImage    = CompilationHelper.CreateAssemblyImage(eventCompilation);

            // Main source for current compilation.
            string source = @"
            using System.Collections.Generic;
            using System.Text.Json.Serialization;
            using ReferencedAssembly;

            namespace JsonSourceGenerator
            {
                [JsonSerializable(typeof(JsonSourceGenerator.IndexViewModel)]
                public partial class JsonContext : JsonSerializerContext
                {
                }

                public class IndexViewModel
                {
                    public List<ActiveOrUpcomingEvent> ActiveOrUpcomingEvents { get; set; }
                    public CampaignSummaryViewModel FeaturedCampaign { get; set; }
                    public bool IsNewAccount { get; set; }
                    public bool HasFeaturedCampaign => FeaturedCampaign != null;
                }
            }";

            MetadataReference[] additionalReferences =
            {
                MetadataReference.CreateFromImage(campaignImage),
                MetadataReference.CreateFromImage(eventImage),
            };

            Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences);

            JsonSourceGenerator generator = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out var generatorDiags, generator);

            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Info, generatorDiags, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Warning, generatorDiags, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Error, generatorDiags, Array.Empty <(Location, string)>());
        }
Exemple #7
0
        public void WarnOnClassesWithInaccessibleJsonIncludeProperties()
        {
            Compilation         compilation = CompilationHelper.CreateCompilationWithInaccessibleJsonIncludeProperties();
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out var generatorDiags, generator);

            string[] expectedWarningDiagnostics = new string[]
            {
                "The member 'Location.Id' has been annotated with the JsonIncludeAttribute but is not visible to the source generator.",
                "The member 'Location.Address2' has been annotated with the JsonIncludeAttribute but is not visible to the source generator.",
                "The member 'Location.Country' has been annotated with the JsonIncludeAttribute but is not visible to the source generator."
            };

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, expectedWarningDiagnostics);
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());
        }
        public static void LocalJsonSerializableAttributeExpectedShape(string assemblyName, bool includeSTJ)
        {
            string source = @"using System;
using System.Text.Json.Serialization;

namespace System.Text.Json.Serialization
{
    [JsonSerializable(typeof(int))]
    [JsonSerializable(typeof(string), TypeInfoPropertyName = ""Str"")]
    internal partial class JsonContext : JsonSerializerContext
    {
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public sealed class JsonSerializableAttribute : JsonAttribute
    {
        public string TypeInfoPropertyName { get; set; }

        public JsonSerializableAttribute(Type type) { }
    }
}";

            Compilation         compilation = CompilationHelper.CreateCompilation(source, additionalReferences: null, assemblyName, includeSTJ);
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out ImmutableArray <Diagnostic> generatorDiags, generator);

            Dictionary <string, Type> types = generator.GetSerializableTypes();

            if (includeSTJ)
            {
                Assert.Equal("System.Int32", types["System.Int32"].FullName);
                Assert.Equal("System.String", types["System.String"].FullName);
            }
            else
            {
                Assert.Null(types);
            }

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());
        }
Exemple #9
0
        public void ProgramsThatDontUseGeneratorCompile()
        {
            // No STJ usage.
            string              source      = @"using System;

public class Program
{
	public static void Main()
	{
		Console.WriteLine(""Hello World"");

    }
}
";
            Compilation         compilation = CompilationHelper.CreateCompilation(source);
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out var generatorDiags, generator);

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());

            // With STJ usage.
            source      = @"using System.Text.Json;

public class Program
{
	public static void Main()
	{
		JsonSerializer.Serialize(""Hello World"");
    }
}
";
            compilation = CompilationHelper.CreateCompilation(source);
            generator   = new JsonSourceGenerator();
            CompilationHelper.RunGenerators(compilation, out generatorDiags, generator);

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());
        }
Exemple #10
0
        public void NameClashSourceGeneration()
        {
            // Without resolution.
            Compilation         compilation = CompilationHelper.CreateRepeatedLocationsCompilation();
            JsonSourceGenerator generator   = new JsonSourceGenerator();

            CompilationHelper.RunGenerators(compilation, out var generatorDiags, generator);

            string[] expectedWarningDiagnostics = new string[] { "There are multiple types named Location. Source was generated for the first one detected. Use 'JsonSerializableAttribute.TypeInfoPropertyName' to resolve this collision." };

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, expectedWarningDiagnostics);
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());

            // With resolution.
            compilation = CompilationHelper.CreateRepeatedLocationsWithResolutionCompilation();
            generator   = new JsonSourceGenerator();
            CompilationHelper.RunGenerators(compilation, out generatorDiags, generator);

            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Info, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Warning, Array.Empty <string>());
            CompilationHelper.CheckDiagnosticMessages(generatorDiags, DiagnosticSeverity.Error, Array.Empty <string>());
        }
Exemple #11
0
        public void EmitsDocumentationOnPublicMembersAndDoesNotCauseCS1591()
        {
            // Compile the referenced assembly first.
            Compilation documentedCompilation = CompilationHelper.CreateReferencedModelWithFullyDocumentedProperties();

            // Emit the image of the referenced assembly.
            byte[] documentedImage = CompilationHelper.CreateAssemblyImage(documentedCompilation);

            // Main source for current compilation.
            string source = @"
            using System.Collections.Generic;
            using System.Text.Json.Serialization;
            using ReferencedAssembly;

            namespace JsonSourceGenerator
            {
                /// <summary>
                /// Documentation
                /// </summary>
                [JsonSerializable(typeof(DocumentedModel))]
                [JsonSerializable(typeof(DocumentedModel2<string>))]
                public partial class JsonContext : JsonSerializerContext
                {
                }

                /// <summary>
                /// Documentation
                /// </summary>
                public class DocumentedModel2<T>
                {
                    /// <summary>
                    /// Documentation
                    /// </summary>
                    public List<Model> Models { get; set; }
                    /// documentation
                    public T Prop { get; set; }
                }

                /// <summary>
                /// Documentation
                /// </summary>
                public class DocumentedModel
                {
                    /// <summary>
                    /// Documentation
                    /// </summary>
                    public List<Model> Models { get; set; }
                }
            }";

            MetadataReference[] additionalReferences =
            {
                MetadataReference.CreateFromImage(documentedImage),
            };

            Compilation compilation = CompilationHelper.CreateCompilation(source, additionalReferences, configureParseOptions: options => options.WithDocumentationMode(DocumentationMode.Diagnose));

            JsonSourceGenerator generator = new JsonSourceGenerator();

            compilation = CompilationHelper.RunGenerators(compilation, out var _, generator);

            using var emitStream = new MemoryStream();
            using var xmlStream  = new MemoryStream();
            var result      = compilation.Emit(emitStream, xmlDocumentationStream: xmlStream);
            var diagnostics = result.Diagnostics;

            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Info, diagnostics, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Warning, diagnostics, Array.Empty <(Location, string)>());
            CompilationHelper.CheckDiagnosticMessages(DiagnosticSeverity.Error, diagnostics, Array.Empty <(Location, string)>());
        }