File: Microsoft.NetCore.Analyzers\Usage\DoNotPassStructToArgumentNullExceptionThrowIfNullTests.cs
Web Access
Project: ..\..\..\src\Microsoft.CodeAnalysis.NetAnalyzers\tests\Microsoft.CodeAnalysis.NetAnalyzers.UnitTests\Microsoft.CodeAnalysis.NetAnalyzers.UnitTests.csproj (Microsoft.CodeAnalysis.NetAnalyzers.UnitTests)
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the MIT license.  See License.txt in the project root for license information.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.NetCore.CSharp.Analyzers.Usage;
using Microsoft.NetCore.VisualBasic.Analyzers.Usage;
using Test.Utilities;
using Xunit;
 
namespace Microsoft.NetCore.Analyzers.Usage.UnitTests
{
    using VerifyCS = CSharpCodeFixVerifier<DoNotPassNonNullableValueToArgumentNullExceptionThrowIfNull, CSharpDoNotPassNonNullableValueToArgumentNullExceptionThrowIfNullFixer>;
    using VerifyVB = VisualBasicCodeFixVerifier<DoNotPassNonNullableValueToArgumentNullExceptionThrowIfNull, BasicDoNotPassNonNullableValueToArgumentNullExceptionThrowIfNullFixer>;
 
    public sealed class DoNotPassStructToArgumentNullExceptionThrowIfNullTests
    {
        #region C#
 
