// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable disable

using System;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Microsoft.CodeAnalysis.UnitTests.Diagnostics;
using static Microsoft.CodeAnalysis.CommonDiagnosticAnalyzers;

namespace Microsoft.CodeAnalysis.CSharp.UnitTests
{
    [CompilerTrait(CompilerFeature.IOperation)]
    public class OperationAnalyzerTests : CompilingTestBase
    {
        private static readonly CSharpParseOptions patternParseOptions = TestOptions.Regular;

        [Fact]
        public void EmptyArrayCSharp()
        {
            const string source = @"
class C
{
    void M1()
    {
        int[] arr1 = new int[0];                       // yes
        byte[] arr2 = { };                             // yes
        C[] arr3 = new C[] { };                        // yes
        string[] arr4 = new string[] { null };         // no
        double[] arr5 = new double[1];                 // no
        int[] arr6 = new[] { 1 };                      // no
        int[][] arr7 = new int[0][];                   // yes
        int[][][][] arr8 = new int[0][][][];           // yes
        int[,] arr9 = new int[0,0];                    // no
        int[][,] arr10 = new int[0][,];                // yes
        int[][,] arr11 = new int[1][,];                // no
        int[,][] arr12 = new int[0,0][];               // no
    }
}";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new EmptyArrayAnalyzer() }, null, null,
                Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0]").WithLocation(6, 22),
                Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "{ }").WithLocation(7, 23),
                Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new C[] { }").WithLocation(8, 20),
                Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][]").WithLocation(12, 24),
                Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][][][]").WithLocation(13, 28),
                Diagnostic(EmptyArrayAnalyzer.UseArrayEmptyDescriptor.Id, "new int[0][,]").WithLocation(15, 26)
                );
        }

        [Fact]
        public void BoxingCSharp()
        {
            const string source = @"
class C
{
    public object M1(object p1, object p2, object p3)
    {
         S v1 = new S();
         S v2 = v1;
         S v3 = v1.M1(v2);
         object v4 = M1(3, this, v1);
         object v5 = v3;
         if (p1 == null)
         {
             return 3;
         }
         if (p2 == null)
         {
             return v3;
         }
         if (p3 == null)
         {
             return v4;
         }
         return v5;
    }
}

struct S
{
    public int X;
    public int Y;
    public object Z;

    public S M1(S p1)
    {
        p1.GetType();
        Z = this;
        X = 1;
        Y = 2;
        return p1;
    }
}

class D
{
    object OField = 33;
    object SField = ""Zap"";
}";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new BoxingOperationAnalyzer() }, null, null,
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "3").WithLocation(9, 25),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "v1").WithLocation(9, 34),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "v3").WithLocation(10, 22),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "3").WithLocation(13, 21),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "v3").WithLocation(17, 21),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "p1").WithLocation(35, 9),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "this").WithLocation(36, 13),
                Diagnostic(BoxingOperationAnalyzer.BoxingDescriptor.Id, "33").WithLocation(45, 21)
                );
        }

        [Fact]
        public void BadStuffCSharp()
        {
            const string source = @"
class C
{
    public void M1(int z)
    {
        Framitz();
        int x = Bexley();
        int y = 10;
        double d = 20;
        M1(y + d);
        goto;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new BadStuffTestAnalyzer() }, null, null,
                Diagnostic(BadStuffTestAnalyzer.InvalidExpressionDescriptor.Id, "Framitz()").WithLocation(6, 9),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "Framitz()").WithLocation(6, 9),
                Diagnostic(BadStuffTestAnalyzer.InvalidExpressionDescriptor.Id, "Framitz").WithLocation(6, 9),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "Framitz").WithLocation(6, 9),
                Diagnostic(BadStuffTestAnalyzer.InvalidExpressionDescriptor.Id, "Bexley()").WithLocation(7, 17),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "Bexley()").WithLocation(7, 17),
                Diagnostic(BadStuffTestAnalyzer.InvalidExpressionDescriptor.Id, "Bexley").WithLocation(7, 17),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "Bexley").WithLocation(7, 17),
                Diagnostic(BadStuffTestAnalyzer.InvalidExpressionDescriptor.Id, "M1(y + d)").WithLocation(10, 9),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "M1(y + d)").WithLocation(10, 9),
                Diagnostic(BadStuffTestAnalyzer.InvalidStatementDescriptor.Id, "goto;").WithLocation(11, 9),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "goto;").WithLocation(11, 9),
                Diagnostic(BadStuffTestAnalyzer.InvalidStatementDescriptor.Id, "").WithLocation(11, 13),
                Diagnostic(BadStuffTestAnalyzer.IsInvalidDescriptor.Id, "").WithLocation(11, 13)
                );
        }

        [Fact]
        public void PatternsNoCrash()
        {
            // ensure that the combination of pattern-matching with ioperation analyzers does not crash.
            const string source = @"
class C
{
    public static void Main() {}
    public void M1(object o)
    {
        switch (o)
        {
            //case string { Length is 2 }:
            //    break;
            case string s:
                break;
            //case System.Collections.ArrayList(2):
            //    break;
        }
        //let x = o is object t ? t : null;
        //o = o match (
        //    case string { Length is 2 }: null
        //    case string s: s
        //    case System.Collections.ArrayList(2): x
        //    case *: throw null
        //);
    }
}
";
            CreateCompilationWithMscorlib461(source, options: TestOptions.DebugExe)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new BadStuffTestAnalyzer() }, null, null);
        }

        [Fact]
        public void BigForCSharp()
        {
            const string source = @"
class C
{
    public void M1()
    {
        int x;
        for (x = 0; x < 200000; x++) {}
      
        for (x = 0; x < 2000000; x++) {}

        for (x = 1500000; x > 0; x -= 2) {}

        for (x = 3000000; x > 0; x -= 2) {}

        for (x = 0; x < 200000; x = x + 1) {}

        for (x = 0; x < 2000000; x = x + 1) {}
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new BigForTestAnalyzer() }, null, null,
                Diagnostic(BigForTestAnalyzer.BigForDescriptor.Id, "for (x = 0; x < 2000000; x++) {}").WithLocation(9, 9),
                Diagnostic(BigForTestAnalyzer.BigForDescriptor.Id, "for (x = 3000000; x > 0; x -= 2) {}").WithLocation(13, 9),
                Diagnostic(BigForTestAnalyzer.BigForDescriptor.Id, "for (x = 0; x < 2000000; x = x + 1) {}").WithLocation(17, 9));
        }

        [Fact]
        public void SwitchCSharp()
        {
            const string source = @"
class C
{
    public void M1(int x, int y)
    {
        switch (x)
        {
            case 1:
                break;
            case 10:
                break;
            default:
                break;
        }

        switch (y)
        {
            case 1:
                break;
            case 1000:
                break;
            default:
                break;
        }

        switch (x)
        {
            case 1:
                break;
            case 1000:
                break;
        }

        switch (y) 
        {
            default:
                break;
        }

        switch (y) {}

        switch (x)
        {
            case : // A missing pattern is treated as a discard by syntax error recovery
                break;
            case 1000:
                break;
        }

    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(
                Diagnostic(ErrorCode.WRN_EmptySwitch, "{").WithLocation(40, 20),
                Diagnostic(ErrorCode.ERR_ConstantExpected, ":").WithLocation(44, 18))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new SwitchTestAnalyzer() }, null, null,
                Diagnostic(SwitchTestAnalyzer.SparseSwitchDescriptor.Id, "y").WithLocation(16, 17),
                Diagnostic(SwitchTestAnalyzer.SparseSwitchDescriptor.Id, "x").WithLocation(26, 17),
                Diagnostic(SwitchTestAnalyzer.NoDefaultSwitchDescriptor.Id, "x").WithLocation(26, 17),
                Diagnostic(SwitchTestAnalyzer.OnlyDefaultSwitchDescriptor.Id, "y").WithLocation(34, 17),
                Diagnostic(SwitchTestAnalyzer.SparseSwitchDescriptor.Id, "y").WithLocation(40, 17),
                Diagnostic(SwitchTestAnalyzer.NoDefaultSwitchDescriptor.Id, "y").WithLocation(40, 17));
        }

        [Fact]
        public void InvocationCSharp()
        {
            const string source = @"
class C
{
    public void M0(int a, params int[] b)
    {
    }

    public void M1(int a, int b, int c, int x, int y, int z)
    {
    }

    public void M2()
    {
        M1(1, 2, 3, 4, 5, 6);
        M1(a: 1, b: 2, c: 3, x: 4, y:5, z:6);
        M1(a: 1, c: 2, b: 3, x: 4, y:5, z:6);
        M1(z: 1, x: 2, y: 3, c: 4, a:5, b:6);
        M0(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
        M0(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
        M0(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
        M0(1);
        M0(1, 2);
        M0(1, 2, 4, 3);
    }

    public void M3(int x = 0, string y = null)
    {
    }

    public void M4()
    {
        M3(0, null);
        M3(0);
        M3(y: null);
        M3(x: 0);
        M3();
    }

    public void M5(int x = 0, params int[] b)
    {
    }

    public void M6()
    {
        M5(1,2,3,4,5);
        M5(1);
        M5(b: new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
        M5(x: 1);
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new InvocationTestAnalyzer() }, null, null,
                Diagnostic(InvocationTestAnalyzer.BigParamArrayArgumentsDescriptor.Id, "M0(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)").WithLocation(19, 9),
                Diagnostic(InvocationTestAnalyzer.BigParamArrayArgumentsDescriptor.Id, "M0(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)").WithLocation(20, 9),
                Diagnostic(InvocationTestAnalyzer.OutOfNumericalOrderArgumentsDescriptor.Id, "3").WithLocation(23, 21),
                Diagnostic(InvocationTestAnalyzer.UseDefaultArgumentDescriptor.Id, "M3(0)").WithArguments("y").WithLocation(33, 9),
                Diagnostic(InvocationTestAnalyzer.UseDefaultArgumentDescriptor.Id, "M3(y: null)").WithArguments("x").WithLocation(34, 9),
                Diagnostic(InvocationTestAnalyzer.UseDefaultArgumentDescriptor.Id, "M3(x: 0)").WithArguments("y").WithLocation(35, 9),
                Diagnostic(InvocationTestAnalyzer.UseDefaultArgumentDescriptor.Id, "M3()").WithArguments("x").WithLocation(36, 9),
                Diagnostic(InvocationTestAnalyzer.UseDefaultArgumentDescriptor.Id, "M3()").WithArguments("y").WithLocation(36, 9),
                Diagnostic(InvocationTestAnalyzer.UseDefaultArgumentDescriptor.Id, "M5(b: new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11})").WithArguments("x").WithLocation(47, 9));
        }

        [Fact]
        public void FieldCouldBeReadOnlyCSharp()
        {
            const string source = @"
class C
{
    int F1;
    const int F2 = 2;
    readonly int F3;
    int F4;
    int F5;
    int F6 = 6;
    int F7;
    int F8 = 8;
    S F9;
    C1 F10 = new C1();

    public C()
    {
        F1 = 1;
        F3 = 3;
        F4 = 4;
        F5 = 5;
    }

    public void M0()
    {
        int x = F1;
        x = F2;
        x = F3;
        x = F4;
        x = F5;
        x = F6;
        x = F7;

        F4 = 4;
        F7 = 7;
        M1(out F1, F5);
        F8++;
        F9.A = 10;
        F9.B = 20;
        F10.A = F9.A;
        F10.B = F9.B;
    }

    public void M1(out int x, int y)
    {
        x = 10;
    }

    struct S
    {
        public int A;
        public int B;
    }

    class C1
    {
        public int A;
        public int B;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new FieldCouldBeReadOnlyAnalyzer() }, null, null,
                Diagnostic(FieldCouldBeReadOnlyAnalyzer.FieldCouldBeReadOnlyDescriptor.Id, "F5").WithLocation(8, 9),
                Diagnostic(FieldCouldBeReadOnlyAnalyzer.FieldCouldBeReadOnlyDescriptor.Id, "F6").WithLocation(9, 9),
                Diagnostic(FieldCouldBeReadOnlyAnalyzer.FieldCouldBeReadOnlyDescriptor.Id, "F10").WithLocation(13, 8));
        }

        [Fact]
        public void StaticFieldCouldBeReadOnlyCSharp()
        {
            const string source = @"
class C
{
    static int F1;
    static readonly int F2 = 2;
    static readonly int F3;
    static int F4;
    static int F5;
    static int F6 = 6;
    static int F7;
    static int F8 = 8;
    static S F9;
    static C1 F10 = new C1();

    static C()
    {
        F1 = 1;
        F3 = 3;
        F4 = 4;
        F5 = 5;
    }

    public static void M0()
    {
        int x = F1;
        x = F2;
        x = F3;
        x = F4;
        x = F5;
        x = F6;
        x = F7;

        F4 = 4;
        F7 = 7;
        M1(out F1, F5);
        F7 = 7;
        F8--;
        F9.A = 10;
        F9.B = 20;
        F10.A = F9.A;
        F10.B = F9.B;
    }

    public static void M1(out int x, int y)
    {
        x = 10;
    }

    struct S
    {
        public int A;
        public int B;
    }

    class C1
    {
        public int A;
        public int B;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new FieldCouldBeReadOnlyAnalyzer() }, null, null,
                Diagnostic(FieldCouldBeReadOnlyAnalyzer.FieldCouldBeReadOnlyDescriptor.Id, "F5").WithLocation(8, 16),
                Diagnostic(FieldCouldBeReadOnlyAnalyzer.FieldCouldBeReadOnlyDescriptor.Id, "F6").WithLocation(9, 16),
                Diagnostic(FieldCouldBeReadOnlyAnalyzer.FieldCouldBeReadOnlyDescriptor.Id, "F10").WithLocation(13, 15));
        }

        [Fact]
        public void LocalCouldBeConstCSharp()
        {
            const string source = @"
class C
{
    public void M0(int p)
    {
        int x = p;
        int y = x;
        const int z = 1;
        int a = 2;
        int b = 3;
        int c = 4;
        int d = 5;
        int e = 6;
        string s = ""ZZZ"";
        b = 3;
        c++;
        d += e + b;
        M1(out y, z, ref a, s);
        S n;
        n.A = 10;
        n.B = 20;
        C1 o = new C1();
        o.A = 10;
        o.B = 20;
    }

    public void M1(out int x, int y, ref int z, string s)
    {
        x = 10;
    }

    struct S
    {
        public int A;
        public int B;
    }

    class C1
    {
        public int A;
        public int B;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new LocalCouldBeConstAnalyzer() }, null, null,
                Diagnostic(LocalCouldBeConstAnalyzer.LocalCouldBeConstDescriptor.Id, "e").WithLocation(13, 13),
                Diagnostic(LocalCouldBeConstAnalyzer.LocalCouldBeConstDescriptor.Id, "s").WithLocation(14, 16));
        }

        [Fact]
        public void SymbolCouldHaveMoreSpecificTypeCSharp()
        {
            const string source = @"
class C
{
    public void M0()
    {
        object a = new Middle();
        object b = new Value(10);
        object c = new Middle();
        c = new Base();
        Base d = new Derived();
        Base e = new Derived();
        e = new Middle();
        Base f = new Middle();
        f = new Base();
        object g = new Derived();
        g = new Base();
        g = new Middle();
        var h = new Middle();
        h = new Derived();
        object i = 3;
        object j;
        j = 10;
        j = 10.1;
        Middle k = new Derived();
        Middle l = new Derived();
        object o = new Middle();
        M(out l, ref o);

        IBase1 ibase1 = null;
        IBase2 ibase2 = null;
        IMiddle imiddle = null;
        IDerived iderived = null;

        object ia = imiddle;
        object ic = imiddle;
        ic = ibase1;
        IBase1 id = iderived;
        IBase1 ie = iderived;
        ie = imiddle;
        IBase1 iff = imiddle;
        iff = ibase1;
        object ig = iderived;
        ig = ibase1;
        ig = imiddle;
        var ih = imiddle;
        ih = iderived;
        IMiddle ik = iderived;
        IMiddle il = iderived;
        object io = imiddle;
        IM(out il, ref io);
        IBase2 im = iderived;
        object isink = ibase2;
        isink = 3;
    }

    object fa = new Middle();
    object fb = new Value(10);
    object fc = new Middle();
    Base fd = new Derived();
    Base fe = new Derived();
    Base ff = new Middle();
    object fg = new Derived();
    Middle fh = new Middle();
    object fi = 3;
    object fj;
    Middle fk = new Derived();
    Middle fl = new Derived();
    object fo = new Middle();

    static IBase1 fibase1 = null;
    static IBase2 fibase2 = null;
    static IMiddle fimiddle = null;
    static IDerived fiderived = null;

    object fia = fimiddle;
    object fic = fimiddle;
    IBase1 fid = fiderived;
    IBase1 fie = fiderived;
    IBase1 fiff = fimiddle;
    object fig = fiderived;
    IMiddle fih = fimiddle;
    IMiddle fik = fiderived;
    IMiddle fil = fiderived;
    object fio = fimiddle;
    object fisink = fibase2;
    IBase2 fim = fiderived;

    void M1()
    {
        fc = new Base();
        fe = new Middle();
        ff = new Base();
        fg = new Base();
        fg = new Middle();
        fh = new Derived();
        fj = 10;
        fj = 10.1;
        M(out fl, ref fo);

        fic = fibase1;
        fie = fimiddle;
        fiff = fibase1;
        fig = fibase1;
        fig = fimiddle;
        fih = fiderived;
        IM(out fil, ref fio);
        fisink = 3;
    }

    void M(out Middle p1, ref object p2)
    {
        p1 = new Middle();
        p2 = null;
    }

    void IM(out IMiddle p1, ref object p2)
    {
        p1 = null;
        p2 = null;
    }
}

class Base
{
}

class Middle : Base
{
}

class Derived : Middle
{
}

struct Value
{
    public Value(int a)
    {
        X = a;
    }

    public int X;
}

interface IBase1
{
}

interface IBase2
{
}

interface IMiddle : IBase1
{
}

interface IDerived : IMiddle, IBase2
{
}

";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new SymbolCouldHaveMoreSpecificTypeAnalyzer() }, null, null,
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "a").WithArguments("a", "Middle").WithLocation(6, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "b").WithArguments("b", "Value").WithLocation(7, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "c").WithArguments("c", "Base").WithLocation(8, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "d").WithArguments("d", "Derived").WithLocation(10, 14),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "e").WithArguments("e", "Middle").WithLocation(11, 14),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "g").WithArguments("g", "Base").WithLocation(15, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "i").WithArguments("i", "int").WithLocation(20, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "k").WithArguments("k", "Derived").WithLocation(24, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "ia").WithArguments("ia", "IMiddle").WithLocation(34, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "ic").WithArguments("ic", "IBase1").WithLocation(35, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "id").WithArguments("id", "IDerived").WithLocation(37, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "ie").WithArguments("ie", "IMiddle").WithLocation(38, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "ig").WithArguments("ig", "IBase1").WithLocation(42, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "ik").WithArguments("ik", "IDerived").WithLocation(47, 17),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.LocalCouldHaveMoreSpecificTypeDescriptor.Id, "im").WithArguments("im", "IDerived").WithLocation(51, 16),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fa").WithArguments("C.fa", "Middle").WithLocation(56, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fb").WithArguments("C.fb", "Value").WithLocation(57, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fc").WithArguments("C.fc", "Base").WithLocation(58, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fd").WithArguments("C.fd", "Derived").WithLocation(59, 10),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fe").WithArguments("C.fe", "Middle").WithLocation(60, 10),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fg").WithArguments("C.fg", "Base").WithLocation(62, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fi").WithArguments("C.fi", "int").WithLocation(64, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fk").WithArguments("C.fk", "Derived").WithLocation(66, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fia").WithArguments("C.fia", "IMiddle").WithLocation(75, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fic").WithArguments("C.fic", "IBase1").WithLocation(76, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fid").WithArguments("C.fid", "IDerived").WithLocation(77, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fie").WithArguments("C.fie", "IMiddle").WithLocation(78, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fig").WithArguments("C.fig", "IBase1").WithLocation(80, 12),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fik").WithArguments("C.fik", "IDerived").WithLocation(82, 13),
                Diagnostic(SymbolCouldHaveMoreSpecificTypeAnalyzer.FieldCouldHaveMoreSpecificTypeDescriptor.Id, "fim").WithArguments("C.fim", "IDerived").WithLocation(86, 12));
        }

        [Fact]
        public void ValueContextsCSharp()
        {
            const string source = @"
class C
{
    public void M0(int a = 16, int b = 17, int c = 18)
    {
    }

    public int f1 = 16;
    public int f2 = 17;
    public int f3 = 18;

    public void M1()
    {
        M0(16, 17, 18);
        M0(f1, f2, f3);
        M0();
    }
}

enum E
{
    A = 16,
    B,
    C = 17,
    D = 18
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new SeventeenTestAnalyzer() }, null, null,
                Diagnostic(SeventeenTestAnalyzer.SeventeenDescriptor.Id, "17").WithLocation(4, 40),
                Diagnostic(SeventeenTestAnalyzer.SeventeenDescriptor.Id, "17").WithLocation(9, 21),
                Diagnostic(SeventeenTestAnalyzer.SeventeenDescriptor.Id, "17").WithLocation(14, 16),
                Diagnostic(SeventeenTestAnalyzer.SeventeenDescriptor.Id, "17").WithLocation(24, 9),
                Diagnostic(SeventeenTestAnalyzer.SeventeenDescriptor.Id, "M0()").WithLocation(16, 9));
        }

        [Fact]
        public void NullArgumentCSharp()
        {
            const string source = @"
class Goo
{
    public Goo(string x)
    {}
}

class C
{
    public void M1(string x, string y)
    {}

    public void M2()
    {
        M1("""", """");
        M1(null, """");
        M1("""", null);
        M1(null, null);
    }

    public void M3()
    {
        var f1 = new Goo("""");
        var f2 = new Goo(null);
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new NullArgumentTestAnalyzer() }, null, null,
                Diagnostic(NullArgumentTestAnalyzer.NullArgumentsDescriptor.Id, "null").WithLocation(16, 12),
                Diagnostic(NullArgumentTestAnalyzer.NullArgumentsDescriptor.Id, "null").WithLocation(17, 16),
                Diagnostic(NullArgumentTestAnalyzer.NullArgumentsDescriptor.Id, "null").WithLocation(18, 12),
                Diagnostic(NullArgumentTestAnalyzer.NullArgumentsDescriptor.Id, "null").WithLocation(18, 18),
                Diagnostic(NullArgumentTestAnalyzer.NullArgumentsDescriptor.Id, "null").WithLocation(24, 26));
        }

        [Fact]
        public void MemberInitializerCSharp()
        {
            const string source = @"
struct Bar
{
    public bool Field;
}

class Goo
{
    public int Field;
    public string Property1 { set; get; }
    public Bar Property2 { set; get; }
}

class C
{
    public void M1()
    {   
        var x1 = new Goo();
        var x2 = new Goo() { Field = 2};
        var x3 = new Goo() { Property1 = """"};
        var x4 = new Goo() { Property1 = """", Field = 2};
        var x5 = new Goo() { Property2 = new Bar { Field = true } };

        var e1 = new Goo() { Property2 = 1 };
        var e2 = new Goo() { "" };      
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(
                // (25,30): error CS1010: Newline in constant
                //         var e2 = new Goo() { " };      
                Diagnostic(ErrorCode.ERR_NewlineInConst, "").WithLocation(25, 30),
                // (26,6): error CS1002: ; expected
                //     }
                Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(26, 6),
                // (27,2): error CS1513: } expected
                // }
                Diagnostic(ErrorCode.ERR_RbraceExpected, "").WithLocation(27, 2),
                // (24,42): error CS0029: Cannot implicitly convert type 'int' to 'Bar'
                //         var e1 = new Goo() { Property2 = 1 };
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "1").WithArguments("int", "Bar").WithLocation(24, 42))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new MemberInitializerTestAnalyzer() }, null, null,
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUseFieldInitializerDescriptor.Id, "Field").WithLocation(19, 30),
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUsePropertyInitializerDescriptor.Id, "Property1").WithLocation(20, 30),
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUsePropertyInitializerDescriptor.Id, "Property1").WithLocation(21, 30),
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUseFieldInitializerDescriptor.Id, "Field").WithLocation(21, 46),
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUsePropertyInitializerDescriptor.Id, "Property2").WithLocation(22, 30),
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUseFieldInitializerDescriptor.Id, "Field").WithLocation(22, 52),
                Diagnostic(MemberInitializerTestAnalyzer.DoNotUsePropertyInitializerDescriptor.Id, "Property2").WithLocation(24, 30));
        }

        [Fact]
        public void AssignmentCSharp()
        {
            const string source = @"
struct Bar
{
    public bool Field;
}

class Goo
{
    public int Field;
    public string Property1 { set; get; }
    public Bar Property2 { set; get; }
}

class C
{
    public void M1()
    {
        var x1 = new Goo();
        var x2 = new Goo() { Field = 2};
        var x3 = new Goo() { Property1 = """"};
        var x4 = new Goo() { Property1 = """", Field = 2};
        var x5 = new Goo() { Property2 = new Bar { Field = true } };
    }

    public void M2()
    {
        var x1 = new Goo() { Property2 = new Bar { Field = true } };
        x1.Field = 10;
        x1.Property1 = null;

        var x2 = new Bar();
        x2.Field = true;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new AssignmentTestAnalyzer() }, null, null,
                Diagnostic("DoNotUseMemberAssignment", "Property2 = new Bar { Field = true }").WithLocation(27, 30),
                Diagnostic("DoNotUseMemberAssignment", "Field = true").WithLocation(27, 52),
                Diagnostic("DoNotUseMemberAssignment", "x1.Field = 10").WithLocation(28, 9),
                Diagnostic("DoNotUseMemberAssignment", "x1.Property1 = null").WithLocation(29, 9),
                Diagnostic("DoNotUseMemberAssignment", "x2.Field = true").WithLocation(32, 9),
                Diagnostic("DoNotUseMemberAssignment", "Field = 2").WithLocation(19, 30),
                Diagnostic("DoNotUseMemberAssignment", @"Property1 = """"").WithLocation(20, 30),
                Diagnostic("DoNotUseMemberAssignment", @"Property1 = """"").WithLocation(21, 30),
                Diagnostic("DoNotUseMemberAssignment", "Field = 2").WithLocation(21, 46),
                Diagnostic("DoNotUseMemberAssignment", "Property2 = new Bar { Field = true }").WithLocation(22, 30),
                Diagnostic("DoNotUseMemberAssignment", "Field = true").WithLocation(22, 52));
        }

        [Fact]
        public void ArrayInitializerCSharp()
        {
            const string source = @"
class C
{
    void M1()
    {
        int[] arr1 = new int[0];                       
        byte[] arr2 = { };                             
        C[] arr3 = new C[] { };                        

        int[] arr4 = new int[] { 1, 2, 3 };            
        byte[] arr5 = { 1, 2, 3 };                     
        C[] arr6 = new C[] { null, null, null };       

        int[] arr7 = new int[] { 1, 2, 3, 4, 5, 6 };                // LargeList
        byte[] arr8 = { 1, 2, 3, 4, 5, 6 };                         // LargeList
        C[] arr9 = new C[] { null, null, null, null, null, null };  // LargeList

        int[,] arr10 = new int[,] { { 1, 2, 3, 4, 5, 6 } };     // LargeList
        byte[,] arr11 = {                                      
                          { 1, 2, 3, 4, 5, 6 },                 // LargeList
                          { 7, 8, 9, 10, 11, 12 }                  // LargeList
                        };
        C[,] arr12 = new C[,] {                                 
                                { null, null, null, null, null, null }  // LargeList
                              };

        int[][] arr13 = new int[][] { new[] { 1,2,3 }, new int[5] };
        int[][] arr14 = new int[][] { new int[] { 1,2,3 }, new[] { 1, 2, 3, 4, 5, 6 } };  // LargeList
    }
}";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new ArrayInitializerTestAnalyzer() }, null, null,
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ 1, 2, 3, 4, 5, 6 }").WithLocation(14, 32),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ 1, 2, 3, 4, 5, 6 }").WithLocation(15, 23),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ null, null, null, null, null, null }").WithLocation(16, 28),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ 1, 2, 3, 4, 5, 6 }").WithLocation(18, 37),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ 1, 2, 3, 4, 5, 6 }").WithLocation(20, 27),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ 7, 8, 9, 10, 11, 12 }").WithLocation(21, 27),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ null, null, null, null, null, null }").WithLocation(24, 33),
                Diagnostic(ArrayInitializerTestAnalyzer.DoNotUseLargeListOfArrayInitializersDescriptor.Id, "{ 1, 2, 3, 4, 5, 6 }").WithLocation(28, 66)
            );
        }

        [Fact]
        public void VariableDeclarationCSharp()
        {
            const string source = @"
public class C
{
    public void M1()
    {
#pragma warning disable CS0168, CS0219
        int a1;
        int b1, b2, b3;
        int c1, c2, c3, c4;
        C[] d1, d2, d3, d4 = { null, null };
        int e1 = 1, e2, e3, e4 = 10;
        int f1, f2, f3, ;
        int g1, g2, g3, g4 =;
#pragma warning restore CS0168, CS0219
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(
                Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(12, 25),
                Diagnostic(ErrorCode.ERR_InvalidExprTerm, ";").WithArguments(";").WithLocation(13, 29))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new VariableDeclarationTestAnalyzer() }, null, null,
                Diagnostic(VariableDeclarationTestAnalyzer.TooManyLocalVarDeclarationsDescriptor.Id, "int c1, c2, c3, c4;").WithLocation(9, 9),
                Diagnostic(VariableDeclarationTestAnalyzer.TooManyLocalVarDeclarationsDescriptor.Id, "C[] d1, d2, d3, d4 = { null, null };").WithLocation(10, 9),
                Diagnostic(VariableDeclarationTestAnalyzer.LocalVarInitializedDeclarationDescriptor.Id, "d4 = { null, null }").WithLocation(10, 25),
                Diagnostic(VariableDeclarationTestAnalyzer.TooManyLocalVarDeclarationsDescriptor.Id, "int e1 = 1, e2, e3, e4 = 10;").WithLocation(11, 9),
                Diagnostic(VariableDeclarationTestAnalyzer.LocalVarInitializedDeclarationDescriptor.Id, "e1 = 1").WithLocation(11, 13),
                Diagnostic(VariableDeclarationTestAnalyzer.LocalVarInitializedDeclarationDescriptor.Id, "e4 = 10").WithLocation(11, 29),
                Diagnostic(VariableDeclarationTestAnalyzer.TooManyLocalVarDeclarationsDescriptor.Id, "int f1, f2, f3, ;").WithLocation(12, 9),
                Diagnostic(VariableDeclarationTestAnalyzer.TooManyLocalVarDeclarationsDescriptor.Id, "int g1, g2, g3, g4 =;").WithLocation(13, 9));
        }

        [Fact]
        public void CaseCSharp()
        {
            const string source = @"class C
{
    public void M1(int x, int y)
    {
        switch (x)
        {
            case 1:
            case 10:
                break;
            default:
                break;
        }

        switch (y)
        {
            case 1:
                break;
            case 1000:
            default:
                break;
        }

        switch (x)
        {
            case 1:
                break;
            case 1000:
                break;
        }

        switch (y)
        {
            default:
                break;
        }

        switch (y) { }

        switch (x)
        {
            case :
            case 1000:
                break;
        }
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(Diagnostic(ErrorCode.WRN_EmptySwitch, "{").WithLocation(37, 20),
                Diagnostic(ErrorCode.ERR_ConstantExpected, ":").WithLocation(41, 18))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new CaseTestAnalyzer() }, null, null,
                Diagnostic(CaseTestAnalyzer.MultipleCaseClausesDescriptor.Id,
@"case 1:
            case 10:
                break;").WithLocation(7, 13),
                Diagnostic(CaseTestAnalyzer.HasDefaultCaseDescriptor.Id, "default:").WithLocation(10, 13),
                Diagnostic(CaseTestAnalyzer.MultipleCaseClausesDescriptor.Id,
@"case 1000:
            default:
                break;").WithLocation(18, 13),
                Diagnostic(CaseTestAnalyzer.HasDefaultCaseDescriptor.Id, "default:").WithLocation(19, 13),
                Diagnostic(CaseTestAnalyzer.HasDefaultCaseDescriptor.Id, "default:").WithLocation(33, 13));
        }

        [Fact]
        public void ImplicitVsExplicitInstancesCSharp()
        {
            const string source = @"
class C
{
    public virtual void M1()
    {
        this.M1();
        M1();
    }
    public void M2()
    {
    }
}

class D : C
{
    public override void M1()
    {
        base.M1();
        M1();
        M2();
    }
}";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new ExplicitVsImplicitInstanceAnalyzer() }, null, null,
                Diagnostic(ExplicitVsImplicitInstanceAnalyzer.ExplicitInstanceDescriptor.Id, "this").WithLocation(6, 9),
                Diagnostic(ExplicitVsImplicitInstanceAnalyzer.ImplicitInstanceDescriptor.Id, "M1").WithLocation(7, 9),
                Diagnostic(ExplicitVsImplicitInstanceAnalyzer.ExplicitInstanceDescriptor.Id, "base").WithLocation(18, 9),
                Diagnostic(ExplicitVsImplicitInstanceAnalyzer.ImplicitInstanceDescriptor.Id, "M1").WithLocation(19, 9),
                Diagnostic(ExplicitVsImplicitInstanceAnalyzer.ImplicitInstanceDescriptor.Id, "M2").WithLocation(20, 9));
        }

        [Fact]
        public void EventAndMethodReferencesCSharp()
        {
            const string source = @"
public delegate void MumbleEventHandler(object sender, System.EventArgs args);

class C
{
    public event MumbleEventHandler Mumble;

    public void OnMumble(System.EventArgs args)
    {
        Mumble += new MumbleEventHandler(Mumbler);
        Mumble += (s, a) => {};
        Mumble += new MumbleEventHandler((s, a) => {});
        Mumble(this, args);
        object o = Mumble;
        MumbleEventHandler d = Mumbler;
        Mumbler(this, null);
        Mumble -= new MumbleEventHandler(Mumbler);
    }

    private void Mumbler(object sender, System.EventArgs args) 
    {
    }
}";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new MemberReferenceAnalyzer() }, null, null,
                // Bug: we are missing diagnostics of "MethodBindingDescriptor" here. https://github.com/dotnet/roslyn/issues/20095
                Diagnostic(MemberReferenceAnalyzer.HandlerAddedDescriptor.Id, "Mumble += new MumbleEventHandler(Mumbler)").WithLocation(10, 9),
                Diagnostic(MemberReferenceAnalyzer.EventReferenceDescriptor.Id, "Mumble").WithLocation(10, 9),
                Diagnostic(MemberReferenceAnalyzer.MethodBindingDescriptor.Id, "Mumbler").WithLocation(10, 42),
                Diagnostic(MemberReferenceAnalyzer.HandlerAddedDescriptor.Id, "Mumble += (s, a) => {}").WithLocation(11, 9),
                Diagnostic(MemberReferenceAnalyzer.EventReferenceDescriptor.Id, "Mumble").WithLocation(11, 9),
                Diagnostic(MemberReferenceAnalyzer.HandlerAddedDescriptor.Id, "Mumble += new MumbleEventHandler((s, a) => {})").WithLocation(12, 9),
                Diagnostic(MemberReferenceAnalyzer.EventReferenceDescriptor.Id, "Mumble").WithLocation(12, 9),
                Diagnostic(MemberReferenceAnalyzer.EventReferenceDescriptor.Id, "Mumble").WithLocation(13, 9),
                Diagnostic(MemberReferenceAnalyzer.EventReferenceDescriptor.Id, "Mumble").WithLocation(14, 20),
                Diagnostic(MemberReferenceAnalyzer.MethodBindingDescriptor.Id, "Mumbler").WithLocation(15, 32),
                Diagnostic(MemberReferenceAnalyzer.HandlerRemovedDescriptor.Id, "Mumble -= new MumbleEventHandler(Mumbler)").WithLocation(17, 9),
                Diagnostic(MemberReferenceAnalyzer.EventReferenceDescriptor.Id, "Mumble").WithLocation(17, 9),
                Diagnostic(MemberReferenceAnalyzer.MethodBindingDescriptor.Id, "Mumbler").WithLocation(17, 42));
        }

        [Fact]
        public void ParamsArraysCSharp()
        {
            const string source = @"
class C
{
    public void M0(int a, params int[] b)
    {
    }

    public void M1()
    {
        M0(1);
        M0(1, 2);
        M0(1, 2, 3, 4);
        M0(1, 2, 3, 4, 5);
        M0(1, 2, 3, 4, 5, 6);
        M0(1, new int[] { 2, 3, 4 });
        M0(1, new int[] { 2, 3, 4, 5 });
        M0(1, new int[] { 2, 3, 4, 5, 6 });
        M2(1, c: 2);
        D d = new D(3, c: 40);
        d = new D(""Hello"", 1, 2, 3, 4);
        d = new D(""Hello"", new int[] { 1, 2, 3, 4 });
        d = new D(""Hello"", 1, 2, 3);
        d = new D(""Hello"", new int[] { 1, 2, 3 });
    }

    public void M2(int a, int b = 10, int c = 20, params int[] d)
    {
    }

    class D
    {
        public D(int a, int b = 10, int c = 20, params int[] d)
        {
        }

        public D(string a, params int[] b)
        {
        }
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new ParamsArrayTestAnalyzer() }, null, null,
                Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "M0(1, 2, 3, 4, 5)").WithLocation(13, 9),
                Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "M0(1, 2, 3, 4, 5, 6)").WithLocation(14, 9),
                Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "new int[] { 2, 3, 4, 5 }"),
                Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "new int[] { 2, 3, 4, 5, 6 }"),
                Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, @"new D(""Hello"", 1, 2, 3, 4)").WithLocation(20, 13),
                Diagnostic(ParamsArrayTestAnalyzer.LongParamsDescriptor.Id, "new int[] { 1, 2, 3, 4 }"));
        }

        [Fact]
        public void FieldInitializersCSharp()
        {
            const string source = @"
class C
{
    public int F1 = 44;
    public string F2 = ""Hello"";
    public int F3 = Goo();

    static int Goo() { return 10; }
    static int Bar(int P1 = 15, int F2 = 33) { return P1 + F2; }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new EqualsValueTestAnalyzer() }, null, null,
                Diagnostic(EqualsValueTestAnalyzer.EqualsValueDescriptor.Id, "= 44").WithLocation(4, 19),
                Diagnostic(EqualsValueTestAnalyzer.EqualsValueDescriptor.Id, "= \"Hello\"").WithLocation(5, 22),
                Diagnostic(EqualsValueTestAnalyzer.EqualsValueDescriptor.Id, "= Goo()").WithLocation(6, 19),
                Diagnostic(EqualsValueTestAnalyzer.EqualsValueDescriptor.Id, "= 33").WithLocation(9, 40));
        }

        [Fact]
        public void OwningSymbolCSharp()
        {
            const string source = @"
class C
{
    public void UnFunkyMethod()
    {
        int x = 0;
        int y = x;
    }

    public void FunkyMethod()
    {
        int x = 0;
        int y = x;
    }

    public int FunkyField = 12;
    public int UnFunkyField = 12;
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new OwningSymbolTestAnalyzer() }, null, null,
                Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "0").WithLocation(12, 17),
                Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "x").WithLocation(13, 17),
                Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "12").WithLocation(16, 29)
                );
        }

        [Fact]
        public void NoneOperationCSharp()
        {
            // BoundStatementList is OperationKind.None
            const string source = @"
class C
{
    public void M0()
    {
        int x = 0;
        int y = x++;
        int z = y++;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new NoneOperationTestAnalyzer() }, null, null);
        }

        [ConditionalFact(typeof(NoIOperationValidation))]
        [WorkItem(9025, "https://github.com/dotnet/roslyn/issues/9025")]
        public void LongArithmeticExpressionCSharp()
        {
            Func<int, string> buildSequenceOfBinaryExpressions =
                (count) =>
                {
                    var builder = new System.Text.StringBuilder();
                    int i;
                    for (i = 0; i < count; i++)
                    {
                        builder.Append((i + 1).ToString(System.Globalization.CultureInfo.InvariantCulture));
                        builder.Append(" * ");
                        builder.Append("f[");
                        builder.Append(i.ToString(System.Globalization.CultureInfo.InvariantCulture));
                        builder.Append("] + ");
                    }

                    builder.Append((i + 1).ToString(System.Globalization.CultureInfo.InvariantCulture));

                    return builder.ToString();
                };
            // This code will cause OperationWalker to throw `InsufficientExecutionStackException`
            var expr = buildSequenceOfBinaryExpressions(8192);
            var source = @"
class Test
{ 
    public static long Calculate1(long[] f)
    {
        long x;
" + $"        x = {expr};" + @"
        return x;
    }
}";

            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new AssignmentOperationSyntaxTestAnalyzer() }, null, null,
                Diagnostic(AssignmentOperationSyntaxTestAnalyzer.AssignmentOperationDescriptor.Id, $"x = {expr}").WithLocation(7, 9),
                Diagnostic(AssignmentOperationSyntaxTestAnalyzer.AssignmentSyntaxDescriptor.Id, $"x = {expr}").WithLocation(7, 9));
        }

        [WorkItem(9020, "https://github.com/dotnet/roslyn/issues/9020")]
        [Fact]
        public void AddressOfExpressionCSharp()
        {
            const string source = @"
public class C
{
   unsafe public void M1()
   {
      int a = 0, b = 0;
      int *i = &(a + b);   // CS0211, the addition of two local variables

      int *j = &a;
   }

   unsafe public void M2()
   {
       int x;
       int* p = &x;
       p = &(*p);
       p = &p[0];
   }
}

class A
{
    public unsafe void M1()
    {
        int[] ints = new int[] { 1, 2, 3 };
        foreach (int i in ints)
        {
            int *j = &i;  
        }

        fixed (int *i = &_i)
        {
            int **j = &i;  
        }
    }

    private int _i = 0;
}";
            CreateCompilationWithMscorlib461(source, options: TestOptions.UnsafeReleaseDll)
            .VerifyDiagnostics(Diagnostic(ErrorCode.ERR_InvalidAddrOp, "a + b").WithLocation(7, 18))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new AddressOfTestAnalyzer() }, null, null,
                Diagnostic("AddressOfOperation", "&(a + b)").WithLocation(7, 16),
                Diagnostic("InvalidAddressOfReference", "a + b").WithLocation(7, 18),
                Diagnostic("AddressOfOperation", "&a").WithLocation(9, 16),
                Diagnostic("AddressOfOperation", "&i").WithLocation(28, 22),
                Diagnostic("AddressOfOperation", "&_i").WithLocation(31, 25),
                Diagnostic("AddressOfOperation", "&i").WithLocation(33, 23),
                Diagnostic("AddressOfOperation", "&x").WithLocation(15, 17),
                Diagnostic("AddressOfOperation", "&(*p)").WithLocation(16, 12),
                Diagnostic("AddressOfOperation", "&p[0]").WithLocation(17, 12));
        }

        [Fact]
        public void LambdaExpressionCSharp()
        {
            const string source = @"
using System;

class B
{
    public void M0()
    {
        Action<int> action1 = input => { };
        Action<int> action2 = input => input++;
        Func<int,bool> func1 = input => { input++; input++; if (input > 0) return true; return false; };
    }
}

public delegate void MumbleEventHandler(object sender, System.EventArgs args);

class C
{
    public event MumbleEventHandler Mumble;

    public void OnMumble(System.EventArgs args)
    {
        Mumble += new MumbleEventHandler((s, e) => { });
        Mumble += (s, e) => { int i = 0; i++; i++; i++; };
        Mumble(this, args);
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new LambdaTestAnalyzer() }, null, null,
                Diagnostic(LambdaTestAnalyzer.LambdaExpressionDescriptor.Id, "input => { }").WithLocation(8, 31),
                Diagnostic(LambdaTestAnalyzer.LambdaExpressionDescriptor.Id, "input => input++").WithLocation(9, 31),
                Diagnostic(LambdaTestAnalyzer.LambdaExpressionDescriptor.Id, "input => { input++; input++; if (input > 0) return true; return false; }").WithLocation(10, 32),
                Diagnostic(LambdaTestAnalyzer.TooManyStatementsInLambdaExpressionDescriptor.Id, "input => { input++; input++; if (input > 0) return true; return false; }").WithLocation(10, 32),
                Diagnostic(LambdaTestAnalyzer.LambdaExpressionDescriptor.Id, "(s, e) => { }").WithLocation(22, 42),
                Diagnostic(LambdaTestAnalyzer.LambdaExpressionDescriptor.Id, "(s, e) => { int i = 0; i++; i++; i++; }").WithLocation(23, 19),
                Diagnostic(LambdaTestAnalyzer.TooManyStatementsInLambdaExpressionDescriptor.Id, "(s, e) => { int i = 0; i++; i++; i++; }").WithLocation(23, 19));
        }

        [WorkItem(8385, "https://github.com/dotnet/roslyn/issues/8385")]
        [Fact]
        public void StaticMemberReferenceCSharp()
        {
            const string source = @"
using System;

public class D
{
    public static event Action E;

    public static int Field;

    public static int Property => 0;

    public static void Method() { }
}

class C
{
    public static event Action E;

    public static void Bar() { }

    void Goo()
    {
        C.E += D.Method;
        C.E();
        C.Bar();

        D.E += () => { };
        D.Field = 1;
        var x = D.Property;
        D.Method();
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E").WithArguments("D.E").WithLocation(6, 32))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new StaticMemberTestAnalyzer() }, null, null,
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "C.E").WithLocation(23, 9),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "D.Method").WithLocation(23, 16),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "C.E").WithLocation(24, 9),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "C.Bar()").WithLocation(25, 9),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "D.E").WithLocation(27, 9),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "D.Field").WithLocation(28, 9),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "D.Property").WithLocation(29, 17),
                Diagnostic(StaticMemberTestAnalyzer.StaticMemberDescriptor.Id, "D.Method()").WithLocation(30, 9));
        }

        [Fact]
        public void LabelOperatorsCSharp()
        {
            const string source = @"
public class A
{
    public void Fred()
    {
        Wilma: goto Betty;
        Betty: goto Wilma;
    }
}
";
            CreateCompilationWithMscorlib461(source)
             .VerifyDiagnostics()
             .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new LabelOperationsTestAnalyzer() }, null, null,
                Diagnostic(LabelOperationsTestAnalyzer.LabelDescriptor.Id, "Wilma: goto Betty;").WithLocation(6, 9),
                Diagnostic(LabelOperationsTestAnalyzer.GotoDescriptor.Id, "goto Betty;").WithLocation(6, 16),
                Diagnostic(LabelOperationsTestAnalyzer.LabelDescriptor.Id, "Betty: goto Wilma;").WithLocation(7, 9),
                Diagnostic(LabelOperationsTestAnalyzer.GotoDescriptor.Id, "goto Wilma;").WithLocation(7, 16));
        }

        [Fact]
        public void UnaryBinaryOperatorsCSharp()
        {
            const string source = @"
public class A
{
    readonly int _value;

    public A (int value)
    {
        _value = value;
    }

    public static A operator +(A x, A y)
    {
        return new A(x._value + y._value);
    }

    public static A operator *(A x, A y)
    {
        return new A(x._value * y._value);
    }

    public static A operator -(A x)
    {
        return new A(-x._value);
    }

    public static A operator +(A x)
    {
        return new A(+x._value);
    }
}

class C
{
    static void Main()
    {
        bool b = false;
        double d = 100;
        A a1 = new A(0);
        A a2 = new A(100);

        b = !b;
        d = d * 100;
        a1 = a1 + a2;
        a1 = -a2;
   }
}
";
            CreateCompilationWithMscorlib461(source)
             .VerifyDiagnostics()
             .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new UnaryAndBinaryOperationsTestAnalyzer() }, null, null,
                Diagnostic(UnaryAndBinaryOperationsTestAnalyzer.BooleanNotDescriptor.Id, "!b").WithLocation(41, 13),
                Diagnostic(UnaryAndBinaryOperationsTestAnalyzer.DoubleMultiplyDescriptor.Id, "d * 100").WithLocation(42, 13),
                Diagnostic(UnaryAndBinaryOperationsTestAnalyzer.OperatorAddMethodDescriptor.Id, "a1 + a2").WithLocation(43, 14),
                Diagnostic(UnaryAndBinaryOperationsTestAnalyzer.OperatorMinusMethodDescriptor.Id, "-a2").WithLocation(44, 14));
        }

        [Fact]
        public void InvalidOperatorsCSharp()
        {
            const string source = @"
public class A
{
    readonly int _value;

    public A (int value)
    {
        _value = value;
    }

    public static A operator +(A x, A y)
    {
        return new A(x._value + y._value);
    }

    public static A operator -(A x, A y)
    {
        return new A(x._value - y._value);
    }
}

class C
{
    static void Main()
    {
        A x = new A(0);
        A y = new A(100);

        x = x + 10;
        x = x + y;
        x = -x;
   }
}
";
            CreateCompilationWithMscorlib461(source)
             .VerifyDiagnostics(Diagnostic(ErrorCode.ERR_BadBinaryOps, "x + 10", new object[] { "+", "A", "int" }).WithLocation(29, 13),
                                Diagnostic(ErrorCode.ERR_BadUnaryOp, "-x", new object[] { "-", "A" }).WithLocation(31, 13))
             // no diagnostics from the analyzer since node it is looking for is invalid
             .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new OperatorPropertyPullerTestAnalyzer() }, null, null);
        }

        [Fact, WorkItem(8520, "https://github.com/dotnet/roslyn/issues/8520")]
        public void NullOperationSyntaxCSharp()
        {
            const string source = @"
class C
{
    public void M0(params int[] b)
    {
    }

    public void M1()
    {
        M0();
        M0(1);
        M0(1, 2);
        M0(new int[] { });
        M0(new int[] { 1 });
        M0(new int[] { 1, 2});
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new NullOperationSyntaxTestAnalyzer() }, null, null,
                Diagnostic(NullOperationSyntaxTestAnalyzer.ParamsArrayOperationDescriptor.Id, "M0()"),
                Diagnostic(NullOperationSyntaxTestAnalyzer.ParamsArrayOperationDescriptor.Id, "M0(1)").WithLocation(11, 9),
                Diagnostic(NullOperationSyntaxTestAnalyzer.ParamsArrayOperationDescriptor.Id, "M0(1, 2)").WithLocation(12, 9));
        }

        [WorkItem(9113, "https://github.com/dotnet/roslyn/issues/9113")]
        [Fact]
        public void ConversionExpressionCSharp()
        {
            const string source = @"
class X
{
    static void Main()
    {
        string three = 3.ToString();

        int x = null.Length;

        int y = string.Empty;

        int i = global::MyType();
    }
}";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(
                // (8,17): error CS0023: Operator '.' cannot be applied to operand of type '<null>'
                //         int x = null.Length;
                Diagnostic(ErrorCode.ERR_BadUnaryOp, "null.Length").WithArguments(".", "<null>").WithLocation(8, 17),
                // (10,17): error CS0029: Cannot implicitly convert type 'string' to 'int'
                //         int y = string.Empty;
                Diagnostic(ErrorCode.ERR_NoImplicitConv, "string.Empty").WithArguments("string", "int").WithLocation(10, 17),
                // (12,25): error CS0400: The type or namespace name 'MyType' could not be found in the global namespace (are you missing an assembly reference?)
                //         int i = global::MyType();
                Diagnostic(ErrorCode.ERR_GlobalSingleTypeNameNotFound, "MyType").WithArguments("MyType").WithLocation(12, 25))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new ConversionExpressionCSharpTestAnalyzer() }, null, null,
                Diagnostic(ConversionExpressionCSharpTestAnalyzer.InvalidConversionExpressionDescriptor.Id, "null.Length").WithLocation(8, 17),
                Diagnostic(ConversionExpressionCSharpTestAnalyzer.InvalidConversionExpressionDescriptor.Id, "string.Empty").WithLocation(10, 17),
                Diagnostic(ConversionExpressionCSharpTestAnalyzer.InvalidConversionExpressionDescriptor.Id, "global::MyType()").WithLocation(12, 17));
        }

        [WorkItem(8114, "https://github.com/dotnet/roslyn/issues/8114")]
        [Fact]
        public void InvalidOperatorCSharp()
        {
            const string source = @"
public class A
{
    public bool Compare(float f)
    {
        return f == float.Nan; // Misspelled
    }

    public string Negate(string f)
    {
        return -f;
    }

    public void Increment(string f)
    {
        f++;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(
                Diagnostic(ErrorCode.ERR_NoSuchMember, "Nan").WithArguments("float", "Nan").WithLocation(6, 27),
                Diagnostic(ErrorCode.ERR_BadUnaryOp, "-f").WithArguments("-", "string").WithLocation(11, 16),
                Diagnostic(ErrorCode.ERR_BadUnaryOp, "f++").WithArguments("++", "string").WithLocation(16, 9))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new InvalidOperatorExpressionTestAnalyzer() }, null, null,
                Diagnostic(InvalidOperatorExpressionTestAnalyzer.InvalidBinaryDescriptor.Id, "f == float.Nan").WithLocation(6, 16),
                Diagnostic(InvalidOperatorExpressionTestAnalyzer.InvalidUnaryDescriptor.Id, "-f").WithLocation(11, 16),
                Diagnostic(InvalidOperatorExpressionTestAnalyzer.InvalidIncrementDescriptor.Id, "f++").WithLocation(16, 9));
        }

        [Fact, WorkItem(9114, "https://github.com/dotnet/roslyn/issues/9114")]
        public void InvalidArgumentCSharp()
        {
            const string source = @"
public class A
{
    public static void Goo(params int a) {}

    public static int Main()
    {
        Goo();
        Goo(1);
        return 1;
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics(
                // (4,28): error CS0225: The params parameter must have a valid collection type
                //     public static void Goo(params int a) {}
                Diagnostic(ErrorCode.ERR_ParamsMustBeCollection, "params").WithLocation(4, 28),
                // (8,9): error CS7036: There is no argument given that corresponds to the required parameter 'a' of 'A.Goo(params int)'
                //         Goo();
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "Goo").WithArguments("a", "A.Goo(params int)").WithLocation(8, 9))
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new InvocationTestAnalyzer() }, null, null);
        }

        [Fact]
        public void ConditionalAccessOperationsCSharp()
        {
            const string source = @"
class C
{
    public int Prop { get; set; }

    public int Field;

    public int this[int i]
    {
        get
        {
            return this.Field;
        }
        set
        {
            this.Field = value;
        }
    }

    public C Field1 = null;

    public void M0(C p)
    {
        var x = p?.Prop;
        x = p?.Field;
        x = p?[0];
        p?.M0(null);

        x = Field1?.Prop;
        x = Field1?.Field;
        x = Field1?[0];
        Field1?.M0(null);
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new ConditionalAccessOperationTestAnalyzer() }, null, null,
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "p?.Prop").WithLocation(24, 17),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "p").WithLocation(24, 17),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "p?.Field").WithLocation(25, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "p").WithLocation(25, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "p?[0]").WithLocation(26, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "p").WithLocation(26, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "p?.M0(null)").WithLocation(27, 9),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "p").WithLocation(27, 9),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "Field1?.Prop").WithLocation(29, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "Field1").WithLocation(29, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "Field1?.Field").WithLocation(30, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "Field1").WithLocation(30, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "Field1?[0]").WithLocation(31, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "Field1").WithLocation(31, 13),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessOperationDescriptor.Id, "Field1?.M0(null)").WithLocation(32, 9),
                Diagnostic(ConditionalAccessOperationTestAnalyzer.ConditionalAccessInstanceOperationDescriptor.Id, "Field1").WithLocation(32, 9));
        }

        [Fact, WorkItem(9116, "https://github.com/dotnet/roslyn/issues/9116")]
        public void LiteralCSharp()
        {
            const string source = @"
public class A
{
    public void M()
    {
        object a = null;
    }
}

struct S
{
    void M(
        int i = 1,
        string str = ""hello"",
        object o = null,
        S s = default(S))
    {
        M();
    }
}
";
            CreateCompilationWithMscorlib461(source)
             .VerifyDiagnostics(Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "a").WithArguments("a").WithLocation(6, 16))
             .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new LiteralTestAnalyzer() }, null, null, Diagnostic("Literal", "null").WithArguments("null").WithLocation(6, 20),
                Diagnostic("Literal", "1").WithArguments("1").WithLocation(13, 17),
                Diagnostic("Literal", @"""hello""").WithArguments(@"""hello""").WithLocation(14, 22),
                Diagnostic("Literal", "null").WithArguments("null").WithLocation(15, 20),
                Diagnostic("Literal", "M()").WithArguments("M()").WithLocation(18, 9),
                Diagnostic("Literal", "M()").WithArguments("M()").WithLocation(18, 9));
        }

        [Fact]
        public void UnaryTrueFalseOperationCSharp()
        {
            const string source = @"
public struct S
{
    private int value;
    public S(int v)
    {
        value = v;
    }
    public static S operator &(S x, S y)
    {
        return new S(x.value + y.value);    
    }
    public static bool operator true(S x)
    {
        return x.value > 0;
    }
    public static bool operator false(S x)
    {
        return x.value <= 0;
    }
}

class C
{
    public void M()
    {
        var x = new S(-1);
        var y = new S(1);
        if (x && y) { }
        else if (x) { }
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new TrueFalseUnaryOperationTestAnalyzer() }, null, null,
                Diagnostic(TrueFalseUnaryOperationTestAnalyzer.UnaryTrueDescriptor.Id, "x && y").WithLocation(29, 13),
                Diagnostic(TrueFalseUnaryOperationTestAnalyzer.UnaryTrueDescriptor.Id, "x").WithLocation(30, 18));
        }

        [Fact]
        public void TestOperationBlockAnalyzer_EmptyMethodBody()
        {
            const string source = @"
class C
{
    public void M()
    {
    }

    public void M2(int i)
    {
    }

    public void M3(int i = 0)
    {
    }
}
";
            CreateCompilationWithMscorlib461(source)
            .VerifyDiagnostics()
            .VerifyAnalyzerDiagnostics(new DiagnosticAnalyzer[] { new OperationBlockAnalyzer() }, null, null,
                Diagnostic("ID", "M2").WithArguments("M2", "Block").WithLocation(8, 17),
                Diagnostic("ID", "M").WithArguments("M", "Block").WithLocation(4, 17),
                Diagnostic("ID", "M3").WithArguments("M3", "ParameterInitializer").WithLocation(12, 17),
                Diagnostic("ID", "M3").WithArguments("M3", "Block").WithLocation(12, 17));
        }
    }
}
