File: Semantics\InterceptorsTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Semantic\Microsoft.CodeAnalysis.CSharp.Semantic.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Semantic.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.
 
#pragma warning disable RSEXPERIMENTAL002 // Tests for experimental API
 
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Reflection.Metadata;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Semantics;
 
public class InterceptorsTests : CSharpTestBase
{
    private static readonly (string text, string path) s_attributesSource = ("""
        namespace System.Runtime.CompilerServices;
 
        [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
        public sealed class InterceptsLocationAttribute : Attribute
        {
            public InterceptsLocationAttribute(string filePath, int line, int character) { }
            public InterceptsLocationAttribute(int version, string data) { }
        }
        """, "attributes.cs");
 
    private static readonly CSharpParseOptions RegularWithInterceptors = TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global");
 
    private static readonly SyntaxTree s_attributesTree = CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors);
 
    [Fact]
    public void FeatureFlag()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M() => Console.Write(1);
            }
            """;
 
        var sadCaseDiagnostics = new[]
        {
            // Program.cs(13,6): error CS9206: An interceptor cannot be declared in the global namespace.
            //     [InterceptsLocation("Program.cs", 4, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorGlobalNamespace, @"InterceptsLocation(""Program.cs"", 4, 3)").WithLocation(13, 6)
        };
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource });
        comp.VerifyEmitDiagnostics(sadCaseDiagnostics);
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreview-experimental"));
        comp.VerifyEmitDiagnostics(sadCaseDiagnostics);
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreview", "false"));
        comp.VerifyEmitDiagnostics(sadCaseDiagnostics);
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("interceptorspreview"));
        comp.VerifyEmitDiagnostics(sadCaseDiagnostics);
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreview", "Global"));
        comp.VerifyEmitDiagnostics(sadCaseDiagnostics);
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsPreview", "global.a"));
        comp.VerifyEmitDiagnostics(sadCaseDiagnostics);
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void FeatureFlag_Granular_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            namespace NS1
            {
                class D
                {
                    [InterceptsLocation("Program.cs", 4, 3)]
                    public static void M() => Console.Write(1);
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS"));
        comp.VerifyEmitDiagnostics(
            // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>' to your project.
            //         [InterceptsLocation("Program.cs", 4, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>").WithLocation(15, 10));
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1.NS2"));
        comp.VerifyEmitDiagnostics(
            // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>' to your project.
            //         [InterceptsLocation("Program.cs", 4, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>").WithLocation(15, 10));
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1"), expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1;NS2"), expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void FeatureFlag_Granular_Checksum_01()
    {
        test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS"), expectedOutput: null,
            // Interceptors.cs(7,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>' to your project.
            //         [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "eY+urAo7Kg2rsKgGSGjShwIAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>").WithLocation(7, 10));
 
        test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1.NS2"), expectedOutput: null,
            // Interceptors.cs(7,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>' to your project.
            //         [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "eY+urAo7Kg2rsKgGSGjShwIAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1</InterceptorsNamespaces>").WithLocation(7, 10));
 
        test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1"), expectedOutput: "1");
 
        test(TestOptions.Regular.WithFeature("InterceptorsNamespaces", "NS1;NS2"), expectedOutput: "1");
 
        void test(CSharpParseOptions options, string? expectedOutput, params DiagnosticDescription[] expected)
        {
            var source = CSharpTestSource.Parse("""
                C.M();
 
                class C
                {
                    public static void M() => throw null!;
                }
                """, path: "Program.cs", options);
 
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics();
 
            var model = comp.GetSemanticModel(source);
            var invocation = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
            var interceptableLocation = model.GetInterceptableLocation(invocation)!;
 
            var interceptors = CSharpTestSource.Parse($$"""
                using System;
 
                namespace NS1
                {
                    class D
                    {
                        {{interceptableLocation.GetInterceptsLocationAttributeSyntax()}}
                        public static void M() => Console.Write(1);
                    }
                }
                """, path: "Interceptors.cs", options);
            var attributesTree = CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, options: options);
 
            comp = CreateCompilation([source, interceptors, attributesTree]);
 
            if (expectedOutput == null)
            {
                comp.VerifyEmitDiagnostics(expected);
            }
            else
            {
                CompileAndVerify(comp, expectedOutput: expectedOutput)
                    .VerifyDiagnostics(expected);
            }
        }
    }
 
    [Fact]
    public void FeatureFlag_Granular_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            namespace NS1.NS2
            {
                class D
                {
                    [InterceptsLocation("Program.cs", 4, 3)]
                    public static void M() => Console.Write(1);
                }
            }
            """;
 
        sadCase("NS2");
        sadCase("true");
        sadCase(" NS1");
        sadCase(";");
        sadCase(";;");
        sadCase("");
        sadCase("NS1 ;");
        sadCase("NS1..NS2;");
        sadCase("ns1");
        sadCase("NS2.NS1");
        sadCase("$NS1&");
 
        happyCase("NS1");
        happyCase("NS1;");
        happyCase(";NS1");
        happyCase("NS1.NS2");
        happyCase("NS2;NS1.NS2");
        happyCase("NS2;;NS1.NS2");
 
        void sadCase(string featureValue)
        {
            var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", featureValue));
            comp.VerifyEmitDiagnostics(
                // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1.NS2</InterceptorsNamespaces>' to your project.
                //         [InterceptsLocation("Program.cs", 4, 3)]
                Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NS1.NS2</InterceptorsNamespaces>").WithLocation(15, 10));
        }
 
        void happyCase(string featureValue)
        {
            var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", featureValue), expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
    }
 
    [Fact]
    public void FeatureFlag_Granular_03()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M() => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", ""));
        comp.VerifyEmitDiagnostics(
            // Program.cs(13,6): error CS9206: An interceptor cannot be declared in the global namespace.
            //     [InterceptsLocation("Program.cs", 4, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorGlobalNamespace, @"InterceptsLocation(""Program.cs"", 4, 3)").WithLocation(13, 6));
    }
 
    [Fact]
    public void FeatureFlag_Granular_04()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            namespace global
            {
                class D
                {
                    [InterceptsLocation("Program.cs", 4, 3)]
                    public static void M() => Console.Write(1);
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global"), expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global"), expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void FeatureFlag_Granular_05()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            namespace global.B
            {
                class D
                {
                    [InterceptsLocation("Program.cs", 4, 3)]
                    public static void M() => Console.Write(1);
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "global.A"));
        comp.VerifyEmitDiagnostics(
            // Program.cs(15,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);global.B</InterceptorsNamespaces>' to your project.
            //         [InterceptsLocation("Program.cs", 4, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);global.B</InterceptorsNamespaces>").WithLocation(15, 10));
    }
 
    [Fact]
    public void SelfInterception()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void Main()
                {
                    InterceptableMethod();
                }
 
 
                [InterceptsLocation("Program.cs", 8, 9)]
                public static void InterceptableMethod() { Console.Write(1); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void StaticInterceptable_StaticInterceptor_NoParameters()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod() { Console.Write("interceptable"); }
 
                public static void Main()
                {
                    InterceptableMethod();
                }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 11, 9)]
                public static void Interceptor1() { Console.Write("interceptor 1"); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor 1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void Accessibility_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod() { Console.Write("interceptable"); }
 
                public static void Main()
                {
                    InterceptableMethod();
                }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 11, 9)]
                private static void Interceptor1() { Console.Write("interceptor 1"); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
                // Program.cs(17,6): error CS9155: Cannot intercept because 'D.Interceptor1()' is not accessible within 'C.Main()'.
                //     [InterceptsLocation("Program.cs", 11, 9)]
                Diagnostic(ErrorCode.ERR_InterceptorNotAccessible, @"InterceptsLocation(""Program.cs"", 11, 9)").WithArguments("D.Interceptor1()", "C.Main()").WithLocation(17, 6));
    }
 
    [Fact]
    public void Accessibility_02()
    {
        // An interceptor declared within a file-local type can intercept a call even if the call site can't normally refer to the file-local type.
        var source1 = """
            using System;
 
            class C
            {
 
                public static void InterceptableMethod() { Console.Write("interceptable"); }
 
                public static void Main()
                {
                    InterceptableMethod();
                }
            }
            """;
 
        var source2 = """
            using System.Runtime.CompilerServices;
            using System;
 
            file class D
            {
                [InterceptsLocation("Program.cs", 10, 9)]
                public static void Interceptor1() { Console.Write("interceptor 1"); }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "Program.cs"), (source2, "Other.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor 1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void FileLocalAttributeDefinitions_01()
    {
        // Treat a file-local declaration of InterceptsLocationAttribute as a well-known attribute within the declaring compilation.
        var source = """
            using System;
            using System.Runtime.CompilerServices;
 
            C.M();
 
            class C
            {
                public static void M() => throw null!;
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M()
                {
                    Console.Write(1);
                }
            }
 
            namespace System.Runtime.CompilerServices
            {
                file class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character) { }
                }
            }
            """;
 
        var verifier = CompileAndVerify((source, "Program.cs"), parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    /// <summary>
    /// File-local InterceptsLocationAttribute from another compilation is not considered to *duplicate* an interception, even if it is inherited.
    /// See also <see cref="DuplicateLocation_03"/>.
    /// </summary>
    [Fact]
    public void FileLocalAttributeDefinitions_02()
    {
        var source1 = """
            using System.Runtime.CompilerServices;
            using System;
 
            var c = new C();
            c.M();
 
            public class C
            {
                public void M() => Console.Write(1);
 
                [InterceptsLocation("Program.cs", 5, 3)]
                public virtual void Interceptor() => throw null!;
            }
 
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
                file sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character)
                    {
                    }
                }
            }
            """;
 
        // Inherited attribute on 'override void Interceptor' from other compilation doesn't cause a call in this compilation to be intercepted.
        var source2 = """
 
 
            // leading blank lines for alignment with the call in the other compilation.
            var d = new D();
            d.M();
 
            class D : C
            {
                public override void Interceptor() => throw null!;
            }
            """;
 
        var comp1 = CreateCompilation((source1, "Program.cs"), parseOptions: RegularWithInterceptors);
        comp1.VerifyEmitDiagnostics();
 
        var comp2Verifier = CompileAndVerify((source2, "Program.cs"), references: new[] { comp1.ToMetadataReference() }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        comp2Verifier.VerifyDiagnostics();
 
        comp2Verifier = CompileAndVerify((source2, "Program.cs"), references: new[] { comp1.EmitToImageReference() }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        comp2Verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableExtensionMethod_InterceptorExtensionMethod()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableExtensionMethod_InterceptorExtensionMethod_NormalForm()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    InterceptableMethod(c, "call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 9)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableInstanceMethod_InterceptorExtensionMethod()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static C Interceptor1(this C i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableInstanceMethod_InterceptorStaticMethod()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static C Interceptor1(C i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9144: Cannot intercept method 'C.InterceptableMethod(string)' with interceptor 'D.Interceptor1(C, string)' because the signatures do not match.
            //     [InterceptsLocation("Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("C.InterceptableMethod(string)", "D.Interceptor1(C, string)").WithLocation(21, 6)
            );
    }
 
    [Fact]
    public void InterceptsLocationDuplicatePath()
    {
        var source0 = ("""
            public class D0
            {
                public static void M()
                {
                    C.InterceptableMethod("a");
                }
            }
            """, "Program.cs");
 
        var source1 = ("""
            public class D1
            {
                public static void M()
                {
                    C.InterceptableMethod("a");
                }
            }
            """, "Program.cs");
 
        var source2 = ("""
            using System.Runtime.CompilerServices;
            using System;
 
            D0.M();
            D1.M();
 
            public class C
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
            }
 
            public static class Interceptor
            {
                [InterceptsLocation("Program.cs", 5, 11)]
                public static void Interceptor1(string param) { Console.Write("interceptor " + param); }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source0, source1, source2, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(15,25): error CS9152: Cannot intercept a call in file with path 'Program.cs' because multiple files in the compilation have this path.
            //     [InterceptsLocation("Program.cs", 5, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorNonUniquePath, @"""Program.cs""").WithArguments("Program.cs").WithLocation(15, 25));
    }
 
    [Fact]
    public void DuplicateLocation_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            C.M();
 
            class C
            {
 
                public static void M() { }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 3, 3)]
                public static void M1() { }
 
                [InterceptsLocation("Program.cs", 3, 3)]
                public static void M2() { }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(13,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 3, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 3, 3)").WithLocation(13, 6),
            // Program.cs(16,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 3, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 3, 3)").WithLocation(16, 6));
    }
 
    [Fact]
    public void DuplicateLocation_02()
    {
        var source0 = """
            using System.Runtime.CompilerServices;
 
            C.M();
 
            class C
            {
 
                public static void M() { }
            }
            """;
 
        var source1 = """
            using System.Runtime.CompilerServices;
 
            class D1
            {
                [InterceptsLocation("Program.cs", 3, 3)]
                public static void M1() { }
            }
            """;
 
        var source2 = """
            using System.Runtime.CompilerServices;
 
            class D2
            {
                [InterceptsLocation("Program.cs", 3, 3)]
                public static void M1() { }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source0, "Program.cs"), (source1, "File1.cs"), (source2, "File2.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // File2.cs(5,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 3, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 3, 3)").WithLocation(5, 6),
            // File1.cs(5,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 3, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 3, 3)").WithLocation(5, 6)
            );
    }
 
    [Fact]
    public void DuplicateLocation_03()
    {
        // InterceptsLocationAttribute is not considered to *duplicate* an interception, even if it is inherited.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            var d = new D();
            d.M();
 
            class C
            {
 
                public void M() => throw null!;
 
                [InterceptsLocation("Program.cs", 5, 3)]
                public virtual void Interceptor() => throw null!;
            }
 
            class D : C
            {
                public override void Interceptor() => Console.Write(1);
            }
 
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Method)]
                public sealed class InterceptableAttribute : Attribute { }
 
                [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character)
                    {
                    }
                }
            }
            """;
 
        var verifier = CompileAndVerify((source, "Program.cs"), parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void DuplicateLocation_04()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            C.M();
 
            class C
            {
 
                public static void M() { }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 3, 3)]
                [InterceptsLocation("Program.cs", 3, 3)]
                public static void M1() { }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(13,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 3, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 3, 3)").WithLocation(13, 6),
            // Program.cs(14,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 3, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 3, 3)").WithLocation(14, 6));
    }
 
    [Fact]
    public void InterceptorVirtual_01()
    {
        // Intercept a method call with a call to a virtual method on the same type.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            c = new D();
            c.M();
 
            class C
            {
 
                public void M() => throw null!;
 
                [InterceptsLocation("Program.cs", 5, 3)]
                [InterceptsLocation("Program.cs", 8, 3)]
                public virtual void Interceptor() => Console.Write("C");
            }
 
            class D : C
            {
                public override void Interceptor() => Console.Write("D");
            }
 
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Method)]
                public sealed class InterceptableAttribute : Attribute { }
 
                [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character)
                    {
                    }
                }
            }
            """;
 
        var verifier = CompileAndVerify((source, "Program.cs"), parseOptions: RegularWithInterceptors, expectedOutput: "CD");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptorVirtual_02()
    {
        // Intercept a call with a virtual method call on the base type.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D d = new D();
            d.M();
 
            class C
            {
                [InterceptsLocation("Program.cs", 5, 3)]
                public virtual void Interceptor() => throw null!;
            }
 
            class D : C
            {
 
                public void M() => throw null!;
 
                public override void Interceptor() => throw null!;
            }
 
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Method)]
                public sealed class InterceptableAttribute : Attribute { }
 
                [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character)
                    {
                    }
                }
            }
            """;
 
        var comp = CreateCompilation((source, "Program.cs"), parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(9,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'D this' on 'D.M()'.
            //     [InterceptsLocation("Program.cs", 5, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 5, 3)").WithArguments("D this", "D.M()").WithLocation(9, 6));
    }
 
    [Fact]
    public void InterceptorOverride_01()
    {
        // Intercept a call with a call to an override method on a derived type.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D d = new D();
            d.M();
 
            class C
            {
 
                public void M() => throw null!;
 
                public virtual void Interceptor() => throw null!;
            }
 
            class D : C
            {
                [InterceptsLocation("Program.cs", 5, 3)] // 1
                public override void Interceptor() => throw null!;
            }
 
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Method)]
                public sealed class InterceptableAttribute : Attribute { }
 
                [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character)
                    {
                    }
                }
            }
            """;
 
        var comp = CreateCompilation((source, "Program.cs"), parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(17,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'C this' on 'C.M()'.
            //     [InterceptsLocation("Program.cs", 5, 3)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 5, 3)").WithArguments("C this", "C.M()").WithLocation(17, 6));
    }
 
    [Fact]
    public void InterceptorOverride_02()
    {
        // Intercept a call with an override method on the same type.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D d = new D();
            d.M();
 
            class C
            {
                public virtual void Interceptor() => throw null!;
            }
 
            class D : C
            {
 
                public void M() => throw null!;
 
                [InterceptsLocation("Program.cs", 5, 3)]
                public override void Interceptor() => Console.Write(1);
            }
 
            namespace System.Runtime.CompilerServices
            {
                [AttributeUsage(AttributeTargets.Method)]
                public sealed class InterceptableAttribute : Attribute { }
 
                [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int character)
                    {
                    }
                }
            }
            """;
 
        var verifier = CompileAndVerify((source, "Program.cs"), parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void EmitMetadataOnly_01()
    {
        // We can emit a ref assembly even though there are duplicate interceptions.
        var source = """
            using System.Runtime.CompilerServices;
 
            class C
            {
                public static void Main()
                {
                    C.M();
                }
 
 
                public static void M() { }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 7, 11)]
                public static void M1() { }
 
                [InterceptsLocation("Program.cs", 7, 11)]
                public static void M2() { }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, emitOptions: EmitOptions.Default.WithEmitMetadataOnly(true));
        verifier.VerifyDiagnostics();
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(16,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 7, 11)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 7, 11)").WithLocation(16, 6),
            // Program.cs(19,6): error CS9153: The indicated call is intercepted multiple times.
            //     [InterceptsLocation("Program.cs", 7, 11)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 7, 11)").WithLocation(19, 6));
    }
 
    [Fact]
    public void EmitMetadataOnly_02()
    {
        // We can't emit a ref assembly when a problem is found with an InterceptsLocationAttribute in the declaration phase.
        // Strictly, we should perhaps allow this emit anyway, but it doesn't feel urgent to do so.
        var source = """
            using System.Runtime.CompilerServices;
 
            C.M();
 
            class C
            {
 
                public static void M() { }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 3, 4)]
                public static void M1() { }
 
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(EmitOptions.Default.WithEmitMetadataOnly(true),
            // Program.cs(13,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '('.
            //     [InterceptsLocation("Program.cs", 3, 4)]
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 3, 4)").WithArguments("(").WithLocation(13, 6));
    }
 
    [Fact]
    public void InterceptsLocationFromMetadata()
    {
        // Verify that `[InterceptsLocation]` on a method from metadata does not cause a call in the current compilation to be intercepted.
        var source0 = """
            using System.Runtime.CompilerServices;
            using System;
 
            public class C0
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
 
                static void M0()
                {
                    InterceptableMethod("1");
                }
            }
 
            public static class D
            {
                [InterceptsLocation("Program.cs", 11, 9)]
                public static void Interceptor1(string param) { Console.Write("interceptor " + param); }
            }
            """;
        var comp0 = CreateCompilation(new[] { (source0, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp0.VerifyEmitDiagnostics();
 
        var source1 = """
 
            using System;
 
            class C1
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
 
                static void Main()
                {
                    InterceptableMethod("1");
                }
            }
            """;
 
        var comp1 = CompileAndVerify(new[] { (source1, "Program.cs") }, new[] { comp0.ToMetadataReference() }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptable 1");
        comp1.VerifyDiagnostics();
 
        comp1 = CompileAndVerify(new[] { (source1, "Program.cs") }, new[] { comp0.EmitToImageReference() }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptable 1");
        comp1.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableDelegateConversion()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    var del = c.InterceptableMethod;
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 21)]
                public static C Interceptor1(this C i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var compilation = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        compilation.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9151: Possible method name 'InterceptableMethod' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 15, 21)]
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 15, 21)").WithArguments("InterceptableMethod").WithLocation(21, 6)
            );
    }
 
    [Fact]
    public void InterceptableNameof()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            static class Program
            {
                public static void Main()
                {
                    _ = nameof(Main);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 7, 13)]
                public static void Interceptor1(object param) { }
            }
            """;
        var compilation = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        compilation.VerifyEmitDiagnostics(
            // Program.cs(7,13): error CS9160: A nameof operator cannot be intercepted.
            //         _ = nameof(Main);
            Diagnostic(ErrorCode.ERR_InterceptorCannotInterceptNameof, "nameof").WithLocation(7, 13)
            );
    }
 
    [Fact]
    public void InterceptableNameof_MethodCall()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Program
            {
                public static void Main()
                {
                    _ = nameof(F);
                }
 
                private static object F = 1;
 
 
                public static string nameof(object param) => throw null!;
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 8, 13)]
                public static string Interceptor1(object param)
                {
                    Console.Write(1);
                    return param.ToString();
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableDoubleUnderscoreReservedIdentifiers()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Program
            {
                public static void Main()
                {
                    M1(__arglist(1, 2, 3));
 
                    int i = 0;
                    TypedReference tr = __makeref(i);
                    ref int ri = ref __refvalue(tr, int);
                    Type t = __reftype(tr);
                }
 
                static void M1(__arglist) { }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 8, 12)] // __arglist
                [InterceptsLocation("Program.cs", 11, 29)] // __makeref
                [InterceptsLocation("Program.cs", 12, 26)] // __refvalue
                [InterceptsLocation("Program.cs", 13, 18)] // __reftype
                public static void Interceptor1(int x, int y, int z) { }
            }
            """;
        var compilation = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        compilation.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '__arglist'.
            //     [InterceptsLocation("Program.cs", 8, 12)] // __arglist
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 8, 12)").WithArguments("__arglist").WithLocation(21, 6),
            // Program.cs(22,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '__makeref'.
            //     [InterceptsLocation("Program.cs", 11, 29)] // __makeref
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 11, 29)").WithArguments("__makeref").WithLocation(22, 6),
            // Program.cs(23,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '__refvalue'.
            //     [InterceptsLocation("Program.cs", 12, 26)] // __refvalue
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 12, 26)").WithArguments("__refvalue").WithLocation(23, 6),
            // Program.cs(24,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '__reftype'.
            //     [InterceptsLocation("Program.cs", 13, 18)] // __reftype
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 13, 18)").WithArguments("__reftype").WithLocation(24, 6)
            );
    }
 
    [Fact]
    public void InterceptableDelegateInvocation_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M(() => Console.Write(1));
            C.M1((() => Console.Write(1), 0));
 
            static class C
            {
                public static void M(Action action)
                {
                    action();
                }
 
                public static void M1((Action action, int) pair)
                {
                    pair.action();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 11, 9)]
                [InterceptsLocation("Program.cs", 16, 14)]
                public static void Interceptor1(this Action action) { action(); Console.Write(2); }
            }
            """;
        var compilation = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        compilation.VerifyEmitDiagnostics(
            // Program.cs(22,6): error CS9207: Cannot intercept 'action' because it is not an invocation of an ordinary member method.
            //     [InterceptsLocation("Program.cs", 11, 9)]
            Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 11, 9)").WithArguments("action").WithLocation(22, 6),
            // Program.cs(23,6): error CS9207: Cannot intercept 'action' because it is not an invocation of an ordinary member method.
            //     [InterceptsLocation("Program.cs", 16, 14)]
            Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 16, 14)").WithArguments("action").WithLocation(23, 6));
    }
 
    [Fact]
    public void InterceptableDelegateInvocation_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M(() => Console.Write(1));
            C.M1((() => Console.Write(1), 0));
 
            static class C
            {
                public static void M(Action action)
                {
                    action!();
                }
 
                public static void M1((Action action, int) pair)
                {
                    pair.action!();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 11, 9)]
                [InterceptsLocation("Program.cs", 16, 14)]
                public static void Interceptor1(this Action action) { action(); Console.Write(2); }
            }
            """;
        var compilation = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        compilation.VerifyEmitDiagnostics(
            // Program.cs(22,6): error CS9151: Possible method name 'action' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 11, 9)]
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 11, 9)").WithArguments("action").WithLocation(22, 6),
            // Program.cs(23,6): error CS9151: Possible method name 'action' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 16, 14)]
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 16, 14)").WithArguments("action").WithLocation(23, 6));
    }
 
    [Fact]
    public void QualifiedNameAtCallSite()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static C InterceptableMethod(C c, string param) { Console.Write("interceptable " + param); return c; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    C.InterceptableMethod(c, "call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static C Interceptor1(C c, string param) { Console.Write("interceptor " + param); return c; }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableStaticMethod_InterceptorExtensionMethod()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static C InterceptableMethod(C c, string param) { Console.Write("interceptable " + param); return c; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    C.InterceptableMethod(c, "call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableExtensionMethod_InterceptorStaticMethod()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            var c = new C();
            c.InterceptableMethod();
 
            class C { }
 
            static class D
            {
 
                public static void InterceptableMethod(this C c) => throw null!;
 
                [InterceptsLocation("Program.cs", 5, 3)]
                public static void Interceptor1(C c) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(14,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'C c' on 'D.InterceptableMethod(C)'.
            //     [InterceptsLocation("Program.cs", 5, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 5, 3)").WithArguments("C c", "D.InterceptableMethod(C)").WithLocation(14, 6));
    }
 
    [Fact]
    public void InterceptableExtensionMethod_InterceptorStaticMethod_NormalForm()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            var c = new C();
            D.InterceptableMethod(c);
 
            class C { }
 
            static class D
            {
 
                public static void InterceptableMethod(this C c) => throw null!;
 
                [InterceptsLocation("Program.cs", 5, 3)]
                public static void Interceptor1(C c) => Console.Write(1);
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableStaticMethod_InterceptorInstanceMethod()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod("call site");
                }
            }
 
            class C
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
 
                [InterceptsLocation("Program.cs", 8, 11)]
                public void Interceptor1(string param) { Console.Write("interceptor " + param); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(17,6): error CS9149: Interceptor must not have a 'this' parameter because 'C.InterceptableMethod(string)' does not have a 'this' parameter.
            //     [InterceptsLocation("Program.cs", 8, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorMustNotHaveThisParameter, @"InterceptsLocation(""Program.cs"", 8, 11)").WithArguments("C.InterceptableMethod(string)").WithLocation(17, 6));
    }
 
    [Fact]
    public void ArgumentLabels()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public void InterceptableMethod(string s1, string s2) { Console.Write(s1 + s2); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod(s2: "World", s1: "Hello ");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor1(this C c, string s1, string s2) { Console.Write("interceptor " + s1 + s2); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor Hello World");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ParameterNameDifference()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public void InterceptableMethod(string s1) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod(s1: "1");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor1(this C c, string s2) { Console.Write(s2); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ParameterNamesInDifferentOrder()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public void InterceptableMethod(string s1, string s2) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("1", "2");
                    c.InterceptableMethod(s2: "4", s1: "3");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                [InterceptsLocation("Program.cs", 16, 11)]
                public static void Interceptor1(this C c, string s2, string s1) { Console.Write(s2); Console.Write(s1); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1234");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void AttributeArgumentLabels_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public void InterceptableMethod() => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", character: 11, line: 15)]
                public static void Interceptor1(this C c) { Console.Write(1); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void AttributeArgumentLabels_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            class C
            {
 
                public void InterceptableMethod() => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", character: 1, line: 50)] // 1
                public static void Interceptor1(this C c) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyDiagnostics(
            // Program.cs(20,53): error CS9142: The given file has '22' lines, which is fewer than the provided line number '50'.
            //     [InterceptsLocation("Program.cs", character: 1, line: 50)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorLineOutOfRange, "line: 50").WithArguments("22", "50").WithLocation(20, 53)
            );
    }
 
    [Fact]
    public void InterceptableExtensionMethod_InterceptorExtensionMethod_Sequence()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site")
                        .InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call siteinterceptable call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableFromMetadata()
    {
        var source1 = """
 
            using System;
 
            public class C
            {
 
                public C InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; }
            }
            """;
 
        var source2 = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 9, 11)]
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
            """;
 
        var comp1 = CreateCompilation(new[] { (source1, "File1.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp1.VerifyEmitDiagnostics();
 
        var verifier = CompileAndVerify((source2, "Program.cs"), references: new[] { comp1.ToMetadataReference() }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor call site");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptsLocation_BadMethodKind()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            static class Program
            {
 
                public static void InterceptableMethod(string param) { }
 
                public static void Main()
                {
                    InterceptableMethod("");
                    Interceptor1("");
 
                    var lambda = [InterceptsLocation("Program.cs", 13, 8)] (string param) => { }; // 1
 
                    [InterceptsLocation("Program.cs", 13, 8)] // 2
                    static void Interceptor1(string param) { }
                }
 
                public static string Prop
                {
                    [InterceptsLocation("Program.cs", 13, 8)] // 3
                    set { }
                }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyDiagnostics(
            // Program.cs(13,23): error CS9146: An interceptor method must be an ordinary member method.
            //         var lambda = [InterceptsLocation("Program.cs", 13, 8)] (string param) => { }; // 1
            Diagnostic(ErrorCode.ERR_InterceptorMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 13, 8)").WithLocation(13, 23),
            // Program.cs(15,10): error CS9146: An interceptor method must be an ordinary member method.
            //         [InterceptsLocation("Program.cs", 13, 8)] // 2
            Diagnostic(ErrorCode.ERR_InterceptorMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 13, 8)").WithLocation(15, 10),
            // Program.cs(21,10): error CS9146: An interceptor method must be an ordinary member method.
            //         [InterceptsLocation("Program.cs", 13, 8)] // 3
            Diagnostic(ErrorCode.ERR_InterceptorMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 13, 8)").WithLocation(21, 10)
            );
    }
 
    [Fact]
    public void InterceptsLocation_BadMethodKind_Checksum()
    {
        var source = CSharpTestSource.Parse("""
            class Program
            {
                public static void InterceptableMethod(string param) { }
 
                public static void Main()
                {
                    InterceptableMethod("");
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var invocation = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var model = comp.GetSemanticModel(source);
        var location = model.GetInterceptableLocation(invocation)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System.Runtime.CompilerServices;
 
            class C
            {
                static void M()
                {
                    Interceptor1("");
                    var lambda = [InterceptsLocation({{location.Version}}, "{{location.Data}}")] (string param) => { }; // 1
 
                    [InterceptsLocation({{location.Version}}, "{{location.Data}}")] // 2
                    static void Interceptor1(string param) { }
                }
 
                public static string Prop
                {
                    [InterceptsLocation({{location.Version}}, "{{location.Data}}")] // 3
                    set { }
                }
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, s_attributesTree]);
        comp.VerifyDiagnostics(
            // Interceptors.cs(8,23): error CS9146: An interceptor method must be an ordinary member method.
            //         var lambda = [InterceptsLocation(1, "OjpNlan67EMibFykRLWBLXgAAABQcm9ncmFtLmNz")] (string param) => { }; // 1
            Diagnostic(ErrorCode.ERR_InterceptorMethodMustBeOrdinary, "InterceptsLocation").WithLocation(8, 23),
            // Interceptors.cs(10,10): error CS9146: An interceptor method must be an ordinary member method.
            //         [InterceptsLocation(1, "OjpNlan67EMibFykRLWBLXgAAABQcm9ncmFtLmNz")] // 2
            Diagnostic(ErrorCode.ERR_InterceptorMethodMustBeOrdinary, "InterceptsLocation").WithLocation(10, 10),
            // Interceptors.cs(16,10): error CS9146: An interceptor method must be an ordinary member method.
            //         [InterceptsLocation(1, "OjpNlan67EMibFykRLWBLXgAAABQcm9ncmFtLmNz")] // 3
            Diagnostic(ErrorCode.ERR_InterceptorMethodMustBeOrdinary, "InterceptsLocation").WithLocation(16, 10)
            );
    }
 
    [Fact]
    public void InterceptableMethod_BadMethodKind_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            class Program
            {
                public static unsafe void Main()
                {
                    // property
                    _ = Prop;
 
                    // constructor
                    new Program();
                }
 
                public static int Prop { get; }
 
                [InterceptsLocation("Program.cs", 8, 13)] // 1
                [InterceptsLocation("Program.cs", 11, 9)] // 2, 'new'
                [InterceptsLocation("Program.cs", 11, 13)] // 3, 'Program'
                static void Interceptor1() { }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, options: TestOptions.UnsafeDebugExe);
        comp.VerifyDiagnostics(
            // Program.cs(16,6): error CS9151: Possible method name 'Prop' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 8, 13)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 8, 13)").WithArguments("Prop").WithLocation(16, 6),
            // Program.cs(17,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token 'new'.
            //     [InterceptsLocation("Program.cs", 11, 9)] // 2, 'new'
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 11, 9)").WithArguments("new").WithLocation(17, 6),
            // Program.cs(18,6): error CS9151: Possible method name 'Program' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 11, 13)] // 3, 'Program'
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 11, 13)").WithArguments("Program").WithLocation(18, 6)
            );
    }
 
    [Fact]
    public void InterceptableMethod_BadMethodKind_Checksum_01()
    {
        var source = CSharpTestSource.Parse("""
            class Program
            {
                public static void Main()
                {
                    // property
                    _ = Prop; // 1 ('Prop')
 
                    // constructor
                    new Program(); // 2 ('new'), 3 ('Program')
                }
 
                public static int Prop { get; }
            }
            """, "Program.cs", options: RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = (CSharpSemanticModel)comp.GetSemanticModel(source);
        var root = source.GetRoot();
 
        var node1 = root.DescendantNodes().First(node => node is IdentifierNameSyntax name && name.Identifier.Text == "Prop");
        var location1 = model.GetInterceptableLocationInternal(node1, cancellationToken: default);
 
        var node2 = root.DescendantNodes().Single(node => node is ObjectCreationExpressionSyntax);
        var location2 = model.GetInterceptableLocationInternal(node2, cancellationToken: default);
 
        var node3 = root.DescendantNodes().Last(node => node is IdentifierNameSyntax name && name.Identifier.Text == "Program");
        var location3 = model.GetInterceptableLocationInternal(node3, cancellationToken: default);
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System.Runtime.CompilerServices;
 
            class C
            {
                [InterceptsLocation({{location1.Version}}, "{{location1.Data}}")] // 1
                [InterceptsLocation({{location2.Version}}, "{{location2.Data}}")] // 2
                [InterceptsLocation({{location3.Version}}, "{{location3.Data}}")] // 3
                static void Interceptor1() { }
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, s_attributesTree]);
        comp.VerifyDiagnostics(
            // Interceptors.cs(5,6): error CS9151: Possible method name 'Prop' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation(1, "hD44wQkJk1har7RM7oznpFkAAABQcm9ncmFtLmNz")] // 1
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, "InterceptsLocation").WithArguments("Prop").WithLocation(5, 6),
            // Interceptors.cs(6,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token 'new'.
            //     [InterceptsLocation(1, "hD44wQkJk1har7RM7oznpG4AAABQcm9ncmFtLmNz")] // 2
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, "InterceptsLocation").WithArguments("new").WithLocation(6, 6),
            // Interceptors.cs(7,6): error CS9151: Possible method name 'Program' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation(1, "hD44wQkJk1har7RM7oznpJQAAABQcm9ncmFtLmNz")] // 3
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, "InterceptsLocation").WithArguments("Program").WithLocation(7, 6)
            );
    }
 
    [Fact]
    public void InterceptableMethod_BadMethodKind_02()
    {
        var source = """
            using System;
            using System.Runtime.CompilerServices;
 
            class Program
            {
                public static unsafe void Main()
                {
                    // delegate
                    Action a = () => throw null!;
                    a();
 
                    // local function
                    void local() => throw null!;
                    local();
 
                    // fnptr invoke
                    delegate*<void> fnptr = &Interceptor1;
                    fnptr();
                }
 
                public static int Prop { get; }
 
                [InterceptsLocation("Program.cs", 10, 9)] // 1
                [InterceptsLocation("Program.cs", 14, 9)] // 2
                [InterceptsLocation("Program.cs", 18, 9)] // 3
                static void Interceptor1() { }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, options: TestOptions.UnsafeDebugExe);
        comp.VerifyEmitDiagnostics(
            // Program.cs(23,6): error CS9207: Cannot intercept 'a' because it is not an invocation of an ordinary member method.
            //     [InterceptsLocation("Program.cs", 10, 9)] // 1
            Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 10, 9)").WithArguments("a").WithLocation(23, 6),
            // Program.cs(24,6): error CS9207: Cannot intercept 'local' because it is not an invocation of an ordinary member method.
            //     [InterceptsLocation("Program.cs", 14, 9)] // 2
            Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 14, 9)").WithArguments("local").WithLocation(24, 6),
            // Program.cs(25,6): error CS9207: Cannot intercept 'fnptr' because it is not an invocation of an ordinary member method.
            //     [InterceptsLocation("Program.cs", 18, 9)] // 3
            Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, @"InterceptsLocation(""Program.cs"", 18, 9)").WithArguments("fnptr").WithLocation(25, 6)
            );
    }
 
    [Fact]
    public void InterceptorCannotBeGeneric_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1
            {
 
                public I1 InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 16, 11)]
                public static I1 Interceptor1<T>(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(22,6): error CS9138: Method 'D.Interceptor1<T>(I1, string)' must be non-generic to match 'C.InterceptableMethod(string)'.
            //     [InterceptsLocation("Program.cs", 16, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorCannotBeGeneric, @"InterceptsLocation(""Program.cs"", 16, 11)").WithArguments("D.Interceptor1<T>(I1, string)", "C.InterceptableMethod(string)").WithLocation(22, 6));
    }
 
    [Fact]
    public void InterceptorCannotBeGeneric_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod("call site");
                }
            }
 
            static class D<T>
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor1(string param) { Console.Write("interceptor " + param); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9138: Method 'D<T>.Interceptor1(string)' cannot be used as an interceptor because its containing type has type parameters.
            //     [InterceptsLocation("Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorContainingTypeCannotBeGeneric, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("D<T>.Interceptor1(string)").WithLocation(21, 6));
    }
 
    [Fact]
    public void InterceptorCannotBeGeneric_Checksum_02()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            interface I1 { }
            class C : I1
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod("call site");
                }
            }
            """, "Program.cs", options: RegularWithInterceptors);
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
 
        var invocation = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var model = comp.GetSemanticModel(source);
        var location = model.GetInterceptableLocation(invocation)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            static class D<T>
            {
                {{location.GetInterceptsLocationAttributeSyntax()}}
                public static void Interceptor1(string param) { Console.Write("interceptor " + param); }
            }
            """, "Interceptors.cs", options: RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, s_attributesTree]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(5,6): error CS9138: Method 'D<T>.Interceptor1(string)' cannot be used as an interceptor because its containing type has type parameters.
            //     [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "ZCdvmiprtZ938pueLU5g6OsAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptorContainingTypeCannotBeGeneric, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("D<T>.Interceptor1(string)").WithLocation(5, 6));
    }
 
    [Fact]
    public void InterceptorCannotBeGeneric_03()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1
            {
 
                public static void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod("call site");
                }
            }
 
            static class Outer<T>
            {
                static class D
                {
                    [InterceptsLocation("Program.cs", 15, 11)]
                    public static void Interceptor1(string param) { Console.Write("interceptor " + param); }
                }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(23,10): error CS9138: Method 'Outer<T>.D.Interceptor1(string)' cannot be used as an interceptor because its containing type has type parameters.
            //         [InterceptsLocation("Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorContainingTypeCannotBeGeneric, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("Outer<T>.D.Interceptor1(string)").WithLocation(23, 10)
            );
    }
 
    [Fact]
    public void InterceptableGeneric_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod<T>(T t) { Console.Write("0"); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod<string>("1");
                    C.InterceptableMethod("2");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)]
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor1(string s) { Console.Write(s); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod<T>(T t) { Console.Write("0"); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod<string>("1");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 30)]
                [InterceptsLocation("Program.cs", 14, 31)]
                [InterceptsLocation("Program.cs", 14, 37)]
                public static void Interceptor1(string s) { Console.Write(s); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(20,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '<'.
            //     [InterceptsLocation("Program.cs", 14, 30)]
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 14, 30)").WithArguments("<").WithLocation(20, 6),
            // Program.cs(21,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token 'string'.
            //     [InterceptsLocation("Program.cs", 14, 31)]
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 14, 31)").WithArguments("string").WithLocation(21, 6),
            // Program.cs(22,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '>'.
            //     [InterceptsLocation("Program.cs", 14, 37)]
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 14, 37)").WithArguments(">").WithLocation(22, 6)
            );
    }
 
    [Fact]
    public void InterceptableGeneric_03()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod<T>(T t) where T : class => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod<string>("1");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)]
                public static void Interceptor1(string s) { Console.Write(s); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_04()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod<T1>(T1 t) => throw null!;
            }
 
            static class Program
            {
                public static void M<T2>(T2 t)
                {
                    C.InterceptableMethod(t);
                    C.InterceptableMethod<T2>(t);
                    C.InterceptableMethod<object>(t);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)] // 1
                [InterceptsLocation("Program.cs", 15, 11)] // 2
                [InterceptsLocation("Program.cs", 16, 11)]
                public static void Interceptor1(object s) { Console.Write(s); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(22,6): error CS9144: Cannot intercept method 'C.InterceptableMethod<T2>(T2)' with interceptor 'D.Interceptor1(object)' because the signatures do not match.
            //     [InterceptsLocation("Program.cs", 14, 11)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 14, 11)").WithArguments("C.InterceptableMethod<T2>(T2)", "D.Interceptor1(object)").WithLocation(22, 6),
            // Program.cs(23,6): error CS9144: Cannot intercept method 'C.InterceptableMethod<T2>(T2)' with interceptor 'D.Interceptor1(object)' because the signatures do not match.
            //     [InterceptsLocation("Program.cs", 15, 11)] // 2
            Diagnostic(ErrorCode.ERR_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("C.InterceptableMethod<T2>(T2)", "D.Interceptor1(object)").WithLocation(23, 6)
            );
    }
 
    [Fact]
    public void InterceptableGeneric_05()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.Usage(1);
            C.Usage(2);
 
            class C
            {
                public static void InterceptableMethod<T1>(T1 t) => throw null!;
 
                public static void Usage<T2>(T2 t)
                {
                    C.InterceptableMethod(t);
                    C.InterceptableMethod<T2>(t);
                    C.InterceptableMethod<object>(t);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 13, 11)]
                [InterceptsLocation("Program.cs", 14, 11)]
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor1<T>(T t) { Console.Write(t); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "111222");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_06()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void InterceptableMethod<T1>(T1 t) => throw null!;
 
                public static void Usage()
                {
                    C.InterceptableMethod("abc");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 10, 11)] // 1
                public static void Interceptor1<T>(T t) where T : struct => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(16,6): error CS0453: The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'D.Interceptor1<T>(T)'
            //     [InterceptsLocation("Program.cs", 10, 11)] // 1
            Diagnostic(ErrorCode.ERR_ValConstraintNotSatisfied, @"InterceptsLocation(""Program.cs"", 10, 11)").WithArguments("D.Interceptor1<T>(T)", "T", "string").WithLocation(16, 6));
    }
 
    [Fact]
    public void InterceptableGeneric_07()
    {
        // original containing type is generic
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D.Usage(1);
            D.Usage(2);
 
            class C<T1>
            {
                public static void InterceptableMethod(T1 t) => throw null!;
            }
 
            static class D
            {
                public static void Usage<T2>(T2 t)
                {
                    C<T2>.InterceptableMethod(t);
                    C<object>.InterceptableMethod(t);
                }
 
                [InterceptsLocation("Program.cs", 16, 15)]
                [InterceptsLocation("Program.cs", 17, 19)]
                public static void Interceptor1<T>(T t) { Console.Write(t); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1122");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_09()
    {
        // original containing type and method are generic
        // interceptor has arity 2
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D.Usage(1, "a");
            D.Usage(2, "b");
 
            class C<T1>
            {
                public static void InterceptableMethod<T2>(T1 t1, T2 t2) => throw null!;
            }
 
            static class D
            {
                public static void Usage<T1, T2>(T1 t1, T2 t2)
                {
                    C<T1>.InterceptableMethod(t1, t2);
                    C<object>.InterceptableMethod<object>(t1, t2);
                }
 
                [InterceptsLocation("Program.cs", 16, 15)]
                [InterceptsLocation("Program.cs", 17, 19)]
                public static void Interceptor1<T1, T2>(T1 t1, T2 t2)
                {
                    Console.Write(t1);
                    Console.Write(t2);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1a1a2b2b");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_10()
    {
        // original containing type and method are generic
        // interceptor has arity 1
 
        // Note: the behavior in this scenario might push us toward using a "unification" model for generic interceptors.
        // All the cases supported in our current design would also be supported by unification, so we should be able to add it later.
        var source = """
            using System.Runtime.CompilerServices;
 
            class C<T1>
            {
                public static void InterceptableMethod<T2>(T1 t1, T2 t2) => throw null!;
            }
 
            static class D
            {
                public static void Usage<T>(object obj, T t)
                {
                    C<object>.InterceptableMethod(obj, t);
                }
 
                [InterceptsLocation("Program.cs", 12, 19)] // 1
                public static void Interceptor1<T>(object obj, T t) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(15,6): error CS9177: Method 'D.Interceptor1<T>(object, T)' must be non-generic or have arity 2 to match 'C<object>.InterceptableMethod<T>(object, T)'.
            //     [InterceptsLocation("Program.cs", 12, 19)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorArityNotCompatible, @"InterceptsLocation(""Program.cs"", 12, 19)").WithArguments("D.Interceptor1<T>(object, T)", "2", "C<object>.InterceptableMethod<T>(object, T)").WithLocation(15, 6));
    }
 
    [Fact]
    public void InterceptableGeneric_11()
    {
        // original containing type and method are generic
        // interceptor has arity 0
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C<T1>
            {
                public static void InterceptableMethod<T2>(T1 t1, T2 t2) => throw null!;
            }
 
            static class D
            {
                public static void Main()
                {
                    C<int>.InterceptableMethod(1, "a");
                    C<int>.InterceptableMethod<string>(2, "b");
                }
 
                [InterceptsLocation("Program.cs", 13, 16)]
                [InterceptsLocation("Program.cs", 14, 16)]
                public static void Interceptor1(int i, string s)
                {
                    Console.Write(i);
                    Console.Write(s);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1a2b");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_12()
    {
        // original grandparent type and method are generic
        // interceptor has arity 2
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D.Usage(1, "a");
            D.Usage(2, "b");
 
            class Outer<T1>
            {
                public class C
                {
                    public static void InterceptableMethod<T2>(T1 t1, T2 t2) => throw null!;
                }
            }
 
            static class D
            {
                public static void Usage<T1, T2>(T1 t1, T2 t2)
                {
                    Outer<T1>.C.InterceptableMethod(t1, t2);
                    Outer<object>.C.InterceptableMethod<object>(t1, t2);
                }
 
                [InterceptsLocation("Program.cs", 19, 21)]
                [InterceptsLocation("Program.cs", 20, 25)]
                public static void Interceptor1<T1, T2>(T1 t1, T2 t2)
                {
                    Console.Write(t1);
                    Console.Write(t2);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1a1a2b2b");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_13()
    {
        // original grandparent type, containing type, and method are generic
        // interceptor has arity 3
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D.Usage(1, 2, 3);
            D.Usage(4, 5, 6);
 
            class Outer<T1>
            {
                public class C<T2>
                {
                    public static void InterceptableMethod<T3>(T1 t1, T2 t2, T3 t3) => throw null!;
                }
            }
 
            static class D
            {
                public static void Usage<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
                {
                    Outer<T1>.C<T2>.InterceptableMethod(t1, t2, t3);
                    Outer<object>.C<object>.InterceptableMethod<object>(t1, t2, t3);
                }
 
                [InterceptsLocation("Program.cs", 19, 25)]
                [InterceptsLocation("Program.cs", 20, 33)]
                public static void Interceptor1<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
                {
                    Console.Write(t1);
                    Console.Write(t2);
                    Console.Write(t3);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "123123456456");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_14()
    {
        // containing type has 2 type parameters, method is generic
        // interceptor has arity 3
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            D.Usage(1, 2, 3);
            D.Usage(4, 5, 6);
 
            class C<T1, T2>
            {
                public static void InterceptableMethod<T3>(T1 t1, T2 t2, T3 t3) => throw null!;
            }
 
            static class D
            {
                public static void Usage<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
                {
                    C<T1, T2>.InterceptableMethod(t1, t2, t3);
                    C<object, object>.InterceptableMethod<object>(t1, t2, t3);
                }
 
                [InterceptsLocation("Program.cs", 16, 19)]
                [InterceptsLocation("Program.cs", 17, 27)]
                public static void Interceptor1<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
                {
                    Console.Write(t1);
                    Console.Write(t2);
                    Console.Write(t3);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "123123456456");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptableGeneric_15()
    {
        // original method is non-generic, interceptor is generic
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.Original();
 
            class C
            {
                public static void Original() => throw null!;
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 4, 3)] // 1
                public static void Interceptor1<T>() => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(13,6): error CS9178: Method 'D.Interceptor1<T>()' must be non-generic to match 'C.Original()'.
            //     [InterceptsLocation("Program.cs", 4, 3)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorCannotBeGeneric, @"InterceptsLocation(""Program.cs"", 4, 3)").WithArguments("D.Interceptor1<T>()", "C.Original()").WithLocation(13, 6));
    }
 
    [Fact]
    public void InterceptableGeneric_16()
    {
        var source = """
            #nullable enable
 
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void InterceptableMethod<T1>(T1 t) => throw null!;
 
                public static void Main()
                {
                    C.InterceptableMethod<string?>(null);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 12, 11)] // 1
                public static void Interceptor1<T>(T t) where T : notnull => Console.Write(1);
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics(
            // Program.cs(18,6): warning CS8714: The type 'string?' cannot be used as type parameter 'T' in the generic type or method 'D.Interceptor1<T>(T)'. Nullability of type argument 'string?' doesn't match 'notnull' constraint.
            //     [InterceptsLocation("Program.cs", 12, 11)] // 1
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInTypeParameterNotNullConstraint, @"InterceptsLocation(""Program.cs"", 12, 11)").WithArguments("D.Interceptor1<T>(T)", "T", "string?").WithLocation(18, 6));
    }
 
    [Fact]
    public void InterceptsLocationBadAttributeArguments_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 1, "10")]
                [InterceptsLocation("Program.cs", 1, 1, 9999)]
                [InterceptsLocation("Program.cs", ERROR, 1)]
                [InterceptsLocation()]
                public static void Interceptor1(string param) { Console.Write("interceptor " + param); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(6,42): error CS1503: Argument 3: cannot convert from 'string' to 'int'
            //     [InterceptsLocation("Program.cs", 1, "10")]
            Diagnostic(ErrorCode.ERR_BadArgType, @"""10""").WithArguments("3", "string", "int").WithLocation(6, 42),
            // Program.cs(7,6): error CS1729: 'InterceptsLocationAttribute' does not contain a constructor that takes 4 arguments
            //     [InterceptsLocation("Program.cs", 1, 1, 9999)]
            Diagnostic(ErrorCode.ERR_BadCtorArgCount, @"InterceptsLocation(""Program.cs"", 1, 1, 9999)").WithArguments("System.Runtime.CompilerServices.InterceptsLocationAttribute", "4").WithLocation(7, 6),
            // Program.cs(8,39): error CS0103: The name 'ERROR' does not exist in the current context
            //     [InterceptsLocation("Program.cs", ERROR, 1)]
            Diagnostic(ErrorCode.ERR_NameNotInContext, "ERROR").WithArguments("ERROR").WithLocation(8, 39),
            // Program.cs(9,6): error CS1729: 'InterceptsLocationAttribute' does not contain a constructor that takes 0 arguments
            //     [InterceptsLocation()]
            Diagnostic(ErrorCode.ERR_BadCtorArgCount, "InterceptsLocation()").WithArguments("System.Runtime.CompilerServices.InterceptsLocationAttribute", "0").WithLocation(9, 6)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPath_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("BAD", 15, 11)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,25): error CS9139: Cannot intercept: compilation does not contain a file with path 'BAD'.
            //     [InterceptsLocation("BAD", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""BAD""").WithArguments("BAD").WithLocation(21, 25)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPath_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("projects/Program.cs", 15, 11)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, PlatformInformation.IsWindows ? @"C:\Users\me\projects\Program.cs" : "/Users/me/projects/Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // C:\Users\me\projects\Program.cs(21,25): error CS9140: Cannot intercept: compilation does not contain a file with path 'projects/Program.cs'. Did you mean to use path 'Program.cs'?
            //     [InterceptsLocation("projects/Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilationWithCandidate, @"""projects/Program.cs""").WithArguments("projects/Program.cs", "Program.cs").WithLocation(21, 25)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPath_03()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C { }
 
            static class Program
            {
 
                public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation(null, 15, 11)]
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(20,25): error CS9150: Interceptor cannot have a 'null' file path.
            //     [InterceptsLocation(null, 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorFilePathCannotBeNull, "null").WithLocation(20, 25)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPath_04()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C { }
 
            static class Program
            {
 
                public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("program.cs", 15, 11)]
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(20,25): error CS9139: Cannot intercept: compilation does not contain a file with path 'program.cs'.
            //     [InterceptsLocation("program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""program.cs""").WithArguments("program.cs").WithLocation(20, 25)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 25, 1)]
                [InterceptsLocation("Program.cs", 26, 1)]
                [InterceptsLocation("Program.cs", 100, 1)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '}'.
            //     [InterceptsLocation("Program.cs", 25, 1)]
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 25, 1)").WithArguments("}").WithLocation(21, 6),
            // Program.cs(22,39): error CS9142: The given file has '25' lines, which is fewer than the provided line number '26'.
            //     [InterceptsLocation("Program.cs", 26, 1)]
            Diagnostic(ErrorCode.ERR_InterceptorLineOutOfRange, "26").WithArguments("25", "26").WithLocation(22, 39),
            // Program.cs(23,39): error CS9142: The given file has '25' lines, which is fewer than the provided line number '100'.
            //     [InterceptsLocation("Program.cs", 100, 1)]
            Diagnostic(ErrorCode.ERR_InterceptorLineOutOfRange, "100").WithArguments("25", "100").WithLocation(23, 39)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_02()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 16, 5)]
                [InterceptsLocation("Program.cs", 16, 6)]
                [InterceptsLocation("Program.cs", 16, 1000)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9141: The provided line and character number does not refer to an interceptable method name, but rather to token '}'.
            //     [InterceptsLocation("Program.cs", 16, 5)]
            Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 16, 5)").WithArguments("}").WithLocation(21, 6),
            // Program.cs(22,43): error CS9143: The given line is '5' characters long, which is fewer than the provided character number '6'.
            //     [InterceptsLocation("Program.cs", 16, 6)]
            Diagnostic(ErrorCode.ERR_InterceptorCharacterOutOfRange, "6").WithArguments("5", "6").WithLocation(22, 43),
            // Program.cs(23,43): error CS9143: The given line is '5' characters long, which is fewer than the provided character number '1000'.
            //     [InterceptsLocation("Program.cs", 16, 1000)]
            Diagnostic(ErrorCode.ERR_InterceptorCharacterOutOfRange, "1000").WithArguments("5", "1000").WithLocation(23, 43)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_03()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 9)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
                // Program.cs(21,6): error CS9141: The provided line and character number does not refer to an interceptable method, but rather to token 'c'.
                //     [InterceptsLocation("Program.cs", 15, 9)]
                Diagnostic(ErrorCode.ERR_InterceptorPositionBadToken, @"InterceptsLocation(""Program.cs"", 15, 9)").WithArguments("c").WithLocation(21, 6)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_04()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 13)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9147: The provided line and character number does not refer to the start of token 'InterceptableMethod'. Did you mean to use line '15' and character '11'?
            //     [InterceptsLocation("Program.cs", 15, 13)]
            Diagnostic(ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition, @"InterceptsLocation(""Program.cs"", 15, 13)").WithArguments("InterceptableMethod", "15", "11").WithLocation(21, 6)
        );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_05()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C { }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.
                        InterceptableMethod("call site");
 
                    c.InterceptableMethod    ("call site");
                }
 
 
                public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; }
 
                [InterceptsLocation("Program.cs", 12, 11)] // intercept spaces before 'InterceptableMethod' token
                [InterceptsLocation("Program.cs", 14, 33)] // intercept spaces after 'InterceptableMethod' token
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
 
            static class CExt
            {
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(20,6): error CS9147: The provided line and character number does not refer to the start of token 'InterceptableMethod'. Did you mean to use line '12' and character '13'?
            //     [InterceptsLocation("Program.cs", 12, 11)] // intercept spaces before 'InterceptableMethod' token
            Diagnostic(ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition, @"InterceptsLocation(""Program.cs"", 12, 11)").WithArguments("InterceptableMethod", "12", "13").WithLocation(20, 6),
            // Program.cs(21,6): error CS9147: The provided line and character number does not refer to the start of token 'InterceptableMethod'. Did you mean to use line '14' and character '11'?
            //     [InterceptsLocation("Program.cs", 14, 33)] // intercept spaces after 'InterceptableMethod' token
            Diagnostic(ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition, @"InterceptsLocation(""Program.cs"", 14, 33)").WithArguments("InterceptableMethod", "14", "11").WithLocation(21, 6)
        );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_06()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C { }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod/*comment*/("call site");
                }
 
 
                public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; }
 
                [InterceptsLocation("Program.cs", 11, 31)] // intercept comment after 'InterceptableMethod' token
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
 
            static class CExt
            {
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(17,6): error CS9147: The provided line and character number does not refer to the start of token 'InterceptableMethod'. Did you mean to use line '11' and character '11'?
            //     [InterceptsLocation("Program.cs", 11, 31)] // intercept comment after 'InterceptableMethod' token
            Diagnostic(ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition, @"InterceptsLocation(""Program.cs"", 11, 31)").WithArguments("InterceptableMethod", "11", "11").WithLocation(17, 6)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_07()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C { }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.
                        // comment
                        InterceptableMethod("call site");
                }
 
 
                public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; }
 
                [InterceptsLocation("Program.cs", 12, 13)] // intercept comment above 'InterceptableMethod' token
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
 
            static class CExt
            {
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
                // Program.cs(19,6): error CS9147: The provided line and character number does not refer to the start of token 'InterceptableMethod'. Did you mean to use line '13' and character '13'?
                //     [InterceptsLocation("Program.cs", 12, 13)] // intercept comment above 'InterceptableMethod' token
                Diagnostic(ErrorCode.ERR_InterceptorMustReferToStartOfTokenPosition, @"InterceptsLocation(""Program.cs"", 12, 13)").WithArguments("InterceptableMethod", "13", "13").WithLocation(19, 6)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_08()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C { }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
 
 
                public static C InterceptableMethod(this C c, string param) { Console.Write("interceptable " + param); return c; }
 
                [InterceptsLocation("Program.cs", -1, 1)] // 1
                [InterceptsLocation("Program.cs", 1, -1)] // 2
                [InterceptsLocation("Program.cs", -1, -1)] // 3
                [InterceptsLocation("Program.cs", 0, 1)] // 4
                [InterceptsLocation("Program.cs", 1, 0)] // 5 
                [InterceptsLocation("Program.cs", 0, 0)] // 6
                public static C Interceptor1(this C c, string param) { Console.Write("interceptor " + param); return c; }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(17,39): error CS9157: Line and character numbers provided to InterceptsLocationAttribute must be positive.
            //     [InterceptsLocation("Program.cs", -1, 1)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorLineCharacterMustBePositive, "-1").WithLocation(17, 39),
            // Program.cs(18,42): error CS9157: Line and character numbers provided to InterceptsLocationAttribute must be positive.
            //     [InterceptsLocation("Program.cs", 1, -1)] // 2
            Diagnostic(ErrorCode.ERR_InterceptorLineCharacterMustBePositive, "-1").WithLocation(18, 42),
            // Program.cs(19,39): error CS9157: Line and character numbers provided to InterceptsLocationAttribute must be positive.
            //     [InterceptsLocation("Program.cs", -1, -1)] // 3
            Diagnostic(ErrorCode.ERR_InterceptorLineCharacterMustBePositive, "-1").WithLocation(19, 39),
            // Program.cs(20,39): error CS9157: Line and character numbers provided to InterceptsLocationAttribute must be positive.
            //     [InterceptsLocation("Program.cs", 0, 1)] // 4
            Diagnostic(ErrorCode.ERR_InterceptorLineCharacterMustBePositive, "0").WithLocation(20, 39),
            // Program.cs(21,42): error CS9157: Line and character numbers provided to InterceptsLocationAttribute must be positive.
            //     [InterceptsLocation("Program.cs", 1, 0)] // 5 
            Diagnostic(ErrorCode.ERR_InterceptorLineCharacterMustBePositive, "0").WithLocation(21, 42),
            // Program.cs(22,39): error CS9157: Line and character numbers provided to InterceptsLocationAttribute must be positive.
            //     [InterceptsLocation("Program.cs", 0, 0)] // 6
            Diagnostic(ErrorCode.ERR_InterceptorLineCharacterMustBePositive, "0").WithLocation(22, 39)
            );
    }
 
    [Fact]
    public void InterceptsLocationBadPosition_Checksum_01()
    {
        var sourceTree = CSharpTestSource.Parse("""
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
            """, options: RegularWithInterceptors);
 
        // test unexpected position within interceptable name token
        var interceptableName = sourceTree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last().GetInterceptableNameSyntax()!;
        var position = interceptableName.Position + 1;
 
        var builder = new BlobBuilder();
        builder.WriteBytes(sourceTree.GetText().GetContentHash());
        builder.WriteInt32(position);
        builder.WriteUTF8("Error");
 
        var base64 = Convert.ToBase64String(builder.ToArray());
 
        var interceptorTree = CSharpTestSource.Parse($$"""
            using System.Runtime.CompilerServices;
            using System;
            
            static class D
            {
                [InterceptsLocation(1, "{{base64}}")]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """, options: RegularWithInterceptors);
        var comp = CreateCompilation([sourceTree, interceptorTree, s_attributesTree]);
        comp.VerifyEmitDiagnostics(
            // (6,6): error CS9235: The data argument to InterceptsLocationAttribute refers to an invalid position in file 'Error'.
            //     [InterceptsLocation(1, "ExWKMussA+NMlN5J0QNXiEMBAABFcnJvcg==")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDataInvalidPosition, "InterceptsLocation").WithArguments("Error").WithLocation(6, 6)
        );
    }
 
    [Theory]
    [InlineData(-1)] // test invalid position
    [InlineData(99999)] // test position past end of the file
    public void InterceptsLocationBadPosition_Checksum_02(int position)
    {
        var sourceTree = CSharpTestSource.Parse("""
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
            """, options: RegularWithInterceptors);
 
        var builder = new BlobBuilder();
        builder.WriteBytes(sourceTree.GetText().GetContentHash());
        builder.WriteInt32(position);
        builder.WriteUTF8("Error");
 
        var base64 = Convert.ToBase64String(builder.ToArray());
 
        var interceptorTree = CSharpTestSource.Parse($$"""
            using System.Runtime.CompilerServices;
            using System;
 
            static class D
            {
                [InterceptsLocation(1, "{{base64}}")]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """, options: RegularWithInterceptors);
        var comp = CreateCompilation([sourceTree, interceptorTree, s_attributesTree]);
        comp.VerifyEmitDiagnostics(
            // (6,6): error CS9235: The data argument to InterceptsLocationAttribute refers to an invalid position in file 'Error'.
            //     [InterceptsLocation(1, "ExWKMussA+NMlN5J0QNXiJ+GAQBFcnJvcg==")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDataInvalidPosition, "InterceptsLocation").WithArguments("Error").WithLocation(6, 6)
        );
    }
 
    [Fact]
    public void SignatureMismatch_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1 { }
 
            static class Program
            {
 
                public static I1 InterceptableMethod(this I1 i1, string param) { Console.Write("interceptable " + param); return i1; }
 
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static I1 Interceptor1(this I1 i1, int param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
                // Program.cs(21,6): error CS9144: Cannot intercept method 'Program.InterceptableMethod(I1, string)' with interceptor 'D.Interceptor1(I1, int)' because the signatures do not match.
                //     [InterceptsLocation("Program.cs", 15, 11)]
                Diagnostic(ErrorCode.ERR_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("Program.InterceptableMethod(I1, string)", "D.Interceptor1(I1, int)").WithLocation(21, 6)
            );
    }
 
    [Fact]
    public void SignatureMismatch_02()
    {
        // Instance method receiver type differs from interceptor 'this' parameter type.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            interface I1 { }
            class C : I1
            {
 
                public I1 InterceptableMethod(string param) { Console.Write("interceptable " + param); return this; }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 16, 11)]
                public static I1 Interceptor1(this I1 i1, string param) { Console.Write("interceptor " + param); return i1; }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(22,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'C this' on 'C.InterceptableMethod(string)'.
            //     [InterceptsLocation("Program.cs", 16, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 16, 11)").WithArguments("C this", "C.InterceptableMethod(string)").WithLocation(22, 6)
            );
    }
 
    [Fact]
    public void SignatureMismatch_03()
    {
        // Instance method 'this' parameter ref kind differs from interceptor 'this' parameter ref kind.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            struct S
            {
 
                public void InterceptableMethod(string param) { Console.Write("interceptable " + param); }
            }
 
            static class Program
            {
                public static void Main()
                {
                    var s = new S();
                    s.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor1(this S s, string param) { Console.Write("interceptor " + param); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'ref S this' on 'S.InterceptableMethod(string)'.
            //     [InterceptsLocation("Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("ref S this", "S.InterceptableMethod(string)").WithLocation(21, 6)
            );
    }
 
    [Fact]
    public void SignatureMismatch_04()
    {
        // Safe nullability difference
        var source = """
            using System.Runtime.CompilerServices;
 
            class C
            {
 
                public string? InterceptableMethod(string param) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.InterceptableMethod("call site");
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)]
                public static string Interceptor1(this C s, string? param) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, options: WithNullableEnable());
        comp.VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void SignatureMismatch_05()
    {
        // Unsafe nullability difference
        var source = """
            using System.Runtime.CompilerServices;
 
            class C
            {
 
                public void Method1(string? param1) => throw null!;
 
 
                public string Method2() => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.Method1("call site");
                    _ = c.Method2();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 17, 11)] // 1
                public static void Interceptor1(this C s, string param2) => throw null!;
 
                [InterceptsLocation("Program.cs", 18, 15)] // 2
                public static string? Interceptor2(this C s) => throw null!;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, options: WithNullableEnable());
        comp.VerifyEmitDiagnostics(
            // Program.cs(24,6): warning CS9159: Nullability of reference types in type of parameter 'param2' doesn't match interceptable method 'C.Method1(string?)'.
            //     [InterceptsLocation("Program.cs", 17, 11)] // 1
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInParameterTypeOnInterceptor, @"InterceptsLocation(""Program.cs"", 17, 11)").WithArguments("param2", "C.Method1(string?)").WithLocation(24, 6),
            // Program.cs(27,6): warning CS9158: Nullability of reference types in return type doesn't match interceptable method 'C.Method2()'.
            //     [InterceptsLocation("Program.cs", 18, 15)] // 2
            Diagnostic(ErrorCode.WRN_NullabilityMismatchInReturnTypeOnInterceptor, @"InterceptsLocation(""Program.cs"", 18, 15)").WithArguments("C.Method2()").WithLocation(27, 6)
            );
 
        comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, options: WithNullableDisable());
        comp.VerifyEmitDiagnostics(
            // Program.cs(6,31): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
            //     public void Method1(string? param1) => throw null!;
            Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(6, 31),
            // Program.cs(28,25): warning CS8632: The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
            //     public static string? Interceptor2(this C s) => throw null!;
            Diagnostic(ErrorCode.WRN_MissingNonNullTypesContextForAnnotation, "?").WithLocation(28, 25)
            );
    }
 
    [Fact]
    public void SignatureMismatch_06()
    {
        // 'dynamic' difference
        var source = """
            using System.Runtime.CompilerServices;
 
            class C
            {
 
                public void Method1(object param1) => throw null!;
 
 
                public dynamic Method2() => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.Method1("call site");
                    _ = c.Method2();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 17, 11)] // 1
                public static void Interceptor1(this C s, dynamic param2) => throw null!;
 
                [InterceptsLocation("Program.cs", 18, 15)] // 2
                public static object Interceptor2(this C s) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(24,6): warning CS9154: Intercepting a call to 'C.Method1(object)' with interceptor 'D.Interceptor1(C, dynamic)', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 17, 11)] // 1
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 17, 11)").WithArguments("C.Method1(object)", "D.Interceptor1(C, dynamic)").WithLocation(24, 6),
            // Program.cs(27,6): warning CS9154: Intercepting a call to 'C.Method2()' with interceptor 'D.Interceptor2(C)', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 18, 15)] // 2
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 18, 15)").WithArguments("C.Method2()", "D.Interceptor2(C)").WithLocation(27, 6)
            );
    }
 
    [Fact]
    public void SignatureMismatch_07()
    {
        // tuple element name difference
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public void Method1((string a, string b) param1) => throw null!;
                public void Method2((string x, string y) param1) => throw null!;
                public void Method3((string, string) param1) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
 
                    c.Method1(default!);
                    c.Method2(default!);
                    c.Method3(default!);
 
                    c.Method1(default!);
                    c.Method2(default!);
                    c.Method3(default!);
 
                    c.Method1(default!);
                    c.Method2(default!);
                    c.Method3(default!);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 17, 11)]
                [InterceptsLocation("Program.cs", 18, 11)] // 1
                [InterceptsLocation("Program.cs", 19, 11)] // 2
                public static void Interceptor1(this C s, (string a, string b) param2) => Console.Write(1);
 
                [InterceptsLocation("Program.cs", 21, 11)] // 3
                [InterceptsLocation("Program.cs", 22, 11)]
                [InterceptsLocation("Program.cs", 23, 11)] // 4
                public static void Interceptor2(this C s, (string x, string y) param2) => Console.Write(2);
 
                [InterceptsLocation("Program.cs", 25, 11)] // 5
                [InterceptsLocation("Program.cs", 26, 11)] // 6
                [InterceptsLocation("Program.cs", 27, 11)]
                public static void Interceptor3(this C s, (string, string) param2) => Console.Write(3);
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "111222333");
        verifier.VerifyDiagnostics(
            // Program.cs(34,6): warning CS9154: Intercepting a call to 'C.Method2((string x, string y))' with interceptor 'D.Interceptor1(C, (string a, string b))', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 18, 11)] // 1
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 18, 11)").WithArguments("C.Method2((string x, string y))", "D.Interceptor1(C, (string a, string b))").WithLocation(34, 6),
            // Program.cs(35,6): warning CS9154: Intercepting a call to 'C.Method3((string, string))' with interceptor 'D.Interceptor1(C, (string a, string b))', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 19, 11)] // 2
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 19, 11)").WithArguments("C.Method3((string, string))", "D.Interceptor1(C, (string a, string b))").WithLocation(35, 6),
            // Program.cs(38,6): warning CS9154: Intercepting a call to 'C.Method1((string a, string b))' with interceptor 'D.Interceptor2(C, (string x, string y))', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 21, 11)] // 3
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 21, 11)").WithArguments("C.Method1((string a, string b))", "D.Interceptor2(C, (string x, string y))").WithLocation(38, 6),
            // Program.cs(40,6): warning CS9154: Intercepting a call to 'C.Method3((string, string))' with interceptor 'D.Interceptor2(C, (string x, string y))', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 23, 11)] // 4
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 23, 11)").WithArguments("C.Method3((string, string))", "D.Interceptor2(C, (string x, string y))").WithLocation(40, 6),
            // Program.cs(43,6): warning CS9154: Intercepting a call to 'C.Method1((string a, string b))' with interceptor 'D.Interceptor3(C, (string, string))', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 25, 11)] // 5
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 25, 11)").WithArguments("C.Method1((string a, string b))", "D.Interceptor3(C, (string, string))").WithLocation(43, 6),
            // Program.cs(44,6): warning CS9154: Intercepting a call to 'C.Method2((string x, string y))' with interceptor 'D.Interceptor3(C, (string, string))', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 26, 11)] // 6
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 26, 11)").WithArguments("C.Method2((string x, string y))", "D.Interceptor3(C, (string, string))").WithLocation(44, 6)
            );
    }
 
    [Fact]
    public void SignatureMismatch_08()
    {
        // nint/IntPtr difference
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public void Method1(nint param1) => throw null!;
                public void Method2(IntPtr param1) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    c.Method1(default!);
                    c.Method2(default!);
 
                    c.Method2(default!);
                    c.Method1(default!);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 16, 11)] // 1
                [InterceptsLocation("Program.cs", 17, 11)]
                public static void Interceptor1(this C s, IntPtr param2) => Console.Write(1);
 
                [InterceptsLocation("Program.cs", 19, 11)] // 2
                [InterceptsLocation("Program.cs", 20, 11)]
                public static void Interceptor2(this C s, nint param2) => Console.Write(2);
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1122");
        verifier.VerifyDiagnostics(
            // Program.cs(26,6): warning CS9154: Intercepting a call to 'C.Method1(nint)' with interceptor 'D.Interceptor1(C, IntPtr)', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 16, 11)] // 1
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 16, 11)").WithArguments("C.Method1(nint)", "D.Interceptor1(C, System.IntPtr)").WithLocation(26, 6),
            // Program.cs(30,6): warning CS9154: Intercepting a call to 'C.Method2(IntPtr)' with interceptor 'D.Interceptor2(C, nint)', but the signatures do not match.
            //     [InterceptsLocation("Program.cs", 19, 11)] // 2
            Diagnostic(ErrorCode.WRN_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 19, 11)").WithArguments("C.Method2(System.IntPtr)", "D.Interceptor2(C, nint)").WithLocation(30, 6));
    }
 
    [Fact]
    public void SignatureMismatch_09()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Program
            {
                public static void InterceptableMethod(ref readonly int x) => Console.Write("interceptable " + x);
 
                public static void Main()
                {
                    int x = 5;
                    InterceptableMethod(in x);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 11, 9)]
                public static void Interceptor(in int x) => Console.Write("interceptor " + x);
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(17,6): error CS9144: Cannot intercept method 'Program.InterceptableMethod(ref readonly int)' with interceptor 'D.Interceptor(in int)' because the signatures do not match.
            //     [InterceptsLocation("Program.cs", 11, 9)]
            Diagnostic(ErrorCode.ERR_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 11, 9)").WithArguments("Program.InterceptableMethod(ref readonly int)", "D.Interceptor(in int)").WithLocation(17, 6));
    }
 
    [Fact]
    public void SignatureMismatch_10()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            struct Program
            {
                public void InterceptableMethod() => Console.Write("Original");
 
                public static void Main()
                {
                    new Program().InterceptableMethod();
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 10, 23)]
                public static void Interceptor(this in Program x) => Console.Write("Intercepted");
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(16,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'ref Program this' on 'Program.InterceptableMethod()'.
            //     [InterceptsLocation("Program.cs", 10, 23)]
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 10, 23)").WithArguments("ref Program this", "Program.InterceptableMethod()").WithLocation(16, 6));
    }
 
    [Fact]
    public void SignatureMismatch_11()
    {
        var source = ("""
            using System;
 
            struct Program
            {
                public readonly void InterceptableMethod() => Console.Write("Original");
 
                public static void Main()
                {
                    new Program().InterceptableMethod();
                }
            }
            """, "Program.cs");
 
        var interceptor = ("""
            using System.Runtime.CompilerServices;
            using System;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 9, 23)]
                public static void Interceptor(this in Program x) => Console.Write("Intercepted");
            }
            """, "Interceptor.cs");
        var verifier = CompileAndVerify(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Original");
        verifier.VerifyDiagnostics();
 
        verifier = CompileAndVerify(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Intercepted");
        verifier.VerifyDiagnostics();
    }
 
    [Theory]
    [InlineData("ref readonly")]
    [InlineData("ref")]
    [WorkItem("https://github.com/dotnet/roslyn/issues/71714")]
    public void SignatureMismatch_12(string interceptorRefKind)
    {
        var source = ("""
            using System;
 
            struct Program
            {
                public readonly void InterceptableMethod() => Console.Write("Original");
 
                public static void Main()
                {
                    new Program().InterceptableMethod();
                }
            }
            """, "Program.cs");
 
        var interceptor = ($$"""
            using System.Runtime.CompilerServices;
            using System;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 9, 23)]
                public static void Interceptor(this {{interceptorRefKind}} Program x) => Console.Write("Intercepted");
            }
            """, "Interceptor.cs");
        var verifier = CompileAndVerify(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Original");
        verifier.VerifyDiagnostics();
 
        // 'this ref readonly' should probably be compatible with 'readonly' original method.
        // Tracked by https://github.com/dotnet/roslyn/issues/71714
        var comp = CreateCompilation(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(6,6): error CS9148: Interceptor must have a 'this' parameter matching parameter 'in Program this' on 'Program.InterceptableMethod()'.
            //     [InterceptsLocation("Program.cs", 9, 23)]
            Diagnostic(ErrorCode.ERR_InterceptorMustHaveMatchingThisParameter, @"InterceptsLocation(""Program.cs"", 9, 23)").WithArguments("in Program this", "Program.InterceptableMethod()").WithLocation(6, 6));
    }
 
    [Fact]
    public void ScopedMismatch_01()
    {
        // Unsafe 'scoped' difference
        var source = """
            using System.Runtime.CompilerServices;
 
            class C
            {
 
                public static ref int InterceptableMethod(scoped ref int value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    int i = 0;
                    C.InterceptableMethod(ref i);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)] // 1
                public static ref int Interceptor1(ref int value) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, options: WithNullableEnable());
        comp.VerifyEmitDiagnostics(
            // Program.cs(20,6): error CS9156: Cannot intercept call to 'C.InterceptableMethod(scoped ref int)' with 'D.Interceptor1(ref int)' because of a difference in 'scoped' modifiers or '[UnscopedRef]' attributes.
            //     [InterceptsLocation("Program.cs", 14, 11)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorScopedMismatch, @"InterceptsLocation(""Program.cs"", 14, 11)").WithArguments("C.InterceptableMethod(scoped ref int)", "D.Interceptor1(ref int)").WithLocation(20, 6)
            );
    }
 
    [Fact]
    public void ScopedMismatch_02()
    {
        // safe 'scoped' difference
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static ref int InterceptableMethod(ref int value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    int i = 0;
                    _ = C.InterceptableMethod(ref i);
                }
            }
 
            static class D
            {
                static int i;
 
                [InterceptsLocation("Program.cs", 15, 15)]
                public static ref int Interceptor1(scoped ref int value)
                {
                    Console.Write(1);
                    return ref i;
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ScopedMismatch_03()
    {
        // safe '[UnscopedRef]' difference
        var source = """
            using System.Diagnostics.CodeAnalysis;
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static ref int InterceptableMethod([UnscopedRef] out int value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    _ = C.InterceptableMethod(out int i);
                }
            }
 
            static class D
            {
                static int i;
 
                [InterceptsLocation("Program.cs", 15, 15)]
                public static ref int Interceptor1(out int value)
                {
                    Console.Write(1);
                    value = 0;
                    return ref i;
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource, (UnscopedRefAttributeDefinition, "UnscopedRefAttribute.cs") }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ScopedMismatch_04()
    {
        // unsafe '[UnscopedRef]' difference
        var source = """
            using System.Diagnostics.CodeAnalysis;
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static ref int InterceptableMethod(out int value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod(out int i);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)] // 1
                public static ref int Interceptor1([UnscopedRef] out int value) => throw null!;
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource, (UnscopedRefAttributeDefinition, "UnscopedRefAttribute.cs") }, parseOptions: RegularWithInterceptors, options: WithNullableEnable());
        comp.VerifyEmitDiagnostics(
            // Program.cs(21,6): error CS9156: Cannot intercept call to 'C.InterceptableMethod(out int)' with 'D.Interceptor1(out int)' because of a difference in 'scoped' modifiers or '[UnscopedRef]' attributes.
            //     [InterceptsLocation("Program.cs", 15, 11)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorScopedMismatch, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("C.InterceptableMethod(out int)", "D.Interceptor1(out int)").WithLocation(21, 6)
            );
    }
 
    [Fact]
    public void ReferenceEquals_01()
    {
        // A call to 'object.ReferenceEquals(a, b)' is defined as being equivalent to '(object)a == b'.
        var source = """
            using System.Runtime.CompilerServices;
 
            static class D
            {
 
                public static bool Interceptable(object? obj1, object? obj2) => throw null!;
 
                public static void M0(object? obj1, object? obj2)
                {
                    if (obj1 == obj2)
                       throw null!;
                }
 
                public static void M1(object? obj1, object? obj2)
                {
                    if (Interceptable(obj1, obj2))
                       throw null!;
                }
 
                public static void M2(object? obj1, object? obj2)
                {
                    if (Interceptable(obj1, obj2))
                       throw null!;
                }
            }
 
            namespace System
            {
                public class Object
                {
                    [InterceptsLocation("Program.cs", 16, 13)]
                    public static bool ReferenceEquals(object? obj1, object? obj2) => throw null!;
 
                    [InterceptsLocation("Program.cs", 22, 13)]
                    public static bool NotReferenceEquals(object? obj1, object? obj2) => throw null!;
                }
 
                public class Void { }
                public struct Boolean { }
                public class String { }
                public class Attribute { }
                public abstract class Enum { }
                public enum AttributeTargets { }
                public class AttributeUsageAttribute : Attribute
                {
                    public AttributeUsageAttribute(AttributeTargets targets) { }
                    public bool AllowMultiple { get; set; }
                    public bool Inherited { get; set; }
                }
                public class Exception { }
                public abstract class ValueType { }
                public struct Int32 { }
                public struct Byte { }
            }
 
            namespace System.Runtime.CompilerServices
            {
                public sealed class InterceptableAttribute : Attribute { }
 
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int column)
                    {
                    }
                }
            }
            """;
        var verifier = CompileAndVerify(CreateEmptyCompilation((source, "Program.cs"), parseOptions: RegularWithInterceptors, options: WithNullableEnable()), verify: Verification.Skipped);
        verifier.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).Verify();
 
        var referenceEqualsCallIL = """
            {
              // Code size        7 (0x7)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  bne.un.s   IL_0006
              IL_0004:  ldnull
              IL_0005:  throw
              IL_0006:  ret
            }
            """;
        verifier.VerifyIL("D.M0", referenceEqualsCallIL);
        verifier.VerifyIL("D.M1", referenceEqualsCallIL);
 
        verifier.VerifyIL("D.M2", """
            {
              // Code size       12 (0xc)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "bool object.NotReferenceEquals(object, object)"
              IL_0007:  brfalse.s  IL_000b
              IL_0009:  ldnull
              IL_000a:  throw
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void ReferenceEquals_02()
    {
        // Intercept a call to object.ReferenceEquals
        var source = """
            using System.Runtime.CompilerServices;
 
            static class D
            {
                public static void M0(object? obj1, object? obj2)
                {
                    if (object.ReferenceEquals(obj1, obj2))
                       throw null!;
                }
 
                [InterceptsLocation("Program.cs", 7, 20)]
                public static bool Interceptor(object? obj1, object? obj2)
                {
                    return false;
                }
            }
 
            namespace System
            {
                public class Object
                {
 
                    public static bool ReferenceEquals(object? obj1, object? obj2) => throw null!;
                }
 
                public class Void { }
                public struct Boolean { }
                public class String { }
                public class Attribute { }
                public abstract class Enum { }
                public enum AttributeTargets { }
                public class AttributeUsageAttribute : Attribute
                {
                    public AttributeUsageAttribute(AttributeTargets targets) { }
                    public bool AllowMultiple { get; set; }
                    public bool Inherited { get; set; }
                }
                public class Exception { }
                public abstract class ValueType { }
                public struct Int32 { }
                public struct Byte { }
            }
 
            namespace System.Runtime.CompilerServices
            {
                public sealed class InterceptableAttribute : Attribute { }
 
                public sealed class InterceptsLocationAttribute : Attribute
                {
                    public InterceptsLocationAttribute(string filePath, int line, int column)
                    {
                    }
                }
            }
            """;
        var verifier = CompileAndVerify(CreateEmptyCompilation((source, "Program.cs"), parseOptions: RegularWithInterceptors, options: WithNullableEnable()), verify: Verification.Skipped);
        verifier.Diagnostics.Where(d => d.Severity == DiagnosticSeverity.Error).Verify();
 
        verifier.VerifyIL("D.M0", """
            {
              // Code size       12 (0xc)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  ldarg.1
              IL_0002:  call       "bool D.Interceptor(object, object)"
              IL_0007:  brfalse.s  IL_000b
              IL_0009:  ldnull
              IL_000a:  throw
              IL_000b:  ret
            }
            """);
    }
 
    [Fact]
    public void ParamsMismatch_01()
    {
        // Test when interceptable method has 'params' parameter.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod(params int[] value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod(1, 2, 3);
                    C.InterceptableMethod(4, 5, 6);
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)]
                public static void Interceptor1(int[] value)
                {
                    foreach (var i in value)
                        Console.Write(i);
                }
 
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor2(params int[] value)
                {
                    foreach (var i in value)
                        Console.Write(i);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "123456");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ParamsMismatch_02()
    {
        // Test when interceptable method lacks 'params' parameter, and interceptor has one, and method is called as if it has one.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod(int[] value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod(1, 2, 3 ); // 1
                    C.InterceptableMethod(4, 5, 6); // 2
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)]
                public static void Interceptor1(int[] value)
                {
                    foreach (var i in value)
                        Console.Write(i);
                }
 
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor2(params int[] value)
                {
                    foreach (var i in value)
                        Console.Write(i);
                }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
                // Program.cs(14,11): error CS1501: No overload for method 'InterceptableMethod' takes 3 arguments
                //         C.InterceptableMethod(1, 2, 3 ); // 1
                Diagnostic(ErrorCode.ERR_BadArgCount, "InterceptableMethod").WithArguments("InterceptableMethod", "3").WithLocation(14, 11),
                // Program.cs(15,11): error CS1501: No overload for method 'InterceptableMethod' takes 3 arguments
                //         C.InterceptableMethod(4, 5, 6); // 2
                Diagnostic(ErrorCode.ERR_BadArgCount, "InterceptableMethod").WithArguments("InterceptableMethod", "3").WithLocation(15, 11));
    }
 
    [Fact]
    public void ParamsMismatch_03()
    {
        // Test when interceptable method lacks 'params' parameter, and interceptor has one, and method is called in normal form.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod(int[] value) => throw null!;
            }
 
            static class Program
            {
                public static void Main()
                {
                    C.InterceptableMethod(new[] { 1, 2, 3 });
                    C.InterceptableMethod(new[] { 4, 5, 6 });
                }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 14, 11)]
                public static void Interceptor1(int[] value)
                {
                    foreach (var i in value)
                        Console.Write(i);
                }
 
                [InterceptsLocation("Program.cs", 15, 11)]
                public static void Interceptor2(params int[] value)
                {
                    foreach (var i in value)
                        Console.Write(i);
                }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "123456");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterpolatedStringHandler_01()
    {
        // Verify that interpolated string-related attributes on an intercepted call use the attributes from the interceptable method.
        var code = """
using System;
using System.Runtime.CompilerServices;
 
var s = new S1();
s.M($"");
 
public struct S1
{
    public S1() { }
    public int Field = 1;
 
 
    public void M([InterpolatedStringHandlerArgument("")] CustomHandler c)
    {
        Console.Write(0);
    }
}
 
public static class S1Ext
{
    [InterceptsLocation("Program.cs", 5, 3)]
    public static void M1(ref this S1 s1, CustomHandler c)
    {
        Console.Write(2);
    }
}
 
partial struct CustomHandler
{
    public CustomHandler(int literalLength, int formattedCount, S1 s)
    {
        Console.Write(1);
    }
}
""";
        var verifier = CompileAndVerify(
            new[]
            {
                (code, "Program.cs"),
                (InterpolatedStringHandlerArgumentAttribute, "a.cs"),
                (GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: false), "b.cs"),
                s_attributesSource
            },
            parseOptions: RegularWithInterceptors,
            expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterpolatedStringHandler_02()
    {
        // Verify that interpolated string-related attributes are ignored on an interceptor in an intercepted call.
        var code = """
using System;
using System.Runtime.CompilerServices;
 
var s = new S1();
s.M($"");
 
public struct S1
{
    public S1() { }
    public int Field = 1;
 
 
    public void M(CustomHandler c)
    {
        Console.Write(0);
    }
}
 
public static class S1Ext
{
    [InterceptsLocation("Program.cs", 5, 3)]
    public static void M1(ref this S1 s1, [InterpolatedStringHandlerArgument("s1")] CustomHandler c)
    {
        Console.Write(1);
    }
}
 
partial struct CustomHandler
{
    public CustomHandler(int literalLength, int formattedCount, S1 s)
    {
        throw null!; // we don't expect this to be called
    }
}
""";
        var verifier = CompileAndVerify(
            new[]
            {
                (code, "Program.cs"),
                (InterpolatedStringHandlerArgumentAttribute, "a.cs"),
                (GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: false), "b.cs"),
                s_attributesSource
            },
            parseOptions: RegularWithInterceptors,
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterpolatedStringHandler_03()
    {
        // Verify that interpolated string attributes on an interceptor don't cause us to somehow pick a different argument.
        var code = """
using System;
using System.Runtime.CompilerServices;
 
var s1 = new S1(1);
var s2 = new S1(2);
S1.M(s1, s2, $"");
 
public struct S1
{
    public S1(int field) => Field = field;
    public int Field = 1;
 
 
    public static void M(S1 s1, S1 s2, [InterpolatedStringHandlerArgument("s1")] CustomHandler c)
    {
        Console.Write(0);
    }
}
 
public static class S1Ext
{
    [InterceptsLocation("Program.cs", 6, 4)]
    public static void M1(S1 s2, S1 s3, [InterpolatedStringHandlerArgument("s2")] CustomHandler c)
    {
        Console.Write(2);
    }
}
 
partial struct CustomHandler
{
    public CustomHandler(int literalLength, int formattedCount, S1 s)
    {
        Console.Write(s.Field);
    }
}
""";
        var verifier = CompileAndVerify(
            new[]
            {
                (code, "Program.cs"),
                (InterpolatedStringHandlerArgumentAttribute, "a.cs"),
                (GetInterpolatedStringCustomHandlerType("CustomHandler", "partial struct", useBoolReturns: false), "b.cs"),
                s_attributesSource
            },
            parseOptions: RegularWithInterceptors,
            expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void LineDirective_01()
    {
        // Verify that line directives are not considered when deciding if a particular call is being intercepted.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod() { Console.Write("interceptable"); }
 
                public static void Main()
                {
                    #line 42 "OtherFile.cs"
                    InterceptableMethod();
                }
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 12, 9)]
                public static void Interceptor1() { Console.Write("interceptor 1"); }
            }
            """;
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "interceptor 1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void LineDirective_02()
    {
        // Verify that line directives are not considered when deciding if a particular call is being intercepted.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
 
                public static void InterceptableMethod() { Console.Write("interceptable"); }
 
                public static void Main()
                {
                    #line 42 "OtherFile.cs"
                    InterceptableMethod();
                }
            }
 
            class D
            {
                [InterceptsLocation("OtherFile.cs", 42, 9)]
                public static void Interceptor1() { Console.Write("interceptor 1"); }
            }
            """;
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // OtherFile.cs(48,25): error CS9139: Cannot intercept: compilation does not contain a file with path 'OtherFile.cs'.
            //     [InterceptsLocation("OtherFile.cs", 42, 9)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""OtherFile.cs""").WithArguments("OtherFile.cs").WithLocation(48, 25));
    }
 
    [Fact]
    public void ObsoleteInterceptor()
    {
        // Expect no Obsolete diagnostics to be reported
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
 
                public static void M() => throw null!;
            }
 
            class D
            {
                [Obsolete]
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M1() => Console.Write(1);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void CallerInfo()
    {
        // CallerLineNumber, etc. on the interceptor doesn't affect the default arguments passed to an intercepted call.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
 
                public static void M(int lineNumber = 1) => throw null!;
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M1([CallerLineNumber] int lineNumber = 0) => Console.Write(lineNumber);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void DefaultArguments_01()
    {
        // Default parameter values on the interceptor doesn't affect the default arguments passed to an intercepted call.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M();
 
            class C
            {
 
                public static void M(int lineNumber = 1) => throw null!;
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M1(int lineNumber = 0) => Console.Write(lineNumber);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void DefaultArguments_02()
    {
        // Interceptor cannot add a default argument when original method lacks it.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C.M(); // 1
 
            class C
            {
                public static void M(int lineNumber) => throw null!;
            }
 
            class D
            {
                [InterceptsLocation("Program.cs", 4, 3)]
                public static void M1(int lineNumber = 0) => Console.Write(lineNumber);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(4,3): error CS7036: There is no argument given that corresponds to the required parameter 'lineNumber' of 'C.M(int)'
            // C.M(); // 1
            Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("lineNumber", "C.M(int)").WithLocation(4, 3));
    }
 
    [Fact]
    public void InterceptorExtern()
    {
        var source = """
            using System.Runtime.CompilerServices;
 
            C.M();
 
            class C
            {
 
                public static void M() => throw null!;
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 3, 3)]
                public static extern void Interceptor();
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, verify: Verification.Skipped);
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size        6 (0x6)
              .maxstack  0
              IL_0000:  call       "void D.Interceptor()"
              IL_0005:  ret
            }
            """);
    }
 
    [Fact]
    public void InterceptorAbstract()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            var d = new D();
            d.M();
 
            abstract class C
            {
 
                public void M() => throw null!;
 
                [InterceptsLocation("Program.cs", 5, 3)]
                public abstract void Interceptor();
            }
 
            class D : C
            {
                public override void Interceptor() => Console.Write(1);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptorInterface()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            I i = new C();
            i.M();
 
            interface I
            {
 
                public void M();
 
                [InterceptsLocation("Program.cs", 5, 3)]
                void Interceptor();
            }
 
            class C : I
            {
                public void M() => throw null!;
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptGetEnumerator()
    {
        var source = """
            using System.Collections;
            using System.Runtime.CompilerServices;
 
            var myEnumerable = new MyEnumerable();
            foreach (var item in myEnumerable)
            {
            }
 
            class MyEnumerable : IEnumerable
            {
                public IEnumerator GetEnumerator() => throw null!;
            }
 
            static class MyEnumerableExt
            {
                [InterceptsLocation("Program.cs", 5, 22)] // 1
                public static IEnumerator GetEnumerator1(this MyEnumerable en) => throw null!;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(16,6): error CS9151: Possible method name 'myEnumerable' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 5, 22)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 5, 22)").WithArguments("myEnumerable").WithLocation(16, 6));
    }
 
    [Fact]
    public void InterceptDispose()
    {
        var source = """
            using System;
            using System.Runtime.CompilerServices;
 
            var myDisposable = new MyDisposable();
            using (myDisposable)
            {
            }
 
            class MyDisposable : IDisposable
            {
                public void Dispose() => throw null!;
            }
 
            static class MyDisposeExt
            {
                [InterceptsLocation("Program.cs", 5, 8)] // 1
                public static void Dispose1(this MyDisposable md) => throw null!;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(16,6): error CS9151: Possible method name 'myDisposable' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 5, 8)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 5, 8)").WithArguments("myDisposable").WithLocation(16, 6)
            );
    }
 
    [Fact]
    public void InterceptDeconstruct()
    {
        var source = """
            using System;
            using System.Runtime.CompilerServices;
 
            var myDeconstructable = new MyDeconstructable();
            var (x, y) = myDeconstructable;
 
            class MyDeconstructable
            {
                public void Deconstruct(out int x, out int y) => throw null!;
            }
 
            static class MyDeconstructableExt
            {
                [InterceptsLocation("Program.cs", 5, 14)] // 1
                public static void Deconstruct1(this MyDeconstructable md, out int x, out int y) => throw null!;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Program.cs(14,6): error CS9151: Possible method name 'myDeconstructable' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("Program.cs", 5, 14)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""Program.cs"", 5, 14)").WithArguments("myDeconstructable").WithLocation(14, 6)
            );
    }
 
    [Fact]
    public void PathMapping_01()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
 
                [InterceptsLocation("/_/Program.cs", 5, 3)]
                public void Interceptor() => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path\""" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "Program.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, "/_/"));
 
        var verifier = CompileAndVerify(
            new[] { (source, path), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)),
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void PathMapping_02()
    {
        // Attribute contains an unmapped path even though compilation uses a pathmap.
        // Because normalizing to the path of the containing file also effectively applies the pathmap, we accept the given path
        var pathPrefix = PlatformInformation.IsWindows ? @"C:\My\Machine\Specific\Path\" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "Program.cs";
        var source = $$"""
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
 
                [InterceptsLocation(@"{{path}}", 5, 3)]
                public void Interceptor() => Console.Write(1);
            }
            """;
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, "/_/"));
 
        var verifier = CompileAndVerify(
            new[] { (source, path), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)),
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void PathMapping_03()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
 
                [InterceptsLocation(@"\_\Program.cs", 5, 3)]
                public void Interceptor() => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path\""" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "Program.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, "/_/"));
 
        var comp = CreateCompilation(
            new[] { (source, path), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)));
        comp.VerifyEmitDiagnostics(PlatformInformation.IsWindows
            // C:\My\Machine\Specific\Path\Program.cs(11,25): error CS9139: Cannot intercept: compilation does not contain a file with path 'C:\_\Program.cs'.
            //     [InterceptsLocation(@"\_\Program.cs", 5, 3)]
            ? Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"@""\_\Program.cs""").WithArguments(@"C:\_\Program.cs").WithLocation(11, 25)
 
            // /My/Machine/Specific/Path/Program.cs(11,25): error CS9139: Cannot intercept: compilation does not contain a file with path '/My/Machine/Specific/Path/\_\Program.cs'.
            //     [InterceptsLocation(@"\_\Program.cs", 5, 3)]
            : Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"@""\_\Program.cs""").WithArguments(@"/My/Machine/Specific/Path/\_\Program.cs").WithLocation(11, 25));
    }
 
    [Fact]
    public void PathMapping_04()
    {
        // Test when unmapped file paths are distinct, but mapped paths are equal.
        var source1 = """
            using System.Runtime.CompilerServices;
            using System;
 
            namespace NS1;
 
            class C
            {
                public static void M0()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
 
                [InterceptsLocation(@"/_/Program.cs", 11, 9)]
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        var source2 = """
            using System.Runtime.CompilerServices;
            using System;
 
            namespace NS2;
 
            class C
            {
                public static void M0()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        var pathPrefix1 = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path1\""" : "/My/Machine/Specific/Path1/";
        var pathPrefix2 = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path2\""" : "/My/Machine/Specific/Path2/";
        var path1 = pathPrefix1 + "Program.cs";
        var path2 = pathPrefix2 + "Program.cs";
        var pathMap = ImmutableArray.Create(
            new KeyValuePair<string, string>(pathPrefix1, "/_/"),
            new KeyValuePair<string, string>(pathPrefix2, "/_/")
            );
 
        var comp = CreateCompilation(
            new[] { (source1, path1), (source2, path2), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugDll.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)));
        comp.VerifyEmitDiagnostics(
            // C:\My\Machine\Specific\Path1\Program.cs(16,25): error CS9152: Cannot intercept a call in file with path '/_/Program.cs' because multiple files in the compilation have this path.
            //     [InterceptsLocation(@"/_/Program.cs", 11, 9)]
            Diagnostic(ErrorCode.ERR_InterceptorNonUniquePath, @"@""/_/Program.cs""").WithArguments("/_/Program.cs").WithLocation(16, 25));
    }
 
    [Fact]
    public void PathMapping_05()
    {
        // Pathmap replacement contains backslashes, and attribute path contains backslashes.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
 
                [InterceptsLocation(@"\_\Program.cs", 5, 3)]
                public void Interceptor() => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path\""" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "Program.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, @"\_\"));
 
        var verifier = CompileAndVerify(
            new[] { (source, path), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)),
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void PathMapping_06()
    {
        // Pathmap mixes slashes and backslashes, attribute path is normalized to slashes
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
 
                [InterceptsLocation(@"/_/Program.cs", 5, 3)]
                public void Interceptor() => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path\""" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "Program.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, @"\_/"));
 
        var comp = CreateCompilation(
            [(source, path), s_attributesSource],
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)));
        comp.VerifyEmitDiagnostics(
            PlatformInformation.IsWindows
                // C:\My\Machine\Specific\Path\Program.cs(11,25): error CS9139: Cannot intercept: compilation does not contain a file with path 'C:\_\Program.cs'.
                //     [InterceptsLocation(@"/_/Program.cs", 5, 3)]
                ? Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"@""/_/Program.cs""").WithArguments(PlatformInformation.IsWindows ? @"C:\_\Program.cs" : "/_/Program.cs").WithLocation(11, 25)
 
                // /My/Machine/Specific/Path/Program.cs(11,25): error CS9139: Cannot intercept: compilation does not contain a file with path '/_/Program.cs'.
                //     [InterceptsLocation(@"/_/Program.cs", 5, 3)]
                : Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"@""/_/Program.cs""").WithArguments("/_/Program.cs").WithLocation(11, 25));
    }
 
    [Fact]
    public void PathMapping_07()
    {
        // Pathmap replacement mixes slashes and backslashes, attribute path matches it
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
 
                [InterceptsLocation(@"\_/Program.cs", 5, 3)]
                public void Interceptor() => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path\""" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "Program.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, @"\_/"));
 
        var verifier = CompileAndVerify(
            new[] { (source, path), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)),
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void PathNormalization_01()
    {
        // No pathmap is present and slashes in the attribute match the FilePath on the syntax tree.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
 
                [InterceptsLocation("src/Program.cs", 9, 11)]
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        var verifier = CompileAndVerify(
            new[] { (source, "src/Program.cs"), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void PathNormalization_02()
    {
        // No pathmap is present and backslashes in the attribute match the FilePath on the syntax tree.
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
 
                [InterceptsLocation(@"src\Program.cs", 9, 11)]
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        var verifier = CompileAndVerify(
            new[] { (source, @"src\Program.cs"), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void PathNormalization_03()
    {
        // Relative paths do not have slashes normalized when pathmap is not present
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
 
                [InterceptsLocation(@"src/Program.cs", 9, 11)]
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, @"src\Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // src\Program.cs(14,25): error CS9140: Cannot intercept: compilation does not contain a file with path 'src/Program.cs'. Did you mean to use path 'src\Program.cs'?
            //     [InterceptsLocation(@"src/Program.cs", 9, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilationWithCandidate, @"@""src/Program.cs""").WithArguments("src/Program.cs", @"src\Program.cs").WithLocation(14, 25));
    }
 
    [Fact]
    public void PathNormalization_04()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
 
                [InterceptsLocation("C:/src/Program.cs", 9, 11)]
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        if (PlatformInformation.IsWindows)
        {
            var verifier = CompileAndVerify(new[] { (source, @"C:\src\Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
        else
        {
            var comp = CreateCompilation(new[] { (source, @"/src/Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
            comp.VerifyEmitDiagnostics(
                // /src/Program.cs(14,25): error CS9139: Cannot intercept: compilation does not contain a file with path '/src/C:/src/Program.cs'.
                //     [InterceptsLocation("C:/src/Program.cs", 9, 11)]
                Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""C:/src/Program.cs""").WithArguments("/src/C:/src/Program.cs").WithLocation(14, 25));
        }
    }
 
    [Fact]
    public void PathNormalization_05()
    {
        // paths in attribute as well as syntax tree have mixed slashes
        var source = """
            using System.Runtime.CompilerServices;
            using System;
 
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
 
                [InterceptsLocation(@"C:\src/Program.cs", 9, 11)]
                public void Interceptor() => Console.Write(1);
            }
            """;
 
        if (PlatformInformation.IsWindows)
        {
            var verifier = CompileAndVerify(new[] { (source, @"C:/src\Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
            verifier.VerifyDiagnostics();
        }
        else
        {
            var comp = CreateCompilation(new[] { (source, @"/src/Program.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
            comp.VerifyEmitDiagnostics(
                // /src/Program.cs(14,25): error CS9139: Cannot intercept: compilation does not contain a file with path '/src/C:\src/Program.cs'.
                //     [InterceptsLocation(@"C:\src/Program.cs", 9, 11)]
                Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"@""C:\src/Program.cs""").WithArguments(@"/src/C:\src/Program.cs").WithLocation(14, 25));
        }
    }
 
    [Fact]
    public void RelativePaths_01()
    {
        var source = """
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        var source2 = """
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/Program.cs", 6, 11)]
                internal static void Interceptor(this C c) => Console.Write(1);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source, PlatformInformation.IsWindows ? @"C:\src\Program.cs" : "/src/Program.cs"), (source2, PlatformInformation.IsWindows ? @"C:\obj\Generated.cs" : "/obj/Generated.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void RelativePaths_02()
    {
        var source = """
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        // interceptor containing file does not have absolute path
        // Therefore we don't resolve the relative path
        var source2 = """
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/Program.cs", 6, 11)]
                internal static void Interceptor(this C c) => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, PlatformInformation.IsWindows ? @"C:\src\Program.cs" : "/src/Program.cs"), (source2, PlatformInformation.IsWindows ? @"Generator\Generated.cs" : "Generator/Generated.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Generator\Generated.cs(6,25): error CS9139: Cannot intercept: compilation does not contain a file with path '../src/Program.cs'.
            //     [InterceptsLocation("../src/Program.cs", 6, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""../src/Program.cs""").WithArguments("../src/Program.cs").WithLocation(6, 25));
    }
 
    [Fact]
    public void RelativePaths_03()
    {
        // intercepted file does not have absolute path
        var source = """
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        var source2 = """
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/Program.cs", 6, 11)]
                internal static void Interceptor(this C c) => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, PlatformInformation.IsWindows ? @"src\Program.cs" : "src/Program.cs"), (source2, PlatformInformation.IsWindows ? @"C:\obj\Generated.cs" : "/obj/Generated.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // C:\obj\Generated.cs(6,25): error CS9139: Cannot intercept: compilation does not contain a file with path 'C:\src\Program.cs'.
            //     [InterceptsLocation("../src/Program.cs", 6, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""../src/Program.cs""").WithArguments(PlatformInformation.IsWindows ? @"C:\src\Program.cs" : "/src/Program.cs").WithLocation(6, 25)
            );
    }
 
    [Fact]
    public void RelativePaths_04()
    {
        var source = """
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        // The relative path resolution of `C:\..` is just `C:\` (and `/..` resolves to `/`).
        var source2 = """
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation("../../src/Program.cs", 6, 11)]
                internal static void Interceptor(this C c) => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, PlatformInformation.IsWindows ? @"C:\src\Program.cs" : "/src/Program.cs"), (source2, PlatformInformation.IsWindows ? @"C:\obj\Generated.cs" : "/obj/Generated.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RelativePaths_05()
    {
        var source = """
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        var source2 = """
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/./Program.cs", 6, 11)]
                internal static void Interceptor(this C c) => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, PlatformInformation.IsWindows ? @"C:\src\Program.cs" : "/src/Program.cs"), (source2, PlatformInformation.IsWindows ? @"C:\obj\Generated.cs" : "/obj/Generated.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RelativePaths_06()
    {
        var source = """
            class C
            {
                public static void Main()
                {
                    C c = new C();
                    c.M();
                }
 
                public void M() => throw null!;
            }
            """;
 
        var source2 = """
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/Program.cs/.", 6, 11)]
                internal static void Interceptor(this C c) => Console.Write(1);
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, PlatformInformation.IsWindows ? @"C:\src\Program.cs" : "/src/Program.cs"), (source2, PlatformInformation.IsWindows ? @"C:\obj\Generated.cs" : "/obj/Generated.cs"), s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void RelativePaths_07()
    {
        var source = """
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
            }
            """;
 
        var source2 = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/Program.cs", 2, 3)]
                public static void Interceptor(this C c) => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """C:\My\Machine\Specific\Path\""" : "/My/Machine/Specific/Path/";
        var path = pathPrefix + "src/Program.cs";
        var path2 = pathPrefix + "obj/Generated.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, "/_/"));
 
        var verifier = CompileAndVerify(
            new[] { (source, path), (source2, path2), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)),
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void RelativePaths_08()
    {
        // SyntaxTree file paths are not absolute. Relative path resolution is not performed.
        var source = """
            C c = new C();
            c.M();
 
            class C
            {
                public void M() => throw null!;
            }
            """;
 
        var source2 = """
            using System.Runtime.CompilerServices;
            using System;
 
            static class Interceptors
            {
                [InterceptsLocation("../src/Program.cs", 2, 3)]
                public static void Interceptor(this C c) => Console.Write(1);
            }
            """;
        var pathPrefix = PlatformInformation.IsWindows ? """My\Machine\Specific\Path\""" : "My/Machine/Specific/Path/";
        var path = pathPrefix + "src/Program.cs";
        var path2 = pathPrefix + "obj/Generated.cs";
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(pathPrefix, "/_/"));
 
        var comp = CreateCompilation(
            new[] { (source, path), (source2, path2), s_attributesSource },
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)));
        comp.VerifyEmitDiagnostics(
            // My\Machine\Specific\Path\obj/Generated.cs(6,25): error CS9139: Cannot intercept: compilation does not contain a file with path '../src/Program.cs'.
            //     [InterceptsLocation("../src/Program.cs", 2, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorPathNotInCompilation, @"""../src/Program.cs""").WithArguments("../src/Program.cs").WithLocation(6, 25));
    }
 
    [Fact]
    public void OldVersusNewResolutionStrategy()
    {
        // relative path resolution will match a file (and the node referenced is not interceptable)
        // exact mapped resolution will match a *different* file (and the node referenced is interceptable)
        var source1 = ("""
            class C1
            {
                void M1()
                {
                    var _ =
                        C.Interceptable;
                }
            }
            """, PlatformInformation.IsWindows ? @"C:\src1\file1.cs" : "/src1/file1.cs");
 
        var directory2 = PlatformInformation.IsWindows ? @"C:\src2\" : "/src2/";
        var path2 = PlatformInformation.IsWindows ? @"C:\src2\file1.cs" : "/src2/file1.cs";
        var source2 = ("""
            class C2
            {
                static void Main()
                {
                    // var _ =
                        C.Interceptable();
                }
            }
 
            class C
            {
                public static void Interceptable() => throw null!;
            }
            """, path2);
 
        var source3 = ("""
            using System.Runtime.CompilerServices;
            using System;
 
            class Interceptors
            {
                [InterceptsLocation("./file1.cs", 6, 15)] // 1
                public static void Interceptor() => Console.Write(1);
            }
            """, PlatformInformation.IsWindows ? @"C:\src1\interceptors.cs" : "/src1/interceptors.cs");
 
        // Demonstrate that "relative path" resolution happens first by triggering the not interceptable error.
        var pathMap = ImmutableArray.Create(new KeyValuePair<string, string>(directory2, "./"));
        var comp = CreateCompilation([source1, source2, source3, s_attributesSource],
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)));
        comp.VerifyEmitDiagnostics(
            // C:\src1\interceptors.cs(6,6): error CS9151: Possible method name 'Interceptable' cannot be intercepted because it is not being invoked.
            //     [InterceptsLocation("./file1.cs", 6, 15)] // 1
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, @"InterceptsLocation(""./file1.cs"", 6, 15)").WithArguments("Interceptable").WithLocation(6, 6));
 
        // excluding 'source1' from the compilation, we fall back to exact match of mapped path, and interception is successful.
        var verifier = CompileAndVerify([source2, source3, s_attributesSource],
            parseOptions: RegularWithInterceptors,
            options: TestOptions.DebugExe.WithSourceReferenceResolver(
                new SourceFileResolver(ImmutableArray<string>.Empty, null, pathMap)),
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterceptorUnmanagedCallersOnly()
    {
        var source = """
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            using System;
 
            C.Interceptable();
 
            class C
            {
                public static void Interceptable() { }
            }
 
            static class D
            {
                [InterceptsLocation("Program.cs", 5, 3)]
                [UnmanagedCallersOnly]
                public static void Interceptor() { }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source, "Program.cs"), s_attributesSource, (UnmanagedCallersOnlyAttributeDefinition, "UnmanagedCallersOnlyAttribute.cs") }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
                // Program.cs(14,6): error CS9161: An interceptor cannot be marked with 'UnmanagedCallersOnlyAttribute'.
                //     [InterceptsLocation("Program.cs", 5, 3)]
                Diagnostic(ErrorCode.ERR_InterceptorCannotUseUnmanagedCallersOnly, @"InterceptsLocation(""Program.cs"", 5, 3)").WithLocation(14, 6));
    }
 
    [Fact]
    public void InterceptorUnmanagedCallersOnly_Checksum()
    {
        var source = CSharpTestSource.Parse("""
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
            using System;
 
            C.Interceptable();
 
            class C
            {
                public static void Interceptable() { }
            }
            """, "Program.cs", RegularWithInterceptors);
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System.Runtime.CompilerServices;
            using System.Runtime.InteropServices;
 
            static class D
            {
                [InterceptsLocation({{locationSpecifier.Version}}, "{{locationSpecifier.Data}}")]
                [UnmanagedCallersOnly]
                public static void Interceptor() { }
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, s_attributesTree, CSharpTestSource.Parse(UnmanagedCallersOnlyAttributeDefinition, "UnmanagedCallersOnlyAttribute.cs", RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9161: An interceptor cannot be marked with 'UnmanagedCallersOnlyAttribute'.
            //     [InterceptsLocation(1, "SnNcyOJQR8oIDrJpnwBmCWIAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptorCannotUseUnmanagedCallersOnly, "InterceptsLocation").WithLocation(6, 6));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70841")]
    public void InterceptorEnumBaseMethod()
    {
        var program = ("""
            using System;
 
            var value = MyEnum.Second;
            Console.WriteLine(value.ToString());
 
            public enum MyEnum
            {
                First,
                Second,
            }
            """, "Program.cs");
 
        var interceptor = ("""
            using System.Runtime.CompilerServices;
 
            namespace MyInterceptors
            {
                public static class Interceptors
                {
                    [InterceptsLocation(@"Program.cs", 4, 25)]
                    public static string OtherToString(this System.Enum value)
                        => "Wrong Value" + value;
                }
            }
            """, "Interceptor.cs");
 
        var verifier = CompileAndVerify(new[] { program, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Second");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       21 (0x15)
              .maxstack  1
              .locals init (MyEnum V_0) //value
              IL_0000:  ldc.i4.1
              IL_0001:  stloc.0
              IL_0002:  ldloca.s   V_0
              IL_0004:  constrained. "MyEnum"
              IL_000a:  callvirt   "string object.ToString()"
              IL_000f:  call       "void System.Console.WriteLine(string)"
              IL_0014:  ret
            }
            """);
 
        verifier = CompileAndVerify(new[] { program, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Wrong ValueSecond");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       17 (0x11)
              .maxstack  1
              IL_0000:  ldc.i4.1
              IL_0001:  box        "MyEnum"
              IL_0006:  call       "string MyInterceptors.Interceptors.OtherToString(System.Enum)"
              IL_000b:  call       "void System.Console.WriteLine(string)"
              IL_0010:  ret
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70841")]
    public void InterceptorStructBaseMethod()
    {
        var program = ("""
            using System;
 
            MyStruct value = default;
            Console.WriteLine(value.Equals((object)1));
 
            public struct MyStruct { }
            """, "Program.cs");
 
        var interceptor = ("""
            using System.Runtime.CompilerServices;
 
            namespace MyInterceptors
            {
                public static class Interceptors
                {
                    [InterceptsLocation(@"Program.cs", 4, 25)]
                    public static bool Equals(this System.ValueType value, object other) => true;
                }
            }
            """, "Interceptor.cs");
 
        var verifier = CompileAndVerify(new[] { program, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "False");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       33 (0x21)
              .maxstack  2
              .locals init (MyStruct V_0) //value
              IL_0000:  ldloca.s   V_0
              IL_0002:  initobj    "MyStruct"
              IL_0008:  ldloca.s   V_0
              IL_000a:  ldc.i4.1
              IL_000b:  box        "int"
              IL_0010:  constrained. "MyStruct"
              IL_0016:  callvirt   "bool object.Equals(object)"
              IL_001b:  call       "void System.Console.WriteLine(bool)"
              IL_0020:  ret
            }
            """);
 
        verifier = CompileAndVerify(new[] { program, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "True");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("<top-level-statements-entry-point>", """
            {
              // Code size       31 (0x1f)
              .maxstack  2
              .locals init (MyStruct V_0)
              IL_0000:  ldloca.s   V_0
              IL_0002:  initobj    "MyStruct"
              IL_0008:  ldloc.0
              IL_0009:  box        "MyStruct"
              IL_000e:  ldc.i4.1
              IL_000f:  box        "int"
              IL_0014:  call       "bool MyInterceptors.Interceptors.Equals(System.ValueType, object)"
              IL_0019:  call       "void System.Console.WriteLine(bool)"
              IL_001e:  ret
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70841")]
    public void InterceptorTypeParameterObjectMethod()
    {
        var program = ("""
            using System;
 
            M("a");
            void M<T>(T value)
            {
                Console.WriteLine(value.Equals((object)1));
            }
 
            public struct MyStruct { }
            """, "Program.cs");
 
        var interceptor = ("""
            using System.Runtime.CompilerServices;
 
            namespace MyInterceptors
            {
                public static class Interceptors
                {
                    [InterceptsLocation(@"Program.cs", 6, 29)]
                    public static new bool Equals(this object value, object other) => true;
                }
            }
            """, "Interceptor.cs");
 
        var verifier = CompileAndVerify(new[] { program, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "False");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("Program.<<Main>$>g__M|0_0<T>(T)", """
            {
              // Code size       25 (0x19)
              .maxstack  2
              IL_0000:  ldarga.s   V_0
              IL_0002:  ldc.i4.1
              IL_0003:  box        "int"
              IL_0008:  constrained. "T"
              IL_000e:  callvirt   "bool object.Equals(object)"
              IL_0013:  call       "void System.Console.WriteLine(bool)"
              IL_0018:  ret
            }
            """);
 
        verifier = CompileAndVerify(new[] { program, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "True");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("Program.<<Main>$>g__M|0_0<T>(T)", """
            {
              // Code size       23 (0x17)
              .maxstack  2
              IL_0000:  ldarg.0
              IL_0001:  box        "T"
              IL_0006:  ldc.i4.1
              IL_0007:  box        "int"
              IL_000c:  call       "bool MyInterceptors.Interceptors.Equals(object, object)"
              IL_0011:  call       "void System.Console.WriteLine(bool)"
              IL_0016:  ret
            }
            """);
    }
 
    [Theory]
    [WorkItem("https://github.com/dotnet/roslyn/issues/70841")]
    [InlineData("where T : struct, I")]
    [InlineData("where T : I")]
    public void InterceptorStructConstrainedInterfaceMethod(string constraints)
    {
        var program = ($$"""
            using System;
 
            C.M(default(MyStruct));
 
            class C
            {
                public static void M<T>(T t) {{constraints}}
                {
                    t.IM();
                }
            }
 
            public struct MyStruct : I
            {
                public void IM()
                {
                    Console.Write("Original");
                }
            }
 
            public interface I
            {
                void IM();
            }
            """, "Program.cs");
 
        var interceptor = ("""
            using System.Runtime.CompilerServices;
            using System;
 
            namespace MyInterceptors
            {
                public static class Interceptors
                {
                    [InterceptsLocation(@"Program.cs", 9, 11)]
                    public static void IM(this I @this) { Console.Write("Interceptor"); }
                }
            }
            """, "Interceptor.cs");
 
        var verifier = CompileAndVerify(new[] { program, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Original");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M<T>(T)", """
            {
              // Code size       14 (0xe)
              .maxstack  1
              IL_0000:  ldarga.s   V_0
              IL_0002:  constrained. "T"
              IL_0008:  callvirt   "void I.IM()"
              IL_000d:  ret
            }
            """);
 
        verifier = CompileAndVerify(new[] { program, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Interceptor");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.M<T>(T)", """
            {
              // Code size       12 (0xc)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  box        "T"
              IL_0006:  call       "void MyInterceptors.Interceptors.IM(I)"
              IL_000b:  ret
            }
            """);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70311")]
    public void InterceptorGeneric_01()
    {
        var source = ("""
            #nullable enable
            using System;
 
            class C
            {
                public string Method1<T>(T arg) => "Original";
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C();
                    string? x = null;
 
                    Console.Write(c.Method1(x));
                }
            }
            """, "Program.cs");
 
        var interceptor = ("""
            #nullable enable
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 16, 25)]
                public static string Generic<T>(this C s, T arg) => "Interceptor";
            }
            """, "Interceptor.cs");
 
        var verifier = CompileAndVerify(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Original");
        verifier.VerifyDiagnostics();
 
        verifier = CompileAndVerify(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Interceptor");
        verifier.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70311")]
    public void InterceptorGeneric_02()
    {
        var source = ("""
            #nullable enable
            using System;
 
            class C<T>
            {
                public string Method1<U>(U arg) => "Original";
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C<int>();
                    string? x = null;
 
                    Console.Write(c.Method1(x));
                }
            }
            """, "Program.cs");
 
        var interceptor = ("""
            #nullable enable
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 16, 25)]
                public static string Generic<T, U>(this C<T> s, U arg) => "Interceptor";
            }
            """, "Interceptor.cs");
 
        var verifier = CompileAndVerify(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Original");
        verifier.VerifyDiagnostics();
 
        verifier = CompileAndVerify(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors, expectedOutput: "Interceptor");
        verifier.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70311")]
    public void InterceptorGeneric_03()
    {
        var source = ("""
            #nullable enable
 
            class C<T>
            {
                public string? Method1<U>(U arg) => null;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C<int>();
                    string? x = null;
 
                    c.Method1(x);
                }
            }
            """, "Program.cs");
 
        var interceptor = ("""
            #nullable enable
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static string? Generic<T, U>(this T s, U arg) => arg?.ToString();
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
 
        comp = CreateCompilation(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(6,6): error CS9144: Cannot intercept method 'C<int>.Method1<string>(string)' with interceptor 'D.Generic<int, string>(int, string)' because the signatures do not match.
            //     [InterceptsLocation("Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_InterceptorSignatureMismatch, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("C<int>.Method1<string>(string)", "D.Generic<int, string>(int, string)").WithLocation(6, 6));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70311")]
    public void InterceptorGeneric_04()
    {
        // interceptor type parameter substitution meets constraints
        var source = ("""
            #nullable enable
 
            class C<T>
            {
                public string? Method1<U>(U arg) => null;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C<int>();
                    string? x = null;
 
                    c.Method1(x);
                }
            }
            """, "Program.cs");
 
        var interceptor = ("""
            #nullable enable
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static string? Generic<T, U>(this C<T> s, U arg) where T : struct => arg?.ToString();
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
 
        comp = CreateCompilation(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/70311")]
    public void InterceptorGeneric_05()
    {
        // interceptor type parameter substitution violates constraints
        var source = ("""
            #nullable enable
 
            class C<T>
            {
                public string? Method1<U>(U arg) => null;
            }
 
            static class Program
            {
                public static void Main()
                {
                    var c = new C<int>();
                    string? x = null;
 
                    c.Method1(x);
                }
            }
            """, "Program.cs");
 
        var interceptor = ("""
            #nullable enable
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 15, 11)]
                public static string? Generic<T, U>(this C<T> s, U arg) where T : class => arg?.ToString();
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics();
 
        comp = CreateCompilation(new[] { source, interceptor, s_attributesSource }, parseOptions: RegularWithInterceptors);
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(6,6): error CS0452: The type 'int' must be a reference type in order to use it as parameter 'T' in the generic type or method 'D.Generic<T, U>(C<T>, U)'
            //     [InterceptsLocation("Program.cs", 15, 11)]
            Diagnostic(ErrorCode.ERR_RefConstraintNotSatisfied, @"InterceptsLocation(""Program.cs"", 15, 11)").WithArguments("D.Generic<T, U>(C<T>, U)", "T", "int").WithLocation(6, 6));
    }
 
    [Theory]
    [CombinatorialData]
    public void GetInterceptorMethod_01(bool checkBeforeDiagnostics)
    {
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 1, 3)]
                public static void Interceptor() => Console.Write(1);
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: RegularWithInterceptors);
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        if (checkBeforeDiagnostics)
        {
            check();
        }
 
        comp.VerifyEmitDiagnostics();
 
        if (!checkBeforeDiagnostics)
        {
            check();
        }
 
        void check()
        {
            var interceptor = model.GetInterceptorMethod(call);
            Assert.Equal("void D.Interceptor()", interceptor.ToTestDisplayString());
        }
    }
 
    [Theory]
    [CombinatorialData]
    public void GetInterceptorMethod_02(bool checkBeforeDiagnostics)
    {
        var source = ("""
            C.M(42);
 
            class C
            {
                public static void M<T>(T t) => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            static class D
            {
                [InterceptsLocation("Program.cs", 1, 3)]
                public static void Interceptor<T>(T t) => Console.Write(t);
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: RegularWithInterceptors);
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        if (checkBeforeDiagnostics)
        {
            check();
        }
 
        comp.VerifyEmitDiagnostics();
 
        if (!checkBeforeDiagnostics)
        {
            check();
        }
 
        void check()
        {
            var interceptor = model.GetInterceptorMethod(call);
            Assert.Equal("void D.Interceptor<T>(T t)", interceptor.ToTestDisplayString());
            Assert.True(interceptor!.IsDefinition);
        }
    }
 
    [Fact]
    public void GetInterceptorMethod_03()
    {
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                static class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor() => Console.Write(1);
                }
            }
 
            class E : Attribute
            {
                [E]
                public void M()
                {
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.D.Interceptor()", interceptor.ToTestDisplayString());
        Assert.True(interceptor.GetSymbol()!.HasComplete(CompletionPart.Attributes));
 
        // Do not bind attributes on methods in irrelevant namespaces when discovering interceptors
        var EM = comp.GetMember<MethodSymbol>("E.M");
        Assert.False(EM.HasComplete(CompletionPart.Attributes));
 
        comp.VerifyEmitDiagnostics();
 
        Assert.True(EM.HasComplete(CompletionPart.Attributes));
    }
 
    [Fact]
    public void GetInterceptorMethod_04()
    {
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace NotInterceptors
            {
                static class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor() => Console.Write(1);
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        // Interceptor declaration is erroneous (not within expected namespace), we don't care about failing to discover it.
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Null(interceptor);
 
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(8,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NotInterceptors</InterceptorsNamespaces>' to your project.
            //         [InterceptsLocation("Program.cs", 1, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NotInterceptors</InterceptorsNamespaces>").WithLocation(8, 10));
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Null(interceptor);
    }
 
    [Fact]
    public void GetInterceptorMethod_05()
    {
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor() => Console.Write(1);
                }
 
                class E : Attribute
                {
                    [E]
                    public void M()
                    {
                    }
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.D.Interceptor()", interceptor.ToTestDisplayString());
        Assert.True(interceptor.GetSymbol()!.HasComplete(CompletionPart.Attributes));
 
        // Possibly irrelevant attributes within interceptors namespaces are still bound when discovering interceptors.
        // https://github.com/dotnet/roslyn/issues/72410: perhaps QuickAttributes should be used in order to bail out in some cases.
        var EM = comp.GetMember<MethodSymbol>("Interceptors.E.M");
        Assert.True(EM.HasComplete(CompletionPart.Attributes));
 
        comp.VerifyEmitDiagnostics();
 
        Assert.True(EM.HasComplete(CompletionPart.Attributes));
    }
 
    [Fact]
    public void GetInterceptorMethod_06()
    {
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                static class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor1(int i) => Console.Write(i);
 
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor2() => Console.Write(2);
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Null(interceptor);
 
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(8,10): error CS9153: The indicated call is intercepted multiple times.
            //         [InterceptsLocation("Program.cs", 1, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 1, 3)").WithLocation(8, 10),
            // Interceptor.cs(11,10): error CS9153: The indicated call is intercepted multiple times.
            //         [InterceptsLocation("Program.cs", 1, 3)]
            Diagnostic(ErrorCode.ERR_DuplicateInterceptor, @"InterceptsLocation(""Program.cs"", 1, 3)").WithLocation(11, 10));
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Null(interceptor);
    }
 
    [Fact]
    public void GetInterceptorMethod_07()
    {
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                static class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor1() => Console.Write(1);
                }
            }
            
            namespace NotInterceptors
            {
                static class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor2() => Console.Write(2);
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.D.Interceptor1()", interceptor.ToTestDisplayString());
 
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(17,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);NotInterceptors</InterceptorsNamespaces>' to your project.
            //         [InterceptsLocation("Program.cs", 1, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);NotInterceptors</InterceptorsNamespaces>").WithLocation(17, 10));
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.D.Interceptor1()", interceptor.ToTestDisplayString());
    }
 
    [Fact]
    public void GetInterceptorMethod_08()
    {
        // Demonstrate that nested types are searched for InterceptsLocationAttributes
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                static class Outer
                {
                    public static class D
                    {
                        [InterceptsLocation("Program.cs", 1, 3)]
                        public static void Interceptor1() => Console.Write(1);
                    }
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.Outer.D.Interceptor1()", interceptor.ToTestDisplayString());
 
        comp.VerifyEmitDiagnostics();
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.Outer.D.Interceptor1()", interceptor.ToTestDisplayString());
    }
 
    [Theory]
    [CombinatorialData]
    public void GetInterceptorMethod_09(bool featureExists)
    {
        // InterceptorsNamespaces is empty or does not exist
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                static class Outer
                {
                    public static class D
                    {
                        [InterceptsLocation("Program.cs", 1, 3)]
                        public static void Interceptor1() => Console.Write(1);
                    }
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: featureExists ? TestOptions.Regular.WithFeature("InterceptorsNamespaces", "") : TestOptions.Regular);
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        Assert.Null(model.GetInterceptorMethod(call));
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(10,14): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);Interceptors</InterceptorsNamespaces>' to your project.
            //             [InterceptsLocation("Program.cs", 1, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);Interceptors</InterceptorsNamespaces>").WithLocation(10, 14));
        Assert.Null(model.GetInterceptorMethod(call));
    }
 
    [Fact]
    public void GetInterceptorMethod_10()
    {
        // InterceptorsNamespaces has duplicates
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                static class Outer
                {
                    public static class D
                    {
                        [InterceptsLocation("Program.cs", 1, 3)]
                        public static void Interceptor1() => Console.Write(1);
                    }
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors;Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.Outer.D.Interceptor1()", interceptor.ToTestDisplayString());
 
        comp.VerifyEmitDiagnostics();
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.Outer.D.Interceptor1()", interceptor.ToTestDisplayString());
    }
 
    [Fact]
    public void GetInterceptorMethod_11()
    {
        // Compilation does not contain any interceptors
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var comp = CreateCompilation(new[] { source, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Null(interceptor);
 
        comp.VerifyEmitDiagnostics();
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Null(interceptor);
    }
 
    [Fact]
    public void GetInterceptorMethod_12()
    {
        // Compilation contains no files
        var comp = CreateCompilation([], parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors"));
 
        // We can't use GetInterceptorMethod without a SemanticModel and we can't get a SemanticModel when the compilation contains no trees.
        // But, we can exercise some internal API for theoretical edge cases to see if it is robust (does not throw, updates expected flags).
        ((SourceModuleSymbol)comp.SourceModule).DiscoverInterceptorsIfNeeded();
        Assert.True(comp.InterceptorsDiscoveryComplete);
    }
 
    [Theory]
    [InlineData("Interceptors")]
    [InlineData("Interceptors.Nested")]
    public void GetInterceptorMethod_13(string @namespace)
    {
        // Demonstrate that nested namespaces are searched for InterceptsLocationAttributes
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                namespace Nested
                {
                    public static class D
                    {
                        [InterceptsLocation("Program.cs", 1, 3)]
                        public static void Interceptor1() => Console.Write(1);
                    }
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", @namespace));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        var interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.Nested.D.Interceptor1()", interceptor.ToTestDisplayString());
 
        comp.VerifyEmitDiagnostics();
 
        interceptor = model.GetInterceptorMethod(call);
        Assert.Equal("void Interceptors.Nested.D.Interceptor1()", interceptor.ToTestDisplayString());
    }
 
    [Fact]
    public void GetInterceptorMethod_14()
    {
        // Interceptor is in a parent of the expected namespace. Not discovered.
        var source = ("""
            C.M();
 
            class C
            {
                public static void M() => throw null;
            }
            """, "Program.cs");
 
        var interceptorSource = ("""
            using System;
            using System.Runtime.CompilerServices;
 
            namespace Interceptors
            {
                public static class D
                {
                    [InterceptsLocation("Program.cs", 1, 3)]
                    public static void Interceptor1() => Console.Write(1);
                }
            }
            """, "Interceptor.cs");
 
        var comp = CreateCompilation(new[] { source, interceptorSource, s_attributesSource }, parseOptions: TestOptions.Regular.WithFeature("InterceptorsNamespaces", "Interceptors.Nested"));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var call = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
 
        Assert.Null(model.GetInterceptorMethod(call));
 
        comp.VerifyEmitDiagnostics(
            // Interceptor.cs(8,10): error CS9137: The 'interceptors' experimental feature is not enabled in this namespace. Add '<InterceptorsNamespaces>$(InterceptorsNamespaces);Interceptors</InterceptorsNamespaces>' to your project.
            //         [InterceptsLocation("Program.cs", 1, 3)]
            Diagnostic(ErrorCode.ERR_InterceptorsFeatureNotEnabled, @"InterceptsLocation(""Program.cs"", 1, 3)").WithArguments("<InterceptorsNamespaces>$(InterceptorsNamespaces);Interceptors</InterceptorsNamespaces>").WithLocation(8, 10));
 
        Assert.Null(model.GetInterceptorMethod(call));
    }
 
    // https://github.com/dotnet/roslyn/issues/72265
    // As part of the work to drop support for file path based interceptors, a significant number of existing tests here will need to be ported to checksum-based.
 
    [Fact]
    public void Checksum_01()
    {
        var source = CSharpTestSource.Parse("""
            class C
            {
                static void M() => throw null!;
 
                static void Main()
                {
                    M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)], expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        // again, but using the accessors for specifically retrieving the individual attribute arguments
        interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation({{locationSpecifier!.Version}}, "{{locationSpecifier.Data}}")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        verifier = CompileAndVerify([source, interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)], expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void Checksum_02()
    {
        var tree = CSharpTestSource.Parse("""
            class C
            {
                static void M() => throw null!;
 
                static void Main()
                {
                    M();
                    M();
                }
            }
            """.NormalizeLineEndings(), "path/to/Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(tree);
        var model = comp.GetSemanticModel(tree);
        if (tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().ToList() is not [var node, var otherNode])
        {
            throw ExceptionUtilities.Unreachable();
        }
 
        var locationSpecifier = model.GetInterceptableLocation(node);
        Assert.False(locationSpecifier!.Equals(null));
 
        // Verify behaviors of the public APIs.
        Assert.Equal("path/to/Program.cs(7,9)", locationSpecifier!.GetDisplayLocation());
        Assert.Equal(1, locationSpecifier.Version);
        Assert.Equal(locationSpecifier, locationSpecifier);
 
        Assert.NotSame(locationSpecifier, model.GetInterceptableLocation(node));
        Assert.Equal(locationSpecifier, model.GetInterceptableLocation(node));
        Assert.Equal(locationSpecifier.GetHashCode(), model.GetInterceptableLocation(node)!.GetHashCode());
 
        // If Data changes it might be the case that 'SourceText.GetContentHash()' has changed algorithms.
        // In this case we need to adjust the SourceMethodSymbolWithAttributes.DecodeInterceptsLocationAttribute impl to remain compatible with v1 and consider introducing a v2 which uses the new content hash algorithm.
        AssertEx.Equal("xRCCFCvTOZMORzSr/fZQFlIAAABQcm9ncmFtLmNz", locationSpecifier.Data);
        AssertEx.Equal("""[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "xRCCFCvTOZMORzSr/fZQFlIAAABQcm9ncmFtLmNz")]""", locationSpecifier.GetInterceptsLocationAttributeSyntax());
 
        var otherLocation = model.GetInterceptableLocation(otherNode)!;
        Assert.NotEqual(locationSpecifier, otherLocation);
        // While it is not incorrect for the HashCodes of these instances to be equal, we don't expect it in this case.
        Assert.NotEqual(locationSpecifier.GetHashCode(), otherLocation.GetHashCode());
 
        Assert.Equal("path/to/Program.cs(8,9)", otherLocation.GetDisplayLocation());
        AssertEx.Equal("xRCCFCvTOZMORzSr/fZQFmAAAABQcm9ncmFtLmNz", otherLocation.Data);
        AssertEx.Equal("""[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "xRCCFCvTOZMORzSr/fZQFmAAAABQcm9ncmFtLmNz")]""", otherLocation.GetInterceptsLocationAttributeSyntax());
 
    }
 
    [Fact]
    public void Checksum_03()
    {
        // Invalid base64
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation(1, "jB4qgCy292LkEGCwmD+R6AcAAAAJAAAAUHJvZ3JhbS5jcw===")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation([interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9231: The data argument to InterceptsLocationAttribute is not in the correct format.
            //     [InterceptsLocation(1, "jB4qgCy292LkEGCwmD+R6AcAAAAJAAAAUHJvZ3JhbS5jcw===")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDataInvalidFormat, "InterceptsLocation").WithLocation(6, 6));
    }
 
    [Fact]
    public void Checksum_04()
    {
        // Test invalid UTF-8 encoded to base64
 
        var builder = new BlobBuilder();
        // all zeros checksum and zero position
        builder.WriteBytes(value: 0, byteCount: 20);
 
        // write invalid utf-8
        builder.WriteByte(0xc0);
 
        var base64 = Convert.ToBase64String(builder.ToArray());
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation(1, "{{base64}}")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation([interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9231: The data argument to InterceptsLocationAttribute is not in the correct format.
            //     [InterceptsLocation(1, "AAAAAAAAAAAAAAAAAAAAAAAAAADA")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDataInvalidFormat, "InterceptsLocation").WithLocation(6, 6));
    }
 
    [Theory]
    [InlineData("")]
    [InlineData("AA==")]
    public void Checksum_05(string data)
    {
        // Test data value too small
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation(1, "{{data}}")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation([interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9231: The data argument to InterceptsLocationAttribute is not in the correct format.
            //     [InterceptsLocation(1, "")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDataInvalidFormat, "InterceptsLocation").WithLocation(6, 6));
    }
 
    [Fact]
    public void Checksum_06()
    {
        // Null data
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation(1, null)]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation([interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9231: The data argument to InterceptsLocationAttribute is not in the correct format.
            //     [InterceptsLocation(1, null)]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDataInvalidFormat, "InterceptsLocation").WithLocation(6, 6));
    }
 
    [Fact]
    public void Checksum_07()
    {
        // File not found
 
        var source = CSharpTestSource.Parse("""
            class C
            {
                static void M() => throw null!;
 
                static void Main()
                {
                    M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation({{locationSpecifier.Version}}, "{{locationSpecifier.Data}}")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp1 = CreateCompilation([interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp1.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9234: Cannot intercept a call in file 'Program.cs' because a matching file was not found in the compilation.
            //     [InterceptsLocation(1, "jB4qgCy292LkEGCwmD+R6FIAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationFileNotFound, "InterceptsLocation").WithArguments("Program.cs").WithLocation(6, 6));
    }
 
    [Fact]
    public void Checksum_08()
    {
        // Duplicate file
 
        var source = """
            class C
            {
                static void M() => throw null!;
 
                static void Main()
                {
                    M();
                }
            }
            """;
        var sourceTree1 = CSharpTestSource.Parse(source, path: "Program1.cs", options: RegularWithInterceptors);
 
        var comp = CreateCompilation(sourceTree1);
        var model = comp.GetSemanticModel(sourceTree1);
        var node = sourceTree1.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation({{locationSpecifier.Version}}, "{{locationSpecifier.Data}}")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp1 = CreateCompilation([
            sourceTree1,
            CSharpTestSource.Parse(source, path: "Program2.cs", options: RegularWithInterceptors),
            interceptors,
            CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp1.GetDiagnostics().Where(d => d.Location.SourceTree == interceptors).Verify(
            // Interceptors.cs(6,6): error CS9233: Cannot intercept a call in file 'Program1.cs' because it is duplicated elsewhere in the compilation.
            //     [InterceptsLocation(1, "jB4qgCy292LkEGCwmD+R6FIAAABQcm9ncmFtMS5jcw==")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationDuplicateFile, "InterceptsLocation").WithArguments("Program1.cs").WithLocation(6, 6));
    }
 
    [Fact]
    public void Checksum_09()
    {
        // Call can be intercepted syntactically but a semantic error occurs when actually performing it.
 
        var source = CSharpTestSource.Parse("""
            using System;
 
            class C
            {
                static Action P { get; } = null!;
 
                static void Main()
                {
                    P();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void P1(this C c) => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(5,6): error CS9207: Cannot intercept 'P' because it is not an invocation of an ordinary member method.
            //     [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "ZnP1PXDK5WDD07FTErR9eWUAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptableMethodMustBeOrdinary, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("P").WithLocation(5, 6));
    }
 
    [Fact]
    public void Checksum_10()
    {
        // Call cannot be intercepted syntactically
 
        var source = CSharpTestSource.Parse("""
            using System;
 
            static class C
            {
                public static void M(this object obj) => throw null!;
 
                static void Main()
                {
                    null();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        comp.VerifyEmitDiagnostics(
            // Program.cs(9,9): error CS0149: Method name expected
            //         null();
            Diagnostic(ErrorCode.ERR_MethodNameExpected, "null").WithLocation(9, 9));
 
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node);
        Assert.Null(locationSpecifier);
    }
 
    [Theory]
    [InlineData(-1)]
    [InlineData(0)]
    [InlineData(2)]
    [InlineData(9999)]
    public void Checksum_11(int version)
    {
        // Bad version
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
            using System.Runtime.CompilerServices;
 
            static class Interceptors
            {
                [InterceptsLocation({{version}}, "jB4qgCy292LkEGCwmD+R6AcAAAAJAAAAUHJvZ3JhbS5jcw===")]
                public static void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation([interceptors, CSharpTestSource.Parse(s_attributesSource.text, s_attributesSource.path, RegularWithInterceptors)]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9232: Version '0' of the interceptors format is not supported. The latest supported version is '1'.
            //     [InterceptsLocation(0, "jB4qgCy292LkEGCwmD+R6AcAAAAJAAAAUHJvZ3JhbS5jcw===")]
            Diagnostic(ErrorCode.ERR_InterceptsLocationUnsupportedVersion, "InterceptsLocation").WithArguments($"{version}").WithLocation(6, 6));
    }
 
    [Fact]
    public void Checksum_12()
    {
        // Attempt to insert null paths into InterceptableLocation.
 
        var tree = CSharpTestSource.Parse("""
            class C
            {
                static void M() => throw null!;
 
                static void Main()
                {
                    M();
                }
            }
            """.NormalizeLineEndings(), path: null, RegularWithInterceptors);
        Assert.Equal("", tree.FilePath);
 
        var comp = CreateCompilation(tree);
        var model = comp.GetSemanticModel(tree);
        var node = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
        Assert.Equal("(7,9)", locationSpecifier.GetDisplayLocation());
        AssertEx.Equal("""[global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "jB4qgCy292LkEGCwmD+R6FIAAAA=")]""", locationSpecifier.GetInterceptsLocationAttributeSyntax());
    }
 
    [Fact]
    public void ConditionalAccess_ReferenceType_01()
    {
        // Conditional access on a non-null value
        var source = CSharpTestSource.Parse("""
            class C
            {
                void M() => throw null!;
 
                static void Main()
                {
                    var c = new C();
                    c?.M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            #nullable enable
            using System;
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this C c) => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void Interceptors.M1(this C c)", method.ToTestDisplayString());
    }
 
    [Fact]
    public void ConditionalAccess_ReferenceType_02()
    {
        // Conditional access on a null value
        var source = CSharpTestSource.Parse("""
            #nullable enable
            using System;
 
            class C
            {
                void M() => throw null!;
 
                static void Main()
                {
                    C? c = null;
                    c?.M();
                    Console.Write(1);
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            #nullable enable
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this C c) => throw null!;
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void Interceptors.M1(this C c)", method.ToTestDisplayString());
    }
 
    [Fact]
    public void ConditionalAccess_NotAnInvocation()
    {
        // use a location specifier which refers to a conditional access that is not being invoked.
        var source = CSharpTestSource.Parse("""
            class C
            {
                int P => throw null!;
 
                static void Main()
                {
                    var c = new C();
                    _ = c?.P;
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = (CSharpSemanticModel)comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<MemberBindingExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocationInternal(node.Name, cancellationToken: default)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            #nullable enable
            using System;
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this C c) => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, s_attributesTree]);
        comp.VerifyEmitDiagnostics(
            // Interceptors.cs(6,6): error CS9151: Possible method name 'P' cannot be intercepted because it is not being invoked.
            //     [global::System.Runtime.CompilerServices.InterceptsLocationAttribute(1, "q2jDXUSFcU71GJHh7313cHEAAABQcm9ncmFtLmNz")]
            Diagnostic(ErrorCode.ERR_InterceptorNameNotInvoked, "global::System.Runtime.CompilerServices.InterceptsLocationAttribute").WithArguments("P").WithLocation(6, 6));
    }
 
    [Fact]
    public void ConditionalAccess_ValueType_01()
    {
        // Conditional access on a nullable value type with a non-null value
        // Note that we can't intercept a conditional-access with an extension due to https://github.com/dotnet/roslyn/issues/71657
        var source = CSharpTestSource.Parse("""
            partial struct S
            {
                void M() => throw null!;
 
                static void Main()
                {
                    S? s = new S();
                    s?.M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            partial struct S
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public void M1() => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void S.M1()", method.ToTestDisplayString());
    }
 
    [Fact]
    public void ConditionalAccess_ValueType_02()
    {
        // Conditional access on a nullable value type with a null value
        var source = CSharpTestSource.Parse("""
            using System;
 
            partial struct S
            {
                void M() => throw null!;
 
                static void Main()
                {
                    S? s = null;
                    s?.M();
                    Console.Write(1);
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            partial struct S
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public void M1() => throw null!;
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void S.M1()", method.ToTestDisplayString());
    }
 
    [Theory]
    [InlineData("p->M();")]
    [InlineData("(*p).M();")]
    public void PointerAccess_01(string invocation)
    {
        var source = CSharpTestSource.Parse($$"""
            struct S
            {
                void M() => throw null!;
 
                static unsafe void Main()
                {
                    S s = default;
                    S* p = &s;
                    {{invocation}}
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe);
        CompileAndVerify(comp, verify: Verification.Fails);
 
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            #nullable enable
            using System;
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this ref S s) => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify(
            [source, interceptors, s_attributesTree],
            options: TestOptions.UnsafeDebugExe,
            verify: Verification.Fails,
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void Interceptors.M1(this ref S s)", method.ToTestDisplayString());
    }
 
    [Theory]
    [CombinatorialData]
    public void PointerAccess_02([CombinatorialValues("p->M();", "(*p).M();")] string invocation, [CombinatorialValues("", "ref ")] string refKind)
    {
        // Original method is an extension
        var source = CSharpTestSource.Parse($$"""
            struct S
            {
                static unsafe void Main()
                {
                    S s = default;
                    S* p = &s;
                    {{invocation}}
                }
            }
 
            static class Ext
            {
                public static void M(this {{refKind}}S s) => throw null!;
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugExe);
        CompileAndVerify(comp, verify: Verification.Fails);
 
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            #nullable enable
            using System;
 
            static class Interceptors
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this {{refKind}}S s) => Console.Write(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify(
            [source, interceptors, s_attributesTree],
            options: TestOptions.UnsafeDebugExe,
            verify: Verification.Fails,
            expectedOutput: "1");
        verifier.VerifyDiagnostics();
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal($"void Interceptors.M1(this {refKind}S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void ReceiverCapturedToTemp_StructRvalueReceiver()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            public struct S
            {
                void M() => Console.WriteLine(0);
 
                public static void Main()
                {
                    new S().M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            public static class C
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this ref S s) => Console.WriteLine(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("S.Main", """
            {
              // Code size       16 (0x10)
              .maxstack  1
              .locals init (S V_0)
              IL_0000:  ldloca.s   V_0
              IL_0002:  initobj    "S"
              IL_0008:  ldloca.s   V_0
              IL_000a:  call       "void C.M1(ref S)"
              IL_000f:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void C.M1(this ref S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void ReceiverCapturedToTemp_StructInReceiver()
    {
        // Implicitly capture receiver to temp in 's.M()' because target method needs a writable reference.
        var source = CSharpTestSource.Parse("""
            using System;
 
            public struct S
            {
                void M() => Console.WriteLine(0);
 
                public static void Main()
                {
                    M0(new S());
                }
 
                static void M0(in S s)
                {
                    s.M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            public static class C
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this ref S s) => Console.WriteLine(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("S.M0", """
            {
              // Code size       15 (0xf)
              .maxstack  1
              .locals init (S V_0)
              IL_0000:  ldarg.0
              IL_0001:  ldobj      "S"
              IL_0006:  stloc.0
              IL_0007:  ldloca.s   V_0
              IL_0009:  call       "void C.M1(ref S)"
              IL_000e:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void C.M1(this ref S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void ReceiverNotCapturedToTemp_StructRefReceiver()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            public struct S
            {
                void M() => Console.WriteLine(0);
 
                public static void Main()
                {
                    S s = default;
                    M0(ref s);
                }
 
                static void M0(ref S s)
                {
                    s.M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            public static class C
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this ref S s) => Console.WriteLine(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("S.M0", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M1(ref S)"
              IL_0006:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void C.M1(this ref S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void ReceiverNotCapturedToTemp_StructReadonlyMethod()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            public struct S
            {
                readonly void M() => Console.WriteLine(0);
 
                public static void Main()
                {
                    M0(new S());
                }
 
                static void M0(in S s)
                {
                    s.M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            public static class C
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this in S s) => Console.WriteLine(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("S.M0", """
            {
              // Code size        7 (0x7)
              .maxstack  1
              IL_0000:  ldarg.0
              IL_0001:  call       "void C.M1(in S)"
              IL_0006:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void C.M1(this in S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void ReceiverNotCapturedToTemp_StructLvalueReceiver()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            public struct S
            {
                void M() => Console.WriteLine(0);
 
                public static void Main()
                {
                    M0(new S());
                }
 
                static void M0(S s)
                {
                    s.M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            public static class C
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this ref S s) => Console.WriteLine(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("S.M0", """
            {
              // Code size        8 (0x8)
              .maxstack  1
              IL_0000:  ldarga.s   V_0
              IL_0002:  call       "void C.M1(ref S)"
              IL_0007:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void C.M1(this ref S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void ReceiverNotCapturedToTemp_ByValueParameter()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            public class C
            {
                void M() => Console.WriteLine(0);
 
                public static void Main()
                {
                    new C().M();
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            public static class SC
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this C c) => Console.WriteLine(1);
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "1");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("C.Main", """
            {
              // Code size       11 (0xb)
              .maxstack  1
              IL_0000:  newobj     "C..ctor()"
              IL_0005:  call       "void SC.M1(C)"
              IL_000a:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void SC.M1(this C c)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void Receiver_RefReturn_NotCapturedToTemp()
    {
        var source = CSharpTestSource.Parse("""
            using System;
 
            public struct S
            {
                public int F;
 
                static S s;
                static ref S RS() => ref s;
 
                void M() => throw null!;
 
                public static void Main()
                {
                    RS().F = 1;
                    Console.Write(RS().F);
                    RS().M();
                    Console.Write(RS().F);
                }
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source);
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single(i => i.ToString() == "RS().M()");
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            public static class SC
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static void M1(this ref S s) => s.F = 2;
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        var verifier = CompileAndVerify([source, interceptors, s_attributesTree], expectedOutput: "12");
        verifier.VerifyDiagnostics();
        verifier.VerifyIL("S.Main", """
            {
              // Code size       52 (0x34)
              .maxstack  2
              IL_0000:  call       "ref S S.RS()"
              IL_0005:  ldc.i4.1
              IL_0006:  stfld      "int S.F"
              IL_000b:  call       "ref S S.RS()"
              IL_0010:  ldfld      "int S.F"
              IL_0015:  call       "void System.Console.Write(int)"
              IL_001a:  call       "ref S S.RS()"
              IL_001f:  call       "void SC.M1(ref S)"
              IL_0024:  call       "ref S S.RS()"
              IL_0029:  ldfld      "int S.F"
              IL_002e:  call       "void System.Console.Write(int)"
              IL_0033:  ret
            }
            """);
 
        comp = (CSharpCompilation)verifier.Compilation;
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        Assert.Equal("void SC.M1(this ref S s)", method.ToTestDisplayString());
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/71657")]
    public void CannotReturnRefToImplicitTemp()
    {
        var source = CSharpTestSource.Parse("""
            using System;
            using System.Diagnostics.CodeAnalysis;
 
            public ref struct S
            {
                static Span<int> Test()
                {
                    return new S().M();
                }
 
                [UnscopedRef]
                public Span<int> M() => default;
            }
            """, "Program.cs", RegularWithInterceptors);
 
        var comp = CreateCompilation(source, targetFramework: TargetFramework.Net90);
        comp.VerifyEmitDiagnostics(
            // Program.cs(8,16): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         return new S().M();
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "new S()").WithLocation(8, 16));
 
        var model = comp.GetSemanticModel(source);
        var node = source.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single(i => i.ToString() == "new S().M()");
        var locationSpecifier = model.GetInterceptableLocation(node)!;
 
        var interceptors = CSharpTestSource.Parse($$"""
            using System;
 
            static class D
            {
                {{locationSpecifier.GetInterceptsLocationAttributeSyntax()}}
                public static Span<int> M(this ref S s) => default;
            }
            """, "Interceptors.cs", RegularWithInterceptors);
 
        comp = CreateCompilation([source, interceptors, s_attributesTree], targetFramework: TargetFramework.Net90);
        comp.VerifyEmitDiagnostics(
            // Program.cs(8,16): error CS8156: An expression cannot be used in this context because it may not be passed or returned by reference
            //         return new S().M();
            Diagnostic(ErrorCode.ERR_RefReturnLvalueExpected, "new S()").WithLocation(8, 16));
 
        model = comp.GetSemanticModel(source);
        var method = model.GetInterceptorMethod(node);
        AssertEx.Equal("System.Span<System.Int32> D.M(this ref S s)", method.ToTestDisplayString());
    }
}