File: src\Analyzers\CSharp\Tests\HiddenExplicitCast\HiddenExplicitCastTests.cs
Web Access
Project: src\src\Features\CSharpTest\Microsoft.CodeAnalysis.CSharp.Features.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Features.UnitTests)
// 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.
 
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Analyzers.HiddenExplicitCast;
using Microsoft.CodeAnalysis.CSharp.CodeFixes.HiddenExplicitCast;
using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions;
using Microsoft.CodeAnalysis.Testing;
using Xunit;
 
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.HiddenExplicitCast;
 
using VerifyCS = CSharpCodeFixVerifier<
    CSharpHiddenExplicitCastDiagnosticAnalyzer,
    CSharpHiddenExplicitCastCodeFixProvider>;
 
public sealed class HiddenExplicitCastTests
{
    [Fact]
    public Task TestInheritanceAndUserDefined()
        => new VerifyCS.Test
        {
            TestCode = """
                class Base { }
                class Derived : Base { }
 
                class Castable
                {
                    public static explicit operator Base(Castable c) => new Base();
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
                        var v = [|(Derived)new Castable()|]; 
                    }
                }
                """,
            FixedCode = """
                class Base { }
                class Derived : Base { }
                
                class Castable
                {
                    public static explicit operator Base(Castable c) => new Base();
                }
                
                class C
                {
                    static void Main(string[] args)
                    {
                        var v = (Derived)(Base)new Castable(); 
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestNullableAndUserDefined()
        => new VerifyCS.Test
        {
            TestCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
 
                        S? s = new S();
                        int i = [|(int)s|];
                    }
                }
                """,
            FixedCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
 
                        S? s = new S();
                        int i = (int)(decimal?)s;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestNumericAndUserDefined()
        => new VerifyCS.Test
        {
            TestCode = """
                struct UnixTime
                {
                    public static explicit operator UnixTime(int i)
                    {
                        return default;
                    }
                }
                
                class C
                {
                    public UnixTime M(long i) => [|(UnixTime)i|];
                }
                """,
            FixedCode = """
                struct UnixTime
                {
                    public static explicit operator UnixTime(int i)
                    {
                        return default;
                    }
                }
                
                class C
                {
                    public UnixTime M(long i) => (UnixTime)(int)i;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestTopLevel()
        => new VerifyCS.Test
        {
            TestCode = """
                S? s = new S();
                int i = [|(int)s|];
 
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
                """,
            FixedCode = """
                S? s = new S();
                int i = (int)(decimal?)s;
 
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
                """,
            LanguageVersion = LanguageVersion.CSharp10,
            TestState = { OutputKind = OutputKind.ConsoleApplication },
        }.RunAsync();
 
    [Fact]
    public Task TestArgument()
        => new VerifyCS.Test
        {
            TestCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
 
                        S? s = new S();
                        Goo([|(int)s|]);
                    }
 
                    static void Goo(int i) { }
                }
                """,
            FixedCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
 
                        S? s = new S();
                        Goo((int)(decimal?)s);
                    }
                
                    static void Goo(int i) { }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestAssignment()
        => new VerifyCS.Test
        {
            TestCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
 
                        S? s = new S();
                        int i;
                        i = [|(int)s|];
                    }
                }
                """,
            FixedCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static void Main(string[] args)
                    {
 
                        S? s = new S();
                        int i;
                        i = (int)(decimal?)s;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestReturn()
        => new VerifyCS.Test
        {
            TestCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static int Main(string[] args)
                    {
 
                        S? s = new S();
                        int i;
                        return [|(int)s|];
                    }
                }
                """,
            FixedCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    static int Main(string[] args)
                    {
 
                        S? s = new S();
                        int i;
                        return (int)(decimal?)s;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestFieldInitializer()
        => new VerifyCS.Test
        {
            TestCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    int i = [|(int)new S()|];
                }
                """,
            FixedCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    int i = (int)(decimal?)new S();
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestPropertyInitializer()
        => new VerifyCS.Test
        {
            TestCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    int X => [|(int)new S()|];
                }
                """,
            FixedCode = """
                public struct S
                {
                    public static explicit operator decimal?(S s) { return 1.0m; }
                }
 
                class C
                {
                    int X => (int)(decimal?)new S();
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToDouble_ThenDoubleToFloat()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator double(Value v) => 1.0;
                }
 
                class C
                {
                    void M()
                    {
                        var v = new Value();
                        float f = [|(float)v|];
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator double(Value v) => 1.0;
                }
 
                class C
                {
                    void M()
                    {
                        var v = new Value();
                        float f = (float)(double)v;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToLong_ThenLongToShort()
        => new VerifyCS.Test
        {
            TestCode = """
                struct BigNumber
                {
                    public static explicit operator long(BigNumber b) => 100L;
                }
 
                class C
                {
                    short M(BigNumber b) => [|(short)b|];
                }
                """,
            FixedCode = """
                struct BigNumber
                {
                    public static explicit operator long(BigNumber b) => 100L;
                }
 
                class C
                {
                    short M(BigNumber b) => (short)(long)b;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToDecimal_ThenDecimalToInt()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Money
                {
                    public static explicit operator decimal(Money m) => 100.50m;
                }
 
                class C
                {
                    int M(Money m) => [|(int)m|];
                }
                """,
            FixedCode = """
                struct Money
                {
                    public static explicit operator decimal(Money m) => 100.50m;
                }
 
                class C
                {
                    int M(Money m) => (int)(decimal)m;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToBaseClass_ThenBaseToDerived()
        => new VerifyCS.Test
        {
            TestCode = """
                class Animal { }
                class Dog : Animal { }
 
                class AnimalFactory
                {
                    public static explicit operator Animal(AnimalFactory f) => new Dog();
                }
 
                class C
                {
                    Dog M(AnimalFactory f) => [|(Dog)f|];
                }
                """,
            FixedCode = """
                class Animal { }
                class Dog : Animal { }
 
                class AnimalFactory
                {
                    public static explicit operator Animal(AnimalFactory f) => new Dog();
                }
 
                class C
                {
                    Dog M(AnimalFactory f) => (Dog)(Animal)f;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToGrandparent_ThenGrandparentToGrandchild()
           => new VerifyCS.Test
           {
               TestCode = """
                class GrandParent { }
                class Parent : GrandParent { }
                class Child : Parent { }
 
                struct Wrapper
                {
                    public static explicit operator GrandParent(Wrapper w) => new Child();
                }
 
                class C
                {
                    Child M(Wrapper w) => [|(Child)w|];
                }
                """,
               FixedCode = """
                class GrandParent { }
                class Parent : GrandParent { }
                class Child : Parent { }
 
                struct Wrapper
                {
                    public static explicit operator GrandParent(Wrapper w) => new Child();
                }
 
                class C
                {
                    Child M(Wrapper w) => (Child)(GrandParent)w;
                }
                """,
           }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToNullableInt_ThenNullableIntToInt()
        => new VerifyCS.Test
        {
            TestCode = """
                struct OptionalNumber
                {
                    public static explicit operator int?(OptionalNumber o) => 42;
                }
 
                class C
                {
                    int M(OptionalNumber o) => [|(int)o|];
                }
                """,
            FixedCode = """
                struct OptionalNumber
                {
                    public static explicit operator int?(OptionalNumber o) => 42;
                }
 
                class C
                {
                    int M(OptionalNumber o) => (int)(int?)o;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToNullableLong_ThenNullableLongToShort()
        => new VerifyCS.Test
        {
            TestCode = """
                struct LargeOptional
                {
                    public static explicit operator long?(LargeOptional l) => 1000L;
                }
 
                class C
                {
                    short M(LargeOptional l) => [|(short)l|];
                }
                """,
            FixedCode = """
                struct LargeOptional
                {
                    public static explicit operator long?(LargeOptional l) => 1000L;
                }
 
                class C
                {
                    short M(LargeOptional l) => (short)(long?)l;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestNullableSourceToUserDefinedFromInt()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Target
                {
                    public static explicit operator Target(int i) => default;
                }
 
                class C
                {
                    Target M(long? l) => [|(Target)l|];
                }
                """,
            FixedCode = """
                struct Target
                {
                    public static explicit operator Target(int i) => default;
                }
 
                class C
                {
                    Target M(long? l) => (Target)(int)l;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestUserDefinedToNullableDouble_ThenToFloat()
        => new VerifyCS.Test
        {
            TestCode = """
                struct PreciseValue
                {
                    public static explicit operator double?(PreciseValue p) => 3.14159;
                }
 
                class C
                {
                    float M(PreciseValue p) => [|(float)p|];
                }
                """,
            FixedCode = """
                struct PreciseValue
                {
                    public static explicit operator double?(PreciseValue p) => 3.14159;
                }
 
                class C
                {
                    float M(PreciseValue p) => (float)(double?)p;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInArrayInitializer()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int[] M(Value v) => new int[] { [|(int)v|] };
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int[] M(Value v) => new int[] { (int)(long)v };
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInConditionalExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v, bool b) => b ? [|(int)v|] : 0;
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v, bool b) => b ? (int)(long)v : 0;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInInterpolatedString()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator double(Value v) => 3.14;
                }
 
                class C
                {
                    string M(Value v) => $"Result: {[|(int)v|]}";
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator double(Value v) => 3.14;
                }
 
                class C
                {
                    string M(Value v) => $"Result: {(int)(double)v}";
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInLambdaExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                using System;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    Func<Value, int> M() => v => [|(int)v|];
                }
                """,
            FixedCode = """
                using System;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    Func<Value, int> M() => v => (int)(long)v;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInObjectInitializer()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class Target
                {
                    public int Number { get; set; }
                }
 
                class C
                {
                    Target M(Value v) => new Target { Number = [|(int)v|] };
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class Target
                {
                    public int Number { get; set; }
                }
 
                class C
                {
                    Target M(Value v) => new Target { Number = (int)(long)v };
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInSwitchExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    string M(Value v) => [|(int)v|] switch
                    {
                        0 => "zero",
                        _ => "other"
                    };
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    string M(Value v) => (int)(long)v switch
                    {
                        0 => "zero",
                        _ => "other"
                    };
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInCollectionInitializer()
        => new VerifyCS.Test
        {
            TestCode = """
                using System.Collections.Generic;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    List<int> M(Value v) => new List<int> { [|(int)v|] };
                }
                """,
            FixedCode = """
                using System.Collections.Generic;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    List<int> M(Value v) => new List<int> { (int)(long)v };
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInLinqSelect()
        => new VerifyCS.Test
        {
            TestCode = """
                using System.Collections.Generic;
                using System.Linq;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    IEnumerable<int> M(IEnumerable<Value> values) => values.Select(v => [|(int)v|]);
                }
                """,
            FixedCode = """
                using System.Collections.Generic;
                using System.Linq;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    IEnumerable<int> M(IEnumerable<Value> values) => values.Select(v => (int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInTupleLiteral()
        => new VerifyCS.Test
        {
            TestCode = """
                    struct Value
                    {
                        public static explicit operator long(Value v) => 100L;
                    }
 
                    class C
                    {
                        (int, int) M(Value v) => ([|(int)v|], 0);
                    }
                    """,
            FixedCode = """
                    struct Value
                    {
                        public static explicit operator long(Value v) => 100L;
                    }
 
                    class C
                    {
                        (int, int) M(Value v) => ((int)(long)v, 0);
                    }
                    """,
        }.RunAsync();
 
    [Fact]
    public Task TestInForLoopInitializer()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        for (int i = [|(int)v|]; i < 10; i++) { }
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        for (int i = (int)(long)v; i < 10; i++) { }
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInYieldReturn()
        => new VerifyCS.Test
        {
            TestCode = """
                using System.Collections.Generic;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    IEnumerable<int> M(Value v)
                    {
                        yield return [|(int)v|];
                    }
                }
                """,
            FixedCode = """
                using System.Collections.Generic;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    IEnumerable<int> M(Value v)
                    {
                        yield return (int)(long)v;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInCheckedExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => checked([|(int)v|]);
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => checked((int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInUncheckedExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => unchecked([|(int)v|]);
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => unchecked((int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInBinaryExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => [|(int)v|] + 1;
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => (int)(long)v + 1;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInComparisonExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    bool M(Value v) => [|(int)v|] > 5;
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    bool M(Value v) => (int)(long)v > 5;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInArrayIndex()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 0L;
                }
 
                class C
                {
                    int M(Value v, int[] arr) => arr[[|(int)v|]];
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 0L;
                }
 
                class C
                {
                    int M(Value v, int[] arr) => arr[(int)(long)v];
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInNullCoalescingExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long?(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => [|(int?)v|] ?? 0;
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long?(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => (int?)(long?)v ?? 0;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInDiscard()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        _ = [|(int)v|];
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        _ = (int)(long)v;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInConstructorArgument()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class Target
                {
                    public Target(int x) { }
                }
 
                class C
                {
                    Target M(Value v) => new Target([|(int)v|]);
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class Target
                {
                    public Target(int x) { }
                }
 
                class C
                {
                    Target M(Value v) => new Target((int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInIndexerArgument()
        => new VerifyCS.Test
        {
            TestCode = """
                using System.Collections.Generic;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 0L;
                }
 
                class C
                {
                    string M(Value v, Dictionary<int, string> dict) => dict[[|(int)v|]];
                }
                """,
            FixedCode = """
                using System.Collections.Generic;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 0L;
                }
 
                class C
                {
                    string M(Value v, Dictionary<int, string> dict) => dict[(int)(long)v];
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInStringConcatenation()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    string M(Value v) => "Value: " + [|(int)v|];
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    string M(Value v) => "Value: " + (int)(long)v;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInRangeExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                using System;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 0L;
                }
 
                class C
                {
                    int[] M(Value v, int[] arr) => arr[[|(int)v|]..];
                }
                """,
            FixedCode = """
                using System;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 0L;
                }
 
                class C
                {
                    int[] M(Value v, int[] arr) => arr[(int)(long)v..];
                }
                """,
            ReferenceAssemblies = ReferenceAssemblies.Net.Net90,
        }.RunAsync();
 
    [Fact]
    public Task TestInQueryExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                using System.Collections.Generic;
                using System.Linq;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    IEnumerable<int> M(IEnumerable<Value> values) =>
                        from v in values
                        select [|(int)v|];
                }
                """,
            FixedCode = """
                using System.Collections.Generic;
                using System.Linq;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    IEnumerable<int> M(IEnumerable<Value> values) =>
                        from v in values
                        select (int)(long)v;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInParenthesizedExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => ([|(int)v|]);
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    int M(Value v) => ((int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInThrowExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                using System;
 
                class MyException : Exception
                {
                    public MyException(int code) { }
                }
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v) => throw new MyException([|(int)v|]);
                }
                """,
            FixedCode = """
                using System;
 
                class MyException : Exception
                {
                    public MyException(int code) { }
                }
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v) => throw new MyException((int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInAwaitExpression()
        => new VerifyCS.Test
        {
            TestCode = """
                using System.Threading.Tasks;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    async Task<int> M(Value v) => await Task.FromResult([|(int)v|]);
                }
                """,
            FixedCode = """
                using System.Threading.Tasks;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    async Task<int> M(Value v) => await Task.FromResult((int)(long)v);
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInNestedCast()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    object M(Value v) => (object)[|(int)v|];
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    object M(Value v) => (object)(int)(long)v;
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInWhileCondition()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        while ([|(int)v|] > 0) { break; }
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        while ((int)(long)v > 0) { break; }
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInIfCondition()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        if ([|(int)v|] > 0) { }
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        if ((int)(long)v > 0) { }
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInSwitchStatement()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    string M(Value v)
                    {
                        switch ([|(int)v|])
                        {
                            case 0: return "zero";
                            default: return "other";
                        }
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    string M(Value v)
                    {
                        switch ((int)(long)v)
                        {
                            case 0: return "zero";
                            default: return "other";
                        }
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInLocalFunctionReturn()
        => new VerifyCS.Test
        {
            TestCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        int Local() => [|(int)v|];
                    }
                }
                """,
            FixedCode = """
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v)
                    {
                        int Local() => (int)(long)v;
                    }
                }
                """,
        }.RunAsync();
 
    [Fact]
    public Task TestInUsingDeclaration()
        => new VerifyCS.Test
        {
            TestCode = """
                using System;
                using System.IO;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v, MemoryStream[] streams)
                    {
                        using var s = streams[[|(int)v|]];
                    }
                }
                """,
            FixedCode = """
                using System;
                using System.IO;
 
                struct Value
                {
                    public static explicit operator long(Value v) => 100L;
                }
 
                class C
                {
                    void M(Value v, MemoryStream[] streams)
                    {
                        using var s = streams[(int)(long)v];
                    }
                }
                """,
        }.RunAsync();
}