File: Symbols\Source\FileModifierTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Symbol.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.
 
#nullable disable
 
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Retargeting;
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;
 
public class FileModifierTests : CSharpTestBase
{
    [Fact]
    public void LangVersion()
    {
        var source = """
            file class C { }
            """;
 
        var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
        comp.VerifyDiagnostics(
            // (1,12): error CS8936: Feature 'file types' is not available in C# 10.0. Please use language version 11.0 or greater.
            // file class C { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "C").WithArguments("file types", "11.0").WithLocation(1, 12));
 
        comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void Nested_01()
    {
        var source = """
            class Outer
            {
                file class C { }
            }
            """;
 
        var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
        comp.VerifyDiagnostics(
            // (3,16): error CS8936: Feature 'file types' is not available in C# 10.0. Please use language version 11.0 or greater.
            //     file class C { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "C").WithArguments("file types", "11.0").WithLocation(3, 16),
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C { }
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16));
 
        comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C { }
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16));
    }
 
    [Fact]
    public void Nested_02()
    {
        var source = """
            file class Outer
            {
                class C { }
            }
            """;
 
        var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
        comp.VerifyDiagnostics(
            // (1,12): error CS8936: Feature 'file types' is not available in C# 10.0. Please use language version 11.0 or greater.
            // file class Outer
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "Outer").WithArguments("file types", "11.0").WithLocation(1, 12));
        verify();
 
        comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
        verify();
 
        void verify()
        {
            var outer = comp.GetMember<NamedTypeSymbol>("Outer");
            Assert.Equal(Accessibility.Internal, outer.DeclaredAccessibility);
            Assert.True(((SourceMemberContainerTypeSymbol)outer).IsFileLocal);
 
            var classC = comp.GetMember<NamedTypeSymbol>("Outer.C");
            Assert.Equal(Accessibility.Private, classC.DeclaredAccessibility);
            Assert.False(((SourceMemberContainerTypeSymbol)classC).IsFileLocal);
        }
    }
 
    [Fact]
    public void Nested_03()
    {
        var source = """
            file class Outer
            {
                file class C { }
            }
            """;
 
        var comp = CreateCompilation(source, parseOptions: TestOptions.Regular10);
        comp.VerifyDiagnostics(
            // (1,12): error CS8936: Feature 'file types' is not available in C# 10.0. Please use language version 11.0 or greater.
            // file class Outer
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "Outer").WithArguments("file types", "11.0").WithLocation(1, 12),
            // (3,16): error CS8936: Feature 'file types' is not available in C# 10.0. Please use language version 11.0 or greater.
            //     file class C { }
            Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion10, "C").WithArguments("file types", "11.0").WithLocation(3, 16),
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C { }
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16));
 
        comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C { }
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16));
    }
 
    [Fact]
    public void Nested_04()
    {
        var source = """
            file class Outer
            {
                public class C { }
            }
 
            class D
            {
                void M(Outer.C c) { } // 1
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (8,10): error CS9051: File-local type 'Outer.C' cannot be used in a member signature in non-file-local type 'D'.
            //     void M(Outer.C c) { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("Outer.C", "D").WithLocation(8, 10));
    }
 
    [Fact]
    public void Nested_05()
    {
        var source = """
            file class Outer
            {
                public class C
                {
                    void M1(Outer outer) { } // ok
                    void M2(C outer) { } // ok
                }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void Nested_06()
    {
        var source = """
            class A1
            {
                internal class A2 { }
            }
            file class B : A1
            {
            }
            class C : B.A2 // ok: base type is bound as A1.A2
            {
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void SameFileUse_01()
    {
        var source = """
            using System;
 
            file class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var symbol = comp.GetMember<NamedTypeSymbol>("C");
        AssertEx.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C", symbol.MetadataName);
 
        // The qualified name here is based on `SymbolDisplayCompilerInternalOptions.IncludeContainingFileForFileTypes`.
        // We don't actually look up based on the file-encoded name of the type.
        // This is similar to how generic types work (lookup based on 'C<T>' instead of 'C`1').
        verifier.VerifyIL("C@<tree 0>.M", @"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldc.i4.1
  IL_0001:  call       ""void System.Console.Write(int)""
  IL_0006:  ret
}");
 
        void symbolValidator(ModuleSymbol symbol)
        {
            Assert.Equal(new[] { "<Module>", "C", "Program", "Microsoft", "System" }, symbol.GlobalNamespace.GetMembers().Select(m => m.Name));
            var classC = symbol.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            Assert.Equal(new[] { "M", ".ctor" }, classC.MemberNames);
        }
    }
 
    [Fact]
    public void SameFileUse_02()
    {
        var source = """
            using System;
 
            file class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { ("", "file1.cs"), (source, "file2.cs") }, expectedOutput: "1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var symbol = comp.GetMember<NamedTypeSymbol>("C");
        AssertEx.Equal("<file2>F66382B88D8E28FDD21CEADA0DE847F8B00DA1324042DD28F8FFC58C454BD6188__C", symbol.MetadataName);
 
        // The qualified name here is based on `SymbolDisplayCompilerInternalOptions.IncludeContainingFileForFileTypes`.
        // We don't actually look up based on the file-encoded name of the type.
        // This is similar to how generic types work (lookup based on 'C<T>' instead of 'C`1').
        verifier.VerifyIL("C@file2.M", @"
{
  // Code size        7 (0x7)
  .maxstack  1
  IL_0000:  ldc.i4.1
  IL_0001:  call       ""void System.Console.Write(int)""
  IL_0006:  ret
}");
 
        void symbolValidator(ModuleSymbol symbol)
        {
            Assert.Equal(new[] { "<Module>", "C", "Program", "Microsoft", "System" }, symbol.GlobalNamespace.GetMembers().Select(m => m.Name));
            var classC = symbol.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            Assert.Equal(new[] { "M", ".ctor" }, classC.MemberNames);
        }
    }
 
    [Fact]
    public void FileEnum_01()
    {
        var source = """
            using System;
 
            file enum E
            {
                E1, E2
            }
 
            class Program
            {
                static void Main()
                {
                    Console.Write(E.E2);
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "E2", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var symbol = comp.GetMember<NamedTypeSymbol>("E");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__E", symbol.MetadataName);
 
        verifier.VerifyIL("Program.Main", @"
{
  // Code size       12 (0xc)
  .maxstack  1
  IL_0000:  ldc.i4.1
  IL_0001:  box        ""E""
  IL_0006:  call       ""void System.Console.Write(object)""
  IL_000b:  ret
}");
 
        void symbolValidator(ModuleSymbol symbol)
        {
            Assert.Equal(new[] { "<Module>", "E", "Program", "Microsoft", "System" }, symbol.GlobalNamespace.GetMembers().Select(m => m.Name));
            var classC = symbol.GlobalNamespace.GetMember<NamedTypeSymbol>("E");
            Assert.Equal(new[] { "value__", "E1", "E2", ".ctor" }, classC.MemberNames);
        }
    }
 
    [Fact]
    public void FileEnum_02()
    {
        var source = """
            using System;
 
            file enum E
            {
                E1, E2
            }
 
            file class Attr : Attribute
            {
                public Attr(E e) { }
            }
 
            [Attr(E.E2)]
            class Program
            {
                static void Main()
                {
                    var data = typeof(Program).GetCustomAttributesData();
                    Console.Write(data[0].ConstructorArguments[0]);
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "(<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__E)1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var symbol = comp.GetMember<NamedTypeSymbol>("E");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__E", symbol.MetadataName);
 
        void symbolValidator(ModuleSymbol symbol)
        {
            Assert.Equal(new[] { "<Module>", "E", "Attr", "Program", "Microsoft", "System" }, symbol.GlobalNamespace.GetMembers().Select(m => m.Name));
            var classC = symbol.GlobalNamespace.GetMember<NamedTypeSymbol>("E");
            Assert.Equal(new[] { "value__", "E1", "E2", ".ctor" }, classC.MemberNames);
        }
    }
 
    [Fact]
    public void FileEnum_03()
    {
        var source = """
            using System;
 
            file enum E
            {
                E1, E2
            }
 
            class Attr : Attribute
            {
                public Attr(E e) { } // 1
            }
 
            [Attr(E.E2)]
            class Program
            {
                static void Main()
                {
                    var data = typeof(Program).GetCustomAttributesData();
                    Console.Write(data[0].ConstructorArguments[0]);
                }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (10,12): error CS9051: File-local type 'E' cannot be used in a member signature in non-file-local type 'Attr'.
            //     public Attr(E e) { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Attr").WithArguments("E", "Attr").WithLocation(10, 12));
    }
 
    [Fact]
    public void FileEnum_04()
    {
        var source = """
            using System;
 
            file enum E
            {
                E1, E2
            }
 
            class Attr : Attribute
            {
                public Attr(object obj) { }
            }
 
            [Attr(E.E2)]
            class Program
            {
                static void Main()
                {
                    var data = typeof(Program).GetCustomAttributesData();
                    Console.Write(data[0].ConstructorArguments[0]);
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "(<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__E)1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var symbol = comp.GetMember<NamedTypeSymbol>("E");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__E", symbol.MetadataName);
 
        void symbolValidator(ModuleSymbol symbol)
        {
            Assert.Equal(new[] { "<Module>", "E", "Attr", "Program", "Microsoft", "System" }, symbol.GlobalNamespace.GetMembers().Select(m => m.Name));
            var classC = symbol.GlobalNamespace.GetMember<NamedTypeSymbol>("E");
            Assert.Equal(new[] { "value__", "E1", "E2", ".ctor" }, classC.MemberNames);
        }
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void NonFileLocalClass_Duplicate()
    {
        var source = @"
public class D { }
 
public partial class C
{
    public class D { }
}
";
        var comp = CreateCompilation(new[] { source, source });
        comp.VerifyEmitDiagnostics(
            // 1.cs(2,14): error CS0101: The namespace '<global namespace>' already contains a definition for 'D'
            // public class D { }
            Diagnostic(ErrorCode.ERR_DuplicateNameInNS, "D").WithArguments("D", "<global namespace>").WithLocation(2, 14),
            // 1.cs(6,18): error CS0102: The type 'C' already contains a definition for 'D'
            //     public class D { }
            Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "D").WithArguments("C", "D").WithLocation(6, 18));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void FileLocalClass_Duplicate()
    {
        var source = @"
file class D { }
 
public partial class C
{
    file class D { } // 1
}
";
        var comp = CreateCompilation(new[] { source, source });
        comp.VerifyEmitDiagnostics(
                    // 1.cs(6,16): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
                    //     file class D { } // 1
                    Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 16),
                    // 0.cs(6,16): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
                    //     file class D { } // 1
                    Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 16));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void NonFileLocalEnum_Duplicate()
    {
        var source = @"
public enum E { }
 
public partial class C
{
    public enum E { }
}
";
        var comp = CreateCompilation(new[] { source, source });
        comp.VerifyEmitDiagnostics(
            // 1.cs(2,13): error CS0101: The namespace '<global namespace>' already contains a definition for 'E'
            // public enum E { }
            Diagnostic(ErrorCode.ERR_DuplicateNameInNS, "E").WithArguments("E", "<global namespace>").WithLocation(2, 13),
            // 1.cs(6,17): error CS0102: The type 'C' already contains a definition for 'E'
            //     public enum E { }
            Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "E").WithArguments("C", "E").WithLocation(6, 17));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void MixedFileLocalClass_Duplicate()
    {
        var source1 = @"
file class D { }
 
public partial class C
{
    file class D { } // 1
}
";
 
        var source2 = @"
public class D { }
 
public partial class C
{
    public class D { }
}
";
 
        var comp = CreateCompilation(new[] { source1, source2 });
        comp.VerifyEmitDiagnostics(
            // 0.cs(6,16): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
            //     file class D { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 16));
 
        comp = CreateCompilation(new[] { source2, source1 });
        comp.VerifyEmitDiagnostics(
            // 0.cs(6,16): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
            //     file class D { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 16));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void FileLocalEnum_Duplicate()
    {
        var source = @"
file enum E { }
 
public partial class C
{
    file enum E { } // 1
}
";
        var comp = CreateCompilation(new[] { source, source });
        comp.VerifyEmitDiagnostics(
            // 1.cs(6,15): error CS9054: File-local type 'C.E' must be defined in a top level type; 'C.E' is a nested type.
            //     file enum E { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "E").WithArguments("C.E").WithLocation(6, 15),
            // 0.cs(6,15): error CS9054: File-local type 'C.E' must be defined in a top level type; 'C.E' is a nested type.
            //     file enum E { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "E").WithArguments("C.E").WithLocation(6, 15));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void MixedFileLocalEnum_Duplicate()
    {
        var source1 = @"
file enum E { }
 
public partial class C
{
    file enum E { } // 1
}
";
 
        var source2 = @"
public enum E { }
 
public partial class C
{
    public enum E { }
}
";
 
        var comp = CreateCompilation(new[] { source1, source2 });
        comp.VerifyEmitDiagnostics(
            // 0.cs(6,15): error CS9054: File-local type 'C.E' must be defined in a top level type; 'C.E' is a nested type.
            //     file enum E { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "E").WithArguments("C.E").WithLocation(6, 15));
 
        comp = CreateCompilation(new[] { source2, source1 });
        comp.VerifyEmitDiagnostics(
            // 0.cs(6,15): error CS9054: File-local type 'C.E' must be defined in a top level type; 'C.E' is a nested type.
            //     file enum E { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "E").WithArguments("C.E").WithLocation(6, 15));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void NonFileLocalDelegate_Duplicate()
    {
        var source = @"
public delegate void D();
 
public partial class C
{
    public delegate void D();
}
";
        var comp = CreateCompilation(new[] { source, source });
        comp.VerifyEmitDiagnostics(
            // 1.cs(2,22): error CS0101: The namespace '<global namespace>' already contains a definition for 'D'
            // public delegate void D();
            Diagnostic(ErrorCode.ERR_DuplicateNameInNS, "D").WithArguments("D", "<global namespace>").WithLocation(2, 22),
            // 1.cs(6,26): error CS0102: The type 'C' already contains a definition for 'D'
            //     public delegate void D();
            Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "D").WithArguments("C", "D").WithLocation(6, 26));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void MixedFileLocalDelegate_Duplicate()
    {
        var source1 = @"
file delegate void D();
 
public partial class C
{
    file delegate void D(); // 1
}
";
 
        var source2 = @"
public delegate void D();
 
public partial class C
{
    public delegate void D();
}
";
 
        var comp = CreateCompilation(new[] { source1, source2 });
        comp.VerifyEmitDiagnostics(
            // 0.cs(6,24): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
            //     file delegate void D(); // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 24));
 
        comp = CreateCompilation(new[] { source2, source1 });
        comp.VerifyEmitDiagnostics(
            // 0.cs(6,24): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
            //     file delegate void D(); // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 24));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/67258")]
    public void FileLocalDelegate_Duplicate()
    {
        var source = @"
file delegate void D();
 
public partial class C
{
    file delegate void D(); // 1
}
";
        var comp = CreateCompilation(new[] { source, source });
        comp.VerifyEmitDiagnostics(
            // 1.cs(6,24): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
            //     file delegate void D(); // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 24),
            // 0.cs(6,24): error CS9054: File-local type 'C.D' must be defined in a top level type; 'C.D' is a nested type.
            //     file delegate void D(); // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "D").WithArguments("C.D").WithLocation(6, 24));
    }
 
    [Fact]
    public void OtherFileUse()
    {
        var source1 = """
            using System;
 
            file class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var source2 = """
            class Program
            {
                static void Main()
                {
                    C.M(); // 1
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (5,9): error CS0103: The name 'C' does not exist in the current context
            //         C.M(); // 1
            Diagnostic(ErrorCode.ERR_NameNotInContext, "C").WithArguments("C").WithLocation(5, 9));
    }
 
    [Fact]
    public void Generic_01()
    {
        var source = """
        using System;
 
        C<int>.M(1);
 
        file class C<T>
        {
            public static void M(T t) { Console.Write(t); }
        }
        """;
 
        var verifier = CompileAndVerify(SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.RegularPreview, path: "path/to/MyFile.cs", encoding: Encoding.Default), expectedOutput: "1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        verifier.VerifyIL("C<T>@MyFile.M(T)", @"
{
  // Code size       12 (0xc)
  .maxstack  1
  IL_0000:  ldarg.0
  IL_0001:  box        ""T""
  IL_0006:  call       ""void System.Console.Write(object)""
  IL_000b:  ret
}
");
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var c = comp.GetMember("C");
        AssertEx.Equal("<MyFile>F5E7157F91336401EED4848664C7CEB8A5E156C0D713F4211A61BDB8932B19EF2__C`1", c.MetadataName);
 
        void symbolValidator(ModuleSymbol module)
        {
            Assert.Equal(new[] { "<Module>", "Program", "C", "Microsoft", "System" }, module.GlobalNamespace.GetMembers().Select(m => m.Name));
 
            var classC = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            AssertEx.Equal("<MyFile>F5E7157F91336401EED4848664C7CEB8A5E156C0D713F4211A61BDB8932B19EF2__C`1", classC.MetadataName);
            Assert.Equal(new[] { "M", ".ctor" }, classC.MemberNames);
        }
    }
 
    [Fact]
    public void BadFileNames_01()
    {
        var source = """
        using System;
 
        C.M();
 
        file class C
        {
            public static void M() { Console.Write(1); }
        }
        """;
 
        const string expectedMetadataName = "<My__File>FCE8825365B7010B8DE2ACFBE270B3B795D1AB2633451F8A6C1A94FB1933D5E4E__C";
        var verifier = CompileAndVerify(SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.RegularPreview, path: "path/to/My<>File.cs", encoding: Encoding.Default), expectedOutput: "1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var c = comp.GetMember("C");
        Assert.Equal("C@My__File", c.ToTestDisplayString());
        AssertEx.Equal(expectedMetadataName, c.MetadataName);
 
        void symbolValidator(ModuleSymbol module)
        {
            Assert.Equal(new[] { "<Module>", "Program", "C", "Microsoft", "System" }, module.GlobalNamespace.GetMembers().Select(m => m.Name));
            var expectedSymbol = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            AssertEx.Equal(expectedMetadataName, expectedSymbol.MetadataName);
            Assert.Equal(new[] { "M", ".ctor" }, expectedSymbol.MemberNames);
        }
    }
 
    [Fact]
    public void BadFileNames_02()
    {
        var source = """
        using System;
 
        C.M();
 
        file class C
        {
            public static void M() { Console.Write(1); }
        }
        """;
 
        var verifier = CompileAndVerify(SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.RegularPreview, path: "path/to/MyGeneratedFile.g.cs", encoding: Encoding.Default), expectedOutput: "1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var c = comp.GetMember("C");
        Assert.Equal("C@MyGeneratedFile_g", c.ToTestDisplayString());
        AssertEx.Equal("<MyGeneratedFile_g>F18307E6C553D2E6465CEA162655C06E2BB2896889519559EB1EE5FA53513F0E8__C", c.MetadataName);
 
        void symbolValidator(ModuleSymbol module)
        {
            Assert.Equal(new[] { "<Module>", "Program", "C", "Microsoft", "System" }, module.GlobalNamespace.GetMembers().Select(m => m.Name));
            var expectedSymbol = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            AssertEx.Equal("<MyGeneratedFile_g>F18307E6C553D2E6465CEA162655C06E2BB2896889519559EB1EE5FA53513F0E8__C", expectedSymbol.MetadataName);
            Assert.Equal(new[] { "M", ".ctor" }, expectedSymbol.MemberNames);
        }
    }
 
    [Theory]
    [InlineData("""
            file class Outer1 { }
            file class Outer2 { }
            """, "Outer2")]
    [InlineData("""
            file class Outer { }
            """, "Outer")]
    public void Determinism(string source, string fileTypeName)
    {
        var (root1, root2) = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? (@"q:\", @"j:\") : ("/q", "/j");
        var testSource1 = CSharpTestSource.Parse(source, Path.Combine(root1, "code.cs"));
        var testSource2 = CSharpTestSource.Parse(source, Path.Combine(root2, "code.cs"));
        var options = TestOptions.DebugDll.WithDeterministic(true);
        var comp1 = CreateCompilation(testSource1, options: options, assemblyName: "filetypes");
        var comp2 = CreateCompilation(testSource2, options: options, assemblyName: "filetypes");
 
        var resolver = new SourceFileResolver(
            ImmutableArray<string>.Empty,
            baseDirectory: null,
            ImmutableArray.Create(new KeyValuePair<string, string>(root2, root1)));
        var comp3 = CreateCompilation(testSource2, options: options.WithSourceReferenceResolver(resolver), assemblyName: "filetypes");
 
        var outer1 = comp1.GetMember<NamedTypeSymbol>(fileTypeName).AssociatedFileIdentifier;
        var outer2 = comp2.GetMember<NamedTypeSymbol>(fileTypeName).AssociatedFileIdentifier;
        var outer3 = comp3.GetMember<NamedTypeSymbol>(fileTypeName).AssociatedFileIdentifier;
        Assert.False(outer1.FilePathChecksumOpt.IsDefaultOrEmpty);
        Assert.False(outer2.FilePathChecksumOpt.IsDefaultOrEmpty);
        Assert.False(outer3.FilePathChecksumOpt.IsDefaultOrEmpty);
        Assert.False(outer1.FilePathChecksumOpt.SequenceEqual(outer2.FilePathChecksumOpt));
        Assert.True(outer1.FilePathChecksumOpt.SequenceEqual(outer3.FilePathChecksumOpt));
 
        var emitOptions = EmitOptions.Default.WithDebugInformationFormat(DebugInformationFormat.Embedded);
        var bytes1 = comp1.EmitToArray(emitOptions);
        var bytes2 = comp2.EmitToArray(emitOptions);
        var bytes3 = comp3.EmitToArray(emitOptions);
        Assert.False(bytes1.SequenceEqual(bytes2));
        Assert.True(bytes1.SequenceEqual(bytes3));
    }
 
    [Fact]
    public void DuplicateFileNames_01()
    {
        var path = "path/to/file.cs";
        var source1 = SyntaxFactory.ParseSyntaxTree("""
            using System;
 
            C.M();
 
            file class C
            {
                public static void M() { Console.Write(1); }
            }
            """, options: TestOptions.RegularPreview, path: path, encoding: Encoding.Default);
        var source2 = SyntaxFactory.ParseSyntaxTree("", options: TestOptions.RegularPreview, path: path, encoding: Encoding.Default);
 
        var comp = CreateCompilation(new[] { source1, source2 }, assemblyName: "comp");
        verify();
 
        comp = CreateCompilation(new[] { source2, source1 }, assemblyName: "comp");
        verify();
 
        void verify()
        {
            comp.VerifyDiagnostics();
            comp.VerifyEmitDiagnostics(
                // path/to/file.cs(5,12): error CS9067: File-local type 'C' must be declared in a file with a unique path. Path 'path/to/file.cs' is used in multiple files.
                // file class C
                Diagnostic(ErrorCode.ERR_FileTypeNonUniquePath, "C").WithArguments("C", "path/to/file.cs").WithLocation(5, 12));
            var classC = comp.GetMember("C");
            Assert.Equal(source1, classC.Locations[0].SourceTree);
            AssertEx.Equal("<file>F620949CDCC480533E3607E5DD92F88E866EC1D65C225D70509A32F831433D9A4__C", classC.MetadataName);
        }
    }
 
    [Fact]
    public void DuplicateFileNames_02()
    {
        var path = "path/to/file.cs";
        var source1 = SyntaxFactory.ParseSyntaxTree("""
            using System;
 
            C.M();
 
            file class C
            {
                public static void M() { Console.Write(1); }
            }
            """, options: TestOptions.RegularPreview, path: path, encoding: Encoding.Default);
        var source2 = SyntaxFactory.ParseSyntaxTree("""
            using System;
 
            namespace NS;
 
            file class C
            {
                public static void M() { Console.Write(2); }
            }
            """, options: TestOptions.RegularPreview, path: path, encoding: Encoding.Default);
 
        var comp = CreateCompilation(new[] { source1, source2 }, assemblyName: "comp");
        verify();
 
        comp = CreateCompilation(new[] { source2, source1 }, assemblyName: "comp");
        verify();
 
        void verify()
        {
            comp.VerifyDiagnostics();
            comp.VerifyEmitDiagnostics(
                // path/to/file.cs(5,12): error CS9067: File-local type 'C' must be declared in a file with a unique path. Path 'path/to/file.cs' is used in multiple files.
                // file class C
                Diagnostic(ErrorCode.ERR_FileTypeNonUniquePath, "C").WithArguments("NS.C", "path/to/file.cs").WithLocation(5, 12),
                // path/to/file.cs(5,12): error CS9067: File-local type 'C' must be declared in a file with a unique path. Path 'path/to/file.cs' is used in multiple files.
                // file class C
                Diagnostic(ErrorCode.ERR_FileTypeNonUniquePath, "C").WithArguments("C", "path/to/file.cs").WithLocation(5, 12));
            var member = comp.GetMember("C");
            Assert.Equal(source1, member.Locations[0].SourceTree);
            AssertEx.Equal("<file>F620949CDCC480533E3607E5DD92F88E866EC1D65C225D70509A32F831433D9A4__C", member.MetadataName);
        }
    }
 
    [Fact]
    public void DuplicateFileNames_03()
    {
        var path = "path/to/file.cs";
        var source1 = SyntaxFactory.ParseSyntaxTree("""
            using System;
 
            namespace NS1.NS2;
 
            file class C<T>
            {
                public static void M() { Console.Write(1); }
            }
            """, options: TestOptions.RegularPreview, path: path, encoding: Encoding.Default);
        var source2 = SyntaxFactory.ParseSyntaxTree("", options: TestOptions.RegularPreview, path: path, encoding: Encoding.Default);
 
        var comp = CreateCompilation(new[] { source1, source2 }, assemblyName: "comp");
        verify();
 
        comp = CreateCompilation(new[] { source2, source1 }, assemblyName: "comp");
        verify();
 
        void verify()
        {
            comp.VerifyDiagnostics();
            comp.VerifyEmitDiagnostics(
                // path/to/file.cs(5,12): error CS9067: File-local type 'C<T>' must be declared in a file with a unique path. Path 'path/to/file.cs' is used in multiple files.
                // file class C<T>
                Diagnostic(ErrorCode.ERR_FileTypeNonUniquePath, "C").WithArguments("NS1.NS2.C<T>", "path/to/file.cs").WithLocation(5, 12));
            var classC = comp.GetMember("NS1.NS2.C");
            Assert.Equal(source1, classC.Locations[0].SourceTree);
            AssertEx.Equal("<file>F620949CDCC480533E3607E5DD92F88E866EC1D65C225D70509A32F831433D9A4__C`1", classC.MetadataName);
        }
    }
 
    [Fact]
    public void DuplicateFileNames_04()
    {
        var source1 = SyntaxFactory.ParseSyntaxTree("""
            using System;
 
            C.M();
 
            file class C
            {
                public static void M() { Console.Write(1); }
            }
            """, options: TestOptions.RegularPreview, path: "path/to/file.cs", encoding: Encoding.Default);
        var source2 = SyntaxFactory.ParseSyntaxTree("", options: TestOptions.RegularPreview, path: "path/to/File.cs", encoding: Encoding.Default);
 
        var comp = CreateCompilation(new[] { source1, source2 }, assemblyName: "comp");
        verify();
 
        comp = CreateCompilation(new[] { source2, source1 }, assemblyName: "comp");
        verify();
 
        void verify()
        {
            comp.VerifyEmitDiagnostics();
            var classC = comp.GetMember("C");
            Assert.Equal(source1, classC.Locations[0].SourceTree);
            AssertEx.Equal("<file>F620949CDCC480533E3607E5DD92F88E866EC1D65C225D70509A32F831433D9A4__C", classC.MetadataName);
        }
    }
 
    [Fact]
    public void DuplicateFileNames_05()
    {
        var source1 = """
            using System;
 
            file class C // 1
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var source2 = """
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file1.cs") });
        comp.VerifyDiagnostics();
        comp.VerifyEmitDiagnostics(
            // file1.cs(3,12): error CS9067: File-local type 'C' must be declared in a file with a unique path. Path 'file1.cs' is used in multiple files.
            // file class C // 1
            Diagnostic(ErrorCode.ERR_FileTypeNonUniquePath, "C").WithArguments("C", "file1.cs").WithLocation(3, 12));
    }
 
    // Data based on Lexer.ScanIdentifier_FastPath, excluding '/', '\', and ':' because those are path separators.
    [Theory]
    [InlineData('&')]
    [InlineData('\0')]
    [InlineData(' ')]
    [InlineData('\r')]
    [InlineData('\n')]
    [InlineData('\t')]
    [InlineData('!')]
    [InlineData('%')]
    [InlineData('(')]
    [InlineData(')')]
    [InlineData('*')]
    [InlineData('+')]
    [InlineData(',')]
    [InlineData('-')]
    [InlineData('.')]
    [InlineData(';')]
    [InlineData('<')]
    [InlineData('=')]
    [InlineData('>')]
    [InlineData('?')]
    [InlineData('[')]
    [InlineData(']')]
    [InlineData('^')]
    [InlineData('{')]
    [InlineData('|')]
    [InlineData('}')]
    [InlineData('~')]
    [InlineData('"')]
    [InlineData('\'')]
    [InlineData('`')]
    public void BadFileNames_03(char badChar)
    {
        var source = """
        using System;
 
        C.M();
 
        file class C
        {
            public static void M() { Console.Write(1); }
        }
        """;
 
        var comp = CreateCompilation(SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.RegularPreview, path: $"path/to/My{badChar}File.cs", encoding: Encoding.Default));
        var sourceFileTypeSymbol = comp.GetMember("C");
 
        var verifier = CompileAndVerify(comp, expectedOutput: "1", symbolValidator: symbolValidator);
        verifier.VerifyDiagnostics();
 
        Assert.Equal("C@My_File", sourceFileTypeSymbol.ToTestDisplayString());
        Assert.Matches(expectedRegexPattern: @"<My_File>F[\w\d]{64}__C", sourceFileTypeSymbol.MetadataName);
 
        void symbolValidator(ModuleSymbol module)
        {
            Assert.Equal(new[] { "<Module>", "Program", "C", "Microsoft", "System" }, module.GlobalNamespace.GetMembers().Select(m => m.Name));
            var expectedSymbol = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            Assert.Equal(sourceFileTypeSymbol.MetadataName, expectedSymbol.MetadataName);
            Assert.Equal(new[] { "M", ".ctor" }, expectedSymbol.MemberNames);
        }
    }
 
    [ConditionalFact(typeof(IsEnglishLocal))]
    public void BadFileNames_04()
    {
        var source1 = """
            new C(); // 1
 
            file class C { } // 2
            """;
 
        var comp = CreateCompilation(SyntaxFactory.ParseSyntaxTree(source1, options: TestOptions.RegularPreview, path: "\uD800.cs"));
        comp.VerifyDiagnostics(
            // ?.cs(1,5): error CS0246: The type or namespace name 'C' could not be found (are you missing a using directive or an assembly reference?)
            // new C(); // 1
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "C").WithArguments("C").WithLocation(1, 5),
            // ?.cs(3,12): error CS9068: File-local type 'C' cannot be used because the containing file path cannot be converted into the equivalent UTF-8 byte representation. Unable to translate Unicode character \\uD800 at index 0 to specified code page.      
            // file class C { } // 2
            Diagnostic(ErrorCode.ERR_FilePathCannotBeConvertedToUtf8, "C")
                .WithArguments(
                    "C",
                    ExecutionConditionUtil.IsCoreClr
                        ? @"Unable to translate Unicode character \\uD800 at index 0 to specified code page."
                        : @"Unable to translate Unicode character \uD800 at index 0 to specified code page.")
                .WithLocation(3, 12)
            );
 
        var classC = comp.GetMember("C");
        Assert.Equal("<_>F<no checksum>__C", classC.MetadataName);
        Assert.Null(comp.GetTypeByMetadataName("<_>F<no checksum>__C"));
    }
 
    [Fact]
    public void Pdb_01()
    {
        var source = """
        using System;
 
        C.M();
 
        file class C
        {
            public static void M() { Console.Write(1); }
        }
        """;
 
        var verifier = CompileAndVerify(SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.RegularPreview, path: "path/to/My+File.cs", encoding: Encoding.Default), expectedOutput: "1", symbolValidator: validateSymbols);
        verifier.VerifyDiagnostics();
 
        var comp = (CSharpCompilation)verifier.Compilation;
        var c = comp.GetMember("C");
        Assert.Equal("C@My_File", c.ToTestDisplayString());
        AssertEx.Equal("<My_File>FA818559F9E8E4AF40425A1819866C71357DE9017B4B7EFE1D34D9F48C0539B6E__C", c.MetadataName);
 
        void validateSymbols(ModuleSymbol module)
        {
            var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
            Assert.NotNull(type);
            Assert.Equal(new[] { "M", ".ctor" }, type.MemberNames);
        }
    }
 
#pragma warning disable format
    [Theory]
    [InlineData("file", "file", "<file1>F96B1D9CB33A43D51528FE81EDAFE5AE31358FE749929AC76B76C64B60DEF129D__C", "<file2>F66382B88D8E28FDD21CEADA0DE847F8B00DA1324042DD28F8FFC58C454BD6188__C")]
    [InlineData("file", "",     "<file1>F96B1D9CB33A43D51528FE81EDAFE5AE31358FE749929AC76B76C64B60DEF129D__C", "C")]
    [InlineData("",     "file", "C",                                                                           "<file2>F66382B88D8E28FDD21CEADA0DE847F8B00DA1324042DD28F8FFC58C454BD6188__C")]
#pragma warning restore format
    public void Duplication_01(string firstFileModifier, string secondFileModifier, string firstMetadataName, string secondMetadataName)
    {
        // A file-local type is allowed to have the same name as a non-file-local type from a different file.
        // When both a file-local type and non-file-local type with the same name are in scope, the file-local type is preferred, since it's "more local".
        var source1 = $$"""
            using System;
 
            {{firstFileModifier}} class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var source2 = $$"""
            using System;
 
            {{secondFileModifier}} class C
            {
                public static void M()
                {
                    Console.Write(2);
                }
            }
            """;
 
        var main = """
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1 + main, "file1.cs"), (source2, "file2.cs") }, expectedOutput: "1");
        var comp = (CSharpCompilation)verifier.Compilation;
        var cs = comp.GetMembers("C");
        var tree = comp.SyntaxTrees[0];
        var expectedSymbol = cs[0];
        AssertEx.Equal(firstMetadataName, expectedSymbol.MetadataName);
        verify();
 
        verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (source2 + main, "file2.cs") }, expectedOutput: "2");
        comp = (CSharpCompilation)verifier.Compilation;
        cs = comp.GetMembers("C");
        tree = comp.SyntaxTrees[1];
        expectedSymbol = cs[1];
        AssertEx.Equal(secondMetadataName, expectedSymbol.MetadataName);
        verify();
 
        void verify()
        {
            verifier.VerifyDiagnostics();
            Assert.Equal(2, cs.Length);
            Assert.Equal(comp.SyntaxTrees[0], cs[0].DeclaringSyntaxReferences.Single().SyntaxTree);
            Assert.Equal(comp.SyntaxTrees[1], cs[1].DeclaringSyntaxReferences.Single().SyntaxTree);
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
            var cReference = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Last().Expression;
            var info = model.GetTypeInfo(cReference);
            Assert.Equal(expectedSymbol.GetPublicSymbol(), info.Type);
        }
    }
 
    [Fact]
    public void Duplication_02()
    {
        // As a sanity check, demonstrate that non-file classes with the same name across different files are disallowed.
        var source1 = """
            using System;
 
            class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var source2 = """
            using System;
 
            class C
            {
                public static void M()
                {
                    Console.Write(2);
                }
            }
            """;
 
        var main = """
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { source1 + main, source2 });
        verify();
 
        comp = CreateCompilation(new[] { source1, source2 + main });
        verify();
 
        void verify()
        {
            comp.VerifyDiagnostics(
                // (3,7): error CS0101: The namespace '<global namespace>' already contains a definition for 'C'
                // class C
                Diagnostic(ErrorCode.ERR_DuplicateNameInNS, "C").WithArguments("C", "<global namespace>").WithLocation(3, 7),
                // (5,24): error CS0111: Type 'C' already defines a member called 'M' with the same parameter types
                //     public static void M()
                Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M").WithArguments("M", "C").WithLocation(5, 24),
                // (14,11): error CS0121: The call is ambiguous between the following methods or properties: 'C.M()' and 'C.M()'
                //         C.M();
                Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M()", "C.M()").WithLocation(14, 11));
 
            var cs = comp.GetMember("C");
            var syntaxReferences = cs.DeclaringSyntaxReferences;
            Assert.Equal(2, syntaxReferences.Length);
            Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[0].SyntaxTree);
            Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[1].SyntaxTree);
        }
    }
 
    [Fact]
    public void Duplication_03()
    {
        var source1 = """
            using System;
 
            partial class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var source2 = """
            partial class C
            {
            }
            """;
 
        var main = """
            using System;
 
            file class C
            {
                public static void M()
                {
                    Console.Write(2);
                }
            }
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (source2, "file2.cs"), (main, "file3.cs") }, expectedOutput: "2");
        var comp = (CSharpCompilation)verifier.Compilation;
        comp.VerifyDiagnostics();
 
        var cs = comp.GetMembers("C");
        Assert.Equal(2, cs.Length);
 
        var c0 = cs[0];
        Assert.True(c0 is SourceMemberContainerTypeSymbol { IsFileLocal: false });
 
        var syntaxReferences = c0.DeclaringSyntaxReferences;
        Assert.Equal(2, syntaxReferences.Length);
        Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[0].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[1].SyntaxTree);
 
        var c1 = cs[1];
        Assert.True(c1 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.Equal(comp.SyntaxTrees[2], c1.DeclaringSyntaxReferences.Single().SyntaxTree);
 
        var tree = comp.SyntaxTrees[2];
        var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
        var cReference = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Last().Expression;
        var info = model.GetTypeInfo(cReference);
        Assert.Equal(c1.GetPublicSymbol(), info.Type);
    }
 
    [Fact]
    public void Duplication_04()
    {
        var source1 = """
            using System;
 
            class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var main = """
            using System;
 
            file partial class C
            {
                public static void M()
                {
                    Console.Write(Number);
                }
            }
 
            file partial class C
            {
                private static int Number => 2;
            }
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (main, "file2.cs") }, expectedOutput: "2");
        var comp = (CSharpCompilation)verifier.Compilation;
        comp.VerifyDiagnostics();
 
        var cs = comp.GetMembers("C");
        Assert.Equal(2, cs.Length);
 
        var c0 = cs[0];
        Assert.True(c0 is SourceMemberContainerTypeSymbol { IsFileLocal: false });
        Assert.Equal(comp.SyntaxTrees[0], c0.DeclaringSyntaxReferences.Single().SyntaxTree);
 
        var c1 = cs[1];
        Assert.True(c1 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
 
        var syntaxReferences = c1.DeclaringSyntaxReferences;
        Assert.Equal(2, syntaxReferences.Length);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[0].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[1].SyntaxTree);
 
        var tree = comp.SyntaxTrees[1];
        var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
        var cReference = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Last().Expression;
        var info = model.GetTypeInfo(cReference);
        Assert.Equal(c1.GetPublicSymbol(), info.Type);
    }
 
    [Theory]
    [CombinatorialData]
    public void Duplication_05(bool firstClassIsFile)
    {
        var source1 = $$"""
            using System;
 
            {{(firstClassIsFile ? "file " : "")}}partial class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var main = """
            using System;
 
            file partial class C
            {
                public static void M()
                {
                    Console.Write(2);
                }
            }
 
            class Program
            {
                static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (main, "file2.cs") }, expectedOutput: "2");
        var comp = (CSharpCompilation)verifier.Compilation;
        comp.VerifyDiagnostics();
 
        var cs = comp.GetMembers("C");
        Assert.Equal(2, cs.Length);
 
        var c0 = cs[0];
        Assert.Equal(firstClassIsFile, ((SourceMemberContainerTypeSymbol)c0).IsFileLocal);
        Assert.Equal(comp.SyntaxTrees[0], c0.DeclaringSyntaxReferences.Single().SyntaxTree);
 
        var c1 = cs[1];
        Assert.True(c1 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.Equal(comp.SyntaxTrees[1], c1.DeclaringSyntaxReferences.Single().SyntaxTree);
 
        var tree = comp.SyntaxTrees[1];
        var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
        var cReference = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Last().Expression;
        var info = model.GetTypeInfo(cReference);
        Assert.Equal(c1.GetPublicSymbol(), info.Type);
    }
 
    [Fact]
    public void Duplication_06()
    {
        // note: we avoid `using System;` here because we don't want to attempt to bind to `System.Number`
        var source1 = """
            namespace NS;
 
            partial class C
            {
                public static void M()
                {
                    System.Console.Write(Number);
                }
            }
            """;
 
        var source2 = """
            namespace NS;
 
            partial class C
            {
                private static int Number => 1;
            }
 
            file class C
            {
                public static void M()
                {
                    System.Console.Write(2);
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // file2.cs(8,12): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // file class C
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(8, 12)
            );
 
        var cs = comp.GetMembers("NS.C");
        Assert.Equal(2, cs.Length);
 
        var c0 = cs[0];
        Assert.True(c0 is SourceMemberContainerTypeSymbol { IsFileLocal: false });
        var syntaxReferences = c0.DeclaringSyntaxReferences;
        Assert.Equal(2, syntaxReferences.Length);
        Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[0].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[1].SyntaxTree);
 
        var c1 = cs[1];
        Assert.True(c1 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.Equal(comp.SyntaxTrees[1], c1.DeclaringSyntaxReferences.Single().SyntaxTree);
 
        comp = CreateCompilation(new[] { (source2, "file2.cs"), (source1, "file1.cs") });
        comp.VerifyDiagnostics(
            // file1.cs(5,24): error CS0111: Type 'C' already defines a member called 'M' with the same parameter types
            //     public static void M()
            Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M").WithArguments("M", "NS.C").WithLocation(5, 24),
            // file1.cs(7,30): error CS0103: The name 'Number' does not exist in the current context
            //         System.Console.Write(Number);
            Diagnostic(ErrorCode.ERR_NameNotInContext, "Number").WithArguments("Number").WithLocation(7, 30),
            // file2.cs(8,12): error CS0260: Missing partial modifier on declaration of type 'C'; another partial declaration of this type exists
            // file class C
            Diagnostic(ErrorCode.ERR_MissingPartial, "C").WithArguments("C").WithLocation(8, 12)
            );
 
        var c = comp.GetMember("NS.C");
        Assert.True(c is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        syntaxReferences = c.DeclaringSyntaxReferences;
        Assert.Equal(3, syntaxReferences.Length);
        Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[0].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[1].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[2].SyntaxTree);
    }
 
    [Fact]
    public void Duplication_07()
    {
        var source1 = """
            using System;
 
            file partial class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var source2 = """
            using System;
 
            file partial class C
            {
                public static void M()
                {
                    Console.Write(Number);
                }
            }
 
            file class C
            {
                private static int Number => 2;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (11,12): error CS0260: Missing partial modifier on declaration of type 'C'; another partial declaration of this type exists
            // file class C
            Diagnostic(ErrorCode.ERR_MissingPartial, "C").WithArguments("C").WithLocation(11, 12));
 
        var cs = comp.GetMembers("C");
        Assert.Equal(2, cs.Length);
 
        var c0 = cs[0];
        Assert.True(c0 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.Equal(comp.SyntaxTrees[0], c0.DeclaringSyntaxReferences.Single().SyntaxTree);
 
        var c1 = cs[1];
        Assert.True(c1 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        var syntaxReferences = c1.DeclaringSyntaxReferences;
        Assert.Equal(2, syntaxReferences.Length);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[0].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[1], syntaxReferences[1].SyntaxTree);
 
        comp = CreateCompilation(new[] { (source2, "file2.cs"), (source1, "file1.cs") });
        comp.VerifyDiagnostics(
            // (11,12): error CS0260: Missing partial modifier on declaration of type 'C'; another partial declaration of this type exists
            // file class C
            Diagnostic(ErrorCode.ERR_MissingPartial, "C").WithArguments("C").WithLocation(11, 12));
 
        cs = comp.GetMembers("C");
        Assert.Equal(2, cs.Length);
 
        c0 = cs[0];
        Assert.True(c0 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        syntaxReferences = c0.DeclaringSyntaxReferences;
        Assert.Equal(2, syntaxReferences.Length);
        Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[0].SyntaxTree);
        Assert.Equal(comp.SyntaxTrees[0], syntaxReferences[1].SyntaxTree);
 
        c1 = cs[1];
        Assert.True(c1 is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.Equal(comp.SyntaxTrees[1], c1.DeclaringSyntaxReferences.Single().SyntaxTree);
    }
 
    [Fact]
    public void Duplication_08()
    {
        var source1 = """
            partial class Outer
            {
                file class C
                {
                    public static void M() { }
                }
            }
            """;
 
        var source2 = """
            partial class Outer
            {
                file class C
                {
                    public static void M() { }
                }
            }
            """;
 
        var source3 = """
            partial class Outer
            {
                public class C
                {
                    public static void M() { }
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs"), (source3, "file3.cs") });
        compilation.VerifyDiagnostics(
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16),
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16));
 
        var classOuter = compilation.GetMember<NamedTypeSymbol>("Outer");
        var cs = classOuter.GetMembers("C");
        Assert.Equal(3, cs.Length);
        Assert.True(cs[0] is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.True(cs[1] is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.True(cs[2] is SourceMemberContainerTypeSymbol { IsFileLocal: false });
    }
 
    [Fact]
    public void Duplication_09()
    {
        var source1 = """
            namespace NS
            {
                file class C
                {
                    public static void M() { }
                }
            }
            """;
 
        var source2 = """
            namespace NS
            {
                file class C
                {
                    public static void M() { }
                }
            }
            """;
 
        var source3 = """
            namespace NS
            {
                public class C
                {
                    public static void M() { }
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs"), (source3, "file3.cs") });
        compilation.VerifyDiagnostics();
 
        var namespaceNS = compilation.GetMember<NamespaceSymbol>("NS");
        var cs = namespaceNS.GetMembers("C");
        Assert.Equal(3, cs.Length);
        Assert.True(cs[0] is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.True(cs[1] is SourceMemberContainerTypeSymbol { IsFileLocal: true });
        Assert.True(cs[2] is SourceMemberContainerTypeSymbol { IsFileLocal: false });
    }
 
    [Theory]
    [InlineData("file", "file")]
    [InlineData("file", "")]
    [InlineData("", "file")]
    public void Duplication_10(string firstFileModifier, string secondFileModifier)
    {
        var source1 = $$"""
            using System;
 
            partial class Program
            {
                {{firstFileModifier}} class C
                {
                    public static void M()
                    {
                        Console.Write(1);
                    }
                }
            }
            """;
 
        var source2 = $$"""
            using System;
 
            partial class Program
            {
                {{secondFileModifier}} class C
                {
                    public static void M()
                    {
                        Console.Write(2);
                    }
                }
            }
            """;
 
        var main = """
            partial class Program
            {
                static void Main()
                {
                    Program.C.M();
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1 + main, "file1.cs"), (source2, "file2.cs") });
        var cs = comp.GetMembers("Program.C");
        var tree = comp.SyntaxTrees[0];
        var expectedSymbol = cs[0];
        verify();
 
        comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2 + main, "file2.cs") });
        cs = comp.GetMembers("Program.C");
        tree = comp.SyntaxTrees[1];
        expectedSymbol = cs[1];
        verify();
 
        void verify()
        {
            comp.GetDiagnostics().Where(d => d.Code is not (int)ErrorCode.ERR_FileTypeNested).Verify();
            Assert.Equal(2, cs.Length);
            Assert.Equal(comp.SyntaxTrees[0], cs[0].DeclaringSyntaxReferences.Single().SyntaxTree);
            Assert.Equal(comp.SyntaxTrees[1], cs[1].DeclaringSyntaxReferences.Single().SyntaxTree);
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
            var cReference = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Last();
            var info = model.GetTypeInfo(cReference);
            Assert.Equal(expectedSymbol.GetPublicSymbol(), info.Type);
        }
    }
 
    [Theory]
    [InlineData("file", "file")]
    [InlineData("file", "")]
    [InlineData("", "file")]
    public void Duplication_11(string firstFileModifier, string secondFileModifier)
    {
        var source1 = $$"""
            using System;
 
            {{firstFileModifier}} partial class Outer
            {
                internal class C
                {
                    public static void M()
                    {
                        Console.Write(1);
                    }
                }
            }
            """;
 
        var source2 = $$"""
            using System;
 
            {{secondFileModifier}} partial class Outer
            {
                internal class C
                {
                    public static void M()
                    {
                        Console.Write(2);
                    }
                }
            }
            """;
 
        var main = """
            class Program
            {
                static void Main()
                {
                    Outer.C.M();
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1 + main, "file1.cs"), (source2, "file2.cs") }, options: TestOptions.DebugExe);
        comp.GetDiagnostics().Where(d => d.Code is not (int)ErrorCode.ERR_FileTypeNested).Verify();
        var outers = comp.GetMembers("Outer");
        var cs = outers.Select(o => ((NamedTypeSymbol)o).GetMember("C")).ToArray();
        var tree = comp.SyntaxTrees[0];
        var expectedSymbol = cs[0];
        verify();
 
        comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2 + main, "file2.cs") }, options: TestOptions.DebugExe);
        comp.GetDiagnostics().Where(d => d.Code is not (int)ErrorCode.ERR_FileTypeNested).Verify();
        outers = comp.GetMembers("Outer");
        cs = outers.Select(o => ((NamedTypeSymbol)o).GetMember("C")).ToArray();
        tree = comp.SyntaxTrees[1];
        expectedSymbol = cs[1];
        verify();
 
        void verify()
        {
            Assert.Equal(2, cs.Length);
            Assert.Equal(comp.SyntaxTrees[0], cs[0].DeclaringSyntaxReferences.Single().SyntaxTree);
            Assert.Equal(comp.SyntaxTrees[1], cs[1].DeclaringSyntaxReferences.Single().SyntaxTree);
 
            var model = comp.GetSemanticModel(tree, ignoreAccessibility: true);
            var cReference = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Last();
            var info = model.GetTypeInfo(cReference);
            Assert.Equal(expectedSymbol.GetPublicSymbol(), info.Type);
        }
    }
 
    [Theory]
    [InlineData("file ")]
    [InlineData("")]
    public void Duplication_13(string fileModifier)
    {
        var userCode = """
            using System;
 
            UserCode.Print();
 
            partial class UserCode
            {
                public static partial void Print();
 
                private class C
                {
                    public static void M() => Console.Write("Program.cs");
                }
            }
            """;
 
        // A source generator must assume that partial classes and namespaces may bring user-defined types into scope.
        // Therefore, generators should reference types they introduce with a `global::`-qualified name.
        var generatedCode = $$"""
            using System;
 
            partial class UserCode
            {
                public static partial void Print()
                {
                    global::C.M(); // binds to 'class C'/'file class C' from global namespace
                    C.M(); // binds to class 'UserCode.C'
                }
            }
 
            {{fileModifier}}class C
            {
                public static void M() => Console.Write("OtherFile.cs");
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (userCode, "file1.cs"), (generatedCode, "file2.cs") }, expectedOutput: "OtherFile.csProgram.cs");
        verifier.VerifyDiagnostics();
    }
 
    [Theory]
    [InlineData("file ")]
    [InlineData("")]
    public void Duplication_14(string fileModifier)
    {
        var userCode = """
            using System;
            using UserNamespace;
 
            GeneratedClass.Print();
 
            namespace UserNamespace
            {
                class C
                {
                    public static void M() => Console.Write("Program.cs");
                }
            }
            """;
 
        // A source generator must assume that partial classes and namespaces may bring user-defined types into scope.
        // Therefore, generators should reference types they introduce with a `global::`-qualified name.
        var generatedCode = $$"""
            using System;
 
            namespace UserNamespace
            {
                class GeneratedClass
                {
                    public static void Print()
                    {
                        global::C.M(); // binds to 'class C'/'file class C' from global namespace
                        C.M(); // binds to class 'UserNamespace.C'
                    }
                }
            }
 
            {{fileModifier}}class C
            {
                public static void M() => Console.Write("OtherFile.cs");
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (userCode, "file1.cs"), (generatedCode, "file2.cs") }, expectedOutput: "OtherFile.csProgram.cs");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void Duplication_15()
    {
        var userCode = """
            using System;
            using UserNamespace;
 
            GeneratedClass.Print();
 
            namespace UserNamespace
            {
                class C
                {
                    public static void M() => Console.Write("Program.cs");
                }
            }
            """;
 
        // Generators can also mitigate the "nearer scope" problem by ensuring no namespace or partial class scopes lie between the declaration and usage of a file type.
        var generatedCode = $$"""
            using System;
 
            namespace UserNamespace
            {
                class GeneratedClass
                {
                    public static void Print()
                    {
                        C.M(); // binds to 'UserNamespace.C@OtherFile'
                    }
                }
 
                file class C
                {
                    public static void M() => Console.Write("OtherFile.cs");
                }
            }

            """;
 
        var verifier = CompileAndVerify(new[] { (userCode, "file1.cs"), (generatedCode, "file2.cs") }, expectedOutput: "OtherFile.cs");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void Duplication_16()
    {
        var source = """
            namespace NS;
 
            file class C { }
            class C { }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (4,7): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(4, 7));
    }
 
    [Fact]
    public void Duplication_17()
    {
        var source = """
            namespace NS;
 
            class C { }
            file class C { }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (4,12): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // file class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(4, 12));
    }
 
    [Fact]
    public void Duplication_18()
    {
        var source = """
            namespace NS;
 
            file class C { }
            class C { }
            class C { }
            """;
 
        var comp = CreateCompilation((source, "file1.cs"));
        comp.VerifyDiagnostics(
            // file1.cs(4,7): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(4, 7),
            // file1.cs(5,7): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(5, 7));
    }
 
    [Fact]
    public void Duplication_19()
    {
        var source = """
            namespace NS;
 
            class C { }
            file class C { }
            class C { }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (4,12): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // file class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(4, 12),
            // (5,7): error CS9070: The namespace 'NS' already contains a definition for 'C' in this file.
            // class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "NS").WithLocation(5, 7));
    }
 
    [Fact]
    public void SignatureUsage_01()
    {
        var source = """
            file class C
            {
            }
 
            class D
            {
                public void M1(C c) { } // 1
                private void M2(C c) { } // 2
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,17): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public void M1(C c) { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("C", "D").WithLocation(7, 17),
            // (8,18): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     private void M2(C c) { } // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("C", "D").WithLocation(8, 18));
    }
 
    [Fact]
    public void SignatureUsage_02()
    {
        var source = """
            file class C
            {
            }
 
            class D
            {
                public C M1() => new C(); // 1
                private C M2() => new C(); // 2
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,14): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public C M1() => new C(); // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("C", "D").WithLocation(7, 14),
            // (8,15): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     private C M2() => new C(); // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("C", "D").WithLocation(8, 15));
    }
 
    [Fact]
    public void SignatureUsage_03()
    {
        var source = """
            file class C
            {
            }
            file delegate void D();
 
            public class E
            {
                C field; // 1
                C property { get; set; } // 2
                object this[C c] { get => c; set { } } // 3
                event D @event; // 4
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (8,7): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'E'.
            //     C field; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "field").WithArguments("C", "E").WithLocation(8, 7),
            // (8,7): warning CS0169: The field 'E.field' is never used
            //     C field; // 1
            Diagnostic(ErrorCode.WRN_UnreferencedField, "field").WithArguments("E.field").WithLocation(8, 7),
            // (9,7): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'E'.
            //     C property { get; set; } // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "property").WithArguments("C", "E").WithLocation(9, 7),
            // (10,12): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'E'.
            //     object this[C c] { get => c; set { } } // 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C", "E").WithLocation(10, 12),
            // (11,13): error CS9051: File-local type 'D' cannot be used in a member signature in non-file-local type 'E'.
            //     event D @event; // 4
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "@event").WithArguments("D", "E").WithLocation(11, 13),
            // (11,13): warning CS0067: The event 'E.event' is never used
            //     event D @event; // 4
            Diagnostic(ErrorCode.WRN_UnreferencedEvent, "@event").WithArguments("E.event").WithLocation(11, 13));
    }
 
    [Fact]
    public void SignatureUsage_04()
    {
        var source = """
            file class C
            {
                public class Inner { }
                public delegate void InnerDelegate();
            }
 
            public class E
            {
                C.Inner field; // 1
                C.Inner property { get; set; } // 2
                object this[C.Inner inner] { get => inner; set { } } // 3
                event C.InnerDelegate @event; // 4
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (9,13): error CS9051: File-local type 'C.Inner' cannot be used in a member signature in non-file-local type 'E'.
            //     C.Inner field; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "field").WithArguments("C.Inner", "E").WithLocation(9, 13),
            // (9,13): warning CS0169: The field 'E.field' is never used
            //     C.Inner field; // 1
            Diagnostic(ErrorCode.WRN_UnreferencedField, "field").WithArguments("E.field").WithLocation(9, 13),
            // (10,13): error CS9051: File-local type 'C.Inner' cannot be used in a member signature in non-file-local type 'E'.
            //     C.Inner property { get; set; } // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "property").WithArguments("C.Inner", "E").WithLocation(10, 13),
            // (11,12): error CS9051: File-local type 'C.Inner' cannot be used in a member signature in non-file-local type 'E'.
            //     object this[C.Inner inner] { get => inner; set { } } // 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C.Inner", "E").WithLocation(11, 12),
            // (12,27): error CS9051: File-local type 'C.InnerDelegate' cannot be used in a member signature in non-file-local type 'E'.
            //     event C.InnerDelegate @event; // 4
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "@event").WithArguments("C.InnerDelegate", "E").WithLocation(12, 27),
            // (12,27): warning CS0067: The event 'E.event' is never used
            //     event C.InnerDelegate @event; // 4
            Diagnostic(ErrorCode.WRN_UnreferencedEvent, "@event").WithArguments("E.event").WithLocation(12, 27));
    }
 
    [Fact]
    public void SignatureUsage_05()
    {
        var source = """
            #pragma warning disable 67, 169 // unused event, field
 
            file class C
            {
                public class Inner { }
                public delegate void InnerDelegate();
            }
 
            file class D
            {
                public class Inner
                {
                    C.Inner field;
                    C.Inner property { get; set; }
                    object this[C.Inner inner] { get => inner; set { } }
                    event C.InnerDelegate @event;
                }
            }
 
            class E
            {
                public class Inner
                {
                    C.Inner field; // 1
                    C.Inner property { get; set; } // 2
                    object this[C.Inner inner] { get => inner; set { } } // 3
                    event C.InnerDelegate @event; // 4
                }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (24,17): error CS9051: File-local type 'C.Inner' cannot be used in a member signature in non-file-local type 'E.Inner'.
            //         C.Inner field; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "field").WithArguments("C.Inner", "E.Inner").WithLocation(24, 17),
            // (25,17): error CS9051: File-local type 'C.Inner' cannot be used in a member signature in non-file-local type 'E.Inner'.
            //         C.Inner property { get; set; } // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "property").WithArguments("C.Inner", "E.Inner").WithLocation(25, 17),
            // (26,16): error CS9051: File-local type 'C.Inner' cannot be used in a member signature in non-file-local type 'E.Inner'.
            //         object this[C.Inner inner] { get => inner; set { } } // 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C.Inner", "E.Inner").WithLocation(26, 16),
            // (27,31): error CS9051: File-local type 'C.InnerDelegate' cannot be used in a member signature in non-file-local type 'E.Inner'.
            //         event C.InnerDelegate @event; // 4
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "@event").WithArguments("C.InnerDelegate", "E.Inner").WithLocation(27, 31));
    }
 
    [Fact]
    public void SignatureUsage_06()
    {
        var source = """
            file class C
            {
            }
 
            delegate void Del1(C c); // 1
            delegate C Del2(); // 2
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (5,15): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'Del1'.
            // delegate void Del1(C c); // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Del1").WithArguments("C", "Del1").WithLocation(5, 15),
            // (6,12): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'Del2'.
            // delegate C Del2(); // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Del2").WithArguments("C", "Del2").WithLocation(6, 12));
    }
 
    [Fact]
    public void SignatureUsage_06_2()
    {
        var source = """
            file class C<T>
            {
            }
 
            delegate void Del1(C<int> c); // 1
            delegate C<int> Del2(); // 2
 
            file delegate void Del3(C<int> c); // ok
            file delegate C<int> Del4(); // ok
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (5,15): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'Del1'.
            // delegate void Del1(C<int> c); // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Del1").WithArguments("C<int>", "Del1").WithLocation(5, 15),
            // (6,17): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'Del2'.
            // delegate C<int> Del2(); // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "Del2").WithArguments("C<int>", "Del2").WithLocation(6, 17));
 
        var del1 = comp.GetMember<NamedTypeSymbol>("Del1");
        var cInt = (ConstructedNamedTypeSymbol)del1.DelegateInvokeMethod.Parameters[0].Type;
        Assert.True(cInt.IsFileLocal);
    }
 
    [Fact]
    public void SignatureUsage_07()
    {
        var source = """
            file class C
            {
            }
 
            class D
            {
                public static D operator +(D d, C c) => d; // 1
                public static C operator -(D d1, D d2) => new C(); // 2
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,30): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public static D operator +(D d, C c) => d; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("C", "D").WithLocation(7, 30),
            // (8,30): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public static C operator -(D d1, D d2) => new C(); // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "-").WithArguments("C", "D").WithLocation(8, 30));
    }
 
    [Fact]
    public void SignatureUsage_08()
    {
        var source = """
            file class C
            {
            }
 
            class D
            {
                public D(C c) { } // 1
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,12): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public D(C c) { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "D").WithArguments("C", "D").WithLocation(7, 12));
    }
 
    [Fact]
    public void SignatureUsage_09()
    {
        var source = """
            file class C
            {
            }
 
            class D
            {
                public C M(C c1, C c2) => c1; // 1, 2, 3
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,14): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public C M(C c1, C c2) => c1; // 1, 2, 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("C", "D").WithLocation(7, 14),
            // (7,14): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public C M(C c1, C c2) => c1; // 1, 2, 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("C", "D").WithLocation(7, 14),
            // (7,14): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D'.
            //     public C M(C c1, C c2) => c1; // 1, 2, 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M").WithArguments("C", "D").WithLocation(7, 14));
    }
 
    [Fact]
    public void SignatureUsage_10()
    {
        var source = """
            #pragma warning disable 67, 169 // unused event, field
 
            file class C<T> { }
            file delegate void Del<T>(T input);
 
            class C1
            {
                private C<int> F; // 1
                private event Del<int> E; // 2
                private void M1(C<int> input) { } // 3
                private C<int> M2() => throw null!; // 4
 
                private C<int> P { get; set; } // 5
                private C<int> this[int i] => throw null!; // 6
            }
 
            file class FC
            {
                private C<int> F;
                private event Del<int> E;
                private void M1(C<int> input) { }
                private C<int> M2() => throw null!;
 
                private C<int> P { get; set; }
                private C<int> this[int i] => throw null!;
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (8,20): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'C1'.
            //     private C<int> F; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "F").WithArguments("C<int>", "C1").WithLocation(8, 20),
            // (9,28): error CS9051: File-local type 'Del<int>' cannot be used in a member signature in non-file-local type 'C1'.
            //     private event Del<int> E; // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "E").WithArguments("Del<int>", "C1").WithLocation(9, 28),
            // (10,18): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'C1'.
            //     private void M1(C<int> input) { } // 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("C<int>", "C1").WithLocation(10, 18),
            // (11,20): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'C1'.
            //     private C<int> M2() => throw null!; // 4
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("C<int>", "C1").WithLocation(11, 20),
            // (13,20): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'C1'.
            //     private C<int> P { get; set; } // 5
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "P").WithArguments("C<int>", "C1").WithLocation(13, 20),
            // (14,20): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'C1'.
            //     private C<int> this[int i] => throw null!; // 6
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "this").WithArguments("C<int>", "C1").WithLocation(14, 20));
 
        verifyConstructedFileType(comp.GetMember<FieldSymbol>("C1.F").Type);
        verifyConstructedFileType(comp.GetMember<EventSymbol>("C1.E").Type);
        verifyConstructedFileType(comp.GetMember<MethodSymbol>("C1.M1").Parameters[0].Type);
        verifyConstructedFileType(comp.GetMember<MethodSymbol>("C1.M2").ReturnType);
        verifyConstructedFileType(comp.GetMember<PropertySymbol>("C1.P").Type);
        verifyConstructedFileType(comp.GetMember<PropertySymbol>("C1.this[]").Type);
 
        void verifyConstructedFileType(TypeSymbol type)
        {
            var cInt = (ConstructedNamedTypeSymbol)type;
            Assert.True(cInt.IsFileLocal);
        }
    }
 
    [Fact]
    public void AccessModifiers_01()
    {
        var source = """
            public file class C { } // 1
            file internal class D { } // 2
            private file class E { } // 3, 4
            file class F { } // ok
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (1,19): error CS9052: File-local type 'C' cannot use accessibility modifiers.
            // public file class C { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "C").WithArguments("C").WithLocation(1, 19),
            // (2,21): error CS9052: File-local type 'D' cannot use accessibility modifiers.
            // file internal class D { } // 2
            Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "D").WithArguments("D").WithLocation(2, 21),
            // (3,20): error CS9052: File-local type 'E' cannot use accessibility modifiers.
            // private file class E { } // 3, 4
            Diagnostic(ErrorCode.ERR_FileTypeNoExplicitAccessibility, "E").WithArguments("E").WithLocation(3, 20),
            // (3,20): error CS1527: Elements defined in a namespace cannot be explicitly declared as private, protected, protected internal, or private protected
            // private file class E { } // 3, 4
            Diagnostic(ErrorCode.ERR_NoNamespacePrivate, "E").WithLocation(3, 20));
    }
 
    [Fact]
    public void DuplicateModifiers_01()
    {
        var source = """
            file file class C { } // 1
            file readonly file struct D { } // 2
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (1,6): error CS1004: Duplicate 'file' modifier
            // file file class C { } // 1
            Diagnostic(ErrorCode.ERR_DuplicateModifier, "file").WithArguments("file").WithLocation(1, 6),
            // (2,15): error CS1004: Duplicate 'file' modifier
            // file readonly file struct D { } // 2
            Diagnostic(ErrorCode.ERR_DuplicateModifier, "file").WithArguments("file").WithLocation(2, 15));
    }
 
    [Fact]
    public void BaseClause_01()
    {
        var source = """
            file class Base { }
            class Derived1 : Base { } // 1
            public class Derived2 : Base { } // 2, 3
            file class Derived3 : Base { } // ok
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (2,7): error CS9053: File-local type 'Base' cannot be used as a base type of non-file-local type 'Derived1'.
            // class Derived1 : Base { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived1").WithArguments("Base", "Derived1").WithLocation(2, 7),
            // (3,14): error CS0060: Inconsistent accessibility: base class 'Base' is less accessible than class 'Derived2'
            // public class Derived2 : Base { } // 2, 3
            Diagnostic(ErrorCode.ERR_BadVisBaseClass, "Derived2").WithArguments("Derived2", "Base").WithLocation(3, 14),
            // (3,14): error CS9053: File-local type 'Base' cannot be used as a base type of non-file-local type 'Derived2'.
            // public class Derived2 : Base { } // 2, 3
            Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived2").WithArguments("Base", "Derived2").WithLocation(3, 14));
    }
 
    [Fact]
    public void BaseClause_02()
    {
        var source = """
            file interface Interface { }
 
            class Derived1 : Interface { } // ok
            file class Derived2 : Interface { } // ok
 
            interface Derived3 : Interface { } // 1
            file interface Derived4 : Interface { } // ok
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (6,11): error CS9053: File-local type 'Interface' cannot be used as a base type of non-file-local type 'Derived3'.
            // interface Derived3 : Interface { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived3").WithArguments("Interface", "Derived3").WithLocation(6, 11));
    }
 
    [Fact]
    public void BaseClause_03()
    {
        var source1 = """
            using System;
            class Base
            {
                public static void M0()
                {
                    Console.Write(1);
                }
            }
            """;
        var source2 = """
            using System;
 
            file class Base
            {
                public static void M0()
                {
                    Console.Write(2);
                }
            }
            file class Program : Base
            {
                static void Main()
                {
                    M0();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (source2, "file2.cs") }, expectedOutput: "2");
        verifier.VerifyDiagnostics();
        var comp = (CSharpCompilation)verifier.Compilation;
 
        var tree = comp.SyntaxTrees[1];
        var model = comp.GetSemanticModel(tree);
 
        var fileClassBase = (NamedTypeSymbol)comp.GetMembers("Base")[1];
        var expectedSymbol = fileClassBase.GetMember("M0");
 
        var node = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var symbolInfo = model.GetSymbolInfo(node.Expression);
        Assert.Equal(expectedSymbol.GetPublicSymbol(), symbolInfo.Symbol);
        Assert.Empty(symbolInfo.CandidateSymbols);
        Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
    }
 
    [Fact]
    public void BaseClause_04()
    {
        var source1 = """
            using System;
            class Base
            {
                public static void M0()
                {
                    Console.Write(1);
                }
            }
            """;
        var source2 = """
            file class Program : Base
            {
                static void Main()
                {
                    M0();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (source2, "file2.cs") }, expectedOutput: "1");
        verifier.VerifyDiagnostics();
        var comp = (CSharpCompilation)verifier.Compilation;
 
        var tree = comp.SyntaxTrees[1];
        var model = comp.GetSemanticModel(tree);
 
        var expectedSymbol = comp.GetMember("Base.M0");
 
        var node = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Last();
        var symbolInfo = model.GetSymbolInfo(node.Expression);
        Assert.Equal(expectedSymbol.GetPublicSymbol(), symbolInfo.Symbol);
        Assert.Empty(symbolInfo.CandidateSymbols);
        Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
    }
 
    [Fact]
    public void BaseClause_05()
    {
        var source = """
            interface I2 { }
            file interface I1 { }
            partial interface Derived : I1 { } // 1
            partial interface Derived : I2 { }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (3,19): error CS9053: File-local type 'I1' cannot be used as a base type of non-file-local type 'Derived'.
            // partial interface Derived : I1 { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeBase, "Derived").WithArguments("I1", "Derived").WithLocation(3, 19));
    }
 
    [Fact]
    public void BaseClause_06()
    {
        var source = """
        file class C<T> { }
 
        class D : C<int> { } // 1
        file class E : C<int> { }
 
        file interface I<T> { }
 
        class F : I<int> { } // ok
        file class G : I<int> { }
 
        interface J : I<int> { } // 2
        file interface K : I<int> { }
        """;
 
        var comp = CreateCompilation((source, "Program.cs"));
        comp.VerifyEmitDiagnostics(
            // Program.cs(3,7): error CS9053: File-local type 'C<int>' cannot be used as a base type of non-file-local type 'D'.
            // class D : C<int>, I<int> { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeBase, "D").WithArguments("C<int>", "D").WithLocation(3, 7),
            // Program.cs(11,11): error CS9053: File-local type 'I<int>' cannot be used as a base type of non-file-local type 'J'.
            // interface J : I<int> { } // 2
            Diagnostic(ErrorCode.ERR_FileTypeBase, "J").WithArguments("I<int>", "J").WithLocation(11, 11));
 
        var cInt = (ConstructedNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("D").BaseTypeNoUseSiteDiagnostics;
        Assert.True(cInt.IsFileLocal);
 
        var iInt = (ConstructedNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("F").InterfacesNoUseSiteDiagnostics()[0];
        Assert.True(iInt.IsFileLocal);
 
        iInt = (ConstructedNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("J").InterfacesNoUseSiteDiagnostics()[0];
        Assert.True(iInt.IsFileLocal);
    }
 
    [Fact]
    public void InterfaceImplementation_01()
    {
        var source = """
            file interface I
            {
                void F();
            }
            class C : I
            {
                public void F() { }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterfaceImplementation_02()
    {
        var source = """
            file interface I
            {
                void F(I i);
            }
            class C : I
            {
                public void F(I i) { } // 1
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,17): error CS9051: File-local type 'I' cannot be used in a member signature in non-file-local type 'C'.
            //     public void F(I i) { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "F").WithArguments("I", "C").WithLocation(7, 17));
    }
 
    [Fact]
    public void InterfaceImplementation_03()
    {
        var source = """
            file interface I
            {
                void F(I i);
            }
            class C : I
            {
                void I.F(I i) { }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,12): error CS9051: File-local type 'I' cannot be used in a member signature in non-file-local type 'C'.
            //     void I.F(I i) { }
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "F").WithArguments("I", "C").WithLocation(7, 12));
    }
 
    [Fact]
    public void InterfaceImplementation_04()
    {
        var source1 = """
            file interface I
            {
                void F();
            }
            partial class C : I
            {
            }
            """;
 
        var source2 = """
            partial class C
            {
                public void F() { }
            }
            """;
 
        // This is similar to how a base class may not have access to an interface (by being from another assembly, etc.),
        // but a derived class might add that interface to its list, and a base member implicitly implements an interface member.
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void InterfaceImplementation_05()
    {
        var source1 = """
            file interface I
            {
                void F();
            }
            partial class C : I // 1
            {
            }
            """;
 
        var source2 = """
            partial class C
            {
                void I.F() { } // 2, 3
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (3,10): error CS0246: The type or namespace name 'I' could not be found (are you missing a using directive or an assembly reference?)
            //     void I.F() { } // 2, 3
            Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I").WithArguments("I").WithLocation(3, 10),
            // (3,10): error CS0538: 'I' in explicit interface declaration is not an interface
            //     void I.F() { } // 2, 3
            Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I").WithArguments("I").WithLocation(3, 10),
            // (5,19): error CS0535: 'C' does not implement interface member 'I.F()'
            // partial class C : I // 1
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", "I.F()").WithLocation(5, 19));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void InterfaceImplementation_06()
    {
        // Ensure that appropriate error is given for duplicate implementations which have a type difference which is insignificant to the runtime.
        var source1 = """
            file interface FI<T>
            {
                public T Prop { get; }
            }
 
            internal class C : FI<object>
            {
                object FI<object>.Prop { get; }
                dynamic FI<dynamic>.Prop { get; }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs") }, targetFramework: TargetFramework.Net70);
        comp.VerifyDiagnostics(
            // F1.cs(6,16): error CS8646: 'FI<object>.Prop' is explicitly implemented more than once.
            // internal class C : FI<object>
            Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "C").WithArguments("FI<object>.Prop").WithLocation(6, 16),
            // F1.cs(9,13): error CS0540: 'C.FI<dynamic>.Prop': containing type does not implement interface 'FI<dynamic>'
            //     dynamic FI<dynamic>.Prop { get; }
            Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "FI<dynamic>").WithArguments("C.FI<dynamic>.Prop", "FI<dynamic>").WithLocation(9, 13)
            );
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void InterfaceImplementation_07()
    {
        // Ensure that appropriate error is given for duplicate implementations which have a type difference which is insignificant to the runtime.
        var source1 = """
            using System;
 
            file interface FI<T>
            {
                public T Prop { get; }
            }
 
            internal class C : FI<nint>, FI<IntPtr>
            {
                nint FI<nint>.Prop { get; }
                IntPtr FI<IntPtr>.Prop { get; }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs") }, targetFramework: TargetFramework.Net70);
        comp.VerifyDiagnostics(
            // F1.cs(8,16): error CS8646: 'FI<nint>.Prop' is explicitly implemented more than once.
            // internal class C : FI<nint>, FI<IntPtr>
            Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "C").WithArguments("FI<nint>.Prop").WithLocation(8, 16),
            // F1.cs(8,30): error CS0528: 'FI<nint>' is already listed in interface list
            // internal class C : FI<nint>, FI<IntPtr>
            Diagnostic(ErrorCode.ERR_DuplicateInterfaceInBaseList, "FI<IntPtr>").WithArguments("FI<nint>").WithLocation(8, 30),
            // F1.cs(11,23): error CS0102: The type 'C' already contains a definition for '<F1>F2A62B10769F2595F65CAD631A41E2B54F5D1B3601B00884A41306FA9AD9BACDB__FI<nint>.Prop'
            //     IntPtr FI<IntPtr>.Prop { get; }
            Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "Prop").WithArguments("C", "<F1>F2A62B10769F2595F65CAD631A41E2B54F5D1B3601B00884A41306FA9AD9BACDB__FI<nint>.Prop").WithLocation(11, 23)
            );
    }
 
    [Fact]
    public void TypeArguments_01()
    {
        var source = """
            file struct S { public int X; }
            class Container<T> { }
            unsafe class Program
            {
                Container<S> M1() => new Container<S>(); // 1
                S[] M2() => new S[0]; // 2
                (S, S) M3() => (new S(), new S()); // 3
                S* M4() => null; // 4
                delegate*<S, void> M5() => null; // 5
            }
            """;
 
        var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll);
        comp.VerifyDiagnostics(
                // (1,28): warning CS0649: Field 'S.X' is never assigned to, and will always have its default value 0
                // file struct S { public int X; }
                Diagnostic(ErrorCode.WRN_UnassignedInternalField, "X").WithArguments("S.X", "0").WithLocation(1, 28),
                // (5,18): error CS9051: File-local type 'Container<S>' cannot be used in a member signature in non-file-local type 'Program'.
                //     Container<S> M1() => new Container<S>(); // 1
                Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M1").WithArguments("Container<S>", "Program").WithLocation(5, 18),
                // (6,9): error CS9051: File-local type 'S[]' cannot be used in a member signature in non-file-local type 'Program'.
                //     S[] M2() => new S[0]; // 2
                Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M2").WithArguments("S[]", "Program").WithLocation(6, 9),
                // (7,12): error CS9051: File-local type '(S, S)' cannot be used in a member signature in non-file-local type 'Program'.
                //     (S, S) M3() => (new S(), new S()); // 3
                Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M3").WithArguments("(S, S)", "Program").WithLocation(7, 12),
                // (8,8): error CS9051: File-local type 'S*' cannot be used in a member signature in non-file-local type 'Program'.
                //     S* M4() => null; // 4
                Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M4").WithArguments("S*", "Program").WithLocation(8, 8),
                // (9,24): error CS9051: File-local type 'delegate*<S, void>' cannot be used in a member signature in non-file-local type 'Program'.
                //     delegate*<S, void> M5() => null; // 5
                Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "M5").WithArguments("delegate*<S, void>", "Program").WithLocation(9, 24));
    }
 
    [Fact]
    public void Constraints_01()
    {
        var source = """
            file class C { }
 
            file class D
            {
                void M<T>(T t) where T : C { } // ok
            }
 
            class E
            {
                void M<T>(T t) where T : C { } // 1
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (10,30): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'E.M<T>(T)'.
            //     void M<T>(T t) where T : C { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "C").WithArguments("C", "E.M<T>(T)").WithLocation(10, 30));
    }
 
    [Theory, WorkItem(62435, "https://github.com/dotnet/roslyn/issues/62435")]
    [InlineData("class")]
    [InlineData("struct")]
    [InlineData("interface")]
    [InlineData("record")]
    [InlineData("record struct")]
    public void Constraints_02(string typeKind)
    {
        var source = $$"""
            file class C { }
 
            file {{typeKind}} D<T> where T : C // ok
            {
            }
 
            {{typeKind}} E<T> where T : C // 1
            {
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (7,{{17 + typeKind.Length}}): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'E<T>'.
            // {{typeKind}} E<T> where T : C // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "C").WithArguments("C", "E<T>").WithLocation(7, 17 + typeKind.Length));
    }
 
    [Fact]
    public void Constraints_03()
    {
        var source = """
            file class C { }
 
            file class D
            {
                void M()
                {
                    local(new C());
                    void local<T>(T t) where T : C { } // ok
                }
            }
 
            class E
            {
                void M()
                {
                    local(new C());
                    void local<T>(T t) where T : C { } // ok
                }
            }
            """;
 
        // Local functions aren't members, so we don't give any diagnostics when their signatures contain file types.
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void Constraints_04()
    {
        var source = """
            file class C { }
 
            file delegate void D1<T>(T t) where T : C; // ok
 
            delegate void D2<T>(T t) where T : C; // 1
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (5,36): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'D2<T>'.
            // delegate void D2<T>(T t) where T : C; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "C").WithArguments("C", "D2<T>").WithLocation(5, 36));
    }
 
    [Fact]
    public void Constraints_05()
    {
        var source = """
            file class C<T> { }
 
            class D
            {
                private void M<T>(T t) where T : C<int> { } // 1
            }
 
            file class E
            {
                private void M<T>(T t) where T : C<int> { } // ok
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (5,38): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'D.M<T>(T)'.
            //     private void M<T>(T t) where T : C<int> { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "C<int>").WithArguments("C<int>", "D.M<T>(T)").WithLocation(5, 38));
 
        var cInt = (ConstructedNamedTypeSymbol)comp.GetMember<MethodSymbol>("D.M").TypeParameters[0].ConstraintTypesNoUseSiteDiagnostics[0].Type;
        Assert.True(cInt.IsFileLocal);
    }
 
    [Fact]
    public void Constraints_06()
    {
        var source = """
            file class C<T> { }
 
            class D<T> where T : C<int> { } // 1
 
            file class E<T> where T : C<int> { } // ok
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (3,22): error CS9051: File-local type 'C<int>' cannot be used in a member signature in non-file-local type 'D<T>'.
            // class D<T> where T : C<int> { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "C<int>").WithArguments("C<int>", "D<T>").WithLocation(3, 22));
 
        var cInt = (ConstructedNamedTypeSymbol)comp.GetMember<NamedTypeSymbol>("D").TypeParameters[0].ConstraintTypesNoUseSiteDiagnostics[0].Type;
        Assert.True(cInt.IsFileLocal);
    }
 
    [Fact]
    public void PrimaryConstructor_01()
    {
        var source = """
            file class C { }
 
            record R1(C c); // 1
            record struct R2(C c); // 2
 
            file record R3(C c);
            file record struct R4(C c);
            """;
 
        var comp = CreateCompilation(new[] { (source, "file1.cs"), (IsExternalInitTypeDefinition, "file2.cs") });
        comp.VerifyDiagnostics(
            // (3,8): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'R1'.
            // record R1(C c); // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R1").WithArguments("C", "R1").WithLocation(3, 8),
            // (3,8): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'R1'.
            // record R1(C c); // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R1").WithArguments("C", "R1").WithLocation(3, 8),
            // (4,15): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'R2'.
            // record struct R2(C c); // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R2").WithArguments("C", "R2").WithLocation(4, 15),
            // (4,15): error CS9051: File-local type 'C' cannot be used in a member signature in non-file-local type 'R2'.
            // record struct R2(C c); // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "R2").WithArguments("C", "R2").WithLocation(4, 15)
            );
    }
 
    [Fact]
    public void Lambda_01()
    {
        var source = """
            file class C { }
 
            class Program
            {
                void M()
                {
                    var lambda = C (C c) => c; // ok
                }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void LocalFunction_01()
    {
        var source = """
            file class C { }
 
            class Program
            {
                void M()
                {
                    local(null!);
                    C local(C c) => c; // ok
                }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
    }
 
    [Fact]
    public void AccessThroughNamespace_01()
    {
        var source = """
            using System;
 
            namespace NS
            {
                file class C
                {
                    public static void M() => Console.Write(1);
                }
            }
 
            class Program
            {
                public static void Main()
                {
                    NS.C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void AccessThroughNamespace_02()
    {
        var source1 = """
            using System;
 
            namespace NS
            {
                file class C
                {
                    public static void M()
                    {
                        Console.Write(1);
                    }
                }
            }
            """;
 
        var source2 = """
            class Program
            {
                static void Main()
                {
                    NS.C.M(); // 1
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (5,9): error CS0234: The type or namespace name 'C' does not exist in the namespace 'NS' (are you missing an assembly reference?)
            //         NS.C.M(); // 1
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "NS.C").WithArguments("C", "NS").WithLocation(5, 9));
    }
 
    [Fact]
    public void AccessThroughType_01()
    {
        var source = """
            using System;
 
            class Outer
            {
                file class C // 1
                {
                    public static void M() => Console.Write(1);
                }
            }
 
            class Program
            {
                public static void Main()
                {
                    Outer.C.M(); // 2
                }
            }
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (5,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(5, 16),
            // (15,15): error CS0122: 'Outer.C' is inaccessible due to its protection level
            //         Outer.C.M(); // 2
            Diagnostic(ErrorCode.ERR_BadAccess, "C").WithArguments("Outer.C").WithLocation(15, 15));
    }
 
    [Fact]
    public void AccessThroughType_02()
    {
        var source1 = """
            using System;
 
            class Outer
            {
                file class C
                {
                    public static void M()
                    {
                        Console.Write(1);
                    }
                }
            }
            """;
 
        var source2 = """
            class Program
            {
                static void Main()
                {
                    Outer.C.M(); // 1
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (5,15): error CS0117: 'Outer' does not contain a definition for 'C'
            //         Outer.C.M(); // 1
            Diagnostic(ErrorCode.ERR_NoSuchMember, "C").WithArguments("Outer", "C").WithLocation(5, 15),
            // (5,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(5, 16));
    }
 
    [Fact]
    public void AccessThroughGlobalUsing_01()
    {
        var usings = """
            global using NS;
            """;
 
        var source = """
            using System;
 
            namespace NS
            {
                file class C
                {
                    public static void M() => Console.Write(1);
                }
            }
 
            class Program
            {
                public static void Main()
                {
                    C.M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (usings, "file1.cs"), (source, "file2.cs"), (IsExternalInitTypeDefinition, "file3.cs") }, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Theory]
    [InlineData("file ")]
    [InlineData("")]
    public void AccessThroughGlobalUsing_02(string fileModifier)
    {
        var source = $$"""
            using System;
 
            namespace NS
            {
                {{fileModifier}}class C
                {
                    public static void M() => Console.Write(1);
                }
            }
 
            class Program
            {
                public static void Main()
                {
                    C.M(); // 1
                }
            }
            """;
 
        // note: 'Usings' is a legacy setting which only works in scripts.
        // https://github.com/dotnet/roslyn/issues/61502
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (IsExternalInitTypeDefinition, "file2.cs") }, options: TestOptions.DebugExe.WithUsings("NS"));
        compilation.VerifyDiagnostics(
            // (15,9): error CS0103: The name 'C' does not exist in the current context
            //         C.M(); // 1
            Diagnostic(ErrorCode.ERR_NameNotInContext, "C").WithArguments("C").WithLocation(15, 9));
    }
 
    [Fact]
    public void GlobalUsingStatic_01()
    {
        var source = """
            global using static C;
 
            file class C
            {
                public static void M() { }
            }
            """;
 
        var main = """
            class Program
            {
                public static void Main()
                {
                    M();
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (main, "file2.cs") });
        compilation.VerifyDiagnostics(
                // (1,1): hidden CS8019: Unnecessary using directive.
                // global using static C;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "global using static C;").WithLocation(1, 1),
                // (1,21): error CS9055: File-local type 'C' cannot be used in a 'global using static' directive.
                // global using static C;
                Diagnostic(ErrorCode.ERR_GlobalUsingStaticFileType, "C").WithArguments("C").WithLocation(1, 21),
                // (5,9): error CS0103: The name 'M' does not exist in the current context
                //         M();
                Diagnostic(ErrorCode.ERR_NameNotInContext, "M").WithArguments("M").WithLocation(5, 9));
    }
 
    [Fact]
    public void GlobalUsingStatic_02()
    {
        var source = """
            global using static Container<C>;
 
            public class Container<T>
            {
            }
 
            file class C
            {
                public static void M() { }
            }
            """;
 
        var main = """
            class Program
            {
                public static void Main()
                {
                    M();
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (main, "file2.cs") });
        compilation.VerifyDiagnostics(
                // (1,1): hidden CS8019: Unnecessary using directive.
                // global using static Container<C>;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "global using static Container<C>;").WithLocation(1, 1),
                // (1,21): error CS9055: File-local type 'Container<C>' cannot be used in a 'global using static' directive.
                // global using static Container<C>;
                Diagnostic(ErrorCode.ERR_GlobalUsingStaticFileType, "Container<C>").WithArguments("Container<C>").WithLocation(1, 21),
                // (5,9): error CS0103: The name 'M' does not exist in the current context
                //         M();
                Diagnostic(ErrorCode.ERR_NameNotInContext, "M").WithArguments("M").WithLocation(5, 9));
    }
 
    [Fact]
    public void GlobalUsingStatic_03()
    {
        var source = """
            global using static C<int>;
 
            file class C<T>
            {
                public static void M() { }
            }
            """;
 
        var main = """
            class Program
            {
                public static void Main()
                {
                    M();
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (main, "file2.cs") });
        compilation.VerifyDiagnostics(
            // file1.cs(1,1): hidden CS8019: Unnecessary using directive.
            // global using static C<int>;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "global using static C<int>;").WithLocation(1, 1),
            // file1.cs(1,21): error CS9055: File-local type 'C<int>' cannot be used in a 'global using static' directive.
            // global using static C<int>;
            Diagnostic(ErrorCode.ERR_GlobalUsingStaticFileType, "C<int>").WithArguments("C<int>").WithLocation(1, 21),
            // file2.cs(5,9): error CS0103: The name 'M' does not exist in the current context
            //         M();
            Diagnostic(ErrorCode.ERR_NameNotInContext, "M").WithArguments("M").WithLocation(5, 9));
    }
 
    [Fact]
    public void UsingStatic_01()
    {
        var source = """
            using System;
            using static C;
 
            file class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
 
            class Program
            {
                public static void Main()
                {
                    M();
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void UsingStatic_02()
    {
        var source1 = """
            using System;
            using static C.D;
 
            M();
 
            file class C
            {
                public class D
                {
                    public static void M() { Console.Write(1); }
                }
            }
            """;
 
        var source2 = """
            using System;
 
            class C
            {
                public class D
                {
                    public static void M() { Console.Write(2); }
                }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (source2, "file2.cs") }, expectedOutput: "1");
        verifier.VerifyDiagnostics();
        var comp = (CSharpCompilation)verifier.Compilation;
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
 
        var members = comp.GetMembers("C");
        Assert.Equal(2, members.Length);
        var expectedMember = ((NamedTypeSymbol)members[0]).GetMember<MethodSymbol>("D.M");
 
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First();
        var symbolInfo = model.GetSymbolInfo(invocation.Expression);
        Assert.Equal(expectedMember.GetPublicSymbol(), symbolInfo.Symbol);
        Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
        Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
    }
 
    [Theory]
    [InlineData("file ")]
    [InlineData("")]
    public void UsingStatic_03(string fileModifier)
    {
        // note: the top-level `class D` "wins" the lookup in this scenario.
        var source1 = $$"""
            using System;
            using static C;
 
            D.M();
 
            {{fileModifier}}class C
            {
                public class D
                {
                    public static void M() { Console.Write(1); }
                }
            }
            """;
 
        var source2 = """
            using System;
 
            class D
            {
                public static void M() { Console.Write(2); }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source1, "file1.cs"), (source2, "file2.cs") }, expectedOutput: "2");
        verifier.VerifyDiagnostics(
            // (2,1): hidden CS8019: Unnecessary using directive.
            // using static C;
            Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static C;").WithLocation(2, 1));
        var comp = (CSharpCompilation)verifier.Compilation;
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
 
        var expectedMember = comp.GetMember("D.M");
 
        var invocation = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().First();
        var symbolInfo = model.GetSymbolInfo(invocation.Expression);
        Assert.Equal(expectedMember.GetPublicSymbol(), symbolInfo.Symbol);
        Assert.Equal(0, symbolInfo.CandidateSymbols.Length);
        Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
    }
 
    [Fact]
    public void TypeShadowing()
    {
        var source = """
            using System;
 
            class Base
            {
                internal class C
                {
                    public static void M()
                    {
                        Console.Write(1);
                    }
                }
            }
 
            class Derived : Base
            {
                new file class C
                {
                }
            }
            """;
 
        var main = """
            class Program
            {
                public static void Main()
                {
                    Derived.C.M();
                }
            }
            """;
 
        // 'Derived.C' is not actually accessible from 'Program', so we just bind to 'Base.C'.
        var compilation = CreateCompilation(new[] { (source, "file.cs"), (main, "file2.cs") });
        compilation.VerifyDiagnostics(
            // (16,20): error CS9054: File-local type 'Derived.C' must be defined in a top level type; 'Derived.C' is a nested type.
            //     new file class C
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Derived.C").WithLocation(16, 20));
 
        var expected = compilation.GetMember<MethodSymbol>("Base.C.M");
 
        var tree = compilation.SyntaxTrees[1];
        var model = compilation.GetSemanticModel(tree);
        var invoked = tree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single().Expression;
        var symbolInfo = model.GetSymbolInfo(invoked);
        Assert.Equal(expected, symbolInfo.Symbol.GetSymbol());
    }
 
    [Fact]
    public void SemanticModel_01()
    {
        var source = """
            namespace NS;
 
            file class C
            {
                public static void M() { }
            }
 
            class Program
            {
                public void M()
                {
                    C.M();
                }
            }
            """;
 
        var compilation = CreateCompilation(source);
        compilation.VerifyDiagnostics();
 
        var tree = compilation.SyntaxTrees[0];
        var body = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Last().Body!;
 
        var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false);
 
        var info = model.GetSymbolInfo(((ExpressionStatementSyntax)body.Statements.First()).Expression);
        Assert.Equal("void NS.C@<tree 0>.M()", info.Symbol.ToTestDisplayString());
 
        var classC = compilation.GetMember("NS.C").GetPublicSymbol();
        Assert.Equal("NS.C@<tree 0>", classC.ToTestDisplayString());
 
        // lookup with no container
        var symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, name: "C");
        Assert.Equal(new[] { classC }, symbols);
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition);
        Assert.Contains(classC, symbols);
 
        // lookup with a correct container
        var nsSymbol = compilation.GetMember<NamespaceSymbol>("NS").GetPublicSymbol();
        Assert.Equal("NS", nsSymbol.ToTestDisplayString());
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol, name: "C");
        Assert.Equal(new[] { classC }, symbols);
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol);
        Assert.Contains(classC, symbols);
 
        // lookup with an incorrect container
        nsSymbol = compilation.GetMember<NamespaceSymbol>("System").GetPublicSymbol();
        Assert.Equal("System", nsSymbol.ToTestDisplayString());
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol, name: "C");
        Assert.Empty(symbols);
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol);
        Assert.DoesNotContain(classC, symbols);
    }
 
    [Fact]
    public void SemanticModel_02()
    {
        var source = """
            namespace NS;
 
            file class C
            {
                public static void M() { }
            }
            """;
 
        var main = """
            namespace NS;
 
            class Program
            {
                public void M()
                {
                    C.M(); // 1
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (main, "file2.cs") });
        compilation.VerifyDiagnostics(
            // (7,9): error CS0103: The name 'C' does not exist in the current context
            //         C.M(); // 1
            Diagnostic(ErrorCode.ERR_NameNotInContext, "C").WithArguments("C").WithLocation(7, 9)
            );
 
        var tree = compilation.SyntaxTrees[1];
        var body = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Last().Body!;
 
        var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false);
 
        var info = model.GetSymbolInfo(((ExpressionStatementSyntax)body.Statements.First()).Expression);
        Assert.Null(info.Symbol);
        Assert.Empty(info.CandidateSymbols);
        Assert.Equal(CandidateReason.None, info.CandidateReason);
 
        var classC = compilation.GetMember("NS.C").GetPublicSymbol();
        Assert.Equal("NS.C@file1", classC.ToTestDisplayString());
 
        // lookup with no container
        var symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, name: "C");
        Assert.Empty(symbols);
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition);
        Assert.DoesNotContain(classC, symbols);
 
        // lookup with a correct container (still don't find the symbol due to lookup occurring in other file)
        var nsSymbol = compilation.GetMember<NamespaceSymbol>("NS").GetPublicSymbol();
        Assert.Equal("NS", nsSymbol.ToTestDisplayString());
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol, name: "C");
        Assert.Empty(symbols);
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol);
        Assert.DoesNotContain(classC, symbols);
 
        // lookup with an incorrect container
        nsSymbol = compilation.GetMember<NamespaceSymbol>("System").GetPublicSymbol();
        Assert.Equal("System", nsSymbol.ToTestDisplayString());
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol, name: "C");
        Assert.Empty(symbols);
 
        symbols = model.LookupSymbols(body.OpenBraceToken.EndPosition, container: nsSymbol);
        Assert.DoesNotContain(classC, symbols);
    }
 
    [Fact]
    public void Speculation_01()
    {
        var source = """
            file class C
            {
                public static void M() { }
            }
 
            class Program
            {
                public void M()
                {
 
                }
            }
            """;
 
        var compilation = CreateCompilation(source);
        compilation.VerifyDiagnostics();
 
        var tree = compilation.SyntaxTrees[0];
        var body = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Last().Body!;
 
        var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false);
 
        var newBody = body.AddStatements(SyntaxFactory.ParseStatement("C.M();"));
        Assert.True(model.TryGetSpeculativeSemanticModel(position: body.OpenBraceToken.EndPosition, newBody, out var speculativeModel));
        var info = speculativeModel!.GetSymbolInfo(((ExpressionStatementSyntax)newBody.Statements.First()).Expression);
        Assert.Equal(compilation.GetMember("C.M").GetPublicSymbol(), info.Symbol);
 
        var classC = compilation.GetMember("C").GetPublicSymbol();
        var symbols = speculativeModel.LookupSymbols(newBody.OpenBraceToken.EndPosition, name: "C");
        Assert.Equal(new[] { classC }, symbols);
 
        symbols = speculativeModel.LookupSymbols(newBody.OpenBraceToken.EndPosition);
        Assert.Contains(classC, symbols);
    }
 
    [Fact]
    public void Speculation_02()
    {
        var source = """
            file class C
            {
                public static void M() { }
            }
            """;
 
        var main = """
            class Program
            {
                public void M()
                {
 
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (main, "file2.cs") });
        compilation.VerifyDiagnostics();
 
        var tree = compilation.SyntaxTrees[1];
        var body = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Last().Body!;
 
        var model = compilation.GetSemanticModel(tree, ignoreAccessibility: false);
 
        var newBody = body.AddStatements(SyntaxFactory.ParseStatement("C.M();"));
        Assert.True(model.TryGetSpeculativeSemanticModel(position: body.OpenBraceToken.EndPosition, newBody, out var speculativeModel));
        var info = speculativeModel!.GetSymbolInfo(((ExpressionStatementSyntax)newBody.Statements.First()).Expression);
        Assert.Null(info.Symbol);
        Assert.Empty(info.CandidateSymbols);
        Assert.Equal(CandidateReason.None, info.CandidateReason);
 
        var symbols = speculativeModel.LookupSymbols(newBody.OpenBraceToken.EndPosition, name: "C");
        Assert.Empty(symbols);
 
        symbols = speculativeModel.LookupSymbols(newBody.OpenBraceToken.EndPosition);
        Assert.DoesNotContain(compilation.GetMember("C").GetPublicSymbol(), symbols);
    }
 
    [Fact]
    public void Cref_01()
    {
        var source = """
            file class C
            {
                public static void M() { }
            }
 
            class Program
            {
                /// <summary>
                /// In the same file as <see cref="C"/>.
                /// </summary>
                public static void M()
                {
 
                }
            }
            """;
 
        var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview.WithDocumentationMode(DocumentationMode.Diagnose));
        compilation.VerifyDiagnostics();
    }
 
    [Fact]
    public void Cref_02()
    {
        var source = """
            file class C
            {
                public static void M() { }
            }
            """;
 
        var main = """
            class Program
            {
                /// <summary>
                /// In a different file than <see cref="C"/>.
                /// </summary>
                public static void M()
                {
 
                }
            }
            """;
 
        var compilation = CreateCompilation(new[] { (source, "file1.cs"), (main, "file2.cs") }, parseOptions: TestOptions.RegularPreview.WithDocumentationMode(DocumentationMode.Diagnose));
        compilation.VerifyDiagnostics(
            // (4,45): warning CS1574: XML comment has cref attribute 'C' that could not be resolved
            //     /// In a different file than <see cref="C"/>.
            Diagnostic(ErrorCode.WRN_BadXMLRef, "C").WithArguments("C").WithLocation(4, 45)
            );
    }
 
    [Fact]
    public void TopLevelStatements()
    {
        var source = """
            using System;
 
            C.M();
 
            file class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void StaticFileClass()
    {
        var source = """
            using System;
 
            C.M();
 
            static file class C
            {
                public static void M()
                {
                    Console.Write(1);
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ExtensionMethod_01()
    {
        var source = """
            using System;
 
            "a".M();
 
            static file class C
            {
                public static void M(this string s)
                {
                    Console.Write(1);
                }
            }
            """;
 
        var verifier = CompileAndVerify(source, expectedOutput: "1");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ExtensionMethod_02()
    {
        var source1 = """
            "a".M(); // 1
            """;
 
        var source2 = """
            using System;
 
            static file class C
            {
                public static void M(this string s)
                {
                    Console.Write(1);
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (1,5): error CS1061: 'string' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
            // "a".M(); // 1
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("string", "M").WithLocation(1, 5));
 
        var tree = comp.SyntaxTrees[0];
        var methodNameSyntax = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Single();
        var model = comp.GetSemanticModel(tree);
 
        var symbolInfo = model.GetSymbolInfo(methodNameSyntax);
        Assert.Null(symbolInfo.Symbol);
        Assert.Empty(symbolInfo.CandidateSymbols);
        Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason);
 
        var aliasInfo = model.GetAliasInfo(methodNameSyntax);
        Assert.Null(aliasInfo);
    }
 
    [Fact]
    public void ExtensionMethod_03()
    {
        var source1 = """
            "a".M(); // 1
            """;
 
        var source2 = """
            using System;
 
            file class C
            {
                static class D
                {
                    public static void M(this string s) // 2
                    {
                        Console.Write(1);
                    }
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics(
            // (1,5): error CS1061: 'string' does not contain a definition for 'M' and no accessible extension method 'M' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
            // "a".M(); // 1
            Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M").WithArguments("string", "M").WithLocation(1, 5),
            // (7,28): error CS1109: Extension methods must be defined in a top level static class; D is a nested class
            //         public static void M(this string s) // 2
            Diagnostic(ErrorCode.ERR_ExtensionMethodsDecl, "M").WithArguments("D").WithLocation(7, 28));
    }
 
    [Fact]
    public void Alias_01()
    {
        var source = """
            namespace NS;
            using C1 = NS.C;
 
            file class C
            {
            }
 
            class D : C1 { } // 1
            """;
 
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics(
            // (8,7): error CS9053: File-local type 'C' cannot be used as a base type of non-file-local type 'D'.
            // class D : C1 { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeBase, "D").WithArguments("NS.C", "NS.D").WithLocation(8, 7));
    }
 
    [Fact]
    public void SymbolDisplay()
    {
        var source1 = """
            file class C1
            {
                public static void M() { }
            }
            """;
 
        var source2 = """
            file class C2
            {
                public static void M() { }
            }
            """;
 
        var comp = CreateCompilation(new[]
        {
            SyntaxFactory.ParseSyntaxTree(source1, TestOptions.RegularPreview),
            SyntaxFactory.ParseSyntaxTree(source2, TestOptions.RegularPreview, path: "path/to/FileB.cs")
        });
        comp.VerifyDiagnostics();
 
        var c1 = comp.GetMember<NamedTypeSymbol>("C1");
        var c2 = comp.GetMember<NamedTypeSymbol>("C2");
        Assert.Equal("C1@<tree 0>", c1.ToTestDisplayString());
        Assert.Equal("C2@FileB", c2.ToTestDisplayString());
 
        Assert.Equal("void C1@<tree 0>.M()", c1.GetMember("M").ToTestDisplayString());
        Assert.Equal("void C2@FileB.M()", c2.GetMember("M").ToTestDisplayString());
    }
 
    [Fact]
    public void Script_01()
    {
        var source1 = """
            using System;
 
            C1.M("a");
 
            static file class C1
            {
                public static void M(this string s) { }
            }
            """;
 
        var comp = CreateSubmission(source1, parseOptions: TestOptions.Script.WithLanguageVersion(LanguageVersion.Preview));
        comp.VerifyDiagnostics(
            // (5,19): error CS9054: File-local type 'C1' must be defined in a top level type; 'C1' is a nested type.
            // static file class C1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C1").WithArguments("C1").WithLocation(5, 19),
            // (7,24): error CS1109: Extension methods must be defined in a top level static class; C1 is a nested class
            //     public static void M(this string s) { }
            Diagnostic(ErrorCode.ERR_ExtensionMethodsDecl, "M").WithArguments("C1").WithLocation(7, 24));
    }
 
    [Fact]
    public void SystemVoid_01()
    {
        var source1 = """
            using System;
 
            void M(Void v) { }
 
            namespace System
            {
                file class Void { }
            }
            """;
 
        // https://github.com/dotnet/roslyn/issues/62331
        // Ideally we would give an error about use of System.Void here.
        var comp = CreateCompilation(source1);
        comp.VerifyDiagnostics(
                // (3,6): warning CS8321: The local function 'M' is declared but never used
                // void M(Void v) { }
                Diagnostic(ErrorCode.WRN_UnreferencedLocalFunction, "M").WithArguments("M").WithLocation(3, 6));
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
 
        var voidTypeSyntax = tree.GetRoot().DescendantNodes().OfType<ParameterSyntax>().Single().Type!;
        var typeInfo = model.GetTypeInfo(voidTypeSyntax);
        Assert.Equal("System.Void@<tree 0>", typeInfo.Type!.ToDisplayString(SymbolDisplayFormat.TestFormat.WithCompilerInternalOptions(SymbolDisplayCompilerInternalOptions.IncludeContainingFileForFileTypes)));
    }
 
    [Fact]
    public void GetTypeByMetadataName_01()
    {
        var source1 = """
            file class C { }
            """;
 
        // from source
        var comp = CreateCompilation(source1);
        comp.VerifyDiagnostics();
        var sourceMember = comp.GetMember<NamedTypeSymbol>("C");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C", sourceMember.MetadataName);
 
        var sourceType = comp.GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C");
        Assert.Equal(sourceMember, sourceType);
 
        Assert.Null(comp.GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__D"));
        Assert.Null(comp.GetTypeByMetadataName("<>F1__C"));
        Assert.Null(comp.GetTypeByMetadataName("F0__C"));
        Assert.Null(comp.GetTypeByMetadataName("<file>F0__C"));
        Assert.Null(comp.GetTypeByMetadataName("C"));
        Assert.Null(comp.GetTypeByMetadataName("C`1"));
 
        // from metadata
        var comp2 = CreateCompilation("", references: new[] { comp.EmitToImageReference() });
        comp2.VerifyDiagnostics();
        var metadataMember = comp2.GetMember<NamedTypeSymbol>("C");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C", metadataMember.MetadataName);
 
        var metadataType = comp2.GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C");
        Assert.Equal(metadataMember, metadataType);
 
        Assert.Null(comp2.GetTypeByMetadataName("C"));
    }
 
    [Fact]
    public void GetTypeByMetadataName_02()
    {
        var source1 = """
            file class C<T> { }
            """;
 
        // from source
        var comp = CreateCompilation(source1);
        comp.VerifyDiagnostics();
        var sourceMember = comp.GetMember<NamedTypeSymbol>("C");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C`1", sourceMember.MetadataName);
 
        var sourceType = comp.GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C`1");
        Assert.Equal(sourceMember, sourceType);
        Assert.Null(comp.GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C"));
        Assert.Null(comp.GetTypeByMetadataName("C"));
        Assert.Null(comp.GetTypeByMetadataName("C`1"));
 
        // from metadata
        var comp2 = CreateCompilation("", references: new[] { comp.EmitToImageReference() });
        comp2.VerifyDiagnostics();
 
        var metadataMember = comp2.GetMember<NamedTypeSymbol>("C");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C`1", metadataMember.MetadataName);
 
        var metadataType = comp2.GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C`1");
        Assert.Equal(metadataMember, metadataType);
 
        Assert.Null(comp2.GetTypeByMetadataName("C`1"));
    }
 
    [Fact]
    public void GetTypeByMetadataName_03()
    {
        var source1 = """
            class Outer
            {
                file class C { } // 1
            }
            """;
 
        // from source
        var comp = CreateCompilation(source1);
        comp.VerifyDiagnostics(
            // (3,16): error CS9054: File-local type 'Outer.C' must be defined in a top level type; 'Outer.C' is a nested type.
            //     file class C { } // 1
            Diagnostic(ErrorCode.ERR_FileTypeNested, "C").WithArguments("Outer.C").WithLocation(3, 16));
        var sourceMember = comp.GetMember<NamedTypeSymbol>("Outer.C");
        Assert.Equal("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C", sourceMember.MetadataName);
 
        var sourceType = comp.GetTypeByMetadataName("Outer.<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C");
        // Note: strictly speaking, it would be reasonable to return the (invalid) nested file-local type symbol here.
        // However, since we don't actually support nested file types, we don't think we need the API to do the additional lookup
        // when the requested type is nested, and so we end up giving a null here.
        Assert.Null(sourceType);
        Assert.Null(comp.GetTypeByMetadataName("Outer.C"));
    }
 
    [Fact]
    public void GetTypeByMetadataName_04()
    {
        var source1 = """
            file class C { }
            """;
 
        var source2 = """
            class C { }
            """;
 
        // from source
        var comp = CreateCompilation(new[] { (source1, "file1.cs"), (source2, "file2.cs") });
        comp.VerifyDiagnostics();
        var sourceMember = comp.GetMembers("C")[0];
        AssertEx.Equal("<file1>F96B1D9CB33A43D51528FE81EDAFE5AE31358FE749929AC76B76C64B60DEF129D__C", sourceMember.MetadataName);
 
        var sourceType = comp.GetTypeByMetadataName("<file1>F96B1D9CB33A43D51528FE81EDAFE5AE31358FE749929AC76B76C64B60DEF129D__C");
        Assert.Equal(sourceMember, sourceType);
 
        var sourceTypeCByMetadataName = comp.GetTypeByMetadataName("C");
        Assert.NotNull(sourceTypeCByMetadataName);
        Assert.Equal("C", sourceTypeCByMetadataName.MetadataName);
        Assert.False(sourceTypeCByMetadataName is SourceMemberContainerTypeSymbol { IsFileLocal: true });
 
        // from metadata
        var comp2 = CreateCompilation("", references: new[] { comp.EmitToImageReference() });
        comp2.VerifyDiagnostics();
 
        var metadataMember = comp2.GetMembers("C")[0];
        Assert.Equal("<file1>F96B1D9CB33A43D51528FE81EDAFE5AE31358FE749929AC76B76C64B60DEF129D__C", metadataMember.MetadataName);
 
        var metadataType = comp2.GetTypeByMetadataName("<file1>F96B1D9CB33A43D51528FE81EDAFE5AE31358FE749929AC76B76C64B60DEF129D__C");
        Assert.Equal(metadataMember, metadataType);
 
        var metadataTypeCByMetadataName = comp2.GetTypeByMetadataName("C");
        Assert.NotNull(metadataTypeCByMetadataName);
        Assert.Equal("C", metadataTypeCByMetadataName.MetadataName);
    }
 
    [CombinatorialData]
    [Theory]
    public void GetTypeByMetadataName_05(bool firstIsMetadataReference, bool secondIsMetadataReference)
    {
        var source1 = """
            file class C { }
            """;
 
        // Create two references containing identically-named file types
        var ref1 = CreateCompilation(source1, assemblyName: "ref1");
        var ref2 = CreateCompilation(source1, assemblyName: "ref2");
 
        var comp = CreateCompilation("", references: new[]
        {
            firstIsMetadataReference ? ref1.ToMetadataReference() : ref1.EmitToImageReference(),
            secondIsMetadataReference ? ref2.ToMetadataReference() : ref2.EmitToImageReference()
        });
        comp.VerifyDiagnostics();
 
        const string metadataName = "<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C";
        var sourceType = comp.GetTypeByMetadataName(metadataName);
        Assert.Null(sourceType);
        Assert.Null(comp.GetTypeByMetadataName("C"));
 
        var types = comp.GetTypesByMetadataName(metadataName);
        Assert.Equal(2, types.Length);
        Assert.Equal(firstIsMetadataReference ? "C@<tree 0>" : "C@<unknown>", types[0].ToTestDisplayString());
        Assert.Equal(secondIsMetadataReference ? "C@<tree 0>" : "C@<unknown>", types[1].ToTestDisplayString());
        Assert.NotEqual(types[0], types[1]);
 
        Assert.Empty(comp.GetTypesByMetadataName("C"));
    }
 
    [Fact]
    public void GetTypeByMetadataName_06()
    {
        var source1 = """
            file class C { }
            file class C { }
            """;
 
        var comp = CreateCompilation(source1);
        comp.VerifyDiagnostics(
            // (2,12): error CS9070: The namespace '<global namespace>' already contains a definition for 'C' in this file.
            // file class C { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "C").WithArguments("C", "<global namespace>").WithLocation(2, 12));
 
        const string metadataName = "<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C";
        var sourceType = ((Compilation)comp).GetTypeByMetadataName(metadataName);
        Assert.Equal("C@<tree 0>", sourceType.ToTestDisplayString());
 
        Assert.Null(((Compilation)comp).GetTypeByMetadataName("C"));
 
        var types = comp.GetTypesByMetadataName(metadataName);
        Assert.Equal(1, types.Length);
        Assert.Same(sourceType, types[0]);
 
        Assert.Empty(comp.GetTypesByMetadataName("C"));
    }
 
    [Fact]
    public void GetTypeByMetadataName_07()
    {
        var source1 = """
            file class C { }
            """;
 
        var comp = CreateCompilation(SyntaxFactory.ParseSyntaxTree(source1, options: TestOptions.RegularPreview, path: "path/to/SomeFile.cs"));
        comp.VerifyDiagnostics();
 
        const string checksum = "0146C6A4DC0D382DC3D534F34EF202BE3FAF72EE35E08C8382B730D5270B6585";
        Assert.Null(comp.GetTypeByMetadataName($"<>F{checksum}__C"));
        Assert.Empty(comp.GetTypesByMetadataName($"<>F{checksum}__C"));
 
        Assert.Null(comp.GetTypeByMetadataName($"<WrongName>F{checksum}__C"));
        Assert.Empty(comp.GetTypesByMetadataName($"<WrongName>F{checksum}__C"));
 
        var sourceType = ((Compilation)comp).GetTypeByMetadataName($"<SomeFile>F{checksum}__C");
        Assert.Equal("C@SomeFile", sourceType.ToTestDisplayString());
 
        var types = comp.GetTypesByMetadataName($"<SomeFile>F{checksum}__C");
        Assert.Equal(1, types.Length);
        Assert.Same(sourceType, types[0]);
    }
 
    [Fact]
    public void GetTypeByMetadataName_08()
    {
        var source1 = """
            file class C { public static void M() { } }
            """;
 
        var comp = CreateCompilation(source1, targetFramework: TargetFramework.Mscorlib40);
        comp.VerifyDiagnostics();
 
        const string metadataName = "<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C";
 
        var member = comp.GetMember<NamedTypeSymbol>("C");
        Assert.Equal(metadataName, member.MetadataName);
 
        Assert.Null(comp.GetTypeByMetadataName("C"));
        Assert.Equal(member, comp.GetTypeByMetadataName(metadataName));
 
        var source2 = """
            class C2
            {
                void M()
                {
                    C.M();
                }
            }
            """;
 
        var comp2 = CreateCompilation(source2, references: new[] { comp.ToMetadataReference() }, targetFramework: TargetFramework.Mscorlib461);
        comp2.VerifyDiagnostics(
        // (5,9): error CS0103: The name 'C' does not exist in the current context
        //         C.M();
        Diagnostic(ErrorCode.ERR_NameNotInContext, "C").WithArguments("C").WithLocation(5, 9)
        );
 
        Assert.NotEqual(comp.Assembly.CorLibrary, comp2.Assembly.CorLibrary);
 
        var retargeted = comp2.GetMember<NamedTypeSymbol>("C");
        Assert.IsType<RetargetingNamedTypeSymbol>(retargeted);
        Assert.Equal(metadataName, retargeted.MetadataName);
 
        Assert.Null(comp2.GetTypeByMetadataName("C"));
        Assert.Equal(retargeted, comp2.GetTypeByMetadataName(metadataName));
    }
 
    [Fact]
    public void AssociatedSyntaxTree_01()
    {
        var source = """
            file class C
            {
                void M(C c)
                {
                }
            }
            """;
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
 
        var expectedChecksum = new byte[] { 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55 };
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var node = tree.GetRoot().DescendantNodes().OfType<ParameterSyntax>().Single();
        var type = (INamedTypeSymbol)model.GetTypeInfo(node.Type!).Type!;
        Assert.Equal("C@<tree 0>", type.ToTestDisplayString());
        var identifier = type.GetSymbol()!.AssociatedFileIdentifier;
        Assert.NotNull(identifier);
        AssertEx.Equal(expectedChecksum, identifier.FilePathChecksumOpt);
        Assert.Empty(identifier.DisplayFilePath);
        Assert.True(type.IsFileLocal);
 
        var referencingMetadataComp = CreateCompilation("", new[] { comp.ToMetadataReference() });
        type = ((Compilation)referencingMetadataComp).GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C")!;
        Assert.Equal("C@<tree 0>", type.ToTestDisplayString());
        identifier = type.GetSymbol()!.AssociatedFileIdentifier;
        Assert.NotNull(identifier);
        AssertEx.Equal(expectedChecksum, identifier.FilePathChecksumOpt);
        Assert.Empty(identifier.DisplayFilePath);
        Assert.True(type.IsFileLocal);
 
        var referencingImageComp = CreateCompilation("", new[] { comp.EmitToImageReference() });
        type = ((Compilation)referencingImageComp).GetTypeByMetadataName("<>FE3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855__C")!;
        Assert.Equal("C@<unknown>", type.ToTestDisplayString());
        identifier = type.GetSymbol()!.AssociatedFileIdentifier;
        Assert.NotNull(identifier);
        AssertEx.Equal(expectedChecksum, identifier.FilePathChecksumOpt);
        Assert.Empty(identifier.DisplayFilePath);
        Assert.False(type.IsFileLocal);
    }
 
    [Fact]
    public void AssociatedSyntaxTree_02()
    {
        var source = """
            class C
            {
                void M(C c)
                {
                }
            }
            """;
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var node = tree.GetRoot().DescendantNodes().OfType<ParameterSyntax>().Single();
        var type = (INamedTypeSymbol)model.GetTypeInfo(node.Type!).Type!;
        Assert.Equal("C", type.ToTestDisplayString());
        Assert.Null(type.GetSymbol()!.AssociatedFileIdentifier);
        Assert.False(type.IsFileLocal);
    }
 
    [Fact]
    public void AssociatedSyntaxTree_03()
    {
        var source = """
            file class C<T>
            {
                void M(C<int> c)
                {
                }
            }
            """;
        var comp = CreateCompilation(source);
        comp.VerifyDiagnostics();
 
        var tree = comp.SyntaxTrees[0];
        var model = comp.GetSemanticModel(tree);
        var node = tree.GetRoot().DescendantNodes().OfType<ParameterSyntax>().Single();
        var type = (INamedTypeSymbol)model.GetTypeInfo(node.Type!).Type!;
        Assert.Equal("C<System.Int32>@<tree 0>", type.ToTestDisplayString());
        var identifier = type.GetSymbol()!.AssociatedFileIdentifier;
        Assert.NotNull(identifier);
        AssertEx.Equal(
            new byte[] { 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55 },
            identifier.FilePathChecksumOpt);
        Assert.Empty(identifier.DisplayFilePath);
        Assert.True(type.IsFileLocal);
    }
 
    [Theory]
    [CombinatorialData]
    public void CannotAccessFromMetadata_01(bool useMetadataReference)
    {
        // Compare to 'InternalsVisibleToAndStrongNameTests.IVTBasicMetadata'
        var fileTypeSource = """
            [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("HasIVTAccess")]
            file class C1 { public static void M1() {} }
            """;
 
        // reused across all compilations to try and trick the binder into thinking it's binding from the same file as 'file class C'.
        var filePath = "file1.cs";
 
        var comp0 = CreateCompilation((fileTypeSource, filePath), options: TestOptions.SigningReleaseDll);
        comp0.VerifyDiagnostics();
 
        var reference = useMetadataReference ? comp0.ToMetadataReference() : comp0.EmitToImageReference();
 
        var useFileTypeSource = """
            class C2
            {
                void M2()
                {
                    C1.M1();
                }
            }
            """;
 
        // Whether or not you have an IVT, the compiler won't bind to a file type from a different compilation.
        verify("DoesNotHaveIVTAccess");
        verify("HasIVTAccess");
        void verify(string assemblyName)
        {
            var comp1 = CreateCompilation(
                (useFileTypeSource, filePath),
                references: new[] { reference },
                assemblyName: assemblyName,
                options: TestOptions.SigningReleaseDll);
            comp1.VerifyDiagnostics(
                // file1.cs(5,9): error CS0103: The name 'C1' does not exist in the current context
                //         C1.M1();
                Diagnostic(ErrorCode.ERR_NameNotInContext, "C1").WithArguments("C1").WithLocation(5, 9));
        }
    }
 
    [Fact]
    public void CannotAccessFromMetadata_02()
    {
        var fileTypeSource = """
            file class C1 { public static void M1() {} }
            """;
 
        // reused across all compilations to try and trick the binder into thinking it's binding from the same file
        var filePath = "file1.cs";
 
        var comp0 = CreateCompilation((fileTypeSource, filePath), options: TestOptions.SigningReleaseDll);
        comp0.VerifyDiagnostics();
        var classC1 = comp0.GetMember<NamedTypeSymbol>("C1");
        Assert.True(classC1.GetPublicSymbol().IsFileLocal);
 
        var reference = comp0.ToMetadataReference();
 
        var useFileTypeSource = """
            class C2
            {
                void M2()
                {
                    C1.M1();
                }
            }
            """;
 
        var comp1 = CreateCompilation(
            (useFileTypeSource, filePath),
            references: new[] { reference },
            targetFramework: TargetFramework.Mscorlib461,
            options: TestOptions.SigningReleaseDll);
        comp1.VerifyDiagnostics(
            // file1.cs(5,9): error CS0103: The name 'C1' does not exist in the current context
            //         C1.M1();
            Diagnostic(ErrorCode.ERR_NameNotInContext, "C1").WithArguments("C1").WithLocation(5, 9));
        var retargeted = comp1.GetMember<NamedTypeSymbol>("C1");
        Assert.IsType<RetargetingNamedTypeSymbol>(retargeted);
        Assert.False(retargeted.GetPublicSymbol().IsFileLocal);
 
        var originalFileIdentifier = classC1.AssociatedFileIdentifier!;
        var retargetedFileIdentifier = retargeted.AssociatedFileIdentifier!;
        Assert.Equal(originalFileIdentifier.DisplayFilePath, retargetedFileIdentifier.DisplayFilePath);
        Assert.Equal((IEnumerable<byte>)originalFileIdentifier.FilePathChecksumOpt, (IEnumerable<byte>)retargetedFileIdentifier.FilePathChecksumOpt);
        Assert.Equal(originalFileIdentifier.EncoderFallbackErrorMessage, retargetedFileIdentifier.EncoderFallbackErrorMessage);
    }
 
    [Fact]
    public void SyntaxTreeAlreadyPresent()
    {
        var tree = SyntaxFactory.ParseSyntaxTree("""
            partial file class C { }
            """,
            path: "file1.cs",
            encoding: Encoding.Default);
 
        var ex = Assert.Throws<ArgumentException>(() => CreateCompilation(new[] { tree, tree }));
        Assert.Equal("trees[1]", ex.ParamName);
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_01()
    {
        var source0 = """
            var c = new C();
            c.Use1();
            c.Use2();
            """;
 
        var source1 = """
            using System;
 
            file interface FI
            {
                void M();
            }
 
            partial class C : FI
            {
                void FI.M() { Console.Write(1); }
 
                public void Use1() { ((FI)this).M(); }
            }
            """;
 
        var source2 = """
            using System;
 
            file interface FI
            {
                void M();
            }
 
            partial class C : FI
            {
                void FI.M() { Console.Write(2); }
 
                public void Use2() { ((FI)this).M(); }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source0, "F0.cs"), (source1, "F1.cs"), (source2, "F2.cs") }, expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_02()
    {
        var source1 = """
            file interface FI
            {
                void M();
            }
 
            partial class C : FI
            {
                void FI.M() => throw null!;
            }
            """;
 
        // Explicit implementation of 'FI.M()' in 'source1' does not implement 'FI.M()' in 'source2'.
        var source2 = """
            file interface FI
            {
                void M();
            }
 
            partial class C : FI
            {
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs"), (source2, "F2.cs") });
        comp.VerifyDiagnostics(
            // F2.cs(6,19): error CS0535: 'C' does not implement interface member 'FI.M()'
            // partial class C : FI
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "FI").WithArguments("C", "FI.M()").WithLocation(6, 19));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_03()
    {
        var source1 = """
            using System.Collections.Generic;
 
            file interface I
            {
                IReadOnlyDictionary<int, string> P { get; }
            }
 
            internal partial class C : I
            {
                private readonly Dictionary<int, string> _p = new() { { 1, "one" }, { 2, "two" } };
                IReadOnlyDictionary<int, string> I.P => _p;
            }
            """;
 
        var source2 = """
            using System.Collections.Generic;
 
            file interface I
            {
                IReadOnlyDictionary<int, string> P { get; }
            }
 
            internal partial class C : I
            {
                IReadOnlyDictionary<int, string> I.P => _p;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs"), (source2, "F2.cs") });
        comp.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_04()
    {
        var source1 = """
            file interface I
            {
                int P { get; }
            }
 
            internal partial class C : I
            {
            }
            """;
 
        var source2 = """
            file interface I
            {
                int P { get; }
            }
 
            internal partial class C : I
            {
                int I.P => 1;
                int I.P => 2;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs"), (source2, "F2.cs") });
        comp.VerifyDiagnostics(
            // F1.cs(6,24): error CS8646: 'I.P' is explicitly implemented more than once.
            // internal partial class C : I
            Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "C").WithArguments("I.P").WithLocation(6, 24),
            // F1.cs(6,28): error CS0535: 'C' does not implement interface member 'I.P'
            // internal partial class C : I
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I").WithArguments("C", "I.P").WithLocation(6, 28),
            // F2.cs(9,11): error CS0102: The type 'C' already contains a definition for '<F2>F141A34209AF0D3C8CA844A7D9A360C895EB14E557F17D27626C519D9BE96AF4A__I.P'
            //     int I.P => 2;
            Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "P").WithArguments("C", "<F2>F141A34209AF0D3C8CA844A7D9A360C895EB14E557F17D27626C519D9BE96AF4A__I.P").WithLocation(9, 11));
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_05()
    {
        var source0 = """
            var c = new C();
            c.Use1();
            c.Use2();
            """;
 
        var source1 = """
            using System;
 
            file interface FI
            {
                int Bar { get; }
            }
 
            internal partial class C : FI
            {
                int FI.Bar => 1;
                public void Use1() => Console.Write(((FI)this).Bar);
            }
            """;
 
        var source2 = """
            using System;
 
            file interface FI
            {
                int Bar { get; }
            }
 
            internal partial class C : FI
            {
                int FI.Bar => 2;
                public void Use2() => Console.Write(((FI)this).Bar);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source0, "F0.cs"), (source1, "F1.cs"), (source2, "F2.cs") }, expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_06()
    {
        var source0 = """
            var c = new C();
            c.Use1();
            c.Use2();
            """;
 
        var source1 = """
            using System;
 
            file interface FI
            {
                event Action E;
            }
 
            internal partial class C : FI
            {
                event Action FI.E { add { Console.Write(1); } remove { } }
                public void Use1() => ((FI)this).E += () => { };
            }
            """;
 
        var source2 = """
            using System;
 
            file interface FI
            {
                event Action E;
            }
 
            internal partial class C : FI
            {
                event Action FI.E { add { Console.Write(2); } remove { } }
                public void Use2() => ((FI)this).E += () => { };
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source0, "F0.cs"), (source1, "F1.cs"), (source2, "F2.cs") }, expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_07()
    {
        var source0 = """
            var c = new C();
            c.Use1();
            c.Use2();
            """;
 
        var source1 = """
            using System;
 
            file interface FI
            {
                int this[int i] { get; }
            }
 
            internal partial class C : FI
            {
                int FI.this[int i] => 1;
                public void Use1() => Console.Write(((FI)this)[0]);
            }
            """;
 
        var source2 = """
            using System;
 
            file interface FI
            {
                int this[int i] { get; }
            }
 
            internal partial class C : FI
            {
                int FI.this[int i] => 2;
                public void Use2() => Console.Write(((FI)this)[0]);
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source0, "F0.cs"), (source1, "F1.cs"), (source2, "F2.cs") }, expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_08()
    {
        // Test explicit implementation of a file interface operator in a partial type multiple times across files.
        // File types can't be used in signatures of non-file types, so this scenario isn't allowed currently,
        // but we'd like to make sure that redundant/invalid duplicate member name diagnostics aren't given here.
        var source1 = """
            file interface FI
            {
                static abstract int operator +(FI fi, int i);
            }
 
            internal partial class C : FI
            {
                static int FI.operator +(FI fi, int i) => throw null!; // 1
            }
            """;
 
        var source2 = """
            file interface FI
            {
                static abstract int operator +(FI fi, int i);
            }
 
            internal partial class C : FI
            {
                static int FI.operator +(FI fi, int i) => throw null!; // 2
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs"), (source2, "F2.cs") }, targetFramework: TargetFramework.Net70);
        comp.VerifyDiagnostics(
            // F2.cs(8,28): error CS9051: File-local type 'FI' cannot be used in a member signature in non-file-local type 'C'.
            //     static int FI.operator +(FI fi, int i) => throw null!; // 2
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("FI", "C").WithLocation(8, 28),
            // F1.cs(8,28): error CS9051: File-local type 'FI' cannot be used in a member signature in non-file-local type 'C'.
            //     static int FI.operator +(FI fi, int i) => throw null!; // 1
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("FI", "C").WithLocation(8, 28)
            );
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_09()
    {
        // Similar to PartialExplicitImplementation_08, except only one of the files contains duplicate operator implementations.
        var source1 = """
            file interface FI
            {
                static abstract int operator +(FI fi, int i);
            }
 
            internal partial class C : FI // 1, 2
            {
            }
            """;
 
        var source2 = """
            file interface FI
            {
                static abstract int operator +(FI fi, int i);
            }
 
            internal partial class C : FI
            {
                static int FI.operator +(FI fi, int i) => throw null!; // 3
                static int FI.operator +(FI fi, int i) => throw null!; // 4, 5
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs"), (source2, "F2.cs") }, targetFramework: TargetFramework.Net70);
        comp.VerifyDiagnostics(
            // F1.cs(6,24): error CS8646: 'FI.operator +(FI, int)' is explicitly implemented more than once.
            // internal partial class C : FI // 1, 2
            Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "C").WithArguments("FI.operator +(FI, int)").WithLocation(6, 24),
            // F1.cs(6,28): error CS0535: 'C' does not implement interface member 'FI.operator +(FI, int)'
            // internal partial class C : FI // 1, 2
            Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "FI").WithArguments("C", "FI.operator +(FI, int)").WithLocation(6, 28),
            // F2.cs(8,28): error CS9051: File-local type 'FI' cannot be used in a member signature in non-file-local type 'C'.
            //     static int FI.operator +(FI fi, int i) => throw null!; // 3
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("FI", "C").WithLocation(8, 28),
            // F2.cs(9,28): error CS9051: File-local type 'FI' cannot be used in a member signature in non-file-local type 'C'.
            //     static int FI.operator +(FI fi, int i) => throw null!; // 4, 5
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("FI", "C").WithLocation(9, 28),
            // F2.cs(9,28): error CS0111: Type 'C' already defines a member called '<F2>F141A34209AF0D3C8CA844A7D9A360C895EB14E557F17D27626C519D9BE96AF4A__FI.op_Addition' with the same parameter types
            //     static int FI.operator +(FI fi, int i) => throw null!; // 4, 5
            Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "+").WithArguments("<F2>F141A34209AF0D3C8CA844A7D9A360C895EB14E557F17D27626C519D9BE96AF4A__FI.op_Addition", "C").WithLocation(9, 28)
            );
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_10()
    {
        // Test explicit implementation of a file interface operator in a partial type.
        // In another file, implement a member in a type with the same source name, but with member name using the metadata name of the same operator.
        // File types can't be used in signatures of non-file types, so this scenario isn't allowed currently,
        // but we'd like to make sure that redundant/invalid duplicate member name diagnostics aren't given here.
        var source1 = """
            file interface FI
            {
                static abstract int operator +(FI fi, int i);
            }
 
            internal partial class C : FI
            {
                static int FI.operator +(FI fi, int i) => throw null!;
            }
            """;
 
        var source2 = """
            file interface FI
            {
                static abstract int op_Addition(FI fi, int i);
            }
 
            internal partial class C : FI
            {
                static int FI.op_Addition(FI fi, int i) => throw null!;
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "F1.cs"), (source2, "F2.cs") }, targetFramework: TargetFramework.Net70);
        comp.VerifyDiagnostics(
            // F2.cs(8,19): error CS9051: File-local type 'FI' cannot be used in a member signature in non-file-local type 'C'.
            //     static int FI.op_Addition(FI fi, int i) => throw null!;
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "op_Addition").WithArguments("FI", "C").WithLocation(8, 19),
            // F1.cs(8,28): error CS9051: File-local type 'FI' cannot be used in a member signature in non-file-local type 'C'.
            //     static int FI.operator +(FI fi, int i) => throw null!;
            Diagnostic(ErrorCode.ERR_FileTypeDisallowedInSignature, "+").WithArguments("FI", "C").WithLocation(8, 28)
            );
    }
 
    [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68219")]
    public void PartialExplicitImplementation_11()
    {
        var source0 = """
            var c = new C();
            c.Use1();
            c.Use2();
 
            interface I<T>
            {
                void M();
            }
            """;
 
        var source1 = """
            using System;
 
            file interface FI { }
 
            partial class C : I<FI>
            {
                void I<FI>.M() { Console.Write(1); }
 
                public void Use1() { ((I<FI>)this).M(); }
            }
            """;
 
        var source2 = """
            using System;
 
            file interface FI { }
 
            partial class C : I<FI>
            {
                void I<FI>.M() { Console.Write(2); }
 
                public void Use2() { ((I<FI>)this).M(); }
            }
            """;
 
        var verifier = CompileAndVerify(new[] { (source0, "F0.cs"), (source1, "F1.cs"), (source2, "F2.cs") }, expectedOutput: "12");
        verifier.VerifyDiagnostics();
    }
 
    [Fact]
    public void ShadowNamespace_01()
    {
        var source1 = """
            namespace App.Widget
            {
                class Inner { }
            }
 
            """;
 
        var source2 = """
            namespace App
            {
                file class Widget { }
            }
 
            """;
 
        var comp = CreateCompilation(new[] { (source1, "File1.cs"), (source2, "File2.cs") });
        comp.VerifyDiagnostics();
 
        comp = CreateCompilation(source1 + source2);
        comp.VerifyDiagnostics(
            // (7,16): error CS9071: The namespace 'App' already contains a definition for 'Widget' in this file.
            //     file class Widget { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "Widget").WithArguments("Widget", "App").WithLocation(7, 16));
 
        comp = CreateCompilation(source2 + source1);
        comp.VerifyDiagnostics(
            // (3,16): error CS9071: The namespace 'App' already contains a definition for 'Widget' in this file.
            //     file class Widget { }
            Diagnostic(ErrorCode.ERR_FileLocalDuplicateNameInNS, "Widget").WithArguments("Widget", "App").WithLocation(3, 16));
    }
 
    [Theory, CombinatorialData]
    public void ShadowNamespace_02(bool useMetadataReference)
    {
        var source1 = """
            namespace App.Widget
            {
                public class Inner { }
            }
 
            """;
 
        var source2 = """
            namespace App
            {
                file class Widget { }
            }
 
            """;
 
        var comp1 = CreateCompilation(new[] { (source1, "File1.cs") });
        comp1.VerifyEmitDiagnostics();
 
        var comp2 = CreateCompilation(new[] { (source2, "File2.cs") }, references: new[] { useMetadataReference ? comp1.ToMetadataReference() : comp1.EmitToImageReference() });
        comp2.VerifyEmitDiagnostics();
 
        comp2 = CreateCompilation(new[] { (source2, "File2.cs") });
        comp2.VerifyEmitDiagnostics();
 
        comp1 = CreateCompilation(new[] { (source1, "File1.cs") }, references: new[] { useMetadataReference ? comp2.ToMetadataReference() : comp2.EmitToImageReference() });
        comp1.VerifyEmitDiagnostics();
    }
 
    [Fact]
    public void ShadowNamespace_03()
    {
        var source1 = """
            namespace App.Widget
            {
                class Inner { }
            }
 
            class C1
            {
                static void M1()
                {
                    new App.Widget(); // 1
                    new App.Widget.Inner();
                }
            }
            """;
 
        var source2 = """
            namespace App
            {
                file class Widget { }
            }
 
            class C2
            {
                static void M2()
                {
                    new App.Widget();
                    new App.Widget.Inner(); // 2
                }
            }
            """;
 
        var comp = CreateCompilation(new[] { (source1, "File1.cs"), (source2, "File2.cs") });
        comp.VerifyDiagnostics(
            // File1.cs(10,13): error CS0118: 'App.Widget' is a namespace but is used like a type
            //         new App.Widget(); // 1
            Diagnostic(ErrorCode.ERR_BadSKknown, "App.Widget").WithArguments("App.Widget", "namespace", "type").WithLocation(10, 13),
            // File2.cs(11,24): error CS0426: The type name 'Inner' does not exist in the type 'Widget'
            //         new App.Widget.Inner(); // 2
            Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInAgg, "Inner").WithArguments("Inner", "App.Widget").WithLocation(11, 24));
    }
}