        #region Diagnostic
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("bool")]
        public Task NotNullable_PassedInConstructor_Diagnostic(string type)
        {
            var code = $@"
using System;
 
public class Test
{{
    public Test({type} x)
    {{
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}};
        Console.WriteLine(x);
    }}
}}";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public Test({type} x)
    {{
        Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("bool")]
        public Task Nullable_PassedInConstructor_Diagnostic(string type)
        {
            var code = $@"
using System;
 
public class Test
{{
    public Test({type}? x)
    {{
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}};
        Console.WriteLine(x);
    }}
}}";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public Test({type}? x)
    {{
        if (!x.HasValue)
        {{
            throw new ArgumentNullException(nameof(x));
        }}
 
        Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("bool")]
        public Task NotNullable_PassedAsLocalVariable_Diagnostic(string type)
        {
            var code = $@"
using System;
 
public class Test
{{
    public void Run()
    {{
        {type} x = default;
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}};
        Console.WriteLine(x);
    }}
}}";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public void Run()
    {{
        {type} x = default;
        Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("bool")]
        public Task Nullable_PassedAsLocalVariable_Diagnostic(string type)
        {
            var code = $@"
using System;
 
public class Test
{{
    public void Run()
    {{
        {type}? x = null;
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}};
        Console.WriteLine(x);
    }}
}}";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public void Run()
    {{
        {type}? x = null;
        if (!x.HasValue)
        {{
            throw new ArgumentNullException(nameof(x));
        }}
 
        Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task NotNullable_CustomStruct_Diagnostic()
        {
            const string code = @"
using System;
 
public class Test
{
    public Test(MyStruct x)
    {
        {|#0:ArgumentNullException.ThrowIfNull(x)|};
        Console.WriteLine(x);
    }
}
 
public struct MyStruct {}";
            const string fixedCode = @"
using System;
 
public class Test
{
    public Test(MyStruct x)
    {
        Console.WriteLine(x);
    }
}
 
public struct MyStruct {}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Nullable_CustomStruct_Diagnostic()
        {
            const string code = @"
using System;
 
public class Test
{
    public Test(MyStruct? x)
    {
        {|#0:ArgumentNullException.ThrowIfNull(x)|};
        Console.WriteLine(x);
    }
}
 
public struct MyStruct {}";
            const string fixedCode = @"
using System;
 
public class Test
{
    public Test(MyStruct? x)
    {
        if (!x.HasValue)
        {
            throw new ArgumentNullException(nameof(x));
        }
 
        Console.WriteLine(x);
    }
}
 
public struct MyStruct {}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [CombinatorialData]
        public Task NotNullable_FullyQualifiedExceptionName_Diagnostic([CombinatorialValues("int", "System.Guid", "bool")] string type,
            [CombinatorialValues("System.ArgumentNullException", "global::System.ArgumentNullException")] string exceptionType)
        {
            var code = $@"
public class Test
{{
    public Test({type} x)
    {{
        {{|#0:{exceptionType}.ThrowIfNull(x)|}};
        System.Console.WriteLine(x);
    }}
}}";
            var fixedCode = $@"
public class Test
{{
    public Test({type} x)
    {{
        System.Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [CombinatorialData]
        public Task Nullable_FullyQualifiedExceptionName_Diagnostic([CombinatorialValues("int", "Guid", "bool")] string type,
            [CombinatorialValues("System.ArgumentNullException", "global::System.ArgumentNullException")] string exceptionType)
        {
            var code = $@"
using System;
 
public class Test
{{
    public Test({type}? x)
    {{
        {{|#0:{exceptionType}.ThrowIfNull(x)|}};
        Console.WriteLine(x);
    }}
}}";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public Test({type}? x)
    {{
        if (!x.HasValue)
        {{
            throw new ArgumentNullException(nameof(x));
        }}
 
        Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("bool")]
        public Task NotNullable_PropertyAccess_Diagnostic(string type)
        {
            var code = $@"
using System;
 
public class Test
{{
    public Test(MyRecord x)
    {{
        {{|#0:ArgumentNullException.ThrowIfNull(x.X)|}};
        Console.WriteLine(x);
    }}
}}
 
public record MyRecord({type} X);";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public Test(MyRecord x)
    {{
        Console.WriteLine(x);
    }}
}}
 
public record MyRecord({type} X);";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                LanguageVersion = LanguageVersion.CSharp9,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("bool")]
        public Task Nullable_PropertyAccess_Diagnostic(string type)
        {
            var code = $@"
using System;
 
public class Test
{{
    public Test(MyRecord x)
    {{
        {{|#0:ArgumentNullException.ThrowIfNull(x.X)|}};
        Console.WriteLine(x);
    }}
}}
 
public record MyRecord({type}? X);";
            var fixedCode = $@"
using System;
 
public class Test
{{
    public Test(MyRecord x)
    {{
        if (!x.X.HasValue)
        {{
            throw new ArgumentNullException(nameof(x.X));
        }}
 
        Console.WriteLine(x);
    }}
}}
 
public record MyRecord({type}? X);";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                LanguageVersion = LanguageVersion.CSharp9,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("MyType")]
        public Task Instantiation_Diagnostic(string type)
        {
            var code = $@"
using System;
 
class Test
{{
    void Run()
    {{
        {{|#0:ArgumentNullException.ThrowIfNull(new {type}())|}};
    }}
}}
 
class MyType {{}}";
            const string fixedCode = @"
using System;
 
class Test
{
    void Run()
    {
    }
}
 
class MyType {}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task EmptyInitializer_Diagnostic()
        {
            const string code = @"
using System;
using System.Collections.Generic;
 
class Test
{
    void Run()
    {
        {|#0:ArgumentNullException.ThrowIfNull(new MyType {})|};
    }
}
 
class MyType {}";
            const string fixedCode = @"
using System;
using System.Collections.Generic;
 
class Test
{
    void Run()
    {
    }
}
 
class MyType {}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Initializer_Diagnostic()
        {
            const string code = @"
using System;
 
class Test
{
    void Run()
    {
        {|#0:ArgumentNullException.ThrowIfNull(new MyType { Name = ""Test"" })|};
    }
}
 
class MyType
{
    public string Name { get; set; }
}";
            const string fixedCode = @"
using System;
 
class Test
{
    void Run()
    {
    }
}
 
class MyType
{
    public string Name { get; set; }
}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task CollectionInitializer_Diagnostic()
        {
            const string code = @"
using System;
using System.Collections.Generic;
 
class Test
{
    void Run()
    {
        {|#0:ArgumentNullException.ThrowIfNull(new List<int> { 1, 2, 3 })|};
    }
}";
            const string fixedCode = @"
using System;
using System.Collections.Generic;
 
class Test
{
    void Run()
    {
    }
}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("int")]
        [InlineData("Guid")]
        [InlineData("MyType")]
        [InlineData("System.Net.Http.HttpClient")]
        public Task Nameof_Diagnostic(string type)
        {
            var code = $@"
using System;
 
class Test
{{
    void Run({type} x)
    {{
        {{|#0:ArgumentNullException.ThrowIfNull(nameof(x))|}};
    }}
}}
 
class MyType {{}}";
            var fixedCode = $@"
using System;
 
class Test
{{
    void Run({type} x)
    {{
    }}
}}
 
class MyType {{}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Generics_Diagnostic()
        {
            const string code = @"
using System;
 
class Test
{
    public void M<T>(T x) where T : struct
    {
        {|#0:ArgumentNullException.ThrowIfNull(x)|};
    }
}";
            const string fixedCode = @"
using System;
 
class Test
{
    public void M<T>(T x) where T : struct
    {
    }
}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task TriviaIsNotPreserved_Diagnostic()
        {
            const string code = @"
using System;
 
class Test
{
    public void M(int x)
    {
        // Throw if null
        {|#0:ArgumentNullException.ThrowIfNull(x)|};
        Console.WriteLine(x);
    }
}";
            const string fixedCode = @"
using System;
 
class Test
{
    public void M(int x)
    {
        Console.WriteLine(x);
    }
}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task TriviaIsPreserved_Diagnostic()
        {
            const string code = @"
using System;
 
class Test
{
    // This is a method.
    public void M(int x)
    {
        {|#0:ArgumentNullException.ThrowIfNull(x)|};
        // Print x
        Console.WriteLine(x);
    }
}";
            const string fixedCode = @"
using System;
 
class Test
{
    // This is a method.
    public void M(int x)
    {
        // Print x
        Console.WriteLine(x);
    }
}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task TwoArguments_Diagnostic()
        {
            const string code = @"
using System;
 
class Test
{
    public void M(int x)
    {
        {|#0:ArgumentNullException.ThrowIfNull(x, nameof(x))|};
        Console.WriteLine(x);
    }
}";
            const string fixedCode = @"
using System;
 
class Test
{
    public void M(int x)
    {
        Console.WriteLine(x);
    }
}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        #endregion
 
        #region No diagnostic
 
        [Theory]
        [InlineData("int")]
        [InlineData("int?")]
        [InlineData("System.Guid")]
        [InlineData("System.Guid?")]
        [InlineData("bool")]
        [InlineData("bool?")]
        [InlineData("MyStruct")]
        [InlineData("MyStruct?")]
        public Task CustomThrowIfNull_NoDiagnostic(string type)
        {
            var code = $@"
#nullable enable
public class Test
{{
    public Test({type} x)
    {{
        ArgumentNullException.ThrowIfNull(x);
        System.Console.WriteLine(x);
    }}
}}
 
public class ArgumentNullException {{
    public static void ThrowIfNull(object? value) => throw null!;
}}
 
public struct MyStruct {{}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                LanguageVersion = LanguageVersion.CSharp8,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("string")]
        [InlineData("string?")]
        [InlineData("int[]")]
        [InlineData("int[]?")]
        [InlineData("Random")]
        [InlineData("Random?")]
        [InlineData("System.Net.Http.HttpClient")]
        [InlineData("System.Net.Http.HttpClient?")]
        public Task ReferenceTypes_NoDiagnostic(string type)
        {
            var code = $@"
using System;
 
#nullable enable
public class Test
{{
    public Test({type} x)
    {{
        ArgumentNullException.ThrowIfNull(x);
        Console.WriteLine(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                LanguageVersion = LanguageVersion.CSharp8,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Record_NoDiagnostic()
        {
            const string code = @"
using System;
 
public class Test
{
    public Test(MyRecord x)
    {
        global::System.ArgumentNullException.ThrowIfNull(x);
        Console.WriteLine(x);
    }
}
 
public record MyRecord;";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                LanguageVersion = LanguageVersion.CSharp9,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("")]
        [InlineData("where T : notnull")]
        [InlineData("where T : class")]
        public Task Generics_NoDiagnostic(string whereClause)
        {
            var code = $@"
using System;
 
class Test
{{
    public void M<T>(T x) {whereClause}
    {{
        ArgumentNullException.ThrowIfNull(x);
    }}
}}";
 
            return new VerifyCS.Test
            {
                TestCode = code,
                LanguageVersion = LanguageVersion.CSharp8,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        #endregion
 
        #endregion
 
        #region VB
 
        #region Diagnostic
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("Boolean")]
        public Task Vb_NotNullable_PassedInConstructor_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type})
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}}
        Console.WriteLine(x)
    End Sub
End Class
";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type})
        Console.WriteLine(x)
    End Sub
End Class
";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("Boolean")]
        public Task Vb_Nullable_PassedInConstructor_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type}?)
       {{|#0:ArgumentNullException.ThrowIfNull(x)|}}
        Console.WriteLine(x)
    End Sub
End Class";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type}?)
        If Not x.HasValue Then
            Throw New ArgumentNullException(NameOf(x))
        End If
 
        Console.WriteLine(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("Boolean")]
        public Task Vb_NotNullable_PassedAsLocalVariable_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Run()
        Dim x As {type} = Nothing
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}}
        Console.WriteLine(x)
    End Sub
End Class";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Run()
        Dim x As {type} = Nothing
        Console.WriteLine(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("Boolean")]
        public Task Vb_Nullable_PassedAsLocalVariable_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Run()
        Dim x As {type}? = Nothing
        {{|#0:ArgumentNullException.ThrowIfNull(x)|}}
        Console.WriteLine(x)
    End Sub
End Class";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Run()
        Dim x As {type}? = Nothing
 
        If Not x.HasValue Then
            Throw New ArgumentNullException(NameOf(x))
        End If
 
        Console.WriteLine(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Vb_NotNullable_CustomStruct_Diagnostic()
        {
            const string code = @"
Imports System
 
Public Class Test
    Public Sub Test(x As MyStruct)
        {|#0:ArgumentNullException.ThrowIfNull(x)|}
        Console.WriteLine(x)
    End Sub
End Class
 
Public Structure MyStruct
End Structure";
            const string fixedCode = @"
Imports System
 
Public Class Test
    Public Sub Test(x As MyStruct)
        Console.WriteLine(x)
    End Sub
End Class
 
Public Structure MyStruct
End Structure";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Vb_Nullable_CustomStruct_Diagnostic()
        {
            const string code = @"
Imports System
 
Public Class Test
    Public Sub Test(x As MyStruct?)
        {|#0:ArgumentNullException.ThrowIfNull(x)|}
        Console.WriteLine(x)
    End Sub
End Class
 
Public Structure MyStruct
End Structure";
            const string fixedCode = @"
Imports System
 
Public Class Test
    Public Sub Test(x As MyStruct?)
        If Not x.HasValue Then
            Throw New ArgumentNullException(NameOf(x))
        End If
 
        Console.WriteLine(x)
    End Sub
End Class
 
Public Structure MyStruct
End Structure";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [CombinatorialData]
        public Task Vb_NotNullable_FullyQualifiedExceptionName_Diagnostic([CombinatorialValues("System.Int32", "System.Guid", "System.Boolean")] string type,
            [CombinatorialValues("System.ArgumentNullException", "Global.System.ArgumentNullException")] string exceptionType)
        {
            var code = $@"
Public Class Test
    Public Sub Test(x As {type})
        {{|#0:{exceptionType}.ThrowIfNull(x)|}}
        System.Console.WriteLine(x)
    End Sub
End Class";
            var fixedCode = $@"
Public Class Test
    Public Sub Test(x As {type})
        System.Console.WriteLine(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [CombinatorialData]
        public Task Vb_Nullable_FullyQualifiedExceptionName_Diagnostic([CombinatorialValues("Int32", "Guid", "Boolean")] string type,
            [CombinatorialValues("System.ArgumentNullException", "Global.System.ArgumentNullException")] string exceptionType)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type}?)
       {{|#0:{exceptionType}.ThrowIfNull(x)|}}
        Console.WriteLine(x)
    End Sub
End Class";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type}?)
        If Not x.HasValue Then
            Throw New ArgumentNullException(NameOf(x))
        End If
 
        Console.WriteLine(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("Boolean")]
        public Task Vb_NotNullable_PropertyAccess_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As MyType)
       {{|#0:ArgumentNullException.ThrowIfNull(x.X)|}}
        Console.WriteLine(x)
    End Sub
End Class
 
Public Class MyType
    Public Dim X As {type}
End Class";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As MyType)
        Console.WriteLine(x)
    End Sub
End Class
 
Public Class MyType
    Public Dim X As {type}
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("Boolean")]
        public Task Vb_Nullable_PropertyAccess_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As MyType)
       {{|#0:ArgumentNullException.ThrowIfNull(x.X)|}}
        Console.WriteLine(x)
    End Sub
End Class
 
Public Class MyType
    Public Dim X As {type}?
End Class";
            var fixedCode = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As MyType)
        If Not x.X.HasValue Then
            Throw New ArgumentNullException(NameOf(x.X))
        End If
 
        Console.WriteLine(x)
    End Sub
End Class
 
Public Class MyType
    Public Dim X As {type}?
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("MyType")]
        public Task Vb_Instantiation_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Class Test
    Sub Run()
        {{|#0:ArgumentNullException.ThrowIfNull(New {type}())|}}
    End Sub
End Class
 
Class MyType
End Class";
            const string fixedCode = @"
Imports System
 
Class Test
    Sub Run()
    End Sub
End Class
 
Class MyType
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("Int32")]
        [InlineData("Guid")]
        [InlineData("MyType")]
        [InlineData("System.Net.Http.HttpClient")]
        public Task Vb_Nameof_Diagnostic(string type)
        {
            var code = $@"
Imports System
 
Class Test
    Sub Run(x As {type})
        {{|#0:ArgumentNullException.ThrowIfNull(nameof(x))|}}
    End Sub
End Class
 
Class MyType
End Class";
            var fixedCode = $@"
Imports System
 
Class Test
    Sub Run(x As {type})
    End Sub
End Class
 
Class MyType
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Vb_Generics_Diagnostic()
        {
            const string code = @"
Imports System
 
Class Test
    Public Sub M(Of T As Structure)(x As T)
        {|#0:ArgumentNullException.ThrowIfNull(x)|}
    End Sub
End Class";
            const string fixedCode = @"
Imports System
 
Class Test
    Public Sub M(Of T As Structure)(x As T)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Vb_Initializer_Diagnostic()
        {
            const string code = @"
Imports System
 
Class Test
    Sub Run()
        {|#0:ArgumentNullException.ThrowIfNull(new MyType With { .Name = ""Test"" })|}
    End Sub
End Class
 
Class MyType
    Public Property Name As String
End Class";
            const string fixedCode = @"
Imports System
 
Class Test
    Sub Run()
    End Sub
End Class
 
Class MyType
    Public Property Name As String
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Fact]
        public Task Vb_CollectionInitializer_Diagnostic()
        {
            const string code = @"
Imports System
Imports System.Collections.Generic
 
Class Test
    Sub Run()
        {|#0:ArgumentNullException.ThrowIfNull(new List(Of Int32) From { 1, 2, 3 })|}
    End Sub
End Class";
            const string fixedCode = @"
Imports System
Imports System.Collections.Generic
 
Class Test
    Sub Run()
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                FixedCode = fixedCode,
                ExpectedDiagnostics = { NonNullableDiagnosticResult },
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        #endregion
 
        #region No diagnostic
 
        [Theory]
        [InlineData("System.Int32")]
        [InlineData("System.Int32?")]
        [InlineData("System.Guid")]
        [InlineData("System.Guid?")]
        [InlineData("System.Boolean")]
        [InlineData("System.Boolean?")]
        [InlineData("MyStruct")]
        [InlineData("MyStruct?")]
        public Task Vb_CustomThrowIfNull_NoDiagnostic(string type)
        {
            var code = $@"
Public Class Test
    Public Sub Test(x As {type})
        ArgumentNullException.ThrowIfNull(x)
        System.Console.WriteLine(x)
    End Sub
End Class
 
Public Class ArgumentNullException
    Public Shared Sub ThrowIfNull(value As Object)
        Throw New System.Exception()
    End Sub
End Class
 
Public Structure MyStruct
End Structure";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("String")]
        [InlineData("Int32()")]
        [InlineData("Random")]
        [InlineData("System.Net.Http.HttpClient")]
        public Task Vb_ReferenceTypes_NoDiagnostic(string type)
        {
            var code = $@"
Imports System
 
Public Class Test
    Public Sub Test(x As {type})
        ArgumentNullException.ThrowIfNull(x)
        Console.WriteLine(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        [Theory]
        [InlineData("")]
        [InlineData("As Class")]
        public Task Vb_Generics_NoDiagnostic(string whereClause)
        {
            var code = $@"
Imports System
 
Class Test
    Public Sub M(Of T {whereClause})(x As T)
        ArgumentNullException.ThrowIfNull(x)
    End Sub
End Class";
 
            return new VerifyVB.Test
            {
                TestCode = code,
                ReferenceAssemblies = ReferenceAssemblies.Net.Net60
            }.RunAsync();
        }
 
        #endregion
 
        #endregion
 
        private static readonly DiagnosticResult NonNullableDiagnosticResult = new DiagnosticResult(DoNotPassNonNullableValueToArgumentNullExceptionThrowIfNull.DoNotPassNonNullableValueDiagnostic)
            .WithLocation(0);
 
        private static readonly DiagnosticResult NullableDiagnosticResult = new DiagnosticResult(DoNotPassNonNullableValueToArgumentNullExceptionThrowIfNull.DoNotPassNullableStructDiagnostic)
            .WithLocation(0);
    }
}