// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Linq; using System.Threading; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols { [CompilerTrait(CompilerFeature.DefaultInterfaceImplementation)] public class DefaultInterfaceImplementationTests : CSharpTestBase { [Fact] [WorkItem(33083, "https://github.com/dotnet/roslyn/issues/33083")] public void MethodImplementation_011() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } "; ValidateMethodImplementation_011(source1); } private static Verification VerifyOnMonoOrCoreClr { get { return ExecutionConditionUtil.IsMonoOrCoreClr ? Verification.Passes : Verification.Skipped; } } private void ValidateMethodImplementation_011(string source) { foreach (string access in new[] { "x.M1();", "new System.Action(x.M1)();" }) { foreach (string typeKind in new[] { "class", "struct" }) { string source1 = source + typeKind + " Test1 " + @": I1 { static void Main() { I1 x = new Test1(); " + access + @" } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { ValidateMethodImplementationTest1_011(m, "void I1.M1()"); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var source2 = typeKind + " Test2 " + @": I1 { static void Main() { I1 x = new Test2(); " + access + @" } } "; foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate2(ModuleSymbol m) { ValidateMethodImplementationTest2_011(m, "void I1.M1()"); } Validate2(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); } } } } private static void ValidateMethodImplementationTest1_011(ModuleSymbol m, string expectedImplementation) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var m1 = i1.GetMembers().OfType().Single(); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); if (m is PEModuleSymbol peModule) { int rva; peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)m1).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } var test1 = m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal(expectedImplementation, test1.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); Assert.Equal("I1", test1.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Assert.Same(m1, i1.FindImplementationForInterfaceMember(m1)); } private static void ValidateMethodImplementationTest2_011(ModuleSymbol m, string expectedImplementation) { var test2 = m.GlobalNamespace.GetTypeMember("Test2"); var i1 = test2.InterfacesNoUseSiteDiagnostics().Single(); Assert.Equal("I1", i1.ToTestDisplayString()); var m1 = i1.GetMember("M1"); Assert.Equal(expectedImplementation, test2.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); Assert.Same(m1, i1.FindImplementationForInterfaceMember(m1)); } [Fact] public void MethodImplementation_012() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 { public void M1() { System.Console.WriteLine(""Test1 M1""); } static void Main() { I1 x = new Test1(); x.M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { ValidateMethodImplementationTest1_011(m, "void Test1.M1()"); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test1 M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var source2 = @" class Test2 : I1 { public void M1() { System.Console.WriteLine(""Test2 M1""); } static void Main() { I1 x = new Test2(); x.M1(); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate2(ModuleSymbol m) { ValidateMethodImplementationTest2_011(m, "void Test2.M1()"); } Validate2(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test2 M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate2(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test2 M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); } [Fact] public void MethodImplementation_013() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 { void I1.M1() { System.Console.WriteLine(""Test1 M1""); } static void Main() { I1 x = new Test1(); x.M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { ValidateMethodImplementationTest1_011(m, "void Test1.I1.M1()"); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test1 M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var source2 = @" class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2 M1""); } static void Main() { I1 x = new Test2(); x.M1(); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate2(ModuleSymbol m) { ValidateMethodImplementationTest2_011(m, "void Test2.I1.M1()"); } Validate2(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test2 M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate2(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test2 M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); } [Fact] public void MethodImplementation_021() { var source1 = @" interface I1 { void M1() { System.Console.WriteLine(""M1""); } void M2() { System.Console.WriteLine(""M2""); } } class Base { void M1() { } } class Derived : Base, I1 { void M2() { } static void Main() { I1 x = new Derived(); x.M1(); x.M2(); } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var m1 = m.GlobalNamespace.GetMember("I1.M1"); var m2 = m.GlobalNamespace.GetMember("I1.M2"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Same(m1, derived.FindImplementationForInterfaceMember(m1)); Assert.Same(m2, derived.FindImplementationForInterfaceMember(m2)); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 M2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void MethodImplementation_022() { var source1 = @" interface I1 { void M1() { System.Console.WriteLine(""M1""); } void M2() { System.Console.WriteLine(""M2""); } } class Base : Test { void M1() { } } class Derived : Base, I1 { void M2() { } static void Main() { I1 x = new Derived(); x.M1(); x.M2(); } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var m1 = m.GlobalNamespace.GetMember("I1.M1"); var m2 = m.GlobalNamespace.GetMember("I1.M2"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Same(m1, derived.FindImplementationForInterfaceMember(m1)); Assert.Same(m2, derived.FindImplementationForInterfaceMember(m2)); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 M2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void MethodImplementation_023() { var source1 = @" interface I1 { void M1() {} void M2() {} } class Base : Test { void M1() { } } class Derived : Base, I1 { void M2() { } static void Main() { I1 x = new Derived(); x.M1(); x.M2(); } } class Test : I1 { void I1.M1() { System.Console.WriteLine(""Test.M1""); } void I1.M2() { System.Console.WriteLine(""Test.M2""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var m1 = m.GlobalNamespace.GetMember("I1.M1"); var m2 = m.GlobalNamespace.GetMember("I1.M2"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("void Test.I1.M1()", derived.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); Assert.Equal("void Test.I1.M2()", derived.FindImplementationForInterfaceMember(m2).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test.M1 Test.M2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void MethodImplementation_024() { var source1 = @" interface I1 { void M1() {} void M2() {} } class Base : Test { new void M1() { } } class Derived : Base, I1 { new void M2() { } static void Main() { I1 x = new Derived(); x.M1(); x.M2(); } } class Test : I1 { public void M1() { System.Console.WriteLine(""Test.M1""); } public void M2() { System.Console.WriteLine(""Test.M2""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var m1 = m.GlobalNamespace.GetMember("I1.M1"); var m2 = m.GlobalNamespace.GetMember("I1.M2"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("void Test.M1()", derived.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); Assert.Equal("void Test.M2()", derived.FindImplementationForInterfaceMember(m2).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test.M1 Test.M2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void MethodImplementation_031() { var source1 = @" interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 { public static void M1() { } static void Main() { I1 x = new Test1(); x.M1(); } } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_032() { var source1 = @" interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : Test2, I1 { public static void M1() { } static void Main() { I1 x = new Test1(); x.M1(); } } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_033() { var source1 = @" interface I1 { void M1() {} } class Test1 : Test2, I1 { public static void M1() { } static void Main() { I1 x = new Test1(); x.M1(); } } class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Equal("void Test2.I1.M1()", test1.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test2.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_034() { var source1 = @" interface I1 { void M1() {} } class Test1 : Test2, I1 { new public static void M1() { } static void Main() { I1 x = new Test1(); x.M1(); } } class Test2 : I1 { public void M1() { System.Console.WriteLine(""Test2.M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Equal("void Test2.M1()", test1.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test2.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_041() { var source1 = @" interface I1 { void M1() { System.Console.WriteLine(""M1""); } int M2() => 2; } class Test1 : I1 { public int M1() { return 0; } public ref int M2() { throw null; } static void Main() { I1 x = new Test1(); x.M1(); System.Console.WriteLine(x.M2()); } } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var m2 = compilation1.GetMember("I1.M2"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); Assert.Same(m2, test1.FindImplementationForInterfaceMember(m2)); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_042() { var source1 = @" interface I1 { void M1() { System.Console.WriteLine(""M1""); } int M2() => 2; } class Test1 : Test2, I1 { public int M1() { return 0; } public ref int M2() { throw null; } static void Main() { I1 x = new Test1(); x.M1(); System.Console.WriteLine(x.M2()); } } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var m2 = compilation1.GetMember("I1.M2"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); Assert.Same(m2, test1.FindImplementationForInterfaceMember(m2)); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_043() { var source1 = @" interface I1 { void M1() {} int M2() => 1; } class Test1 : Test2, I1 { public int M1() { return 0; } public ref int M2() { throw null; } static void Main() { I1 x = new Test1(); x.M1(); System.Console.WriteLine(x.M2()); } } class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } int I1.M2() => 2; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var m2 = compilation1.GetMember("I1.M2"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Equal("void Test2.I1.M1()", test1.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); Assert.Equal("System.Int32 Test2.I1.M2()", test1.FindImplementationForInterfaceMember(m2).ToTestDisplayString()); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test2.M1 2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_044() { var source1 = @" interface I1 { void M1() {} int M2() => 1; } class Test1 : Test2, I1 { new public int M1() { return 0; } new public ref int M2() { throw null; } static void Main() { I1 x = new Test1(); x.M1(); System.Console.WriteLine(x.M2()); } } class Test2 : I1 { public void M1() { System.Console.WriteLine(""Test2.M1""); } public int M2() => 2; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var m1 = compilation1.GetMember("I1.M1"); var m2 = compilation1.GetMember("I1.M2"); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Equal("void Test2.M1()", test1.FindImplementationForInterfaceMember(m1).ToTestDisplayString()); Assert.Equal("System.Int32 Test2.M2()", test1.FindImplementationForInterfaceMember(m2).ToTestDisplayString()); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test2.M1 2", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test1Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); } [Fact] public void MethodImplementation_051() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation1.GetMember("I1.M1"); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); compilation1.VerifyDiagnostics( // (4,10): error CS8501: Target runtime doesn't support default interface implementation. // void M1() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(4, 10) ); Assert.True(m1.IsMetadataVirtual()); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); m1 = compilation3.GetMember("I1.M1"); var test2 = compilation3.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.M1()' cannot implement interface member 'I1.M1()' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.M1()", "I1.M1()", "Test2").WithLocation(2, 15) ); } [Fact] public void MethodImplementation_052() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" class Test2 : I1 {} "; foreach (var reference in new[] { compilation1.EmitToImageReference(), compilation1.ToMetadataReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation3.GetMember("I1.M1"); var test2 = compilation3.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.M1()' cannot implement interface member 'I1.M1()' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.M1()", "I1.M1()", "Test2").WithLocation(2, 15) ); } } [Fact] public void MethodImplementation_053() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" public interface I2 { void M2(); } class Test2 : I2 { public void M2() {} } "; foreach (var reference in new[] { compilation1.EmitToImageReference(), compilation1.ToMetadataReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation3.GetMember("I1.M1"); var test2 = compilation3.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(m1)); compilation3.VerifyDiagnostics(); } } [Fact] public void MethodImplementation_061() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation1.GetMember("I1.M1"); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); compilation1.VerifyDiagnostics( // (4,10): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // void M1() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(4, 10), // (4,10): error CS8701: Target runtime doesn't support default interface implementation. // void M1() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(4, 10) ); Assert.True(m1.IsMetadataVirtual()); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); m1 = compilation3.GetMember("I1.M1"); var test2 = compilation3.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.M1()' cannot implement interface member 'I1.M1()' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.M1()", "I1.M1()", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.M1()' cannot implement interface member 'I1.M1()' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.M1()", "I1.M1()", "Test2").WithLocation(2, 15) ); } [Fact] public void MethodImplementation_071() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation1.GetMember("I1.M1"); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); compilation1.VerifyDiagnostics( // (4,10): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // void M1() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(4, 10) ); Assert.True(m1.IsMetadataVirtual()); var source2 = @" class Test2 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); m1 = compilation2.GetMember("I1.M1"); var test2 = compilation2.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test2Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test2"); Assert.Equal("I1", test2Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); }); var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); m1 = compilation3.GetMember("I1.M1"); test2 = compilation3.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.M1()' cannot implement interface member 'I1.M1()' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.M1()", "I1.M1()", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15) ); } [Fact] public void MethodImplementation_081() { var source1 = @" public interface I1 { I1 M1() { throw null; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation1.GetMember("I1.M1"); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); compilation1.VerifyDiagnostics( // (4,8): error CS8501: Target runtime doesn't support default interface implementation. // I1 M1() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(4, 8) ); Assert.True(m1.IsMetadataVirtual()); } [Fact] public void MethodImplementation_091() { var source1 = @" public interface I1 { static void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); var m1 = compilation1.GetMember("I1.M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsStatic); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); compilation1.VerifyDiagnostics( // (4,17): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static void M1() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(4, 17) ); Assert.False(m1.IsMetadataVirtual()); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (4,17): error CS8701: Target runtime doesn't support default interface implementation. // static void M1() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(4, 17) ); } [Fact] public void MethodImplementation_101() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""M1""); } } public interface I2 : I1 {} class Test1 : I2 { static void Main() { I1 x = new Test1(); x.M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var m1 = compilation1.GetMember("I1.M1"); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); compilation1.VerifyDiagnostics(); Assert.True(m1.IsMetadataVirtual()); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var result = (PEMethodSymbol)i1.GetMember("M1"); Assert.True(result.IsMetadataVirtual()); Assert.False(result.IsAbstract); Assert.True(result.IsVirtual); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); int rva; ((PEModuleSymbol)m).Module.GetMethodDefPropsOrThrow(result.Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); var test1Result = m.GlobalNamespace.GetTypeMember("Test1"); var interfaces = test1Result.InterfacesNoUseSiteDiagnostics().ToArray(); Assert.Equal(2, interfaces.Length); Assert.Equal("I2", interfaces[0].ToTestDisplayString()); Assert.Equal("I1", interfaces[1].ToTestDisplayString()); }); var source2 = @" class Test2 : I2 { static void Main() { I1 x = new Test2(); x.M1(); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); m1 = compilation2.GetMember("I1.M1"); var test2 = compilation2.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test2Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test2"); var interfaces = test2Result.InterfacesNoUseSiteDiagnostics().ToArray(); Assert.Equal(2, interfaces.Length); Assert.Equal("I2", interfaces[0].ToTestDisplayString()); Assert.Equal("I1", interfaces[1].ToTestDisplayString()); }); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); m1 = compilation3.GetMember("I1.M1"); test2 = compilation3.GetTypeByMetadataName("Test2"); Assert.Same(m1, test2.FindImplementationForInterfaceMember(m1)); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test2Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test2"); var interfaces = test2Result.InterfacesNoUseSiteDiagnostics().ToArray(); Assert.Equal(2, interfaces.Length); Assert.Equal("I2", interfaces[0].ToTestDisplayString()); Assert.Equal("I1", interfaces[1].ToTestDisplayString()); }); } [Fact] public void MethodImplementation_111() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { } "; var source2 = @" #nullable enable class Test1 : I2, I1 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I1.M1 I1.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementation_112() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { } "; var source2 = @" #nullable enable class Test1 : I1, I2 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I1", "I2", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[0].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I1, I2 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I1.M1 I1.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementation_113() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { } public interface I3 : I1 { } "; var source2 = @" #nullable enable class Test1 : I2, I3 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I1.M1 I1.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementation_114() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { } public interface I3 : I1 { } "; var source2 = @" #nullable enable class Test1 : I3, I2 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I3", "I1", "I2", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I3, I2 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I1.M1 I1.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void PropertyImplementation_101() { var source1 = @" public interface I1 { int P1 { get { System.Console.WriteLine(""get P1""); return 0; } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "; ValidatePropertyImplementation_101(source1); } private void ValidatePropertyImplementation_101(string source1) { ValidatePropertyImplementation_101(source1, "P1", haveGet: true, haveSet: false, accessCode: @" _ = i1.P1; ", expectedOutput: "get P1"); } private void ValidatePropertyImplementation_101(string source1, string propertyName, bool haveGet, bool haveSet, string accessCode, string expectedOutput) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { ValidatePropertyImplementationTest1_101(m, propertyName, haveGet, haveSet); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expectedOutput : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1 i1 = new Test2(); " + accessCode + @" } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate2(ModuleSymbol m) { ValidatePropertyImplementationTest2_101(m, propertyName, haveGet, haveSet); } Validate2(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expectedOutput : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate2(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expectedOutput : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); } private static void ValidatePropertyImplementationTest1_101(ModuleSymbol m, string propertyName, bool haveGet, bool haveSet) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var p1 = i1.GetMember(propertyName); Assert.Equal(!haveSet, p1.IsReadOnly); Assert.Equal(!haveGet, p1.IsWriteOnly); if (haveGet) { ValidateAccessor(p1.GetMethod); } else { Assert.Null(p1.GetMethod); } if (haveSet) { ValidateAccessor(p1.SetMethod); } else { Assert.Null(p1.SetMethod); } void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); if (m is PEModuleSymbol peModule) { int rva; if (haveGet) { peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)p1.GetMethod).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } if (haveSet) { peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)p1.SetMethod).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } } var test1 = m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); if (haveGet) { Assert.Same(p1.GetMethod, test1.FindImplementationForInterfaceMember(p1.GetMethod)); } if (haveSet) { Assert.Same(p1.SetMethod, test1.FindImplementationForInterfaceMember(p1.SetMethod)); } } private static void ValidatePropertyImplementationTest2_101(ModuleSymbol m, string propertyName, bool haveGet, bool haveSet) { var test2 = m.GlobalNamespace.GetTypeMember("Test2"); Assert.Equal("I1", test2.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); var p1 = test2.InterfacesNoUseSiteDiagnostics().Single().GetMember(propertyName); Assert.Same(p1, test2.FindImplementationForInterfaceMember(p1)); if (haveGet) { var getP1 = p1.GetMethod; Assert.Same(getP1, test2.FindImplementationForInterfaceMember(getP1)); } if (haveSet) { var setP1 = p1.SetMethod; Assert.Same(setP1, test2.FindImplementationForInterfaceMember(setP1)); } } [Fact] public void PropertyImplementation_102() { var source1 = @" public interface I1 { int P1 { get { System.Console.WriteLine(""get P1""); return 0; } set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.P1 = i1.P1; } } "; ValidatePropertyImplementation_102(source1); } private void ValidatePropertyImplementation_102(string source1) { ValidatePropertyImplementation_101(source1, "P1", haveGet: true, haveSet: true, accessCode: @" i1.P1 = i1.P1; ", expectedOutput: @"get P1 set P1"); } [Fact] public void PropertyImplementation_103() { var source1 = @" public interface I1 { int P1 { set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } } "; ValidatePropertyImplementation_103(source1); } private void ValidatePropertyImplementation_103(string source1) { ValidatePropertyImplementation_101(source1, "P1", haveGet: false, haveSet: true, accessCode: @" i1.P1 = 1; ", expectedOutput: "set P1"); } [Fact] public void PropertyImplementation_104() { var source1 = @" public interface I1 { int P1 => Test1.GetInt(); } class Test1 : I1 { public static int GetInt() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "; ValidatePropertyImplementation_101(source1); } [Fact] public void PropertyImplementation_105() { var source1 = @" public interface I1 { int P1 {add; remove;} => 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,13): error CS1014: A get or set accessor expected // int P1 {add; remove;} => 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 13), // (4,18): error CS1014: A get or set accessor expected // int P1 {add; remove;} => 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "remove").WithLocation(4, 18), // (4,9): error CS0548: 'I1.P1': property or indexer must have at least one accessor // int P1 {add; remove;} => 0; Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 9), // (4,5): error CS8057: Block bodies and expression bodies cannot both be provided. // int P1 {add; remove;} => 0; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "int P1 {add; remove;} => 0;").WithLocation(4, 5) ); var p1 = compilation1.GetMember("I1.P1"); Assert.True(p1.IsAbstract); Assert.Null(p1.GetMethod); Assert.Null(p1.SetMethod); Assert.True(p1.IsReadOnly); Assert.True(p1.IsWriteOnly); } [Fact] public void PropertyImplementation_106() { var source1 = @" public interface I1 { int P1 {get; set;} => 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,5): error CS8057: Block bodies and expression bodies cannot both be provided. // int P1 {get; set;} => 0; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "int P1 {get; set;} => 0;").WithLocation(4, 5) ); var p1 = compilation1.GetMember("I1.P1"); Assert.True(p1.IsAbstract); Assert.True(p1.GetMethod.IsAbstract); Assert.True(p1.SetMethod.IsAbstract); Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); } [Fact] public void PropertyImplementation_107() { var source1 = @" public interface I1 { int P1 {add; remove;} = 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( // (4,13): error CS1014: A get or set accessor expected // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 13), // (4,18): error CS1014: A get or set accessor expected // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "remove").WithLocation(4, 18), // (4,9): error CS8050: Only auto-implemented properties can have initializers. // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 9), // (4,9): error CS0548: 'I1.P1': property or indexer must have at least one accessor // int P1 {add; remove;} = 0; Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 9) ); var p1 = compilation1.GetMember("I1.P1"); Assert.True(p1.IsAbstract); Assert.Null(p1.GetMethod); Assert.Null(p1.SetMethod); Assert.True(p1.IsReadOnly); Assert.True(p1.IsWriteOnly); } [Fact] public void PropertyImplementation_108() { var source1 = @" public interface I1 { int P1 {get; set;} = 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( // (4,9): error CS8050: Only auto-implemented properties can have initializers. // int P1 {get; set;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 9) ); var p1 = compilation1.GetMember("I1.P1"); Assert.True(p1.IsAbstract); Assert.True(p1.GetMethod.IsAbstract); Assert.True(p1.SetMethod.IsAbstract); Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); } [Fact] public void PropertyImplementation_109() { var source1 = @" public interface I1 { int P1 { get { System.Console.WriteLine(""get P1""); return 0; } set; } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md, // we don't want to allow only one accessor to have an implementation. compilation1.VerifyDiagnostics( // (11,9): error CS0501: 'I1.P1.set' must declare a body because it is not marked abstract, extern, or partial // set; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P1.set").WithLocation(11, 9) ); var p1 = compilation1.GetMember("I1.P1"); var getP1 = p1.GetMethod; var setP1 = p1.SetMethod; Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(getP1.IsAbstract); Assert.True(getP1.IsVirtual); Assert.False(setP1.IsAbstract); Assert.True(setP1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(getP1, test1.FindImplementationForInterfaceMember(getP1)); Assert.Same(setP1, test1.FindImplementationForInterfaceMember(setP1)); Assert.True(getP1.IsMetadataVirtual()); Assert.True(setP1.IsMetadataVirtual()); } [Fact] public void PropertyImplementation_110() { var source1 = @" public interface I1 { int P1 { get; set => System.Console.WriteLine(""set P1""); } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md, // we don't want to allow only one accessor to have an implementation. compilation1.VerifyDiagnostics( // (6,9): error CS0501: 'I1.P1.get' must declare a body because it is not marked abstract, extern, or partial // get; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P1.get").WithLocation(6, 9) ); var p1 = compilation1.GetMember("I1.P1"); var getP1 = p1.GetMethod; var setP1 = p1.SetMethod; Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(getP1.IsAbstract); Assert.True(getP1.IsVirtual); Assert.False(setP1.IsAbstract); Assert.True(setP1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(getP1, test1.FindImplementationForInterfaceMember(getP1)); Assert.Same(setP1, test1.FindImplementationForInterfaceMember(setP1)); Assert.True(getP1.IsMetadataVirtual()); Assert.True(setP1.IsMetadataVirtual()); } [Fact] public void PropertyImplementation_201() { var source1 = @" interface I1 { int P1 => 1; int P2 => 2; int P3 { get => 3; } int P4 { get => 4; } int P5 { set => System.Console.WriteLine(5); } int P6 { set => System.Console.WriteLine(6); } int P7 { get { return 7;} set {System.Console.WriteLine(71);} } int P8 { get { return 8;} set {System.Console.WriteLine(81);} } } class Base { int P1 => 10; int P3 { get => 30; } int P5 { set => System.Console.WriteLine(50); } int P7 { get { return 70;} set {} } } class Derived : Base, I1 { int P2 => 20; int P4 { get => 40; } int P6 { set => System.Console.WriteLine(60); } int P8 { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1.P1); System.Console.WriteLine(i1.P2); System.Console.WriteLine(i1.P3); System.Console.WriteLine(i1.P4); i1.P5 = 0; i1.P6 = 0; System.Console.WriteLine(i1.P7); i1.P7 = 0; System.Console.WriteLine(i1.P8); i1.P8 = 0; } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidatePropertyImplementation_201(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"1 2 3 4 5 6 7 71 8 81 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidatePropertyImplementation_201(m); }); } private static void ValidatePropertyImplementation_201(ModuleSymbol m) { var p1 = m.GlobalNamespace.GetMember("I1.P1"); var p2 = m.GlobalNamespace.GetMember("I1.P2"); var p3 = m.GlobalNamespace.GetMember("I1.P3"); var p4 = m.GlobalNamespace.GetMember("I1.P4"); var p5 = m.GlobalNamespace.GetMember("I1.P5"); var p6 = m.GlobalNamespace.GetMember("I1.P6"); var p7 = m.GlobalNamespace.GetMember("I1.P7"); var p8 = m.GlobalNamespace.GetMember("I1.P8"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Same(p1, derived.FindImplementationForInterfaceMember(p1)); Assert.Same(p2, derived.FindImplementationForInterfaceMember(p2)); Assert.Same(p3, derived.FindImplementationForInterfaceMember(p3)); Assert.Same(p4, derived.FindImplementationForInterfaceMember(p4)); Assert.Same(p5, derived.FindImplementationForInterfaceMember(p5)); Assert.Same(p6, derived.FindImplementationForInterfaceMember(p6)); Assert.Same(p7, derived.FindImplementationForInterfaceMember(p7)); Assert.Same(p8, derived.FindImplementationForInterfaceMember(p8)); Assert.Same(p1.GetMethod, derived.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Same(p2.GetMethod, derived.FindImplementationForInterfaceMember(p2.GetMethod)); Assert.Same(p3.GetMethod, derived.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Same(p4.GetMethod, derived.FindImplementationForInterfaceMember(p4.GetMethod)); Assert.Same(p5.SetMethod, derived.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Same(p6.SetMethod, derived.FindImplementationForInterfaceMember(p6.SetMethod)); Assert.Same(p7.GetMethod, derived.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Same(p8.GetMethod, derived.FindImplementationForInterfaceMember(p8.GetMethod)); Assert.Same(p7.SetMethod, derived.FindImplementationForInterfaceMember(p7.SetMethod)); Assert.Same(p8.SetMethod, derived.FindImplementationForInterfaceMember(p8.SetMethod)); } [Fact] public void PropertyImplementation_202() { var source1 = @" interface I1 { int P1 => 1; int P2 => 2; int P3 { get => 3; } int P4 { get => 4; } int P5 { set => System.Console.WriteLine(5); } int P6 { set => System.Console.WriteLine(6); } int P7 { get { return 7;} set {System.Console.WriteLine(71);} } int P8 { get { return 8;} set {System.Console.WriteLine(81);} } } class Base : Test { int P1 => 10; int P3 { get => 30; } int P5 { set => System.Console.WriteLine(50); } int P7 { get { return 70;} set {} } } class Derived : Base, I1 { int P2 => 20; int P4 { get => 40; } int P6 { set => System.Console.WriteLine(60); } int P8 { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1.P1); System.Console.WriteLine(i1.P2); System.Console.WriteLine(i1.P3); System.Console.WriteLine(i1.P4); i1.P5 = 0; i1.P6 = 0; System.Console.WriteLine(i1.P7); i1.P7 = 0; System.Console.WriteLine(i1.P8); i1.P8 = 0; } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidatePropertyImplementation_201(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"1 2 3 4 5 6 7 71 8 81 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidatePropertyImplementation_201(m); }); } [Fact] public void PropertyImplementation_203() { var source1 = @" interface I1 { int P1 => 1; int P2 => 2; int P3 { get => 3; } int P4 { get => 4; } int P5 { set => System.Console.WriteLine(5); } int P6 { set => System.Console.WriteLine(6); } int P7 { get { return 7;} set {} } int P8 { get { return 8;} set {} } } class Base : Test { int P1 => 10; int P3 { get => 30; } int P5 { set => System.Console.WriteLine(50); } int P7 { get { return 70;} set {} } } class Derived : Base, I1 { int P2 => 20; int P4 { get => 40; } int P6 { set => System.Console.WriteLine(60); } int P8 { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1.P1); System.Console.WriteLine(i1.P2); System.Console.WriteLine(i1.P3); System.Console.WriteLine(i1.P4); i1.P5 = 0; i1.P6 = 0; System.Console.WriteLine(i1.P7); i1.P7 = 0; System.Console.WriteLine(i1.P8); i1.P8 = 0; } } class Test : I1 { int I1.P1 => 100; int I1.P2 => 200; int I1.P3 { get => 300; } int I1.P4 { get => 400; } int I1.P5 { set => System.Console.WriteLine(500); } int I1.P6 { set => System.Console.WriteLine(600); } int I1.P7 { get { return 700;} set {System.Console.WriteLine(701);} } int I1.P8 { get { return 800;} set {System.Console.WriteLine(801);} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var p1 = m.GlobalNamespace.GetMember("I1.P1"); var p2 = m.GlobalNamespace.GetMember("I1.P2"); var p3 = m.GlobalNamespace.GetMember("I1.P3"); var p4 = m.GlobalNamespace.GetMember("I1.P4"); var p5 = m.GlobalNamespace.GetMember("I1.P5"); var p6 = m.GlobalNamespace.GetMember("I1.P6"); var p7 = m.GlobalNamespace.GetMember("I1.P7"); var p8 = m.GlobalNamespace.GetMember("I1.P8"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("System.Int32 Test.I1.P1 { get; }", derived.FindImplementationForInterfaceMember(p1).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P2 { get; }", derived.FindImplementationForInterfaceMember(p2).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P3 { get; }", derived.FindImplementationForInterfaceMember(p3).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P4 { get; }", derived.FindImplementationForInterfaceMember(p4).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P5 { set; }", derived.FindImplementationForInterfaceMember(p5).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P6 { set; }", derived.FindImplementationForInterfaceMember(p6).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P7 { get; set; }", derived.FindImplementationForInterfaceMember(p7).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P8 { get; set; }", derived.FindImplementationForInterfaceMember(p8).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P1.get", derived.FindImplementationForInterfaceMember(p1.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P2.get", derived.FindImplementationForInterfaceMember(p2.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P3.get", derived.FindImplementationForInterfaceMember(p3.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P4.get", derived.FindImplementationForInterfaceMember(p4.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.P5.set", derived.FindImplementationForInterfaceMember(p5.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.P6.set", derived.FindImplementationForInterfaceMember(p6.SetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P7.get", derived.FindImplementationForInterfaceMember(p7.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.P8.get", derived.FindImplementationForInterfaceMember(p8.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.P7.set", derived.FindImplementationForInterfaceMember(p7.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.P8.set", derived.FindImplementationForInterfaceMember(p8.SetMethod).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"100 200 300 400 500 600 700 701 800 801 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void PropertyImplementation_204() { var source1 = @" interface I1 { int P1 => 1; int P2 => 2; int P3 { get => 3; } int P4 { get => 4; } int P5 { set => System.Console.WriteLine(5); } int P6 { set => System.Console.WriteLine(6); } int P7 { get { return 7;} set {} } int P8 { get { return 8;} set {} } } class Base : Test { new int P1 => 10; new int P3 { get => 30; } new int P5 { set => System.Console.WriteLine(50); } new int P7 { get { return 70;} set {} } } class Derived : Base, I1 { new int P2 => 20; new int P4 { get => 40; } new int P6 { set => System.Console.WriteLine(60); } new int P8 { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1.P1); System.Console.WriteLine(i1.P2); System.Console.WriteLine(i1.P3); System.Console.WriteLine(i1.P4); i1.P5 = 0; i1.P6 = 0; System.Console.WriteLine(i1.P7); i1.P7 = 0; System.Console.WriteLine(i1.P8); i1.P8 = 0; } } class Test : I1 { public int P1 => 100; public int P2 => 200; public int P3 { get => 300; } public int P4 { get => 400; } public int P5 { set => System.Console.WriteLine(500); } public int P6 { set => System.Console.WriteLine(600); } public int P7 { get { return 700;} set {System.Console.WriteLine(701);} } public int P8 { get { return 800;} set {System.Console.WriteLine(801);} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var p1 = m.GlobalNamespace.GetMember("I1.P1"); var p2 = m.GlobalNamespace.GetMember("I1.P2"); var p3 = m.GlobalNamespace.GetMember("I1.P3"); var p4 = m.GlobalNamespace.GetMember("I1.P4"); var p5 = m.GlobalNamespace.GetMember("I1.P5"); var p6 = m.GlobalNamespace.GetMember("I1.P6"); var p7 = m.GlobalNamespace.GetMember("I1.P7"); var p8 = m.GlobalNamespace.GetMember("I1.P8"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("System.Int32 Test.P1 { get; }", derived.FindImplementationForInterfaceMember(p1).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P2 { get; }", derived.FindImplementationForInterfaceMember(p2).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P3 { get; }", derived.FindImplementationForInterfaceMember(p3).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P4 { get; }", derived.FindImplementationForInterfaceMember(p4).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P5 { set; }", derived.FindImplementationForInterfaceMember(p5).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P6 { set; }", derived.FindImplementationForInterfaceMember(p6).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P7 { get; set; }", derived.FindImplementationForInterfaceMember(p7).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P8 { get; set; }", derived.FindImplementationForInterfaceMember(p8).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P1.get", derived.FindImplementationForInterfaceMember(p1.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P2.get", derived.FindImplementationForInterfaceMember(p2.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P3.get", derived.FindImplementationForInterfaceMember(p3.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P4.get", derived.FindImplementationForInterfaceMember(p4.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.P5.set", derived.FindImplementationForInterfaceMember(p5.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.P6.set", derived.FindImplementationForInterfaceMember(p6.SetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P7.get", derived.FindImplementationForInterfaceMember(p7.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.P8.get", derived.FindImplementationForInterfaceMember(p8.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.P7.set", derived.FindImplementationForInterfaceMember(p7.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.P8.set", derived.FindImplementationForInterfaceMember(p8.SetMethod).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"100 200 300 400 500 600 700 701 800 801 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void PropertyImplementation_501() { var source1 = @" public interface I1 { int P1 => 1; int P3 { get => 3; } int P5 { set => System.Console.WriteLine(5); } int P7 { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,15): error CS8501: Target runtime doesn't support default interface implementation. // int P1 => 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "1").WithLocation(4, 15), // (6,7): error CS8501: Target runtime doesn't support default interface implementation. // { get => 3; } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 7), // (8,7): error CS8501: Target runtime doesn't support default interface implementation. // { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(8, 7), // (11,9): error CS8501: Target runtime doesn't support default interface implementation. // get { return 7;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(11, 9), // (12,9): error CS8501: Target runtime doesn't support default interface implementation. // set {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(12, 9) ); ValidatePropertyImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.P7.set' cannot implement interface member 'I1.P7.set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.set", "I1.P7.set", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P1.get' cannot implement interface member 'I1.P1.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.get", "I1.P1.get", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P3.get' cannot implement interface member 'I1.P3.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P3.get", "I1.P3.get", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P5.set' cannot implement interface member 'I1.P5.set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P5.set", "I1.P5.set", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P7.get' cannot implement interface member 'I1.P7.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.get", "I1.P7.get", "Test2").WithLocation(2, 15) ); ValidatePropertyImplementation_501(compilation3.SourceModule, "Test2"); } private static void ValidatePropertyImplementation_501(ModuleSymbol m, string typeName) { var derived = m.GlobalNamespace.GetTypeMember(typeName); var i1 = derived.InterfacesNoUseSiteDiagnostics().Single(); Assert.Equal("I1", i1.ToTestDisplayString()); var p1 = i1.GetMember("P1"); var p3 = i1.GetMember("P3"); var p5 = i1.GetMember("P5"); var p7 = i1.GetMember("P7"); Assert.True(p1.IsVirtual); Assert.True(p3.IsVirtual); Assert.True(p5.IsVirtual); Assert.True(p7.IsVirtual); Assert.False(p1.IsAbstract); Assert.False(p3.IsAbstract); Assert.False(p5.IsAbstract); Assert.False(p7.IsAbstract); Assert.Same(p1, derived.FindImplementationForInterfaceMember(p1)); Assert.Same(p3, derived.FindImplementationForInterfaceMember(p3)); Assert.Same(p5, derived.FindImplementationForInterfaceMember(p5)); Assert.Same(p7, derived.FindImplementationForInterfaceMember(p7)); Assert.True(p1.GetMethod.IsVirtual); Assert.True(p3.GetMethod.IsVirtual); Assert.True(p5.SetMethod.IsVirtual); Assert.True(p7.GetMethod.IsVirtual); Assert.True(p7.SetMethod.IsVirtual); Assert.True(p1.GetMethod.IsMetadataVirtual()); Assert.True(p3.GetMethod.IsMetadataVirtual()); Assert.True(p5.SetMethod.IsMetadataVirtual()); Assert.True(p7.GetMethod.IsMetadataVirtual()); Assert.True(p7.SetMethod.IsMetadataVirtual()); Assert.False(p1.GetMethod.IsAbstract); Assert.False(p3.GetMethod.IsAbstract); Assert.False(p5.SetMethod.IsAbstract); Assert.False(p7.GetMethod.IsAbstract); Assert.False(p7.SetMethod.IsAbstract); Assert.Same(p1.GetMethod, derived.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Same(p3.GetMethod, derived.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Same(p5.SetMethod, derived.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Same(p7.GetMethod, derived.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Same(p7.SetMethod, derived.FindImplementationForInterfaceMember(p7.SetMethod)); } [Fact] public void PropertyImplementation_502() { var source1 = @" public interface I1 { int P1 => 1; int P3 { get => 3; } int P5 { set => System.Console.WriteLine(5); } int P7 { get { return 7;} set {} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.P7.set' cannot implement interface member 'I1.P7.set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.set", "I1.P7.set", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P1.get' cannot implement interface member 'I1.P1.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.get", "I1.P1.get", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P3.get' cannot implement interface member 'I1.P3.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P3.get", "I1.P3.get", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P5.set' cannot implement interface member 'I1.P5.set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P5.set", "I1.P5.set", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P7.get' cannot implement interface member 'I1.P7.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.get", "I1.P7.get", "Test2").WithLocation(2, 15) ); ValidatePropertyImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void PropertyImplementation_503() { var source1 = @" public interface I1 { int P1 => 1; int P3 { get => 3; } int P5 { set => System.Console.WriteLine(5); } int P7 { get { return 7;} set {} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" public interface I2 { void M2(); } class Test2 : I2 { public void M2() {} } "; var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var test2 = compilation3.GetTypeByMetadataName("Test2"); var i1 = compilation3.GetTypeByMetadataName("I1"); Assert.Equal("I1", i1.ToTestDisplayString()); var p1 = i1.GetMember("P1"); var p3 = i1.GetMember("P3"); var p5 = i1.GetMember("P5"); var p7 = i1.GetMember("P7"); Assert.Null(test2.FindImplementationForInterfaceMember(p1)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p7)); Assert.Null(test2.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p7.SetMethod)); compilation3.VerifyDiagnostics(); } [Fact] public void PropertyImplementation_601() { var source1 = @" public interface I1 { int P1 => 1; int P3 { get => 3; } int P5 { set => System.Console.WriteLine(5); } int P7 { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,15): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P1 => 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "1").WithArguments("default interface implementation", "8.0").WithLocation(4, 15), // (4,15): error CS8701: Target runtime doesn't support default interface implementation. // int P1 => 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "1").WithLocation(4, 15), // (5,14): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P3 { get => 3; } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(5, 14), // (5,14): error CS8701: Target runtime doesn't support default interface implementation. // int P3 { get => 3; } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(5, 14), // (6,14): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P5 { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(6, 14), // (6,14): error CS8701: Target runtime doesn't support default interface implementation. // int P5 { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(6, 14), // (7,14): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(7, 14), // (7,14): error CS8701: Target runtime doesn't support default interface implementation. // int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(7, 14), // (7,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(7, 31), // (7,31): error CS8701: Target runtime doesn't support default interface implementation. // int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(7, 31) ); ValidatePropertyImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.P7.set' cannot implement interface member 'I1.P7.set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.set", "I1.P7.set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P7.set' cannot implement interface member 'I1.P7.set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.set", "I1.P7.set", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P1.get' cannot implement interface member 'I1.P1.get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.get", "I1.P1.get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P1.get' cannot implement interface member 'I1.P1.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.get", "I1.P1.get", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P3.get' cannot implement interface member 'I1.P3.get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P3.get", "I1.P3.get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P3.get' cannot implement interface member 'I1.P3.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P3.get", "I1.P3.get", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P5.set' cannot implement interface member 'I1.P5.set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P5.set", "I1.P5.set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P5.set' cannot implement interface member 'I1.P5.set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P5.set", "I1.P5.set", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P7.get' cannot implement interface member 'I1.P7.get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.get", "I1.P7.get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.P7.get' cannot implement interface member 'I1.P7.get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.get", "I1.P7.get", "Test2").WithLocation(2, 15) ); ValidatePropertyImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void PropertyImplementation_701() { var source1 = @" public interface I1 { int P1 => 1; int P3 { get => 3; } int P5 { set => System.Console.WriteLine(5); } int P7 { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,15): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P1 => 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "1").WithArguments("default interface implementation", "8.0").WithLocation(4, 15), // (5,14): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P3 { get => 3; } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(5, 14), // (6,14): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P5 { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(6, 14), // (7,14): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(7, 14), // (7,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(7, 31) ); ValidatePropertyImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidatePropertyImplementation_501(compilation2.SourceModule, "Test2"); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test2Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test2"); Assert.Equal("I1", test2Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidatePropertyImplementation_501(m, "Test2"); }); var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.P7.set' cannot implement interface member 'I1.P7.set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.set", "I1.P7.set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P1.get' cannot implement interface member 'I1.P1.get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P1.get", "I1.P1.get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P3.get' cannot implement interface member 'I1.P3.get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P3.get", "I1.P3.get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P5.set' cannot implement interface member 'I1.P5.set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P5.set", "I1.P5.set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.P7.get' cannot implement interface member 'I1.P7.get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.P7.get", "I1.P7.get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15) ); ValidatePropertyImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void PropertyImplementation_901() { var source1 = @" public interface I1 { static int P1 => 1; static int P3 { get => 3; } static int P5 { set => System.Console.WriteLine(5); } static int P7 { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,22): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int P1 => 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "1").WithArguments("default interface implementation", "8.0").WithLocation(4, 22), // (5,21): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int P3 { get => 3; } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(5, 21), // (6,21): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int P5 { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(6, 21), // (7,21): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(7, 21), // (7,38): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int P7 { get { return 7;} set {} } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(7, 38) ); var derived = compilation1.SourceModule.GlobalNamespace.GetTypeMember("Test1"); var i1 = derived.InterfacesNoUseSiteDiagnostics().Single(); Assert.Equal("I1", i1.ToTestDisplayString()); var p1 = i1.GetMember("P1"); var p3 = i1.GetMember("P3"); var p5 = i1.GetMember("P5"); var p7 = i1.GetMember("P7"); Assert.True(p1.IsStatic); Assert.True(p3.IsStatic); Assert.True(p5.IsStatic); Assert.True(p7.IsStatic); Assert.False(p1.IsVirtual); Assert.False(p3.IsVirtual); Assert.False(p5.IsVirtual); Assert.False(p7.IsVirtual); Assert.False(p1.IsAbstract); Assert.False(p3.IsAbstract); Assert.False(p5.IsAbstract); Assert.False(p7.IsAbstract); Assert.Null(derived.FindImplementationForInterfaceMember(p1)); Assert.Null(derived.FindImplementationForInterfaceMember(p3)); Assert.Null(derived.FindImplementationForInterfaceMember(p5)); Assert.Null(derived.FindImplementationForInterfaceMember(p7)); Assert.True(p1.GetMethod.IsStatic); Assert.True(p3.GetMethod.IsStatic); Assert.True(p5.SetMethod.IsStatic); Assert.True(p7.GetMethod.IsStatic); Assert.True(p7.SetMethod.IsStatic); Assert.False(p1.GetMethod.IsVirtual); Assert.False(p3.GetMethod.IsVirtual); Assert.False(p5.SetMethod.IsVirtual); Assert.False(p7.GetMethod.IsVirtual); Assert.False(p7.SetMethod.IsVirtual); Assert.False(p1.GetMethod.IsMetadataVirtual()); Assert.False(p3.GetMethod.IsMetadataVirtual()); Assert.False(p5.SetMethod.IsMetadataVirtual()); Assert.False(p7.GetMethod.IsMetadataVirtual()); Assert.False(p7.SetMethod.IsMetadataVirtual()); Assert.False(p1.GetMethod.IsAbstract); Assert.False(p3.GetMethod.IsAbstract); Assert.False(p5.SetMethod.IsAbstract); Assert.False(p7.GetMethod.IsAbstract); Assert.False(p7.SetMethod.IsAbstract); Assert.Null(derived.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Null(derived.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Null(derived.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Null(derived.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Null(derived.FindImplementationForInterfaceMember(p7.SetMethod)); } [Fact] public void IndexerImplementation_101() { var source1 = @" public interface I1 { int this[int i] { get { System.Console.WriteLine(""get P1""); return 0; } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "; ValidateIndexerImplementation_101(source1); } private void ValidateIndexerImplementation_101(string source1) { ValidatePropertyImplementation_101(source1, "this[]", haveGet: true, haveSet: false, accessCode: @" _ = i1[0]; ", expectedOutput: "get P1"); } [Fact] public void IndexerImplementation_102() { var source1 = @" public interface I1 { int this[int i] { get { System.Console.WriteLine(""get P1""); return 0; } set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1[0] = i1[0]; } } "; ValidateIndexerImplementation_102(source1); } private void ValidateIndexerImplementation_102(string source1) { ValidatePropertyImplementation_101(source1, "this[]", haveGet: true, haveSet: true, accessCode: @" i1[0] = i1[0]; ", expectedOutput: @"get P1 set P1"); } [Fact] public void IndexerImplementation_103() { var source1 = @" public interface I1 { int this[int i] { set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } } "; ValidateIndexerImplementation_103(source1); } private void ValidateIndexerImplementation_103(string source1) { ValidatePropertyImplementation_101(source1, "this[]", haveGet: false, haveSet: true, accessCode: @" i1[0] = 1; ", expectedOutput: "set P1"); } [Fact] public void IndexerImplementation_104() { var source1 = @" public interface I1 { int this[int i] => Test1.GetInt(); } class Test1 : I1 { public static int GetInt() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "; ValidateIndexerImplementation_101(source1); } [Fact] public void IndexerImplementation_105() { var source1 = @" public interface I1 { int this[int i] {add; remove;} => 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,22): error CS1014: A get or set accessor expected // int this[int i] {add; remove;} => 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 22), // (4,27): error CS1014: A get or set accessor expected // int this[int i] {add; remove;} => 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "remove").WithLocation(4, 27), // (4,9): error CS0548: 'I1.this[int]': property or indexer must have at least one accessor // int this[int i] {add; remove;} => 0; Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "this").WithArguments("I1.this[int]").WithLocation(4, 9), // (4,5): error CS8057: Block bodies and expression bodies cannot both be provided. // int this[int i] {add; remove;} => 0; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "int this[int i] {add; remove;} => 0;").WithLocation(4, 5) ); var p1 = compilation1.GetMember("I1.this[]"); Assert.True(p1.IsAbstract); Assert.Null(p1.GetMethod); Assert.Null(p1.SetMethod); Assert.True(p1.IsReadOnly); Assert.True(p1.IsWriteOnly); } [Fact] public void IndexerImplementation_106() { var source1 = @" public interface I1 { int this[int i] {get; set;} => 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,5): error CS8057: Block bodies and expression bodies cannot both be provided. // int this[int i] {get; set;} => 0; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "int this[int i] {get; set;} => 0;").WithLocation(4, 5) ); var p1 = compilation1.GetMember("I1.this[]"); Assert.True(p1.IsAbstract); Assert.True(p1.GetMethod.IsAbstract); Assert.True(p1.SetMethod.IsAbstract); Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); } [Fact] public void IndexerImplementation_107() { var source1 = @" public interface I1 { int this[int i] {add; remove;} = 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,36): error CS1519: Invalid token '=' in class, struct, or interface member declaration // int this[int i] {add; remove;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(4, 36), // (4,22): error CS1014: A get or set accessor expected // int this[int i] {add; remove;} = 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "add").WithLocation(4, 22), // (4,27): error CS1014: A get or set accessor expected // int this[int i] {add; remove;} = 0; Diagnostic(ErrorCode.ERR_GetOrSetExpected, "remove").WithLocation(4, 27), // (4,9): error CS0548: 'I1.this[int]': property or indexer must have at least one accessor // int this[int i] {add; remove;} = 0; Diagnostic(ErrorCode.ERR_PropertyWithNoAccessors, "this").WithArguments("I1.this[int]").WithLocation(4, 9) ); var p1 = compilation1.GetMember("I1.this[]"); Assert.True(p1.IsAbstract); Assert.Null(p1.GetMethod); Assert.Null(p1.SetMethod); Assert.True(p1.IsReadOnly); Assert.True(p1.IsWriteOnly); } [Fact] public void IndexerImplementation_108() { var source1 = @" public interface I1 { int this[int i] {get; set;} = 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,33): error CS1519: Invalid token '=' in class, struct, or interface member declaration // int this[int i] {get; set;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(4, 33) ); var p1 = compilation1.GetMember("I1.this[]"); Assert.True(p1.IsAbstract); Assert.True(p1.GetMethod.IsAbstract); Assert.True(p1.SetMethod.IsAbstract); Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); } [Fact] public void IndexerImplementation_109() { var source1 = @" public interface I1 { int this[int i] { get { System.Console.WriteLine(""get P1""); return 0; } set; } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md, // we don't want to allow only one accessor to have an implementation. compilation1.VerifyDiagnostics( // (11,9): error CS0501: 'I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial // set; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.this[int].set") ); var p1 = compilation1.GetMember("I1.this[]"); var getP1 = p1.GetMethod; var setP1 = p1.SetMethod; Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(getP1.IsAbstract); Assert.True(getP1.IsVirtual); Assert.False(setP1.IsAbstract); Assert.True(setP1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(getP1, test1.FindImplementationForInterfaceMember(getP1)); Assert.Same(setP1, test1.FindImplementationForInterfaceMember(setP1)); Assert.True(getP1.IsMetadataVirtual()); Assert.True(setP1.IsMetadataVirtual()); } [Fact] public void IndexerImplementation_110() { var source1 = @" public interface I1 { int this[int i] { get; set => System.Console.WriteLine(""set P1""); } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-04-18.md, // we don't want to allow only one accessor to have an implementation. compilation1.VerifyDiagnostics( // (6,9): error CS0501: 'I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // get; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.this[int].get") ); var p1 = compilation1.GetMember("I1.this[]"); var getP1 = p1.GetMethod; var setP1 = p1.SetMethod; Assert.False(p1.IsReadOnly); Assert.False(p1.IsWriteOnly); Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(getP1.IsAbstract); Assert.True(getP1.IsVirtual); Assert.False(setP1.IsAbstract); Assert.True(setP1.IsVirtual); var test1 = compilation1.GetTypeByMetadataName("Test1"); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(getP1, test1.FindImplementationForInterfaceMember(getP1)); Assert.Same(setP1, test1.FindImplementationForInterfaceMember(setP1)); Assert.True(getP1.IsMetadataVirtual()); Assert.True(setP1.IsMetadataVirtual()); } [Fact] public void IndexerImplementation_201() { var source1 = @" interface I1 { int this[sbyte i] => 1; int this[byte i] => 2; int this[short i] { get => 3; } int this[ushort i] { get => 4; } int this[int i] { set => System.Console.WriteLine(5); } int this[uint i] { set => System.Console.WriteLine(6); } int this[long i] { get { return 7;} set {System.Console.WriteLine(71);} } int this[ulong i] { get { return 8;} set {System.Console.WriteLine(81);} } } class Base { int this[sbyte i] => 10; int this[short i] { get => 30; } int this[int i] { set => System.Console.WriteLine(50); } int this[long i] { get { return 70;} set {} } } class Derived : Base, I1 { int this[byte i] => 20; int this[ushort i] { get => 40; } int this[uint i] { set => System.Console.WriteLine(60); } int this[ulong i] { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1[(sbyte)0]); System.Console.WriteLine(i1[(byte)0]); System.Console.WriteLine(i1[(short)0]); System.Console.WriteLine(i1[(ushort)0]); i1[(int)0] = 0; i1[(uint)0] = 0; System.Console.WriteLine(i1[(long)0]); i1[(long)0] = 0; System.Console.WriteLine(i1[(ulong)0]); i1[(ulong)0] = 0; } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateIndexerImplementation_201(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"1 2 3 4 5 6 7 71 8 81 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidateIndexerImplementation_201(m); }); } private static void ValidateIndexerImplementation_201(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var indexers = i1.GetMembers("this[]"); var p1 = (PropertySymbol)indexers[0]; var p2 = (PropertySymbol)indexers[1]; var p3 = (PropertySymbol)indexers[2]; var p4 = (PropertySymbol)indexers[3]; var p5 = (PropertySymbol)indexers[4]; var p6 = (PropertySymbol)indexers[5]; var p7 = (PropertySymbol)indexers[6]; var p8 = (PropertySymbol)indexers[7]; var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Same(p1, derived.FindImplementationForInterfaceMember(p1)); Assert.Same(p2, derived.FindImplementationForInterfaceMember(p2)); Assert.Same(p3, derived.FindImplementationForInterfaceMember(p3)); Assert.Same(p4, derived.FindImplementationForInterfaceMember(p4)); Assert.Same(p5, derived.FindImplementationForInterfaceMember(p5)); Assert.Same(p6, derived.FindImplementationForInterfaceMember(p6)); Assert.Same(p7, derived.FindImplementationForInterfaceMember(p7)); Assert.Same(p8, derived.FindImplementationForInterfaceMember(p8)); Assert.Same(p1.GetMethod, derived.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Same(p2.GetMethod, derived.FindImplementationForInterfaceMember(p2.GetMethod)); Assert.Same(p3.GetMethod, derived.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Same(p4.GetMethod, derived.FindImplementationForInterfaceMember(p4.GetMethod)); Assert.Same(p5.SetMethod, derived.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Same(p6.SetMethod, derived.FindImplementationForInterfaceMember(p6.SetMethod)); Assert.Same(p7.GetMethod, derived.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Same(p8.GetMethod, derived.FindImplementationForInterfaceMember(p8.GetMethod)); Assert.Same(p7.SetMethod, derived.FindImplementationForInterfaceMember(p7.SetMethod)); Assert.Same(p8.SetMethod, derived.FindImplementationForInterfaceMember(p8.SetMethod)); } [Fact] public void IndexerImplementation_202() { var source1 = @" interface I1 { int this[sbyte i] => 1; int this[byte i] => 2; int this[short i] { get => 3; } int this[ushort i] { get => 4; } int this[int i] { set => System.Console.WriteLine(5); } int this[uint i] { set => System.Console.WriteLine(6); } int this[long i] { get { return 7;} set {System.Console.WriteLine(71);} } int this[ulong i] { get { return 8;} set {System.Console.WriteLine(81);} } } class Base : Test { int this[sbyte i] => 10; int this[short i] { get => 30; } int this[int i] { set => System.Console.WriteLine(50); } int this[long i] { get { return 70;} set {} } } class Derived : Base, I1 { int this[byte i] => 20; int this[ushort i] { get => 40; } int this[uint i] { set => System.Console.WriteLine(60); } int this[ulong i] { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1[(sbyte)0]); System.Console.WriteLine(i1[(byte)0]); System.Console.WriteLine(i1[(short)0]); System.Console.WriteLine(i1[(ushort)0]); i1[(int)0] = 0; i1[(uint)0] = 0; System.Console.WriteLine(i1[(long)0]); i1[(long)0] = 0; System.Console.WriteLine(i1[(ulong)0]); i1[(ulong)0] = 0; } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateIndexerImplementation_201(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"1 2 3 4 5 6 7 71 8 81 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidateIndexerImplementation_201(m); }); } [Fact] public void IndexerImplementation_203() { var source1 = @" interface I1 { int this[sbyte i] => 1; int this[byte i] => 2; int this[short i] { get => 3; } int this[ushort i] { get => 4; } int this[int i] { set => System.Console.WriteLine(5); } int this[uint i] { set => System.Console.WriteLine(6); } int this[long i] { get { return 7;} set {} } int this[ulong i] { get { return 8;} set {} } } class Base : Test { int this[sbyte i] => 10; int this[short i] { get => 30; } int this[int i] { set => System.Console.WriteLine(50); } int this[long i] { get { return 70;} set {} } } class Derived : Base, I1 { int this[byte i] => 20; int this[ushort i] { get => 40; } int this[uint i] { set => System.Console.WriteLine(60); } int this[ulong i] { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1[(sbyte)0]); System.Console.WriteLine(i1[(byte)0]); System.Console.WriteLine(i1[(short)0]); System.Console.WriteLine(i1[(ushort)0]); i1[(int)0] = 0; i1[(uint)0] = 0; System.Console.WriteLine(i1[(long)0]); i1[(long)0] = 0; System.Console.WriteLine(i1[(ulong)0]); i1[(ulong)0] = 0; } } class Test : I1 { int I1.this[sbyte i] => 100; int I1.this[byte i] => 200; int I1.this[short i] { get => 300; } int I1.this[ushort i] { get => 400; } int I1.this[int i] { set => System.Console.WriteLine(500); } int I1.this[uint i] { set => System.Console.WriteLine(600); } int I1.this[long i] { get { return 700;} set {System.Console.WriteLine(701);} } int I1.this[ulong i] { get { return 800;} set {System.Console.WriteLine(801);} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var indexers = i1.GetMembers("this[]"); var p1 = (PropertySymbol)indexers[0]; var p2 = (PropertySymbol)indexers[1]; var p3 = (PropertySymbol)indexers[2]; var p4 = (PropertySymbol)indexers[3]; var p5 = (PropertySymbol)indexers[4]; var p6 = (PropertySymbol)indexers[5]; var p7 = (PropertySymbol)indexers[6]; var p8 = (PropertySymbol)indexers[7]; var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); string name = m is PEModuleSymbol ? "Item" : "this"; Assert.Equal("System.Int32 Test.I1." + name + "[System.SByte i] { get; }", derived.FindImplementationForInterfaceMember(p1).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.Byte i] { get; }", derived.FindImplementationForInterfaceMember(p2).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.Int16 i] { get; }", derived.FindImplementationForInterfaceMember(p3).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.UInt16 i] { get; }", derived.FindImplementationForInterfaceMember(p4).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.Int32 i] { set; }", derived.FindImplementationForInterfaceMember(p5).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.UInt32 i] { set; }", derived.FindImplementationForInterfaceMember(p6).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.Int64 i] { get; set; }", derived.FindImplementationForInterfaceMember(p7).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1." + name + "[System.UInt64 i] { get; set; }", derived.FindImplementationForInterfaceMember(p8).ToTestDisplayString()); if (m is PEModuleSymbol) { Assert.Equal("System.Int32 Test.I1.get_Item(System.SByte i)", derived.FindImplementationForInterfaceMember(p1.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.get_Item(System.Byte i)", derived.FindImplementationForInterfaceMember(p2.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.get_Item(System.Int16 i)", derived.FindImplementationForInterfaceMember(p3.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.get_Item(System.UInt16 i)", derived.FindImplementationForInterfaceMember(p4.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.set_Item(System.Int32 i, System.Int32 value)", derived.FindImplementationForInterfaceMember(p5.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.set_Item(System.UInt32 i, System.Int32 value)", derived.FindImplementationForInterfaceMember(p6.SetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.get_Item(System.Int64 i)", derived.FindImplementationForInterfaceMember(p7.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.get_Item(System.UInt64 i)", derived.FindImplementationForInterfaceMember(p8.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.set_Item(System.Int64 i, System.Int32 value)", derived.FindImplementationForInterfaceMember(p7.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.set_Item(System.UInt64 i, System.Int32 value)", derived.FindImplementationForInterfaceMember(p8.SetMethod).ToTestDisplayString()); } else { Assert.Equal("System.Int32 Test.I1.this[System.SByte i].get", derived.FindImplementationForInterfaceMember(p1.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.this[System.Byte i].get", derived.FindImplementationForInterfaceMember(p2.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.this[System.Int16 i].get", derived.FindImplementationForInterfaceMember(p3.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.this[System.UInt16 i].get", derived.FindImplementationForInterfaceMember(p4.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.this[System.Int32 i].set", derived.FindImplementationForInterfaceMember(p5.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.this[System.UInt32 i].set", derived.FindImplementationForInterfaceMember(p6.SetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.this[System.Int64 i].get", derived.FindImplementationForInterfaceMember(p7.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.I1.this[System.UInt64 i].get", derived.FindImplementationForInterfaceMember(p8.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.this[System.Int64 i].set", derived.FindImplementationForInterfaceMember(p7.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.this[System.UInt64 i].set", derived.FindImplementationForInterfaceMember(p8.SetMethod).ToTestDisplayString()); } } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"100 200 300 400 500 600 700 701 800 801 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void IndexerImplementation_204() { var source1 = @" interface I1 { int this[sbyte i] => 1; int this[byte i] => 2; int this[short i] { get => 3; } int this[ushort i] { get => 4; } int this[int i] { set => System.Console.WriteLine(5); } int this[uint i] { set => System.Console.WriteLine(6); } int this[long i] { get { return 7;} set {} } int this[ulong i] { get { return 8;} set {} } } class Base : Test { new int this[sbyte i] => 10; new int this[short i] { get => 30; } new int this[int i] { set => System.Console.WriteLine(50); } new int this[long i] { get { return 70;} set {} } } class Derived : Base, I1 { new int this[byte i] => 20; new int this[ushort i] { get => 40; } new int this[uint i] { set => System.Console.WriteLine(60); } new int this[ulong i] { get { return 80;} set {} } static void Main() { I1 i1 = new Derived(); System.Console.WriteLine(i1[(sbyte)0]); System.Console.WriteLine(i1[(byte)0]); System.Console.WriteLine(i1[(short)0]); System.Console.WriteLine(i1[(ushort)0]); i1[(int)0] = 0; i1[(uint)0] = 0; System.Console.WriteLine(i1[(long)0]); i1[(long)0] = 0; System.Console.WriteLine(i1[(ulong)0]); i1[(ulong)0] = 0; } } class Test : I1 { public int this[sbyte i] => 100; public int this[byte i] => 200; public int this[short i] { get => 300; } public int this[ushort i] { get => 400; } public int this[int i] { set => System.Console.WriteLine(500); } public int this[uint i] { set => System.Console.WriteLine(600); } public int this[long i] { get { return 700;} set {System.Console.WriteLine(701);} } public int this[ulong i] { get { return 800;} set {System.Console.WriteLine(801);} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var indexers = i1.GetMembers("this[]"); var p1 = (PropertySymbol)indexers[0]; var p2 = (PropertySymbol)indexers[1]; var p3 = (PropertySymbol)indexers[2]; var p4 = (PropertySymbol)indexers[3]; var p5 = (PropertySymbol)indexers[4]; var p6 = (PropertySymbol)indexers[5]; var p7 = (PropertySymbol)indexers[6]; var p8 = (PropertySymbol)indexers[7]; var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("System.Int32 Test.this[System.SByte i] { get; }", derived.FindImplementationForInterfaceMember(p1).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Byte i] { get; }", derived.FindImplementationForInterfaceMember(p2).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Int16 i] { get; }", derived.FindImplementationForInterfaceMember(p3).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.UInt16 i] { get; }", derived.FindImplementationForInterfaceMember(p4).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Int32 i] { set; }", derived.FindImplementationForInterfaceMember(p5).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.UInt32 i] { set; }", derived.FindImplementationForInterfaceMember(p6).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Int64 i] { get; set; }", derived.FindImplementationForInterfaceMember(p7).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.UInt64 i] { get; set; }", derived.FindImplementationForInterfaceMember(p8).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.SByte i].get", derived.FindImplementationForInterfaceMember(p1.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Byte i].get", derived.FindImplementationForInterfaceMember(p2.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Int16 i].get", derived.FindImplementationForInterfaceMember(p3.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.UInt16 i].get", derived.FindImplementationForInterfaceMember(p4.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.this[System.Int32 i].set", derived.FindImplementationForInterfaceMember(p5.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.this[System.UInt32 i].set", derived.FindImplementationForInterfaceMember(p6.SetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.Int64 i].get", derived.FindImplementationForInterfaceMember(p7.GetMethod).ToTestDisplayString()); Assert.Equal("System.Int32 Test.this[System.UInt64 i].get", derived.FindImplementationForInterfaceMember(p8.GetMethod).ToTestDisplayString()); Assert.Equal("void Test.this[System.Int64 i].set", derived.FindImplementationForInterfaceMember(p7.SetMethod).ToTestDisplayString()); Assert.Equal("void Test.this[System.UInt64 i].set", derived.FindImplementationForInterfaceMember(p8.SetMethod).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"100 200 300 400 500 600 700 701 800 801 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void IndexerImplementation_501() { var source1 = @" public interface I1 { int this[sbyte i] => 1; int this[short i] { get => 3; } int this[int i] { set => System.Console.WriteLine(5); } int this[long i] { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,26): error CS8501: Target runtime doesn't support default interface implementation. // int this[sbyte i] => 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "1").WithLocation(4, 26), // (6,7): error CS8501: Target runtime doesn't support default interface implementation. // { get => 3; } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 7), // (8,7): error CS8501: Target runtime doesn't support default interface implementation. // { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(8, 7), // (11,9): error CS8501: Target runtime doesn't support default interface implementation. // get { return 7;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(11, 9), // (12,9): error CS8501: Target runtime doesn't support default interface implementation. // set {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(12, 9) ); ValidateIndexerImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.this[long].set' cannot implement interface member 'I1.this[long].set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].set", "I1.this[long].set", "Test2"), // (2,15): error CS8502: 'I1.this[sbyte].get' cannot implement interface member 'I1.this[sbyte].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[sbyte].get", "I1.this[sbyte].get", "Test2"), // (2,15): error CS8502: 'I1.this[short].get' cannot implement interface member 'I1.this[short].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[short].get", "I1.this[short].get", "Test2"), // (2,15): error CS8502: 'I1.this[int].set' cannot implement interface member 'I1.this[int].set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].set", "I1.this[int].set", "Test2"), // (2,15): error CS8502: 'I1.this[long].get' cannot implement interface member 'I1.this[long].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].get", "I1.this[long].get", "Test2") ); ValidateIndexerImplementation_501(compilation3.SourceModule, "Test2"); } private static void ValidateIndexerImplementation_501(ModuleSymbol m, string typeName) { var derived = m.GlobalNamespace.GetTypeMember(typeName); var i1 = derived.InterfacesNoUseSiteDiagnostics().Single(); Assert.Equal("I1", i1.ToTestDisplayString()); var indexers = i1.GetMembers("this[]"); var p1 = (PropertySymbol)indexers[0]; var p3 = (PropertySymbol)indexers[1]; var p5 = (PropertySymbol)indexers[2]; var p7 = (PropertySymbol)indexers[3]; Assert.True(p1.IsVirtual); Assert.True(p3.IsVirtual); Assert.True(p5.IsVirtual); Assert.True(p7.IsVirtual); Assert.False(p1.IsAbstract); Assert.False(p3.IsAbstract); Assert.False(p5.IsAbstract); Assert.False(p7.IsAbstract); Assert.Same(p1, derived.FindImplementationForInterfaceMember(p1)); Assert.Same(p3, derived.FindImplementationForInterfaceMember(p3)); Assert.Same(p5, derived.FindImplementationForInterfaceMember(p5)); Assert.Same(p7, derived.FindImplementationForInterfaceMember(p7)); Assert.True(p1.GetMethod.IsVirtual); Assert.True(p3.GetMethod.IsVirtual); Assert.True(p5.SetMethod.IsVirtual); Assert.True(p7.GetMethod.IsVirtual); Assert.True(p7.SetMethod.IsVirtual); Assert.True(p1.GetMethod.IsMetadataVirtual()); Assert.True(p3.GetMethod.IsMetadataVirtual()); Assert.True(p5.SetMethod.IsMetadataVirtual()); Assert.True(p7.GetMethod.IsMetadataVirtual()); Assert.True(p7.SetMethod.IsMetadataVirtual()); Assert.False(p1.GetMethod.IsAbstract); Assert.False(p3.GetMethod.IsAbstract); Assert.False(p5.SetMethod.IsAbstract); Assert.False(p7.GetMethod.IsAbstract); Assert.False(p7.SetMethod.IsAbstract); Assert.Same(p1.GetMethod, derived.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Same(p3.GetMethod, derived.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Same(p5.SetMethod, derived.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Same(p7.GetMethod, derived.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Same(p7.SetMethod, derived.FindImplementationForInterfaceMember(p7.SetMethod)); } [Fact] public void IndexerImplementation_502() { var source1 = @" public interface I1 { int this[sbyte i] => 1; int this[short i] { get => 3; } int this[int i] { set => System.Console.WriteLine(5); } int this[long i] { get { return 7;} set {} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.this[short].get' cannot implement interface member 'I1.this[short].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[short].get", "I1.this[short].get", "Test2"), // (2,15): error CS8502: 'I1.this[int].set' cannot implement interface member 'I1.this[int].set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].set", "I1.this[int].set", "Test2"), // (2,15): error CS8502: 'I1.this[long].get' cannot implement interface member 'I1.this[long].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].get", "I1.this[long].get", "Test2"), // (2,15): error CS8502: 'I1.this[long].set' cannot implement interface member 'I1.this[long].set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].set", "I1.this[long].set", "Test2"), // (2,15): error CS8502: 'I1.this[sbyte].get' cannot implement interface member 'I1.this[sbyte].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[sbyte].get", "I1.this[sbyte].get", "Test2") ); ValidateIndexerImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void IndexerImplementation_503() { var source1 = @" public interface I1 { int this[sbyte i] => 1; int this[short i] { get => 3; } int this[int i] { set => System.Console.WriteLine(5); } int this[long i] { get { return 7;} set {} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" public interface I2 { void M2(); } class Test2 : I2 { public void M2() {} } "; var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var test2 = compilation3.GetTypeByMetadataName("Test2"); var i1 = compilation3.GetTypeByMetadataName("I1"); Assert.Equal("I1", i1.ToTestDisplayString()); var indexers = i1.GetMembers("this[]"); var p1 = (PropertySymbol)indexers[0]; var p3 = (PropertySymbol)indexers[1]; var p5 = (PropertySymbol)indexers[2]; var p7 = (PropertySymbol)indexers[3]; Assert.Null(test2.FindImplementationForInterfaceMember(p1)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p7)); Assert.Null(test2.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p3.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p5.SetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p7.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p7.SetMethod)); compilation3.VerifyDiagnostics(); } [Fact] public void IndexerImplementation_601() { var source1 = @" public interface I1 { int this[sbyte i] => 1; int this[short i] { get => 3; } int this[int i] { set => System.Console.WriteLine(5); } int this[long i] { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,26): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int this[sbyte i] => 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "1").WithArguments("default interface implementation", "8.0").WithLocation(4, 26), // (4,26): error CS8701: Target runtime doesn't support default interface implementation. // int this[sbyte i] => 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "1").WithLocation(4, 26), // (6,7): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // { get => 3; } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(6, 7), // (6,7): error CS8701: Target runtime doesn't support default interface implementation. // { get => 3; } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 7), // (8,7): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(8, 7), // (8,7): error CS8701: Target runtime doesn't support default interface implementation. // { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(8, 7), // (11,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // get { return 7;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(11, 9), // (11,9): error CS8701: Target runtime doesn't support default interface implementation. // get { return 7;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(11, 9), // (12,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // set {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(12, 9), // (12,9): error CS8701: Target runtime doesn't support default interface implementation. // set {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(12, 9) ); ValidateIndexerImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.this[long].set' cannot implement interface member 'I1.this[long].set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].set", "I1.this[long].set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.this[long].set' cannot implement interface member 'I1.this[long].set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].set", "I1.this[long].set", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[sbyte].get' cannot implement interface member 'I1.this[sbyte].get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[sbyte].get", "I1.this[sbyte].get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.this[sbyte].get' cannot implement interface member 'I1.this[sbyte].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[sbyte].get", "I1.this[sbyte].get", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[short].get' cannot implement interface member 'I1.this[short].get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[short].get", "I1.this[short].get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.this[short].get' cannot implement interface member 'I1.this[short].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[short].get", "I1.this[short].get", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[int].set' cannot implement interface member 'I1.this[int].set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].set", "I1.this[int].set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.this[int].set' cannot implement interface member 'I1.this[int].set' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].set", "I1.this[int].set", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[long].get' cannot implement interface member 'I1.this[long].get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].get", "I1.this[long].get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.this[long].get' cannot implement interface member 'I1.this[long].get' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].get", "I1.this[long].get", "Test2").WithLocation(2, 15) ); ValidateIndexerImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void IndexerImplementation_701() { var source1 = @" public interface I1 { int this[sbyte i] => 1; int this[short i] { get => 3; } int this[int i] { set => System.Console.WriteLine(5); } int this[long i] { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,26): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int this[sbyte i] => 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "1").WithArguments("default interface implementation", "8.0").WithLocation(4, 26), // (6,7): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // { get => 3; } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(6, 7), // (8,7): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(8, 7), // (11,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // get { return 7;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(11, 9), // (12,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // set {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(12, 9) ); ValidateIndexerImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateIndexerImplementation_501(compilation2.SourceModule, "Test2"); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test2Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test2"); Assert.Equal("I1", test2Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidateIndexerImplementation_501(m, "Test2"); }); var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.this[long].set' cannot implement interface member 'I1.this[long].set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].set", "I1.this[long].set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[sbyte].get' cannot implement interface member 'I1.this[sbyte].get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[sbyte].get", "I1.this[sbyte].get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[short].get' cannot implement interface member 'I1.this[short].get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[short].get", "I1.this[short].get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[int].set' cannot implement interface member 'I1.this[int].set' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[int].set", "I1.this[int].set", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.this[long].get' cannot implement interface member 'I1.this[long].get' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.this[long].get", "I1.this[long].get", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15) ); ValidateIndexerImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void IndexerImplementation_901() { var source1 = @" public interface I1 { static int this[sbyte i] => 1; static int this[short i] { get => 3; } static int this[int i] { set => System.Console.WriteLine(5); } static int this[long i] { get { return 7;} set {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,16): error CS0106: The modifier 'static' is not valid for this item // static int this[sbyte i] => 1; Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(4, 16), // (4,33): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int this[sbyte i] => 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "1").WithArguments("default interface implementation", "8.0").WithLocation(4, 33), // (5,16): error CS0106: The modifier 'static' is not valid for this item // static int this[short i] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(5, 16), // (6,7): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // { get => 3; } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(6, 7), // (7,16): error CS0106: The modifier 'static' is not valid for this item // static int this[int i] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(7, 16), // (8,7): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // { set => System.Console.WriteLine(5); } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(8, 7), // (9,16): error CS0106: The modifier 'static' is not valid for this item // static int this[long i] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(9, 16), // (11,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // get { return 7;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(11, 9), // (12,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // set {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(12, 9) ); ValidateIndexerImplementation_501(compilation1.SourceModule, "Test1"); } [Fact] public void EventImplementation_101() { var source1 = @" public interface I1 { event System.Action E1 { add { System.Console.WriteLine(""add E1""); } } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (4,25): error CS0065: 'I1.E1': event property must have both add and remove accessors // event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 25) }, haveAdd: true, haveRemove: false); } private void ValidateEventImplementation_101(string source1, DiagnosticDescription[] expected, bool haveAdd, bool haveRemove) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics(expected); ValidateEventImplementationTest1_101(compilation1.SourceModule, haveAdd, haveRemove); var source2 = @" class Test2 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate2(ModuleSymbol m) { ValidateEventImplementationTest2_101(m, haveAdd, haveRemove); } Validate2(compilation2.SourceModule); compilation2.VerifyDiagnostics(); Assert.NotEmpty(expected); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); } private static void ValidateEventImplementationTest1_101(ModuleSymbol m, bool haveAdd, bool haveRemove) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var e1 = i1.GetMember("E1"); var addE1 = e1.AddMethod; var rmvE1 = e1.RemoveMethod; if (haveAdd) { ValidateAccessor(addE1); } else { Assert.Null(addE1); } if (haveRemove) { ValidateAccessor(rmvE1); } else { Assert.Null(rmvE1); } void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } Assert.False(e1.IsAbstract); Assert.True(e1.IsVirtual); Assert.False(e1.IsSealed); Assert.False(e1.IsStatic); Assert.False(e1.IsExtern); Assert.False(e1.IsOverride); Assert.Equal(Accessibility.Public, e1.DeclaredAccessibility); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); if (m is PEModuleSymbol peModule) { int rva; if (haveAdd) { peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)addE1).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } if (haveRemove) { peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)rmvE1).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } } var test1 = m.GlobalNamespace.GetTypeMember("Test1"); Assert.Equal("I1", test1.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Assert.Same(e1, test1.FindImplementationForInterfaceMember(e1)); if (haveAdd) { Assert.Same(addE1, test1.FindImplementationForInterfaceMember(addE1)); } if (haveRemove) { Assert.Same(rmvE1, test1.FindImplementationForInterfaceMember(rmvE1)); } } private static void ValidateEventImplementationTest2_101(ModuleSymbol m, bool haveAdd, bool haveRemove) { var test2 = m.GlobalNamespace.GetTypeMember("Test2"); Assert.Equal("I1", test2.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); var e1 = test2.InterfacesNoUseSiteDiagnostics().Single().GetMember("E1"); Assert.Same(e1, test2.FindImplementationForInterfaceMember(e1)); if (haveAdd) { var addP1 = e1.AddMethod; Assert.Same(addP1, test2.FindImplementationForInterfaceMember(addP1)); } if (haveRemove) { var rmvP1 = e1.RemoveMethod; Assert.Same(rmvP1, test2.FindImplementationForInterfaceMember(rmvP1)); } } [Fact] public void EventImplementation_102() { var source1 = @" public interface I1 { event System.Action E1 { add => System.Console.WriteLine(""add E1""); remove => System.Console.WriteLine(""remove E1""); } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.E1 += null; i1.E1 -= null; } } "; ValidateEventImplementation_102(source1); } private void ValidateEventImplementation_102(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { ValidateEventImplementationTest1_101(m, haveAdd: true, haveRemove: true); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E1 remove E1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1 i1 = new Test2(); i1.E1 += null; i1.E1 -= null; } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate2(ModuleSymbol m) { ValidateEventImplementationTest2_101(m, haveAdd: true, haveRemove: true); } Validate2(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E1 remove E1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate2(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E1 remove E1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); } [Fact] public void EventImplementation_103() { var source1 = @" public interface I1 { event System.Action E1 { remove { System.Console.WriteLine(""remove E1""); } } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (4,25): error CS0065: 'I1.E1': event property must have both add and remove accessors // event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 25) }, haveAdd: false, haveRemove: true); } [Fact] public void EventImplementation_104() { var source1 = @" public interface I1 { event System.Action E1 { add; } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (6,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(6, 12), // (4,25): error CS0065: 'I1.E1': event property must have both add and remove accessors // event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 25) }, haveAdd: true, haveRemove: false); } [Fact] public void EventImplementation_105() { var source1 = @" public interface I1 { event System.Action E1 { remove; } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (6,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(6, 15), // (4,25): error CS0065: 'I1.E1': event property must have both add and remove accessors // event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 25) }, haveAdd: false, haveRemove: true); } [Fact] public void EventImplementation_106() { var source1 = @" public interface I1 { event System.Action E1 { } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (4,25): error CS0065: 'I1.E1': event property must have both add and remove accessors // event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 25) }, haveAdd: false, haveRemove: false); } [Fact] public void EventImplementation_107() { var source1 = @" public interface I1 { event System.Action E1 { add; remove; } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (6,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(6, 12), // (7,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(7, 15) }, haveAdd: true, haveRemove: true); } [Fact] public void EventImplementation_108() { var source1 = @" public interface I1 { event System.Action E1 { get; set; } => 0; } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (8,7): error CS1519: Invalid token '=>' in class, struct, or interface member declaration // } => 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=>").WithArguments("=>").WithLocation(8, 7), // (6,9): error CS1055: An add or remove accessor expected // get; Diagnostic(ErrorCode.ERR_AddOrRemoveExpected, "get").WithLocation(6, 9), // (7,9): error CS1055: An add or remove accessor expected // set; Diagnostic(ErrorCode.ERR_AddOrRemoveExpected, "set").WithLocation(7, 9), // (4,25): error CS0065: 'I1.E1': event property must have both add and remove accessors // event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1") }, haveAdd: false, haveRemove: false); } [Fact] public void EventImplementation_109() { var source1 = @" public interface I1 { event System.Action E1 { add => throw null; remove; } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (7,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(7, 15) }, haveAdd: true, haveRemove: true); } [Fact] public void EventImplementation_110() { var source1 = @" public interface I1 { event System.Action E1 { add; remove => throw null; } } class Test1 : I1 {} "; ValidateEventImplementation_101(source1, new[] { // (6,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(6, 12) }, haveAdd: true, haveRemove: true); } [Fact] public void EventImplementation_201() { var source1 = @" interface I1 { event System.Action E7 { add {System.Console.WriteLine(""add E7"");} remove {System.Console.WriteLine(""remove E7"");} } event System.Action E8 { add {System.Console.WriteLine(""add E8"");} remove {System.Console.WriteLine(""remove E8"");} } } class Base { event System.Action E7; } class Derived : Base, I1 { event System.Action E8 { add {} remove {} } static void Main() { I1 i1 = new Derived(); i1.E7 += null; i1.E7 -= null; i1.E8 += null; i1.E8 -= null; } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (10,25): warning CS0067: The event 'Base.E7' is never used // event System.Action E7; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E7").WithArguments("Base.E7").WithLocation(10, 25) ); ValidateEventImplementation_201(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E7 remove E7 add E8 remove E8", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidateEventImplementation_201(m); }); } private static void ValidateEventImplementation_201(ModuleSymbol m) { var e7 = m.GlobalNamespace.GetMember("I1.E7"); var e8 = m.GlobalNamespace.GetMember("I1.E8"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Same(e7, derived.FindImplementationForInterfaceMember(e7)); Assert.Same(e8, derived.FindImplementationForInterfaceMember(e8)); Assert.Same(e7.AddMethod, derived.FindImplementationForInterfaceMember(e7.AddMethod)); Assert.Same(e8.AddMethod, derived.FindImplementationForInterfaceMember(e8.AddMethod)); Assert.Same(e7.RemoveMethod, derived.FindImplementationForInterfaceMember(e7.RemoveMethod)); Assert.Same(e8.RemoveMethod, derived.FindImplementationForInterfaceMember(e8.RemoveMethod)); } [Fact] public void EventImplementation_202() { var source1 = @" interface I1 { event System.Action E7 { add {System.Console.WriteLine(""add E7"");} remove {System.Console.WriteLine(""remove E7"");} } event System.Action E8 { add {System.Console.WriteLine(""add E8"");} remove {System.Console.WriteLine(""remove E8"");} } } class Base : Test { event System.Action E7; } class Derived : Base, I1 { event System.Action E8 { add {} remove {} } static void Main() { I1 i1 = new Derived(); i1.E7 += null; i1.E7 -= null; i1.E8 += null; i1.E8 -= null; } } class Test : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (10,25): warning CS0067: The event 'Base.E7' is never used // event System.Action E7; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E7").WithArguments("Base.E7").WithLocation(10, 25) ); ValidateEventImplementation_201(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E7 remove E7 add E8 remove E8", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidateEventImplementation_201(m); }); } [Fact] public void EventImplementation_203() { var source1 = @" interface I1 { event System.Action E7 { add {} remove {} } event System.Action E8 { add {} remove {} } } class Base : Test { event System.Action E7; } class Derived : Base, I1 { event System.Action E8 { add {} remove {} } static void Main() { I1 i1 = new Derived(); i1.E7 += null; i1.E7 -= null; i1.E8 += null; i1.E8 -= null; } } class Test : I1 { event System.Action I1.E7 { add {System.Console.WriteLine(""add E7"");} remove {System.Console.WriteLine(""remove E7"");} } event System.Action I1.E8 { add {System.Console.WriteLine(""add E8"");} remove {System.Console.WriteLine(""remove E8"");} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (10,25): warning CS0067: The event 'Base.E7' is never used // event System.Action E7; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E7").WithArguments("Base.E7").WithLocation(10, 25) ); void Validate(ModuleSymbol m) { var e7 = m.GlobalNamespace.GetMember("I1.E7"); var e8 = m.GlobalNamespace.GetMember("I1.E8"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("event System.Action Test.I1.E7", derived.FindImplementationForInterfaceMember(e7).ToTestDisplayString()); Assert.Equal("event System.Action Test.I1.E8", derived.FindImplementationForInterfaceMember(e8).ToTestDisplayString()); Assert.Equal("void Test.I1.E7.add", derived.FindImplementationForInterfaceMember(e7.AddMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.E8.add", derived.FindImplementationForInterfaceMember(e8.AddMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.E7.remove", derived.FindImplementationForInterfaceMember(e7.RemoveMethod).ToTestDisplayString()); Assert.Equal("void Test.I1.E8.remove", derived.FindImplementationForInterfaceMember(e8.RemoveMethod).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E7 remove E7 add E8 remove E8", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void EventImplementation_204() { var source1 = @" interface I1 { event System.Action E7 { add {} remove {} } event System.Action E8 { add {} remove {} } } class Base : Test { new event System.Action E7; } class Derived : Base, I1 { new event System.Action E8 { add {} remove {} } static void Main() { I1 i1 = new Derived(); i1.E7 += null; i1.E7 -= null; i1.E8 += null; i1.E8 -= null; } } class Test : I1 { public event System.Action E7 { add {System.Console.WriteLine(""add E7"");} remove {System.Console.WriteLine(""remove E7"");} } public event System.Action E8 { add {System.Console.WriteLine(""add E8"");} remove {System.Console.WriteLine(""remove E8"");} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (10,29): warning CS0067: The event 'Base.E7' is never used // new event System.Action E7; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E7").WithArguments("Base.E7").WithLocation(10, 29) ); void Validate(ModuleSymbol m) { var e7 = m.GlobalNamespace.GetMember("I1.E7"); var e8 = m.GlobalNamespace.GetMember("I1.E8"); var derived = m.ContainingAssembly.GetTypeByMetadataName("Derived"); Assert.Equal("event System.Action Test.E7", derived.FindImplementationForInterfaceMember(e7).ToTestDisplayString()); Assert.Equal("event System.Action Test.E8", derived.FindImplementationForInterfaceMember(e8).ToTestDisplayString()); Assert.Equal("void Test.E7.add", derived.FindImplementationForInterfaceMember(e7.AddMethod).ToTestDisplayString()); Assert.Equal("void Test.E8.add", derived.FindImplementationForInterfaceMember(e8.AddMethod).ToTestDisplayString()); Assert.Equal("void Test.E7.remove", derived.FindImplementationForInterfaceMember(e7.RemoveMethod).ToTestDisplayString()); Assert.Equal("void Test.E8.remove", derived.FindImplementationForInterfaceMember(e8.RemoveMethod).ToTestDisplayString()); } Validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"add E7 remove E7 add E8 remove E8", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var derivedResult = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Derived"); Assert.Equal("I1", derivedResult.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); Validate(m); }); } [Fact] public void EventImplementation_501() { var source1 = @" public interface I1 { event System.Action E7 { add {} remove {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,9): error CS8501: Target runtime doesn't support default interface implementation. // add {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(6, 9), // (7,9): error CS8501: Target runtime doesn't support default interface implementation. // remove {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(7, 9) ); ValidateEventImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.E7.remove' cannot implement interface member 'I1.E7.remove' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.remove", "I1.E7.remove", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.E7.add' cannot implement interface member 'I1.E7.add' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.add", "I1.E7.add", "Test2").WithLocation(2, 15) ); ValidateEventImplementation_501(compilation3.SourceModule, "Test2"); } private static void ValidateEventImplementation_501(ModuleSymbol m, string typeName) { var derived = m.GlobalNamespace.GetTypeMember(typeName); var i1 = derived.InterfacesNoUseSiteDiagnostics().Single(); Assert.Equal("I1", i1.ToTestDisplayString()); var e7 = i1.GetMember("E7"); Assert.True(e7.IsVirtual); Assert.False(e7.IsAbstract); Assert.Same(e7, derived.FindImplementationForInterfaceMember(e7)); Assert.True(e7.AddMethod.IsVirtual); Assert.True(e7.RemoveMethod.IsVirtual); Assert.True(e7.AddMethod.IsMetadataVirtual()); Assert.True(e7.RemoveMethod.IsMetadataVirtual()); Assert.False(e7.AddMethod.IsAbstract); Assert.False(e7.RemoveMethod.IsAbstract); Assert.Same(e7.AddMethod, derived.FindImplementationForInterfaceMember(e7.AddMethod)); Assert.Same(e7.RemoveMethod, derived.FindImplementationForInterfaceMember(e7.RemoveMethod)); } [Fact] public void EventImplementation_502() { var source1 = @" public interface I1 { event System.Action E7 { add {} remove {} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, targetFramework: TargetFramework.DesktopLatestExtended, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8502: 'I1.E7.remove' cannot implement interface member 'I1.E7.remove' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.remove", "I1.E7.remove", "Test2").WithLocation(2, 15), // (2,15): error CS8502: 'I1.E7.add' cannot implement interface member 'I1.E7.add' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.add", "I1.E7.add", "Test2").WithLocation(2, 15) ); ValidateEventImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void EventImplementation_503() { var source1 = @" public interface I1 { event System.Action E7 { add {} remove {} } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" public interface I2 { void M2(); } class Test2 : I2 { public void M2() {} } "; var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var test2 = compilation3.GetTypeByMetadataName("Test2"); var i1 = compilation3.GetTypeByMetadataName("I1"); Assert.Equal("I1", i1.ToTestDisplayString()); var e7 = i1.GetMember("E7"); Assert.Null(test2.FindImplementationForInterfaceMember(e7)); Assert.Null(test2.FindImplementationForInterfaceMember(e7.AddMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(e7.RemoveMethod)); compilation3.VerifyDiagnostics(); } [Fact] public void EventImplementation_601() { var source1 = @" public interface I1 { event System.Action E7 { add {} remove {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // add {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(6, 9), // (6,9): error CS8701: Target runtime doesn't support default interface implementation. // add {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(6, 9), // (7,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // remove {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(7, 9), // (7,9): error CS8701: Target runtime doesn't support default interface implementation. // remove {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(7, 9) ); ValidateEventImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular7_3); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.E7.remove' cannot implement interface member 'I1.E7.remove' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.remove", "I1.E7.remove", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.E7.remove' cannot implement interface member 'I1.E7.remove' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.remove", "I1.E7.remove", "Test2").WithLocation(2, 15), // (2,15): error CS8506: 'I1.E7.add' cannot implement interface member 'I1.E7.add' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.add", "I1.E7.add", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8502: 'I1.E7.add' cannot implement interface member 'I1.E7.add' in type 'Test2' because the target runtime doesn't support default interface implementation. // class Test2 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.add", "I1.E7.add", "Test2").WithLocation(2, 15) ); ValidateEventImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void EventImplementation_701() { var source1 = @" public interface I1 { event System.Action E7 { add {} remove {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // add {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(6, 9), // (7,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // remove {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(7, 9) ); ValidateEventImplementation_501(compilation1.SourceModule, "Test1"); var source2 = @" class Test2 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateEventImplementation_501(compilation2.SourceModule, "Test2"); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => { var test2Result = (PENamedTypeSymbol)m.GlobalNamespace.GetTypeMember("Test2"); Assert.Equal("I1", test2Result.InterfacesNoUseSiteDiagnostics().Single().ToTestDisplayString()); ValidateEventImplementation_501(m, "Test2"); }); var compilation3 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8506: 'I1.E7.remove' cannot implement interface member 'I1.E7.remove' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.remove", "I1.E7.remove", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15), // (2,15): error CS8506: 'I1.E7.add' cannot implement interface member 'I1.E7.add' in type 'Test2' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test2 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.E7.add", "I1.E7.add", "Test2", "default interface implementation", "7.3", "8.0").WithLocation(2, 15) ); ValidateEventImplementation_501(compilation3.SourceModule, "Test2"); } [Fact] public void EventImplementation_901() { var source1 = @" public interface I1 { static event System.Action E7 { add {} remove {} } } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // add {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(6, 9), // (7,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // remove {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(7, 9) ); var derived = compilation1.GlobalNamespace.GetTypeMember("Test1"); var i1 = derived.InterfacesNoUseSiteDiagnostics().Single(); Assert.Equal("I1", i1.ToTestDisplayString()); var e7 = i1.GetMember("E7"); Assert.False(e7.IsVirtual); Assert.False(e7.IsAbstract); Assert.True(e7.IsStatic); Assert.Null(derived.FindImplementationForInterfaceMember(e7)); Assert.False(e7.AddMethod.IsVirtual); Assert.False(e7.RemoveMethod.IsVirtual); Assert.False(e7.AddMethod.IsMetadataVirtual()); Assert.False(e7.RemoveMethod.IsMetadataVirtual()); Assert.False(e7.AddMethod.IsAbstract); Assert.False(e7.RemoveMethod.IsAbstract); Assert.True(e7.AddMethod.IsStatic); Assert.True(e7.RemoveMethod.IsStatic); Assert.Null(derived.FindImplementationForInterfaceMember(e7.AddMethod)); Assert.Null(derived.FindImplementationForInterfaceMember(e7.RemoveMethod)); } [Fact] public void BaseIsNotAllowed_01() { var source1 = @" public interface I1 { void M1() { base.GetHashCode(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,9): error CS0174: A base class is required for a 'base' reference // base.GetHashCode(); Diagnostic(ErrorCode.ERR_NoBaseClass, "base").WithLocation(6, 9) ); } [Fact] public void ThisIsAllowed_01() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } int P1 { get { System.Console.WriteLine(""I1.get_P1""); return 0; } set => System.Console.WriteLine(""I1.set_P1""); } event System.Action E1 { add => System.Console.WriteLine(""I1.add_E1""); remove => System.Console.WriteLine(""I1.remove_E1""); } } public interface I2 : I1 { void M2() { System.Console.WriteLine(""I2.M2""); System.Console.WriteLine(this.GetHashCode()); this.M1(); this.P1 = this.P1; this.E1 += null; this.E1 -= null; this.M3(); this.P3 = this.P3; this.E3 += null; this.E3 -= null; } int P2 { get { System.Console.WriteLine(""I2.get_P2""); System.Console.WriteLine(this.GetHashCode()); this.M1(); this.P1 = this.P1; this.E1 += null; this.E1 -= null; this.M3(); this.P3 = this.P3; this.E3 += null; this.E3 -= null; return 0; } set { System.Console.WriteLine(""I2.set_P2""); System.Console.WriteLine(this.GetHashCode()); this.M1(); this.P1 = this.P1; this.E1 += null; this.E1 -= null; this.M3(); this.P3 = this.P3; this.E3 += null; this.E3 -= null; } } event System.Action E2 { add { System.Console.WriteLine(""I2.add_E2""); System.Console.WriteLine(this.GetHashCode()); this.M1(); this.P1 = this.P1; this.E1 += null; this.E1 -= null; this.M3(); this.P3 = this.P3; this.E3 += null; this.E3 -= null; } remove { System.Console.WriteLine(""I2.remove_E2""); System.Console.WriteLine(this.GetHashCode()); this.M1(); this.P1 = this.P1; this.E1 += null; this.E1 -= null; this.M3(); this.P3 = this.P3; this.E3 += null; this.E3 -= null; } } void M3() { System.Console.WriteLine(""I2.M3""); } int P3 { get { System.Console.WriteLine(""I2.get_P3""); return 0; } set => System.Console.WriteLine(""I2.set_P3""); } event System.Action E3 { add => System.Console.WriteLine(""I2.add_E3""); remove => System.Console.WriteLine(""I2.remove_E3""); } } class Test1 : I2 { static void Main() { I2 x = new Test1(); x.M2(); x.P2 = x.P2; x.E2 += null; x.E2 -= null; } public override int GetHashCode() { return 123; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.get_P2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.set_P2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.add_E2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.remove_E2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 ", verify: VerifyOnMonoOrCoreClr); } [Fact] public void ThisIsAllowed_02() { var source1 = @" public interface I1 { public int F1; } public interface I2 : I1 { void M2() { this.F1 = this.F2; } int P2 { get { this.F1 = this.F2; return 0; } set { this.F1 = this.F2; } } event System.Action E2 { add { this.F1 = this.F2; } remove { this.F1 = this.F2; } } public int F2; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,16): error CS0525: Interfaces cannot contain fields // public int F1; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 16), // (39,16): error CS0525: Interfaces cannot contain fields // public int F2; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F2").WithLocation(39, 16) ); } [Fact] public void ImplicitThisIsAllowed_01() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } int P1 { get { System.Console.WriteLine(""I1.get_P1""); return 0; } set => System.Console.WriteLine(""I1.set_P1""); } event System.Action E1 { add => System.Console.WriteLine(""I1.add_E1""); remove => System.Console.WriteLine(""I1.remove_E1""); } } public interface I2 : I1 { void M2() { System.Console.WriteLine(""I2.M2""); System.Console.WriteLine(GetHashCode()); M1(); P1 = P1; E1 += null; E1 -= null; M3(); P3 = P3; E3 += null; E3 -= null; } int P2 { get { System.Console.WriteLine(""I2.get_P2""); System.Console.WriteLine(GetHashCode()); M1(); P1 = P1; E1 += null; E1 -= null; M3(); P3 = P3; E3 += null; E3 -= null; return 0; } set { System.Console.WriteLine(""I2.set_P2""); System.Console.WriteLine(GetHashCode()); M1(); P1 = P1; E1 += null; E1 -= null; M3(); P3 = P3; E3 += null; E3 -= null; } } event System.Action E2 { add { System.Console.WriteLine(""I2.add_E2""); System.Console.WriteLine(GetHashCode()); M1(); P1 = P1; E1 += null; E1 -= null; M3(); P3 = P3; E3 += null; E3 -= null; } remove { System.Console.WriteLine(""I2.remove_E2""); System.Console.WriteLine(GetHashCode()); M1(); P1 = P1; E1 += null; E1 -= null; M3(); P3 = P3; E3 += null; E3 -= null; } } void M3() { System.Console.WriteLine(""I2.M3""); } int P3 { get { System.Console.WriteLine(""I2.get_P3""); return 0; } set => System.Console.WriteLine(""I2.set_P3""); } event System.Action E3 { add => System.Console.WriteLine(""I2.add_E3""); remove => System.Console.WriteLine(""I2.remove_E3""); } } class Test1 : I2 { static void Main() { I2 x = new Test1(); x.M2(); x.P2 = x.P2; x.E2 += null; x.E2 -= null; } public override int GetHashCode() { return 123; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.get_P2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.set_P2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.add_E2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 I2.remove_E2 123 I1.M1 I1.get_P1 I1.set_P1 I1.add_E1 I1.remove_E1 I2.M3 I2.get_P3 I2.set_P3 I2.add_E3 I2.remove_E3 ", verify: VerifyOnMonoOrCoreClr); } [Fact] public void ImplicitThisIsAllowed_02() { var source1 = @" public interface I1 { public int F1; } public interface I2 : I1 { void M2() { F1 = F2; } int P2 { get { F1 = F2; return 0; } set { F1 = F2; } } event System.Action E2 { add { F1 = F2; } remove { F1 = F2; } } public int F2; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,16): error CS0525: Interfaces cannot contain fields // public int F1; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 16), // (39,16): error CS0525: Interfaces cannot contain fields // public int F2; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F2").WithLocation(39, 16) ); } [Fact] public void MethodModifiers_01() { var source1 = @" public interface I1 { public void M01(); protected void M02(); protected internal void M03(); internal void M04(); private void M05(); static void M06(); virtual void M07(); sealed void M08(); override void M09(); abstract void M10(); extern void M11(); async void M12(); private protected void M13(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (12,19): error CS0106: The modifier 'override' is not valid for this item // override void M09(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "M09").WithArguments("override").WithLocation(12, 19), // (15,16): error CS1994: The 'async' modifier can only be used in methods that have a body. // async void M12(); Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M12").WithLocation(15, 16), // (8,18): error CS0501: 'I1.M05()' must declare a body because it is not marked abstract, extern, or partial // private void M05(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M05").WithArguments("I1.M05()").WithLocation(8, 18), // (9,17): error CS0501: 'I1.M06()' must declare a body because it is not marked abstract, extern, or partial // static void M06(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M06").WithArguments("I1.M06()").WithLocation(9, 17), // (10,18): error CS0501: 'I1.M07()' must declare a body because it is not marked abstract, extern, or partial // virtual void M07(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M07").WithArguments("I1.M07()").WithLocation(10, 18), // (11,17): error CS0501: 'I1.M08()' must declare a body because it is not marked abstract, extern, or partial // sealed void M08(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M08").WithArguments("I1.M08()").WithLocation(11, 17), // (14,17): warning CS0626: Method, operator, or accessor 'I1.M11()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void M11(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M11").WithArguments("I1.M11()").WithLocation(14, 17) ); ValidateSymbolsMethodModifiers_01(compilation1); } private static void ValidateSymbolsMethodModifiers_01(CSharpCompilation compilation1) { var i1 = compilation1.GetTypeByMetadataName("I1"); var m01 = i1.GetMember("M01"); Assert.True(m01.IsAbstract); Assert.False(m01.IsVirtual); Assert.True(m01.IsMetadataVirtual()); Assert.False(m01.IsSealed); Assert.False(m01.IsStatic); Assert.False(m01.IsExtern); Assert.False(m01.IsAsync); Assert.False(m01.IsOverride); Assert.Equal(Accessibility.Public, m01.DeclaredAccessibility); var m02 = i1.GetMember("M02"); Assert.True(m02.IsAbstract); Assert.False(m02.IsVirtual); Assert.True(m02.IsMetadataVirtual()); Assert.False(m02.IsSealed); Assert.False(m02.IsStatic); Assert.False(m02.IsExtern); Assert.False(m02.IsAsync); Assert.False(m02.IsOverride); Assert.Equal(Accessibility.Protected, m02.DeclaredAccessibility); var m03 = i1.GetMember("M03"); Assert.True(m03.IsAbstract); Assert.False(m03.IsVirtual); Assert.True(m03.IsMetadataVirtual()); Assert.False(m03.IsSealed); Assert.False(m03.IsStatic); Assert.False(m03.IsExtern); Assert.False(m03.IsAsync); Assert.False(m03.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, m03.DeclaredAccessibility); var m04 = i1.GetMember("M04"); Assert.True(m04.IsAbstract); Assert.False(m04.IsVirtual); Assert.True(m04.IsMetadataVirtual()); Assert.False(m04.IsSealed); Assert.False(m04.IsStatic); Assert.False(m04.IsExtern); Assert.False(m04.IsAsync); Assert.False(m04.IsOverride); Assert.Equal(Accessibility.Internal, m04.DeclaredAccessibility); var m05 = i1.GetMember("M05"); Assert.False(m05.IsAbstract); Assert.False(m05.IsVirtual); Assert.False(m05.IsMetadataVirtual()); Assert.False(m05.IsSealed); Assert.False(m05.IsStatic); Assert.False(m05.IsExtern); Assert.False(m05.IsAsync); Assert.False(m05.IsOverride); Assert.Equal(Accessibility.Private, m05.DeclaredAccessibility); var m06 = i1.GetMember("M06"); Assert.False(m06.IsAbstract); Assert.False(m06.IsVirtual); Assert.False(m06.IsMetadataVirtual()); Assert.False(m06.IsSealed); Assert.True(m06.IsStatic); Assert.False(m06.IsExtern); Assert.False(m06.IsAsync); Assert.False(m06.IsOverride); Assert.Equal(Accessibility.Public, m06.DeclaredAccessibility); var m07 = i1.GetMember("M07"); Assert.False(m07.IsAbstract); Assert.True(m07.IsVirtual); Assert.True(m07.IsMetadataVirtual()); Assert.False(m07.IsSealed); Assert.False(m07.IsStatic); Assert.False(m07.IsExtern); Assert.False(m07.IsAsync); Assert.False(m07.IsOverride); Assert.Equal(Accessibility.Public, m07.DeclaredAccessibility); var m08 = i1.GetMember("M08"); Assert.False(m08.IsAbstract); Assert.False(m08.IsVirtual); Assert.False(m08.IsMetadataVirtual()); Assert.False(m08.IsSealed); Assert.False(m08.IsStatic); Assert.False(m08.IsExtern); Assert.False(m08.IsAsync); Assert.False(m08.IsOverride); Assert.Equal(Accessibility.Public, m08.DeclaredAccessibility); var m09 = i1.GetMember("M09"); Assert.True(m09.IsAbstract); Assert.False(m09.IsVirtual); Assert.True(m09.IsMetadataVirtual()); Assert.False(m09.IsSealed); Assert.False(m09.IsStatic); Assert.False(m09.IsExtern); Assert.False(m09.IsAsync); Assert.False(m09.IsOverride); Assert.Equal(Accessibility.Public, m09.DeclaredAccessibility); var m10 = i1.GetMember("M10"); Assert.True(m10.IsAbstract); Assert.False(m10.IsVirtual); Assert.True(m10.IsMetadataVirtual()); Assert.False(m10.IsSealed); Assert.False(m10.IsStatic); Assert.False(m10.IsExtern); Assert.False(m10.IsAsync); Assert.False(m10.IsOverride); Assert.Equal(Accessibility.Public, m10.DeclaredAccessibility); var m11 = i1.GetMember("M11"); Assert.False(m11.IsAbstract); Assert.True(m11.IsVirtual); Assert.True(m11.IsMetadataVirtual()); Assert.False(m11.IsSealed); Assert.False(m11.IsStatic); Assert.True(m11.IsExtern); Assert.False(m11.IsAsync); Assert.False(m11.IsOverride); Assert.Equal(Accessibility.Public, m11.DeclaredAccessibility); var m12 = i1.GetMember("M12"); Assert.True(m12.IsAbstract); Assert.False(m12.IsVirtual); Assert.True(m12.IsMetadataVirtual()); Assert.False(m12.IsSealed); Assert.False(m12.IsStatic); Assert.False(m12.IsExtern); Assert.True(m12.IsAsync); Assert.False(m12.IsOverride); Assert.Equal(Accessibility.Public, m12.DeclaredAccessibility); var m13 = i1.GetMember("M13"); Assert.True(m13.IsAbstract); Assert.False(m13.IsVirtual); Assert.True(m13.IsMetadataVirtual()); Assert.False(m13.IsSealed); Assert.False(m13.IsStatic); Assert.False(m13.IsExtern); Assert.False(m13.IsAsync); Assert.False(m13.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, m13.DeclaredAccessibility); } [Fact] public void MethodModifiers_02() { var source1 = @" public interface I1 { public void M01(); protected void M02(); protected internal void M03(); internal void M04(); private void M05(); static void M06(); virtual void M07(); sealed void M08(); override void M09(); abstract void M10(); extern void M11(); async void M12(); private protected void M13(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,17): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public void M01(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M01").WithArguments("public", "7.3", "8.0").WithLocation(4, 17), // (5,20): error CS8703: The modifier 'protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // protected void M02(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M02").WithArguments("protected", "7.3", "8.0").WithLocation(5, 20), // (6,29): error CS8703: The modifier 'protected internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // protected internal void M03(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M03").WithArguments("protected internal", "7.3", "8.0").WithLocation(6, 29), // (7,19): error CS8503: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal void M04(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M04").WithArguments("internal", "7.3", "8.0").WithLocation(7, 19), // (8,18): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private void M05(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M05").WithArguments("private", "7.3", "8.0").WithLocation(8, 18), // (9,17): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static void M06(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M06").WithArguments("static", "7.3", "8.0").WithLocation(9, 17), // (10,18): error CS8503: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual void M07(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M07").WithArguments("virtual", "7.3", "8.0").WithLocation(10, 18), // (11,17): error CS8503: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // sealed void M08(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M08").WithArguments("sealed", "7.3", "8.0").WithLocation(11, 17), // (12,19): error CS0106: The modifier 'override' is not valid for this item // override void M09(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "M09").WithArguments("override").WithLocation(12, 19), // (13,19): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // abstract void M10(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M10").WithArguments("abstract", "7.3", "8.0").WithLocation(13, 19), // (14,17): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern void M11(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M11").WithArguments("extern", "7.3", "8.0").WithLocation(14, 17), // (15,16): error CS8503: The modifier 'async' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // async void M12(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M12").WithArguments("async", "7.3", "8.0").WithLocation(15, 16), // (15,16): error CS1994: The 'async' modifier can only be used in methods that have a body. // async void M12(); Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M12").WithLocation(15, 16), // (8,18): error CS0501: 'I1.M05()' must declare a body because it is not marked abstract, extern, or partial // private void M05(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M05").WithArguments("I1.M05()").WithLocation(8, 18), // (9,17): error CS0501: 'I1.M06()' must declare a body because it is not marked abstract, extern, or partial // static void M06(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M06").WithArguments("I1.M06()").WithLocation(9, 17), // (10,18): error CS0501: 'I1.M07()' must declare a body because it is not marked abstract, extern, or partial // virtual void M07(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M07").WithArguments("I1.M07()").WithLocation(10, 18), // (11,17): error CS0501: 'I1.M08()' must declare a body because it is not marked abstract, extern, or partial // sealed void M08(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M08").WithArguments("I1.M08()").WithLocation(11, 17), // (14,17): warning CS0626: Method, operator, or accessor 'I1.M11()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void M11(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M11").WithArguments("I1.M11()").WithLocation(14, 17), // (16,28): error CS8703: The modifier 'private protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private protected void M13(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M13").WithArguments("private protected", "7.3", "8.0").WithLocation(16, 28) ); ValidateSymbolsMethodModifiers_01(compilation1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (5,20): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected void M02(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "M02").WithLocation(5, 20), // (6,29): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal void M03(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "M03").WithLocation(6, 29), // (8,18): error CS0501: 'I1.M05()' must declare a body because it is not marked abstract, extern, or partial // private void M05(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M05").WithArguments("I1.M05()").WithLocation(8, 18), // (9,17): error CS0501: 'I1.M06()' must declare a body because it is not marked abstract, extern, or partial // static void M06(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M06").WithArguments("I1.M06()").WithLocation(9, 17), // (10,18): error CS0501: 'I1.M07()' must declare a body because it is not marked abstract, extern, or partial // virtual void M07(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M07").WithArguments("I1.M07()").WithLocation(10, 18), // (11,17): error CS0501: 'I1.M08()' must declare a body because it is not marked abstract, extern, or partial // sealed void M08(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M08").WithArguments("I1.M08()").WithLocation(11, 17), // (12,19): error CS0106: The modifier 'override' is not valid for this item // override void M09(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "M09").WithArguments("override").WithLocation(12, 19), // (14,17): error CS8701: Target runtime doesn't support default interface implementation. // extern void M11(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M11").WithLocation(14, 17), // (14,17): warning CS0626: Method, operator, or accessor 'I1.M11()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void M11(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M11").WithArguments("I1.M11()").WithLocation(14, 17), // (15,16): error CS1994: The 'async' modifier can only be used in methods that have a body. // async void M12(); Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M12").WithLocation(15, 16), // (16,28): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected void M13(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "M13").WithLocation(16, 28) ); ValidateSymbolsMethodModifiers_01(compilation2); } [Fact] [WorkItem(33083, "https://github.com/dotnet/roslyn/issues/33083")] public void MethodModifiers_03() { var source1 = @" public interface I1 { public virtual void M1() { System.Console.WriteLine(""M1""); } } "; ValidateMethodImplementation_011(source1); } [Fact] public void MethodModifiers_04() { var source1 = @" public interface I1 { public abstract void M1(); void M2(); } class Test1 : I1 { public void M1() { System.Console.WriteLine(""M1""); } public void M2() { System.Console.WriteLine(""M2""); } static void Main() { I1 x = new Test1(); x.M1(); x.M2(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: @"M1 M2", symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var methodName in new[] { "M1", "M2" }) { var m1 = i1.GetMember(methodName); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Same(test1.GetMember(methodName), test1.FindImplementationForInterfaceMember(m1)); } } } [Fact] public void MethodModifiers_05() { var source1 = @" public interface I1 { public abstract void M1(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3); compilation1.VerifyDiagnostics( // (4,26): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract void M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M1").WithArguments("abstract", "7.3", "8.0").WithLocation(4, 26), // (4,26): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract void M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M1").WithArguments("public", "7.3", "8.0").WithLocation(4, 26) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); } [Fact] public void MethodModifiers_06() { var source1 = @" public interface I1 { public static void M1() { System.Console.WriteLine(""M1""); } internal static void M2() { System.Console.WriteLine(""M2""); M3(); } private static void M3() { System.Console.WriteLine(""M3""); } } class Test1 : I1 { static void Main() { I1.M1(); I1.M2(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 M2 M3", symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var tuple in new[] { (name: "M1", access: Accessibility.Public), (name: "M2", access: Accessibility.Internal), (name: "M3", access: Accessibility.Private) }) { var m1 = i1.GetMember(tuple.name); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.True(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(tuple.access, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); } } } [Fact] public void MethodModifiers_07() { var source1 = @" public interface I1 { abstract static void M1(); virtual static void M2() { } sealed static void M3() { } static void M4() { } } class Test1 : I1 { void I1.M4() {} void I1.M1() {} void I1.M2() {} void I1.M3() {} } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (10,24): error CS0238: 'I1.M3()' cannot be sealed because it is not an override // sealed static void M3() Diagnostic(ErrorCode.ERR_SealedNonOverride, "M3").WithArguments("I1.M3()").WithLocation(10, 24), // (6,25): error CS0112: A static member 'I1.M2()' cannot be marked as override, virtual, or abstract // virtual static void M2() Diagnostic(ErrorCode.ERR_StaticNotVirtual, "M2").WithArguments("I1.M2()").WithLocation(6, 25), // (4,26): error CS0112: A static member 'I1.M1()' cannot be marked as override, virtual, or abstract // abstract static void M1(); Diagnostic(ErrorCode.ERR_StaticNotVirtual, "M1").WithArguments("I1.M1()").WithLocation(4, 26), // (21,13): error CS0539: 'Test1.M4()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M4() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M4").WithArguments("Test1.M4()").WithLocation(21, 13), // (22,13): error CS0539: 'Test1.M1()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M1() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("Test1.M1()").WithLocation(22, 13), // (23,13): error CS0539: 'Test1.M2()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M2() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M2").WithArguments("Test1.M2()").WithLocation(23, 13), // (24,13): error CS0539: 'Test1.M3()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M3() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M3").WithArguments("Test1.M3()").WithLocation(24, 13) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.True(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); var m2 = i1.GetMember("M2"); Assert.False(m2.IsAbstract); Assert.True(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.True(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Public, m2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); Assert.False(m3.IsAbstract); Assert.False(m3.IsVirtual); Assert.False(m3.IsMetadataVirtual()); Assert.True(m3.IsSealed); Assert.True(m3.IsStatic); Assert.False(m3.IsExtern); Assert.False(m3.IsAsync); Assert.False(m3.IsOverride); Assert.Equal(Accessibility.Public, m3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m3)); } [Fact] public void MethodModifiers_08() { var source1 = @" public interface I1 { private void M1() { System.Console.WriteLine(""M1""); } void M4() { System.Console.WriteLine(""M4""); M1(); } } class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M4(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M4 M1", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); var m1 = i1.GetMember("M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); } } [Fact] public void MethodModifiers_09() { var source1 = @" public interface I1 { abstract private void M1(); virtual private void M2() { } sealed private void M3() { } } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (10,25): error CS0238: 'I1.M3()' cannot be sealed because it is not an override // sealed private void M3() Diagnostic(ErrorCode.ERR_SealedNonOverride, "M3").WithArguments("I1.M3()").WithLocation(10, 25), // (6,26): error CS0621: 'I1.M2()': virtual or abstract members cannot be private // virtual private void M2() Diagnostic(ErrorCode.ERR_VirtualPrivate, "M2").WithArguments("I1.M2()").WithLocation(6, 26), // (4,27): error CS0621: 'I1.M1()': virtual or abstract members cannot be private // abstract private void M1(); Diagnostic(ErrorCode.ERR_VirtualPrivate, "M1").WithArguments("I1.M1()").WithLocation(4, 27), // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(15, 15) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); var m2 = i1.GetMember("M2"); Assert.False(m2.IsAbstract); Assert.True(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.False(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Private, m2.DeclaredAccessibility); Assert.Same(m2, test1.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); Assert.False(m3.IsAbstract); Assert.False(m3.IsVirtual); Assert.False(m3.IsMetadataVirtual()); Assert.True(m3.IsSealed); Assert.False(m3.IsStatic); Assert.False(m3.IsExtern); Assert.False(m3.IsAsync); Assert.False(m3.IsOverride); Assert.Equal(Accessibility.Private, m3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m3)); } [Fact] public void MethodModifiers_10_01() { var source1 = @" public interface I1 { internal abstract void M1(); void M2() {M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } public void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (9,15): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(9, 15) ); ValidateMethodModifiersImplicit_10(compilation1.SourceModule, Accessibility.Internal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Internal); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15) ); ValidateMethodModifiersImplicit_10(compilation3.SourceModule, Accessibility.Internal); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics( // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15) ); ValidateMethodModifiersImplicit_10(compilation4.SourceModule, Accessibility.Internal); var source3 = @" class Test2 : I1 { } "; var compilation5 = CreateCompilation(source3, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.M1()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation5, "Test2"); var compilation6 = CreateCompilation(source3, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation6.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation6.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.M1()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation6, "Test2"); } private static void ValidateI1M1NotImplemented(CSharpCompilation compilation, string className) { var test2 = compilation.GetTypeByMetadataName(className); var i1 = compilation.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.Null(test2.FindImplementationForInterfaceMember(m1)); } private static void ValidateMethodModifiersImplicit_10(ModuleSymbol m, Accessibility accessibility) { ValidateMethodModifiers_10(m, implementedByBase: false, isExplicit: false, accessibility); } private static void ValidateMethodModifiersExplicit_10(ModuleSymbol m, Accessibility accessibility) { ValidateMethodModifiers_10(m, implementedByBase: false, isExplicit: true, accessibility); } private static void ValidateMethodModifiersImplicitInTest2_10(ModuleSymbol m, Accessibility accessibility) { ValidateMethodModifiers_10(m, implementedByBase: true, isExplicit: false, accessibility); } private static void ValidateMethodModifiersExplicitInTest2_10(ModuleSymbol m, Accessibility accessibility) { ValidateMethodModifiers_10(m, implementedByBase: true, isExplicit: true, accessibility); } private static void ValidateMethodModifiers_10(ModuleSymbol m, bool implementedByBase, bool isExplicit, Accessibility accessibility) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var m1 = i1.GetMember("M1"); ValidateMethodModifiers_10(m1, accessibility); var implementation = (implementedByBase ? test1.BaseTypeNoUseSiteDiagnostics : test1).GetMember((isExplicit ? "I1." : "") + "M1"); Assert.NotNull(implementation); Assert.Same(implementation, test1.FindImplementationForInterfaceMember(m1)); var i2 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").SingleOrDefault(); Assert.Equal(implementation.IsVirtual || implementation.IsAbstract || isExplicit || (!implementedByBase && (object)i2 != null && (object)implementation == test1.FindImplementationForInterfaceMember(i2.GetMember("M1"))), implementation.IsMetadataVirtual()); } private static void ValidateMethodModifiers_10(MethodSymbol m1, Accessibility accessibility) { Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(accessibility, m1.DeclaredAccessibility); } [Fact] public void MethodModifiers_10_02() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallM1(new Test1()); } public virtual void M1() { System.Console.WriteLine(""M1""); } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.Internal, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15) ); } private void ValidateMethodModifiers_10_02(string source1, string source2, Accessibility accessibility, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); ValidateMethodModifiersImplicit_10(compilation1.SourceModule, accessibility); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), accessibility); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected); ValidateMethodModifiersImplicit_10(compilation3.SourceModule, accessibility); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(expected); ValidateMethodModifiersImplicit_10(compilation4.SourceModule, accessibility); } [Fact] public void MethodModifiers_10_03() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallM1(new Test1()); } void I1.M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: "M1", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicit_10(m, Accessibility.Internal)); ValidateMethodModifiersExplicit_10(compilation1.SourceModule, Accessibility.Internal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Internal); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics( // (9,13): error CS0122: 'I1.M1()' is inaccessible due to its protection level // void I1.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(9, 13) ); ValidateMethodModifiersExplicit_10(compilation3.SourceModule, Accessibility.Internal); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics( // (9,13): error CS0122: 'I1.M1()' is inaccessible due to its protection level // void I1.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(9, 13) ); ValidateMethodModifiersExplicit_10(compilation4.SourceModule, Accessibility.Internal); } [Fact] public void MethodModifiers_10_04() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } public class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallM1(new Test1()); } public void M1() { System.Console.WriteLine(""Test1.M1""); } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.Internal, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_10_05() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } public class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallM1(new Test1()); } public virtual void M1() { System.Console.WriteLine(""Test1.M1""); } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.Internal, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_10_06() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } public class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallM1(new Test3()); } public abstract void M1(); } class Test3 : Test1 { public override void M1() { System.Console.WriteLine(""Test3.M1""); } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.Internal, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_10_07() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } public class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallM1(new Test1()); } public void M1() { System.Console.WriteLine(""Test1.M1""); } } public interface I2 { void M1(); } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.Internal, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_10_08() { var source1 = @" public interface I1 { internal abstract void M1(); } public class TestHelper { public static void CallM1(I1 x) {x.M1();} } public class Test2 : I1 { void I1.M1() { System.Console.WriteLine(""Test2.M1""); } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallM1(new Test1()); } public virtual int M1() { System.Console.WriteLine(""Test1.M1""); return 0; } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: "Test2.M1", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicitInTest2_10(m, Accessibility.Internal)); ValidateMethodModifiersExplicitInTest2_10(compilation1.SourceModule, Accessibility.Internal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Internal); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation3, expectedOutput: "Test2.M1", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicitInTest2_10(m, Accessibility.Internal)); ValidateMethodModifiersExplicitInTest2_10(compilation3.SourceModule, Accessibility.Internal); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation4, expectedOutput: "Test2.M1", verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicitInTest2_10(m, Accessibility.Internal)); ValidateMethodModifiersExplicitInTest2_10(compilation4.SourceModule, Accessibility.Internal); } [Fact] public void MethodModifiers_10_09() { var source1 = @" public interface I1 { internal abstract void M1(); void M2() {M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } public virtual int M1() { System.Console.WriteLine(""M1""); return 0; } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (9,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(9, 15) ); ValidateI1M1NotImplemented(compilation1, "Test1"); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Internal); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation3, "Test1"); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics( // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation4, "Test1"); } [Fact] public void MethodModifiers_10_10() { var source1 = @" public interface I1 { internal abstract void M1(); } "; var source2 = @" class Test2 : I1 { public void M1() { System.Console.WriteLine(""M1""); } } class Test1 : Test2, I1 { } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (7,15): error CS8504: 'Test2' does not implement interface member 'I1.M1()'. 'Test2.M1()' cannot implicitly implement a non-public member. // class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.M1()", "Test2.M1()").WithLocation(7, 15) ); ValidateMethodModifiersImplicitInTest2_10(compilation1.SourceModule, Accessibility.Internal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Internal); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics( // (2,15): error CS8504: 'Test2' does not implement interface member 'I1.M1()'. 'Test2.M1()' cannot implicitly implement a non-public member. // class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.M1()", "Test2.M1()") ); ValidateMethodModifiersImplicitInTest2_10(compilation3.SourceModule, Accessibility.Internal); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics( // (2,15): error CS8504: 'Test2' does not implement interface member 'I1.M1()'. 'Test2.M1()' cannot implicitly implement a non-public member. // class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.M1()", "Test2.M1()") ); ValidateMethodModifiersImplicitInTest2_10(compilation4.SourceModule, Accessibility.Internal); } [Fact] public void MethodModifiers_10_11() { var source1 = @" public interface I1 { internal abstract void M1(); } public class Test2 : I1 { public void M1() { System.Console.WriteLine(""M1""); } } "; var source2 = @" class Test1 : Test2, I1 { } "; var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, assemblyName: "MethodModifiers_10_11"); compilation2.VerifyDiagnostics( // (7,22): error CS8504: 'Test2' does not implement interface member 'I1.M1()'. 'Test2.M1()' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.M1()", "Test2.M1()").WithLocation(7, 22) ); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(); ValidateMethodModifiersImplicitInTest2_10(compilation3.SourceModule, Accessibility.Internal); var compilation3Ref = compilation3.EmitToImageReference(); var compilation4 = CreateCompilation("", new[] { compilation2.ToMetadataReference(), compilation3Ref }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); ValidateMethodModifiersImplicitInTest2_10(compilation4.GetReferencedAssemblySymbol(compilation3Ref).Modules[0], Accessibility.Internal); } [Fact] public void MethodModifiers_11() { var source1 = @" public interface I1 { internal abstract void M1(); } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(7, 15) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Internal, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); } [Fact] public void MethodModifiers_12() { var source1 = @" public interface I1 { public sealed void M1() { System.Console.WriteLine(""M1""); } } class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M1(); } public void M1() { System.Console.WriteLine(""Test1.M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); var m1 = i1.GetMember("M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); } CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); } [Fact] public void MethodModifiers_13() { var source1 = @" public interface I1 { public sealed void M1() { System.Console.WriteLine(""M1""); } abstract sealed void M2(); virtual sealed void M3() { } public sealed void M4(); } class Test1 : I1 { void I1.M1() {} void I1.M2() {} void I1.M3() {} void I1.M4() {} } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (15,24): error CS0501: 'I1.M4()' must declare a body because it is not marked abstract, extern, or partial // public sealed void M4(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M4").WithArguments("I1.M4()").WithLocation(15, 24), // (9,26): error CS0238: 'I1.M2()' cannot be sealed because it is not an override // abstract sealed void M2(); Diagnostic(ErrorCode.ERR_SealedNonOverride, "M2").WithArguments("I1.M2()").WithLocation(9, 26), // (11,25): error CS0238: 'I1.M3()' cannot be sealed because it is not an override // virtual sealed void M3() Diagnostic(ErrorCode.ERR_SealedNonOverride, "M3").WithArguments("I1.M3()").WithLocation(11, 25), // (23,13): error CS0539: 'Test1.M4()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M4() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M4").WithArguments("Test1.M4()").WithLocation(23, 13), // (20,13): error CS0539: 'Test1.M1()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M1() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("Test1.M1()").WithLocation(20, 13), // (21,13): error CS0539: 'Test1.M2()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M2() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M2").WithArguments("Test1.M2()").WithLocation(21, 13), // (22,13): error CS0539: 'Test1.M3()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M3() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M3").WithArguments("Test1.M3()").WithLocation(22, 13) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); Assert.Null(test2.FindImplementationForInterfaceMember(m1)); var m2 = i1.GetMember("M2"); Assert.True(m2.IsAbstract); Assert.False(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.True(m2.IsSealed); Assert.False(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Public, m2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m2)); Assert.Null(test2.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); Assert.False(m3.IsAbstract); Assert.True(m3.IsVirtual); Assert.True(m3.IsMetadataVirtual()); Assert.True(m3.IsSealed); Assert.False(m3.IsStatic); Assert.False(m3.IsExtern); Assert.False(m3.IsAsync); Assert.False(m3.IsOverride); Assert.Equal(Accessibility.Public, m3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m3)); Assert.Null(test2.FindImplementationForInterfaceMember(m3)); var m4 = i1.GetMember("M4"); Assert.False(m4.IsAbstract); Assert.False(m4.IsVirtual); Assert.False(m4.IsMetadataVirtual()); Assert.False(m4.IsSealed); Assert.False(m4.IsStatic); Assert.False(m4.IsExtern); Assert.False(m4.IsAsync); Assert.False(m4.IsOverride); Assert.Equal(Accessibility.Public, m4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m4)); Assert.Null(test2.FindImplementationForInterfaceMember(m4)); } [Fact] public void MethodModifiers_14() { var source1 = @" public interface I1 { abstract virtual void M2(); virtual abstract void M3() { } } class Test1 : I1 { void I1.M2() {} void I1.M3() {} } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,27): error CS0500: 'I1.M3()' cannot declare a body because it is marked abstract // virtual abstract void M3() Diagnostic(ErrorCode.ERR_AbstractHasBody, "M3").WithArguments("I1.M3()").WithLocation(6, 27), // (6,27): error CS0503: The abstract method 'I1.M3()' cannot be marked virtual // virtual abstract void M3() Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "M3").WithArguments("method", "I1.M3()").WithLocation(6, 27), // (4,27): error CS0503: The abstract method 'I1.M2()' cannot be marked virtual // abstract virtual void M2(); Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "M2").WithArguments("method", "I1.M2()").WithLocation(4, 27), // (17,15): error CS0535: 'Test2' does not implement interface member 'I1.M3()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M3()").WithLocation(17, 15), // (17,15): error CS0535: 'Test2' does not implement interface member 'I1.M2()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M2()").WithLocation(17, 15) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var i1 = compilation1.GetTypeByMetadataName("I1"); foreach (var methodName in new[] { "M2", "M3" }) { var m2 = i1.GetMember(methodName); Assert.True(m2.IsAbstract); Assert.True(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.False(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Public, m2.DeclaredAccessibility); Assert.Same(test1.GetMember("I1." + methodName), test1.FindImplementationForInterfaceMember(m2)); Assert.Null(test2.FindImplementationForInterfaceMember(m2)); } } [Fact] public void MethodModifiers_15() { var source1 = @" public interface I1 { extern void M1(); virtual extern void M2(); static extern void M3(); private extern void M4(); extern sealed void M5(); } class Test1 : I1 { } class Test2 : I1 { void I1.M1() {} void I1.M2() {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test2 = m.GlobalNamespace.GetTypeMember("Test2"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); var m1 = i1.GetMember("M1"); bool isSource = !(m is PEModuleSymbol); Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.Equal(isSource, m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); Assert.Same(test2.GetMember("I1.M1"), test2.FindImplementationForInterfaceMember(m1)); var m2 = i1.GetMember("M2"); Assert.False(m2.IsAbstract); Assert.True(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.False(m2.IsStatic); Assert.Equal(isSource, m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Public, m2.DeclaredAccessibility); Assert.Same(m2, test1.FindImplementationForInterfaceMember(m2)); Assert.Same(test2.GetMember("I1.M2"), test2.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); Assert.False(m3.IsAbstract); Assert.False(m3.IsVirtual); Assert.False(m3.IsMetadataVirtual()); Assert.False(m3.IsSealed); Assert.True(m3.IsStatic); Assert.Equal(isSource, m3.IsExtern); Assert.False(m3.IsAsync); Assert.False(m3.IsOverride); Assert.Equal(Accessibility.Public, m3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m3)); Assert.Null(test2.FindImplementationForInterfaceMember(m3)); var m4 = i1.GetMember("M4"); Assert.False(m4.IsAbstract); Assert.False(m4.IsVirtual); Assert.False(m4.IsMetadataVirtual()); Assert.False(m4.IsSealed); Assert.False(m4.IsStatic); Assert.Equal(isSource, m4.IsExtern); Assert.False(m4.IsAsync); Assert.False(m4.IsOverride); Assert.Equal(Accessibility.Private, m4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m4)); Assert.Null(test2.FindImplementationForInterfaceMember(m4)); var m5 = i1.GetMember("M5"); Assert.False(m5.IsAbstract); Assert.False(m5.IsVirtual); Assert.False(m5.IsMetadataVirtual()); Assert.False(m5.IsSealed); Assert.False(m5.IsStatic); Assert.Equal(isSource, m5.IsExtern); Assert.False(m5.IsAsync); Assert.False(m5.IsOverride); Assert.Equal(Accessibility.Public, m5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m5)); Assert.Null(test2.FindImplementationForInterfaceMember(m5)); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (4,17): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern void M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M1").WithArguments("extern", "7.3", "8.0").WithLocation(4, 17), // (5,25): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern void M2(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M2").WithArguments("extern", "7.3", "8.0").WithLocation(5, 25), // (5,25): error CS8503: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern void M2(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M2").WithArguments("virtual", "7.3", "8.0").WithLocation(5, 25), // (6,24): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static extern void M3(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M3").WithArguments("static", "7.3", "8.0").WithLocation(6, 24), // (6,24): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static extern void M3(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M3").WithArguments("extern", "7.3", "8.0").WithLocation(6, 24), // (7,25): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern void M4(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M4").WithArguments("private", "7.3", "8.0").WithLocation(7, 25), // (7,25): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern void M4(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M4").WithArguments("extern", "7.3", "8.0").WithLocation(7, 25), // (8,24): error CS8503: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed void M5(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M5").WithArguments("sealed", "7.3", "8.0").WithLocation(8, 24), // (8,24): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed void M5(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M5").WithArguments("extern", "7.3", "8.0").WithLocation(8, 24), // (4,17): warning CS0626: Method, operator, or accessor 'I1.M1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void M1(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M1").WithArguments("I1.M1()").WithLocation(4, 17), // (5,25): warning CS0626: Method, operator, or accessor 'I1.M2()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern void M2(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M2").WithArguments("I1.M2()").WithLocation(5, 25), // (6,24): warning CS0626: Method, operator, or accessor 'I1.M3()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern void M3(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M3").WithArguments("I1.M3()").WithLocation(6, 24), // (7,25): warning CS0626: Method, operator, or accessor 'I1.M4()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern void M4(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M4").WithArguments("I1.M4()").WithLocation(7, 25), // (8,24): warning CS0626: Method, operator, or accessor 'I1.M5()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed void M5(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M5").WithArguments("I1.M5()").WithLocation(8, 24) ); Validate(compilation2.SourceModule); var compilation3 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (4,17): error CS8501: Target runtime doesn't support default interface implementation. // extern void M1(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(4, 17), // (5,25): error CS8501: Target runtime doesn't support default interface implementation. // virtual extern void M2(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M2").WithLocation(5, 25), // (6,24): error CS8701: Target runtime doesn't support default interface implementation. // static extern void M3(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M3").WithLocation(6, 24), // (7,25): error CS8501: Target runtime doesn't support default interface implementation. // private extern void M4(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M4").WithLocation(7, 25), // (8,24): error CS8501: Target runtime doesn't support default interface implementation. // extern sealed void M5(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M5").WithLocation(8, 24), // (4,17): warning CS0626: Method, operator, or accessor 'I1.M1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void M1(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M1").WithArguments("I1.M1()").WithLocation(4, 17), // (5,25): warning CS0626: Method, operator, or accessor 'I1.M2()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern void M2(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M2").WithArguments("I1.M2()").WithLocation(5, 25), // (6,24): warning CS0626: Method, operator, or accessor 'I1.M3()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern void M3(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M3").WithArguments("I1.M3()").WithLocation(6, 24), // (7,25): warning CS0626: Method, operator, or accessor 'I1.M4()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern void M4(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M4").WithArguments("I1.M4()").WithLocation(7, 25), // (8,24): warning CS0626: Method, operator, or accessor 'I1.M5()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed void M5(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M5").WithArguments("I1.M5()").WithLocation(8, 24) ); Validate(compilation3.SourceModule); } [Fact] public void MethodModifiers_16() { var source1 = @" public interface I1 { abstract extern void M1(); extern void M2() {} static extern void M3(); private extern void M4(); extern sealed void M5(); } class Test1 : I1 { } class Test2 : I1 { void I1.M1() {} void I1.M2() {} void I1.M3() {} void I1.M4() {} void I1.M5() {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,26): error CS0180: 'I1.M1()' cannot be both extern and abstract // abstract extern void M1(); Diagnostic(ErrorCode.ERR_AbstractAndExtern, "M1").WithArguments("I1.M1()").WithLocation(4, 26), // (5,17): error CS0179: 'I1.M2()' cannot be extern and declare a body // extern void M2() {} Diagnostic(ErrorCode.ERR_ExternHasBody, "M2").WithArguments("I1.M2()").WithLocation(5, 17), // (11,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(11, 15), // (19,13): error CS0539: 'Test2.M3()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M3() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M3").WithArguments("Test2.M3()").WithLocation(19, 13), // (20,13): error CS0539: 'Test2.M4()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M4() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M4").WithArguments("Test2.M4()").WithLocation(20, 13), // (21,13): error CS0539: 'Test2.M5()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M5() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M5").WithArguments("Test2.M5()").WithLocation(21, 13), // (6,24): warning CS0626: Method, operator, or accessor 'I1.M3()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern void M3(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M3").WithArguments("I1.M3()").WithLocation(6, 24), // (7,25): warning CS0626: Method, operator, or accessor 'I1.M4()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern void M4(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M4").WithArguments("I1.M4()").WithLocation(7, 25), // (8,24): warning CS0626: Method, operator, or accessor 'I1.M5()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed void M5(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M5").WithArguments("I1.M5()").WithLocation(8, 24) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.True(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); Assert.Same(test2.GetMember("I1.M1"), test2.FindImplementationForInterfaceMember(m1)); var m2 = i1.GetMember("M2"); Assert.False(m2.IsAbstract); Assert.True(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.False(m2.IsStatic); Assert.True(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Public, m2.DeclaredAccessibility); Assert.Same(m2, test1.FindImplementationForInterfaceMember(m2)); Assert.Same(test2.GetMember("I1.M2"), test2.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); Assert.Null(test2.FindImplementationForInterfaceMember(m3)); var m4 = i1.GetMember("M4"); Assert.Null(test2.FindImplementationForInterfaceMember(m4)); var m5 = i1.GetMember("M5"); Assert.Null(test2.FindImplementationForInterfaceMember(m5)); } [Fact] public void MethodModifiers_17() { var source1 = @" public interface I1 { abstract void M1() {} abstract private void M2() {} abstract static void M3() {} static extern void M4() {} override sealed void M5() {} } class Test1 : I1 { } class Test2 : I1 { void I1.M1() {} void I1.M2() {} void I1.M3() {} void I1.M4() {} void I1.M5() {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,19): error CS0500: 'I1.M1()' cannot declare a body because it is marked abstract // abstract void M1() {} Diagnostic(ErrorCode.ERR_AbstractHasBody, "M1").WithArguments("I1.M1()").WithLocation(4, 19), // (5,27): error CS0500: 'I1.M2()' cannot declare a body because it is marked abstract // abstract private void M2() {} Diagnostic(ErrorCode.ERR_AbstractHasBody, "M2").WithArguments("I1.M2()").WithLocation(5, 27), // (6,26): error CS0500: 'I1.M3()' cannot declare a body because it is marked abstract // abstract static void M3() {} Diagnostic(ErrorCode.ERR_AbstractHasBody, "M3").WithArguments("I1.M3()").WithLocation(6, 26), // (7,24): error CS0179: 'I1.M4()' cannot be extern and declare a body // static extern void M4() {} Diagnostic(ErrorCode.ERR_ExternHasBody, "M4").WithArguments("I1.M4()").WithLocation(7, 24), // (8,26): error CS0106: The modifier 'override' is not valid for this item // override sealed void M5() {} Diagnostic(ErrorCode.ERR_BadMemberFlag, "M5").WithArguments("override").WithLocation(8, 26), // (5,27): error CS0621: 'I1.M2()': virtual or abstract members cannot be private // abstract private void M2() {} Diagnostic(ErrorCode.ERR_VirtualPrivate, "M2").WithArguments("I1.M2()").WithLocation(5, 27), // (6,26): error CS0112: A static member 'I1.M3()' cannot be marked as override, virtual, or abstract // abstract static void M3() {} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "M3").WithArguments("I1.M3()").WithLocation(6, 26), // (11,15): error CS0535: 'Test1' does not implement interface member 'I1.M2()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M2()").WithLocation(11, 15), // (11,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(11, 15), // (18,13): error CS0122: 'I1.M2()' is inaccessible due to its protection level // void I1.M2() {} Diagnostic(ErrorCode.ERR_BadAccess, "M2").WithArguments("I1.M2()").WithLocation(18, 13), // (19,13): error CS0539: 'Test2.M3()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M3() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M3").WithArguments("Test2.M3()").WithLocation(19, 13), // (20,13): error CS0539: 'Test2.M4()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M4() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M4").WithArguments("Test2.M4()").WithLocation(20, 13), // (21,13): error CS0539: 'Test2.M5()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M5() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M5").WithArguments("Test2.M5()").WithLocation(21, 13) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); Assert.Same(test2.GetMember("I1.M1"), test2.FindImplementationForInterfaceMember(m1)); var m2 = i1.GetMember("M2"); Assert.True(m2.IsAbstract); Assert.False(m2.IsVirtual); Assert.True(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.False(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Private, m2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m2)); Assert.Same(test2.GetMember("I1.M2"), test2.FindImplementationForInterfaceMember(m2)); var m3 = i1.GetMember("M3"); Assert.True(m3.IsAbstract); Assert.False(m3.IsVirtual); Assert.True(m3.IsMetadataVirtual()); Assert.False(m3.IsSealed); Assert.True(m3.IsStatic); Assert.False(m3.IsExtern); Assert.False(m3.IsAsync); Assert.False(m3.IsOverride); Assert.Equal(Accessibility.Public, m3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m3)); Assert.Null(test2.FindImplementationForInterfaceMember(m3)); var m4 = i1.GetMember("M4"); Assert.False(m4.IsAbstract); Assert.False(m4.IsVirtual); Assert.False(m4.IsMetadataVirtual()); Assert.False(m4.IsSealed); Assert.True(m4.IsStatic); Assert.True(m4.IsExtern); Assert.False(m4.IsAsync); Assert.False(m4.IsOverride); Assert.Equal(Accessibility.Public, m4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m4)); Assert.Null(test2.FindImplementationForInterfaceMember(m4)); var m5 = i1.GetMember("M5"); Assert.False(m5.IsAbstract); Assert.False(m5.IsVirtual); Assert.False(m5.IsMetadataVirtual()); Assert.False(m5.IsSealed); Assert.False(m5.IsStatic); Assert.False(m5.IsExtern); Assert.False(m5.IsAsync); Assert.False(m5.IsOverride); Assert.Equal(Accessibility.Public, m5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m5)); Assert.Null(test2.FindImplementationForInterfaceMember(m5)); } [Fact(Skip = "https://github.com/dotnet/roslyn/issues/34658")] [WorkItem(34658, "https://github.com/dotnet/roslyn/issues/34658")] public void MethodModifiers_18() { var source1 = @" using System.Threading; using System.Threading.Tasks; public interface I1 { public static async Task M1() { await Task.Factory.StartNew(() => System.Console.WriteLine(""M1"")); } } class Test1 : I1 { static void Main() { I1.M1().Wait(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "M1", symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); var m1 = i1.GetMember("M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.True(m1.IsStatic); Assert.False(m1.IsExtern); Assert.Equal(!(m is PEModuleSymbol), m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Public, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); } } [Fact] public void MethodModifiers_20() { var source1 = @" public interface I1 { internal void M1() { System.Console.WriteLine(""M1""); } void M2() {M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var m1 = i1.GetMember("M1"); ValidateMethod(m1); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); } void ValidateMethod(MethodSymbol m1) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Internal, m1.DeclaredAccessibility); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); ValidateMethod(m1); } var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation4, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation4.SourceModule); } [Fact] public void MethodModifiers_21() { var source1 = @" public interface I1 { private static void M1() {} internal static void M2() {} public static void M3() {} static void M4() {} } class Test1 { static void Main() { I1.M1(); I1.M2(); I1.M3(); I1.M4(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (17,12): error CS0122: 'I1.M1()' is inaccessible due to its protection level // I1.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(17, 12) ); var source2 = @" class Test2 { static void Main() { I1.M1(); I1.M2(); I1.M3(); I1.M4(); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (6,12): error CS0122: 'I1.M1()' is inaccessible due to its protection level // I1.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(6, 12), // (7,12): error CS0122: 'I1.M2()' is inaccessible due to its protection level // I1.M2(); Diagnostic(ErrorCode.ERR_BadAccess, "M2").WithArguments("I1.M2()").WithLocation(7, 12) ); } [Fact] public void MethodModifiers_22() { var source1 = @" public partial interface I1 { static partial void M1(); [Test2(1)] static partial void M2(); static partial void Main() { M1(); M2(); new System.Action(M2).Invoke(); } } public partial interface I1 { [Test2(2)] static partial void M2() { System.Console.WriteLine(""M2""); } static partial void Main(); } class Test1 : I1 { } [System.AttributeUsage(System.AttributeTargets.All, AllowMultiple = true)] class Test2 : System.Attribute { public Test2(int x) {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M2 M2"); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.True(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); Assert.True(m1.IsPartialMethod()); Assert.Null(m1.PartialImplementationPart); var m2 = i1.GetMember("M2"); Assert.False(m2.IsAbstract); Assert.False(m2.IsVirtual); Assert.False(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.True(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Private, m2.DeclaredAccessibility); Assert.True(m2.IsPartialMethod()); Assert.Equal(2, m2.GetAttributes().Length); Assert.Equal("Test2(1)", m2.GetAttributes()[0].ToString()); Assert.Equal("Test2(2)", m2.GetAttributes()[1].ToString()); var m2Impl = m2.PartialImplementationPart; Assert.False(m2Impl.IsAbstract); Assert.False(m2Impl.IsVirtual); Assert.False(m2Impl.IsMetadataVirtual()); Assert.False(m2Impl.IsSealed); Assert.True(m2Impl.IsStatic); Assert.False(m2Impl.IsExtern); Assert.False(m2Impl.IsAsync); Assert.False(m2Impl.IsOverride); Assert.Equal(Accessibility.Private, m2Impl.DeclaredAccessibility); Assert.True(m2Impl.IsPartialMethod()); Assert.Same(m2, m2Impl.PartialDefinitionPart); Assert.Equal(2, m2Impl.GetAttributes().Length); Assert.Equal("Test2(1)", m2Impl.GetAttributes()[0].ToString()); Assert.Equal("Test2(2)", m2Impl.GetAttributes()[1].ToString()); } [Fact] public void MethodModifiers_23() { var source1 = @" public partial interface I1 { partial void M1(); [Test2(1)] partial void M2(); void M3() { M1(); M2(); new System.Action(M2).Invoke(); } } public partial interface I1 { [Test2(2)] partial void M2() { System.Console.WriteLine(""M2""); } } class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M3(); } } [System.AttributeUsage(System.AttributeTargets.All, AllowMultiple = true)] class Test2 : System.Attribute { public Test2(int x) {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M2 M2", verify: VerifyOnMonoOrCoreClr); var i1 = compilation1.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); Assert.True(m1.IsPartialMethod()); Assert.Null(m1.PartialImplementationPart); var m2 = i1.GetMember("M2"); Assert.False(m2.IsAbstract); Assert.False(m2.IsVirtual); Assert.False(m2.IsMetadataVirtual()); Assert.False(m2.IsSealed); Assert.False(m2.IsStatic); Assert.False(m2.IsExtern); Assert.False(m2.IsAsync); Assert.False(m2.IsOverride); Assert.Equal(Accessibility.Private, m2.DeclaredAccessibility); Assert.True(m2.IsPartialMethod()); Assert.Equal(2, m2.GetAttributes().Length); Assert.Equal("Test2(1)", m2.GetAttributes()[0].ToString()); Assert.Equal("Test2(2)", m2.GetAttributes()[1].ToString()); var m2Impl = m2.PartialImplementationPart; Assert.False(m2Impl.IsAbstract); Assert.False(m2Impl.IsVirtual); Assert.False(m2Impl.IsMetadataVirtual()); Assert.False(m2Impl.IsSealed); Assert.False(m2Impl.IsStatic); Assert.False(m2Impl.IsExtern); Assert.False(m2Impl.IsAsync); Assert.False(m2Impl.IsOverride); Assert.Equal(Accessibility.Private, m2Impl.DeclaredAccessibility); Assert.True(m2Impl.IsPartialMethod()); Assert.Same(m2, m2Impl.PartialDefinitionPart); Assert.Equal(2, m2Impl.GetAttributes().Length); Assert.Equal("Test2(1)", m2Impl.GetAttributes()[0].ToString()); Assert.Equal("Test2(2)", m2Impl.GetAttributes()[1].ToString()); } [Fact] public void MethodModifiers_24() { var source1 = @" public partial interface I1 { static partial void M1(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3); compilation1.VerifyDiagnostics( // (4,25): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static partial void M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M1").WithArguments("static", "7.3", "8.0").WithLocation(4, 25), // (4,25): error CS8703: The modifier 'partial' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static partial void M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M1").WithArguments("partial", "7.3", "8.0").WithLocation(4, 25) ); } [Fact] public void MethodModifiers_25() { var source1 = @" public partial interface I1 { partial void M1(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,18): error CS8703: The modifier 'partial' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // partial void M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "M1").WithArguments("partial", "7.3", "8.0").WithLocation(4, 18) ); } [Fact] public void MethodModifiers_26() { var source1 = @" public partial interface I1 { static partial int M1(); public static partial void M2(); internal static partial void M3(); private static partial void M4(); static partial void M5(out int x); static partial void M6(); static void M7() {} static partial void M8() {} static partial void M9(); static partial void M10(); } public partial interface I1 { static void M6() {} static partial void M7(); static partial void M8() {} static partial void M9(); static extern partial void M10(); protected static partial void M11(); protected internal static partial void M12(); private protected static partial void M13(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,24): error CS0766: Partial methods must have a void return type // static partial int M1(); Diagnostic(ErrorCode.ERR_PartialMethodMustReturnVoid, "M1").WithLocation(4, 24), // (5,32): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // public static partial void M2(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M2").WithLocation(5, 32), // (6,34): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // internal static partial void M3(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M3").WithLocation(6, 34), // (7,33): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // private static partial void M4(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M4").WithLocation(7, 33), // (8,25): error CS0752: A partial method cannot have out parameters // static partial void M5(out int x); Diagnostic(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, "M5").WithLocation(8, 25), // (11,25): error CS0759: No defining declaration found for implementing declaration of partial method 'I1.M8()' // static partial void M8() {} Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "M8").WithArguments("I1.M8()").WithLocation(11, 25), // (18,17): error CS0111: Type 'I1' already defines a member called 'M6' with the same parameter types // static void M6() {} Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M6").WithArguments("M6", "I1").WithLocation(18, 17), // (19,25): error CS0111: Type 'I1' already defines a member called 'M7' with the same parameter types // static partial void M7(); Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M7").WithArguments("M7", "I1").WithLocation(19, 25), // (20,25): error CS0757: A partial method may not have multiple implementing declarations // static partial void M8() {} Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneActual, "M8").WithLocation(20, 25), // (21,25): error CS0756: A partial method may not have multiple defining declarations // static partial void M9(); Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneLatent, "M9").WithLocation(21, 25), // (22,32): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // static extern partial void M10(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M10").WithLocation(22, 32), // (22,32): error CS0756: A partial method may not have multiple defining declarations // static extern partial void M10(); Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneLatent, "M10").WithLocation(22, 32), // (23,35): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // protected static partial void M11(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M11").WithLocation(23, 35), // (24,44): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // protected internal static partial void M12(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M12").WithLocation(24, 44), // (25,43): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // private protected static partial void M13(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M13").WithLocation(25, 43) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (4,24): error CS0766: Partial methods must have a void return type // static partial int M1(); Diagnostic(ErrorCode.ERR_PartialMethodMustReturnVoid, "M1").WithLocation(4, 24), // (5,32): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // public static partial void M2(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M2").WithLocation(5, 32), // (6,34): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // internal static partial void M3(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M3").WithLocation(6, 34), // (7,33): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // private static partial void M4(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M4").WithLocation(7, 33), // (8,25): error CS0752: A partial method cannot have out parameters // static partial void M5(out int x); Diagnostic(ErrorCode.ERR_PartialMethodCannotHaveOutParameters, "M5").WithLocation(8, 25), // (10,17): error CS8701: Target runtime doesn't support default interface implementation. // static void M7() {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M7").WithLocation(10, 17), // (11,25): error CS8701: Target runtime doesn't support default interface implementation. // static partial void M8() {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M8").WithLocation(11, 25), // (11,25): error CS0759: No defining declaration found for implementing declaration of partial method 'I1.M8()' // static partial void M8() {} Diagnostic(ErrorCode.ERR_PartialMethodMustHaveLatent, "M8").WithArguments("I1.M8()").WithLocation(11, 25), // (18,17): error CS8701: Target runtime doesn't support default interface implementation. // static void M6() {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M6").WithLocation(18, 17), // (18,17): error CS0111: Type 'I1' already defines a member called 'M6' with the same parameter types // static void M6() {} Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M6").WithArguments("M6", "I1").WithLocation(18, 17), // (19,25): error CS0111: Type 'I1' already defines a member called 'M7' with the same parameter types // static partial void M7(); Diagnostic(ErrorCode.ERR_MemberAlreadyExists, "M7").WithArguments("M7", "I1").WithLocation(19, 25), // (20,25): error CS8701: Target runtime doesn't support default interface implementation. // static partial void M8() {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M8").WithLocation(20, 25), // (20,25): error CS0757: A partial method may not have multiple implementing declarations // static partial void M8() {} Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneActual, "M8").WithLocation(20, 25), // (21,25): error CS0756: A partial method may not have multiple defining declarations // static partial void M9(); Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneLatent, "M9").WithLocation(21, 25), // (22,32): error CS8701: Target runtime doesn't support default interface implementation. // static extern partial void M10(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M10").WithLocation(22, 32), // (22,32): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // static extern partial void M10(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M10").WithLocation(22, 32), // (22,32): error CS0756: A partial method may not have multiple defining declarations // static extern partial void M10(); Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneLatent, "M10").WithLocation(22, 32), // (23,35): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // protected static partial void M11(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M11").WithLocation(23, 35), // (24,44): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // protected internal static partial void M12(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M12").WithLocation(24, 44), // (25,43): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // private protected static partial void M13(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M13").WithLocation(25, 43) ); } [Fact] public void MethodModifiers_27() { var source1 = @" partial interface I1 : I2 { sealed partial void M1(); abstract partial void M2(); virtual partial void M3(); partial void M4(); partial void M5(); partial void M6(); partial void I2.M7(); } partial interface I1 : I2 { sealed partial void M4() {} abstract partial void M5(); virtual partial void M6() {} partial void I2.M7() {} } interface I2 { void M7(); partial void M8(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,25): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // sealed partial void M1(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M1").WithLocation(4, 25), // (5,27): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // abstract partial void M2(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M2").WithLocation(5, 27), // (6,26): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // virtual partial void M3(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M3").WithLocation(6, 26), // (10,21): error CS0754: A partial method may not explicitly implement an interface method // partial void I2.M7(); Diagnostic(ErrorCode.ERR_PartialMethodNotExplicit, "M7").WithLocation(10, 21), // (15,25): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // sealed partial void M4() {} Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M4").WithLocation(15, 25), // (16,27): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // abstract partial void M5(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M5").WithLocation(16, 27), // (16,27): error CS0756: A partial method may not have multiple defining declarations // abstract partial void M5(); Diagnostic(ErrorCode.ERR_PartialMethodOnlyOneLatent, "M5").WithLocation(16, 27), // (17,26): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // virtual partial void M6() {} Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M6").WithLocation(17, 26), // (19,21): error CS0754: A partial method may not explicitly implement an interface method // partial void I2.M7() {} Diagnostic(ErrorCode.ERR_PartialMethodNotExplicit, "M7").WithLocation(19, 21), // (25,18): error CS0751: A partial method must be declared within a partial class, partial struct, or partial interface // partial void M8(); Diagnostic(ErrorCode.ERR_PartialMethodOnlyInPartialClass, "M8").WithLocation(25, 18) ); } [Fact] public void MethodModifiers_28() { var source1 = @" partial interface I1 { partial void M1(); class C : I1 { void I1.M1() {} } } public partial interface I1 { partial void M1() {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (8,17): error CS0539: 'I1.C.M1()' in explicit interface declaration is not found among members of the interface that can be implemented // void I1.M1() {} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("I1.C.M1()").WithLocation(8, 17) ); } [Fact] public void MethodModifiers_29() { var source1 = @" public partial interface I1 { partial void M1(); static partial void M2(); void M3() { new System.Action(M1).Invoke(); new System.Action(M2).Invoke(); } partial static void M4(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,27): error CS0762: Cannot create delegate from method 'I1.M1()' because it is a partial method without an implementing declaration // new System.Action(M1).Invoke(); Diagnostic(ErrorCode.ERR_PartialMethodToDelegate, "M1").WithArguments("I1.M1()").WithLocation(9, 27), // (10,27): error CS0762: Cannot create delegate from method 'I1.M2()' because it is a partial method without an implementing declaration // new System.Action(M2).Invoke(); Diagnostic(ErrorCode.ERR_PartialMethodToDelegate, "M2").WithArguments("I1.M2()").WithLocation(10, 27), // (13,5): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void' // partial static void M4(); Diagnostic(ErrorCode.ERR_PartialMisplaced, "partial").WithLocation(13, 5) ); } [Fact] public void MethodModifiers_30() { var source1 = @" public partial interface I1 { static partial void Main(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // error CS5001: Program does not contain a static 'Main' method suitable for an entry point Diagnostic(ErrorCode.ERR_NoEntryPoint).WithLocation(1, 1) ); } [Fact] public void MethodModifiers_31() { var source1 = @" public partial interface I1 { static partial void M1() where T : struct; static partial void M1() {} static partial void M2(params int[] x); static partial void M2(int[] x) {} static partial void M3(); partial void M3() {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (5,25): error CS0761: Partial method declarations of 'I1.M1()' have inconsistent constraints for type parameter 'T' // static partial void M1() {} Diagnostic(ErrorCode.ERR_PartialMethodInconsistentConstraints, "M1").WithArguments("I1.M1()", "T").WithLocation(5, 25), // (8,25): error CS0758: Both partial method declarations must use a params parameter or neither may use a params parameter // static partial void M2(int[] x) {} Diagnostic(ErrorCode.ERR_PartialMethodParamsDifference, "M2").WithLocation(8, 25), // (11,18): error CS0763: Both partial method declarations must be static or neither may be static // partial void M3() {} Diagnostic(ErrorCode.ERR_PartialMethodStaticDifference, "M3").WithLocation(11, 18) ); } [Fact] public void MethodModifiers_32() { var source1 = @" partial interface I1 { partial void M1(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation1.VerifyDiagnostics(); var source2 = @" partial interface I1 { partial void M1() {} } "; var compilation2 = CreateCompilation(source1 + source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,18): error CS8701: Target runtime doesn't support default interface implementation. // partial void M1() {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(9, 18) ); } [Fact] public void MethodModifiers_33() { var source0 = @" public interface I1 { protected static void M1() { System.Console.WriteLine(""M1""); } protected internal static void M2() { System.Console.WriteLine(""M2""); } private protected static void M3() { System.Console.WriteLine(""M3""); } } "; var source1 = @" class Test1 : I1 { static void Main() { I1.M1(); I1.M2(); I1.M3(); } } "; var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 M2 M3", symbolValidator: validate, verify: VerifyOnMonoOrCoreClr); validate(compilation1.SourceModule); var source2 = @" class Test1 { static void Main() { I1.M2(); } } "; var compilation2 = CreateCompilation(source0 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M2", verify: VerifyOnMonoOrCoreClr); var compilation3 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); var source3 = @" class Test1 : I1 { static void Main() { I1.M1(); I1.M2(); } } "; var source4 = @" class Test1 { static void Main() { I1.M1(); I1.M2(); I1.M3(); } } "; foreach (var reference in new[] { compilation3.ToMetadataReference(), compilation3.EmitToImageReference() }) { var compilation4 = CreateCompilation(source3, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 M2", verify: VerifyOnMonoOrCoreClr); var compilation5 = CreateCompilation(source4, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics( // (6,12): error CS0122: 'I1.M1()' is inaccessible due to its protection level // I1.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(6, 12), // (7,12): error CS0122: 'I1.M2()' is inaccessible due to its protection level // I1.M2(); Diagnostic(ErrorCode.ERR_BadAccess, "M2").WithArguments("I1.M2()").WithLocation(7, 12), // (8,12): error CS0122: 'I1.M3()' is inaccessible due to its protection level // I1.M3(); Diagnostic(ErrorCode.ERR_BadAccess, "M3").WithArguments("I1.M3()").WithLocation(8, 12) ); var compilation6 = CreateCompilation(source1, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation6.VerifyDiagnostics( // (8,12): error CS0122: 'I1.M3()' is inaccessible due to its protection level // I1.M3(); Diagnostic(ErrorCode.ERR_BadAccess, "M3").WithArguments("I1.M3()").WithLocation(8, 12) ); } void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var tuple in new[] { (name: "M1", access: Accessibility.Protected), (name: "M2", access: Accessibility.ProtectedOrInternal), (name: "M3", access: Accessibility.ProtectedAndInternal) }) { var m1 = i1.GetMember(tuple.name); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.True(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(tuple.access, m1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(m1)); } } } [Fact] public void MethodModifiers_34() { var source1 = @" public interface I1 { protected abstract void M1(); } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M1(); } public void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); var expected = new DiagnosticDescription[] { // (2,15): error CS8704: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15), // (7,11): error CS1540: Cannot access protected member 'I1.M1()' via a qualifier of type 'I1'; the qualifier must be of type 'Test1' (or derived from it) // x.M1(); Diagnostic(ErrorCode.ERR_BadProtectedAccess, "M1").WithArguments("I1.M1()", "I1", "Test1").WithLocation(7, 11) }; compilation1.VerifyDiagnostics(expected); ValidateMethodModifiersImplicit_10(compilation1.SourceModule, Accessibility.Protected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Protected); var source3 = @" class Test2 : I1 { } "; foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected); ValidateMethodModifiersImplicit_10(compilation3.SourceModule, Accessibility.Protected); var compilation5 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.M1()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation5, "Test2"); } } [Fact] public void MethodModifiers_35() { var source1 = @" public interface I1 { protected internal abstract void M1(); } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M1(); } public virtual void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (2,15): error CS8704: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15) ); ValidateMethodModifiersImplicit_10(compilation1.SourceModule, Accessibility.ProtectedOrInternal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.ProtectedOrInternal); var source3 = @" class Test2 : I1 { } "; foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8704: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15), // (7,11): error CS1540: Cannot access protected member 'I1.M1()' via a qualifier of type 'I1'; the qualifier must be of type 'Test1' (or derived from it) // x.M1(); Diagnostic(ErrorCode.ERR_BadProtectedAccess, "M1").WithArguments("I1.M1()", "I1", "Test1").WithLocation(7, 11) ); ValidateMethodModifiersImplicit_10(compilation3.SourceModule, Accessibility.ProtectedOrInternal); var compilation5 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.M1()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation5, "Test2"); } } [Fact] public void MethodModifiers_36() { var source1 = @" public interface I1 { private protected abstract void M1(); } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M1(); } public void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (2,15): error CS8704: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15), // (7,11): error CS1540: Cannot access protected member 'I1.M1()' via a qualifier of type 'I1'; the qualifier must be of type 'Test1' (or derived from it) // x.M1(); Diagnostic(ErrorCode.ERR_BadProtectedAccess, "M1").WithArguments("I1.M1()", "I1", "Test1").WithLocation(7, 11) ); ValidateMethodModifiersImplicit_10(compilation1.SourceModule, Accessibility.ProtectedAndInternal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.ProtectedAndInternal); var source3 = @" class Test2 : I1 { } "; foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8704: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 15), // (7,11): error CS0122: 'I1.M1()' is inaccessible due to its protection level // x.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(7, 11) ); ValidateMethodModifiersImplicit_10(compilation3.SourceModule, Accessibility.ProtectedAndInternal); var compilation5 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.M1()' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.M1()").WithLocation(2, 15) ); ValidateI1M1NotImplemented(compilation5, "Test2"); } } [Fact] public void MethodModifiers_37() { var source1 = @" public interface I1 { protected abstract void M1(); static void M2(I1 x) => x.M1(); } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); I1.M2(x); } void I1.M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicit_10(m, Accessibility.Protected)); ValidateMethodModifiersExplicit_10(compilation1.SourceModule, Accessibility.Protected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.Protected); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.StandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: "M1", symbolValidator: (m) => ValidateMethodModifiersExplicit_10(m, Accessibility.Protected)); ValidateMethodModifiersExplicit_10(compilation3.SourceModule, Accessibility.Protected); } } [Fact] public void MethodModifiers_38() { var source1 = @" public interface I1 { protected internal abstract void M1(); static void M2(I1 x) => x.M1(); } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); I1.M2(x); } void I1.M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicit_10(m, Accessibility.ProtectedOrInternal)); ValidateMethodModifiersExplicit_10(compilation1.SourceModule, Accessibility.ProtectedOrInternal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.ProtectedOrInternal); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.StandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: "M1", symbolValidator: (m) => ValidateMethodModifiersExplicit_10(m, Accessibility.ProtectedOrInternal)); ValidateMethodModifiersExplicit_10(compilation3.SourceModule, Accessibility.ProtectedOrInternal); } } [Fact] public void MethodModifiers_39() { var source1 = @" public interface I1 { private protected abstract void M1(); static void M2(I1 x) => x.M1(); } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); I1.M2(x); } void I1.M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: (m) => ValidateMethodModifiersExplicit_10(m, Accessibility.ProtectedAndInternal)); ValidateMethodModifiersExplicit_10(compilation1.SourceModule, Accessibility.ProtectedAndInternal); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); ValidateMethodModifiers_10(compilation2.GetTypeByMetadataName("I1").GetMember("M1"), Accessibility.ProtectedAndInternal); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.StandardLatest); compilation3.VerifyDiagnostics( // (10,13): error CS0122: 'I1.M1()' is inaccessible due to its protection level // void I1.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(10, 13) ); ValidateMethodModifiersExplicit_10(compilation3.SourceModule, Accessibility.ProtectedAndInternal); } } [Fact] public void MethodModifiers_40() { var source1 = @" public interface I1 { protected abstract void M1(); } public class Test2 : I1 { void I1.M1() { } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { } public void M1() { } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.Protected, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_41() { var source1 = @" public interface I1 { protected internal abstract void M1(); } public class Test2 : I1 { void I1.M1() { } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { } public void M1() { } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.ProtectedOrInternal, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_42() { var source1 = @" public interface I1 { private protected abstract void M1(); } public class Test2 : I1 { void I1.M1() { } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { } public virtual void M1() { } } "; ValidateMethodModifiers_10_02(source1, source2, Accessibility.ProtectedAndInternal, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.M1()", "Test1.M1()").WithLocation(2, 22) ); } [Fact] public void MethodModifiers_43() { var source1 = @" public interface I1 { protected void M1() { System.Console.WriteLine(""M1""); } void M2() {M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate1); validate1(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); validateMethod(m1); } foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate1); validate1(compilation3.SourceModule); } void validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var m1 = i1.GetMember("M1"); validateMethod(m1); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); } void validateMethod(MethodSymbol m1) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Protected, m1.DeclaredAccessibility); } } [Fact] public void MethodModifiers_44() { var source1 = @" public interface I1 { protected internal void M1() { System.Console.WriteLine(""M1""); } void M2() {M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate1); validate1(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); validateMethod(m1); } foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate1); validate1(compilation3.SourceModule); } void validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var m1 = i1.GetMember("M1"); validateMethod(m1); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); } void validateMethod(MethodSymbol m1) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, m1.DeclaredAccessibility); } } [Fact] public void MethodModifiers_45() { var source1 = @" public interface I1 { private protected void M1() { System.Console.WriteLine(""M1""); } void M2() {M1();} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate1); validate1(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var m1 = i1.GetMember("M1"); validateMethod(m1); } foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate1); validate1(compilation3.SourceModule); } void validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var m1 = i1.GetMember("M1"); validateMethod(m1); Assert.Same(m1, test1.FindImplementationForInterfaceMember(m1)); } void validateMethod(MethodSymbol m1) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, m1.DeclaredAccessibility); } } [Fact] public void ImplicitThisIsAllowed_03() { var source1 = @" public interface I1 { public int F1; void M1() { System.Console.WriteLine(""I1.M1""); } int P1 { get { System.Console.WriteLine(""I1.get_P1""); return 0; } set => System.Console.WriteLine(""I1.set_P1""); } event System.Action E1 { add => System.Console.WriteLine(""I1.add_E1""); remove => System.Console.WriteLine(""I1.remove_E1""); } public interface I2 : I1 { void M2() { M1(); P1 = P1; E1 += null; E1 -= null; F1 = 0; } } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,16): error CS0525: Interfaces cannot contain fields // public int F1; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 16) ); } [Fact] public void ImplicitThisIsAllowed_04() { var source1 = @" public interface I1 { public int F1; void M1() { System.Console.WriteLine(""I1.M1""); } int P1 { get { System.Console.WriteLine(""I1.get_P1""); return 0; } set => System.Console.WriteLine(""I1.set_P1""); } event System.Action E1 { add => System.Console.WriteLine(""I1.add_E1""); remove => System.Console.WriteLine(""I1.remove_E1""); } public interface I2 { void M2() { M1(); P1 = P1; E1 += null; E1 -= null; F1 = 0; } } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,16): error CS0525: Interfaces cannot contain fields // public int F1; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 16), // (31,13): error CS0120: An object reference is required for the non-static field, method, or property 'I1.M1()' // M1(); Diagnostic(ErrorCode.ERR_ObjectRequired, "M1").WithArguments("I1.M1()").WithLocation(31, 13), // (32,13): error CS0120: An object reference is required for the non-static field, method, or property 'I1.P1' // P1 = P1; Diagnostic(ErrorCode.ERR_ObjectRequired, "P1").WithArguments("I1.P1").WithLocation(32, 13), // (32,18): error CS0120: An object reference is required for the non-static field, method, or property 'I1.P1' // P1 = P1; Diagnostic(ErrorCode.ERR_ObjectRequired, "P1").WithArguments("I1.P1").WithLocation(32, 18), // (33,13): error CS0120: An object reference is required for the non-static field, method, or property 'I1.E1' // E1 += null; Diagnostic(ErrorCode.ERR_ObjectRequired, "E1").WithArguments("I1.E1").WithLocation(33, 13), // (34,13): error CS0120: An object reference is required for the non-static field, method, or property 'I1.E1' // E1 -= null; Diagnostic(ErrorCode.ERR_ObjectRequired, "E1").WithArguments("I1.E1").WithLocation(34, 13), // (35,13): error CS0120: An object reference is required for the non-static field, method, or property 'I1.F1' // F1 = 0; Diagnostic(ErrorCode.ERR_ObjectRequired, "F1").WithArguments("I1.F1").WithLocation(35, 13) ); } [Fact] public void ImplicitThisIsAllowed_05() { var source1 = @" public class C1 { public int F1; void M1() { System.Console.WriteLine(""I1.M1""); } int P1 { get { System.Console.WriteLine(""I1.get_P1""); return 0; } set => System.Console.WriteLine(""I1.set_P1""); } event System.Action E1 { add => System.Console.WriteLine(""I1.add_E1""); remove => System.Console.WriteLine(""I1.remove_E1""); } public interface I2 { void M2() { M1(); P1 = P1; E1 += null; E1 -= null; F1 = 0; } } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (31,13): error CS0120: An object reference is required for the non-static field, method, or property 'C1.M1()' // M1(); Diagnostic(ErrorCode.ERR_ObjectRequired, "M1").WithArguments("C1.M1()").WithLocation(31, 13), // (32,13): error CS0120: An object reference is required for the non-static field, method, or property 'C1.P1' // P1 = P1; Diagnostic(ErrorCode.ERR_ObjectRequired, "P1").WithArguments("C1.P1").WithLocation(32, 13), // (32,18): error CS0120: An object reference is required for the non-static field, method, or property 'C1.P1' // P1 = P1; Diagnostic(ErrorCode.ERR_ObjectRequired, "P1").WithArguments("C1.P1").WithLocation(32, 18), // (33,13): error CS0120: An object reference is required for the non-static field, method, or property 'C1.E1' // E1 += null; Diagnostic(ErrorCode.ERR_ObjectRequired, "E1").WithArguments("C1.E1").WithLocation(33, 13), // (34,13): error CS0120: An object reference is required for the non-static field, method, or property 'C1.E1' // E1 -= null; Diagnostic(ErrorCode.ERR_ObjectRequired, "E1").WithArguments("C1.E1").WithLocation(34, 13), // (35,13): error CS0120: An object reference is required for the non-static field, method, or property 'C1.F1' // F1 = 0; Diagnostic(ErrorCode.ERR_ObjectRequired, "F1").WithArguments("C1.F1").WithLocation(35, 13) ); } [Fact] public void PropertyModifiers_01() { var source1 = @" public interface I1 { public int P01 {get; set;} protected int P02 {get;} protected internal int P03 {set;} internal int P04 {get;} private int P05 {set;} static int P06 {get;} virtual int P07 {set;} sealed int P08 {get;} override int P09 {set;} abstract int P10 {get;} extern int P11 {get; set;} int P12 { public get; set;} int P13 { get; protected set;} int P14 { protected internal get; set;} int P15 { get; internal set;} int P16 { private get; set;} int P17 { private get;} private protected int P18 {get;} int P19 { get; private protected set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (8,22): error CS0501: 'I1.P05.set' must declare a body because it is not marked abstract, extern, or partial // private int P05 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P05.set").WithLocation(8, 22), // (10,22): error CS0501: 'I1.P07.set' must declare a body because it is not marked abstract, extern, or partial // virtual int P07 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P07.set").WithLocation(10, 22), // (11,21): error CS0501: 'I1.P08.get' must declare a body because it is not marked abstract, extern, or partial // sealed int P08 {get;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P08.get").WithLocation(11, 21), // (12,18): error CS0106: The modifier 'override' is not valid for this item // override int P09 {set;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 18), // (16,22): error CS0273: The accessibility modifier of the 'I1.P12.get' accessor must be more restrictive than the property or indexer 'I1.P12' // int P12 { public get; set;} Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "get").WithArguments("I1.P12.get", "I1.P12").WithLocation(16, 22), // (20,23): error CS0442: 'I1.P16.get': abstract properties cannot have private accessors // int P16 { private get; set;} Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I1.P16.get").WithLocation(20, 23), // (21,9): error CS0276: 'I1.P17': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int P17 { private get;} Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P17").WithArguments("I1.P17").WithLocation(21, 9), // (14,21): warning CS0626: Method, operator, or accessor 'I1.P11.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.P11.get").WithLocation(14, 21), // (14,26): warning CS0626: Method, operator, or accessor 'I1.P11.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I1.P11.set").WithLocation(14, 26) ); ValidateSymbolsPropertyModifiers_01(compilation1); } private static void ValidateSymbolsPropertyModifiers_01(CSharpCompilation compilation1) { var i1 = compilation1.GetTypeByMetadataName("I1"); var p01 = i1.GetMember("P01"); Assert.True(p01.IsAbstract); Assert.False(p01.IsVirtual); Assert.False(p01.IsSealed); Assert.False(p01.IsStatic); Assert.False(p01.IsExtern); Assert.False(p01.IsOverride); Assert.Equal(Accessibility.Public, p01.DeclaredAccessibility); VaidateP01Accessor(p01.GetMethod); VaidateP01Accessor(p01.SetMethod); void VaidateP01Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p02 = i1.GetMember("P02"); var p02get = p02.GetMethod; Assert.True(p02.IsAbstract); Assert.False(p02.IsVirtual); Assert.False(p02.IsSealed); Assert.False(p02.IsStatic); Assert.False(p02.IsExtern); Assert.False(p02.IsOverride); Assert.Equal(Accessibility.Protected, p02.DeclaredAccessibility); Assert.True(p02get.IsAbstract); Assert.False(p02get.IsVirtual); Assert.True(p02get.IsMetadataVirtual()); Assert.False(p02get.IsSealed); Assert.False(p02get.IsStatic); Assert.False(p02get.IsExtern); Assert.False(p02get.IsAsync); Assert.False(p02get.IsOverride); Assert.Equal(Accessibility.Protected, p02get.DeclaredAccessibility); var p03 = i1.GetMember("P03"); var p03set = p03.SetMethod; Assert.True(p03.IsAbstract); Assert.False(p03.IsVirtual); Assert.False(p03.IsSealed); Assert.False(p03.IsStatic); Assert.False(p03.IsExtern); Assert.False(p03.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, p03.DeclaredAccessibility); Assert.True(p03set.IsAbstract); Assert.False(p03set.IsVirtual); Assert.True(p03set.IsMetadataVirtual()); Assert.False(p03set.IsSealed); Assert.False(p03set.IsStatic); Assert.False(p03set.IsExtern); Assert.False(p03set.IsAsync); Assert.False(p03set.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, p03set.DeclaredAccessibility); var p04 = i1.GetMember("P04"); var p04get = p04.GetMethod; Assert.True(p04.IsAbstract); Assert.False(p04.IsVirtual); Assert.False(p04.IsSealed); Assert.False(p04.IsStatic); Assert.False(p04.IsExtern); Assert.False(p04.IsOverride); Assert.Equal(Accessibility.Internal, p04.DeclaredAccessibility); Assert.True(p04get.IsAbstract); Assert.False(p04get.IsVirtual); Assert.True(p04get.IsMetadataVirtual()); Assert.False(p04get.IsSealed); Assert.False(p04get.IsStatic); Assert.False(p04get.IsExtern); Assert.False(p04get.IsAsync); Assert.False(p04get.IsOverride); Assert.Equal(Accessibility.Internal, p04get.DeclaredAccessibility); var p05 = i1.GetMember("P05"); var p05set = p05.SetMethod; Assert.False(p05.IsAbstract); Assert.False(p05.IsVirtual); Assert.False(p05.IsSealed); Assert.False(p05.IsStatic); Assert.False(p05.IsExtern); Assert.False(p05.IsOverride); Assert.Equal(Accessibility.Private, p05.DeclaredAccessibility); Assert.False(p05set.IsAbstract); Assert.False(p05set.IsVirtual); Assert.False(p05set.IsMetadataVirtual()); Assert.False(p05set.IsSealed); Assert.False(p05set.IsStatic); Assert.False(p05set.IsExtern); Assert.False(p05set.IsAsync); Assert.False(p05set.IsOverride); Assert.Equal(Accessibility.Private, p05set.DeclaredAccessibility); var p06 = i1.GetMember("P06"); var p06get = p06.GetMethod; Assert.False(p06.IsAbstract); Assert.False(p06.IsVirtual); Assert.False(p06.IsSealed); Assert.True(p06.IsStatic); Assert.False(p06.IsExtern); Assert.False(p06.IsOverride); Assert.Equal(Accessibility.Public, p06.DeclaredAccessibility); Assert.False(p06get.IsAbstract); Assert.False(p06get.IsVirtual); Assert.False(p06get.IsMetadataVirtual()); Assert.False(p06get.IsSealed); Assert.True(p06get.IsStatic); Assert.False(p06get.IsExtern); Assert.False(p06get.IsAsync); Assert.False(p06get.IsOverride); Assert.Equal(Accessibility.Public, p06get.DeclaredAccessibility); var p07 = i1.GetMember("P07"); var p07set = p07.SetMethod; Assert.False(p07.IsAbstract); Assert.True(p07.IsVirtual); Assert.False(p07.IsSealed); Assert.False(p07.IsStatic); Assert.False(p07.IsExtern); Assert.False(p07.IsOverride); Assert.Equal(Accessibility.Public, p07.DeclaredAccessibility); Assert.False(p07set.IsAbstract); Assert.True(p07set.IsVirtual); Assert.True(p07set.IsMetadataVirtual()); Assert.False(p07set.IsSealed); Assert.False(p07set.IsStatic); Assert.False(p07set.IsExtern); Assert.False(p07set.IsAsync); Assert.False(p07set.IsOverride); Assert.Equal(Accessibility.Public, p07set.DeclaredAccessibility); var p08 = i1.GetMember("P08"); var p08get = p08.GetMethod; Assert.False(p08.IsAbstract); Assert.False(p08.IsVirtual); Assert.False(p08.IsSealed); Assert.False(p08.IsStatic); Assert.False(p08.IsExtern); Assert.False(p08.IsOverride); Assert.Equal(Accessibility.Public, p08.DeclaredAccessibility); Assert.False(p08get.IsAbstract); Assert.False(p08get.IsVirtual); Assert.False(p08get.IsMetadataVirtual()); Assert.False(p08get.IsSealed); Assert.False(p08get.IsStatic); Assert.False(p08get.IsExtern); Assert.False(p08get.IsAsync); Assert.False(p08get.IsOverride); Assert.Equal(Accessibility.Public, p08get.DeclaredAccessibility); var p09 = i1.GetMember("P09"); var p09set = p09.SetMethod; Assert.True(p09.IsAbstract); Assert.False(p09.IsVirtual); Assert.False(p09.IsSealed); Assert.False(p09.IsStatic); Assert.False(p09.IsExtern); Assert.False(p09.IsOverride); Assert.Equal(Accessibility.Public, p09.DeclaredAccessibility); Assert.True(p09set.IsAbstract); Assert.False(p09set.IsVirtual); Assert.True(p09set.IsMetadataVirtual()); Assert.False(p09set.IsSealed); Assert.False(p09set.IsStatic); Assert.False(p09set.IsExtern); Assert.False(p09set.IsAsync); Assert.False(p09set.IsOverride); Assert.Equal(Accessibility.Public, p09set.DeclaredAccessibility); var p10 = i1.GetMember("P10"); var p10get = p10.GetMethod; Assert.True(p10.IsAbstract); Assert.False(p10.IsVirtual); Assert.False(p10.IsSealed); Assert.False(p10.IsStatic); Assert.False(p10.IsExtern); Assert.False(p10.IsOverride); Assert.Equal(Accessibility.Public, p10.DeclaredAccessibility); Assert.True(p10get.IsAbstract); Assert.False(p10get.IsVirtual); Assert.True(p10get.IsMetadataVirtual()); Assert.False(p10get.IsSealed); Assert.False(p10get.IsStatic); Assert.False(p10get.IsExtern); Assert.False(p10get.IsAsync); Assert.False(p10get.IsOverride); Assert.Equal(Accessibility.Public, p10get.DeclaredAccessibility); var p11 = i1.GetMember("P11"); Assert.False(p11.IsAbstract); Assert.True(p11.IsVirtual); Assert.False(p11.IsSealed); Assert.False(p11.IsStatic); Assert.True(p11.IsExtern); Assert.False(p11.IsOverride); Assert.Equal(Accessibility.Public, p11.DeclaredAccessibility); ValidateP11Accessor(p11.GetMethod); ValidateP11Accessor(p11.SetMethod); void ValidateP11Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p12 = i1.GetMember("P12"); Assert.True(p12.IsAbstract); Assert.False(p12.IsVirtual); Assert.False(p12.IsSealed); Assert.False(p12.IsStatic); Assert.False(p12.IsExtern); Assert.False(p12.IsOverride); Assert.Equal(Accessibility.Public, p12.DeclaredAccessibility); ValidateP12Accessor(p12.GetMethod); ValidateP12Accessor(p12.SetMethod); void ValidateP12Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p13 = i1.GetMember("P13"); Assert.True(p13.IsAbstract); Assert.False(p13.IsVirtual); Assert.False(p13.IsSealed); Assert.False(p13.IsStatic); Assert.False(p13.IsExtern); Assert.False(p13.IsOverride); Assert.Equal(Accessibility.Public, p13.DeclaredAccessibility); ValidateP13Accessor(p13.GetMethod, Accessibility.Public); ValidateP13Accessor(p13.SetMethod, Accessibility.Protected); void ValidateP13Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p14 = i1.GetMember("P14"); Assert.True(p14.IsAbstract); Assert.False(p14.IsVirtual); Assert.False(p14.IsSealed); Assert.False(p14.IsStatic); Assert.False(p14.IsExtern); Assert.False(p14.IsOverride); Assert.Equal(Accessibility.Public, p14.DeclaredAccessibility); ValidateP14Accessor(p14.GetMethod, Accessibility.ProtectedOrInternal); ValidateP14Accessor(p14.SetMethod, Accessibility.Public); void ValidateP14Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p15 = i1.GetMember("P15"); Assert.True(p15.IsAbstract); Assert.False(p15.IsVirtual); Assert.False(p15.IsSealed); Assert.False(p15.IsStatic); Assert.False(p15.IsExtern); Assert.False(p15.IsOverride); Assert.Equal(Accessibility.Public, p15.DeclaredAccessibility); ValidateP15Accessor(p15.GetMethod, Accessibility.Public); ValidateP15Accessor(p15.SetMethod, Accessibility.Internal); void ValidateP15Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p16 = i1.GetMember("P16"); Assert.True(p16.IsAbstract); Assert.False(p16.IsVirtual); Assert.False(p16.IsSealed); Assert.False(p16.IsStatic); Assert.False(p16.IsExtern); Assert.False(p16.IsOverride); Assert.Equal(Accessibility.Public, p16.DeclaredAccessibility); ValidateP16Accessor(p16.GetMethod, Accessibility.Private); ValidateP16Accessor(p16.SetMethod, Accessibility.Public); void ValidateP16Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p17 = i1.GetMember("P17"); var p17get = p17.GetMethod; Assert.True(p17.IsAbstract); Assert.False(p17.IsVirtual); Assert.False(p17.IsSealed); Assert.False(p17.IsStatic); Assert.False(p17.IsExtern); Assert.False(p17.IsOverride); Assert.Equal(Accessibility.Public, p17.DeclaredAccessibility); Assert.True(p17get.IsAbstract); Assert.False(p17get.IsVirtual); Assert.True(p17get.IsMetadataVirtual()); Assert.False(p17get.IsSealed); Assert.False(p17get.IsStatic); Assert.False(p17get.IsExtern); Assert.False(p17get.IsAsync); Assert.False(p17get.IsOverride); Assert.Equal(Accessibility.Private, p17get.DeclaredAccessibility); var p18 = i1.GetMember("P18"); var p18get = p18.GetMethod; Assert.True(p18.IsAbstract); Assert.False(p18.IsVirtual); Assert.False(p18.IsSealed); Assert.False(p18.IsStatic); Assert.False(p18.IsExtern); Assert.False(p18.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, p18.DeclaredAccessibility); Assert.True(p18get.IsAbstract); Assert.False(p18get.IsVirtual); Assert.True(p18get.IsMetadataVirtual()); Assert.False(p18get.IsSealed); Assert.False(p18get.IsStatic); Assert.False(p18get.IsExtern); Assert.False(p18get.IsAsync); Assert.False(p18get.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, p18get.DeclaredAccessibility); var p19 = i1.GetMember("P19"); Assert.True(p19.IsAbstract); Assert.False(p19.IsVirtual); Assert.False(p19.IsSealed); Assert.False(p19.IsStatic); Assert.False(p19.IsExtern); Assert.False(p19.IsOverride); Assert.Equal(Accessibility.Public, p19.DeclaredAccessibility); ValidateP13Accessor(p19.GetMethod, Accessibility.Public); ValidateP13Accessor(p19.SetMethod, Accessibility.ProtectedAndInternal); } [Fact] public void PropertyModifiers_02() { var source1 = @" public interface I1 { public int P01 {get; set;} protected int P02 {get;} protected internal int P03 {set;} internal int P04 {get;} private int P05 {set;} static int P06 {get;} virtual int P07 {set;} sealed int P08 {get;} override int P09 {set;} abstract int P10 {get;} extern int P11 {get; set;} int P12 { public get; set;} int P13 { get; protected set;} int P14 { protected internal get; set;} int P15 { get; internal set;} int P16 { private get; set;} int P17 { private get;} private protected int P18 {get;} int P19 { get; private protected set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,16): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public int P01 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P01").WithArguments("public", "7.3", "8.0").WithLocation(4, 16), // (5,19): error CS8703: The modifier 'protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // protected int P02 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P02").WithArguments("protected", "7.3", "8.0").WithLocation(5, 19), // (6,28): error CS8703: The modifier 'protected internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // protected internal int P03 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P03").WithArguments("protected internal", "7.3", "8.0").WithLocation(6, 28), // (7,18): error CS8503: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal int P04 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P04").WithArguments("internal", "7.3", "8.0").WithLocation(7, 18), // (8,17): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private int P05 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P05").WithArguments("private", "7.3", "8.0").WithLocation(8, 17), // (8,22): error CS0501: 'I1.P05.set' must declare a body because it is not marked abstract, extern, or partial // private int P05 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P05.set").WithLocation(8, 22), // (9,16): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static int P06 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P06").WithArguments("static", "7.3", "8.0").WithLocation(9, 16), // (9,21): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int P06 {get;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 21), // (10,17): error CS8503: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual int P07 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P07").WithArguments("virtual", "7.3", "8.0").WithLocation(10, 17), // (10,22): error CS0501: 'I1.P07.set' must declare a body because it is not marked abstract, extern, or partial // virtual int P07 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P07.set").WithLocation(10, 22), // (11,16): error CS8503: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // sealed int P08 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P08").WithArguments("sealed", "7.3", "8.0").WithLocation(11, 16), // (11,21): error CS0501: 'I1.P08.get' must declare a body because it is not marked abstract, extern, or partial // sealed int P08 {get;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P08.get").WithLocation(11, 21), // (12,18): error CS0106: The modifier 'override' is not valid for this item // override int P09 {set;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 18), // (13,18): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // abstract int P10 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P10").WithArguments("abstract", "7.3", "8.0").WithLocation(13, 18), // (14,16): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern int P11 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P11").WithArguments("extern", "7.3", "8.0").WithLocation(14, 16), // (16,22): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P12 { public get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("public", "7.3", "8.0").WithLocation(16, 22), // (16,22): error CS0273: The accessibility modifier of the 'I1.P12.get' accessor must be more restrictive than the property or indexer 'I1.P12' // int P12 { public get; set;} Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "get").WithArguments("I1.P12.get", "I1.P12").WithLocation(16, 22), // (17,30): error CS8703: The modifier 'protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P13 { get; protected set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("protected", "7.3", "8.0").WithLocation(17, 30), // (18,34): error CS8703: The modifier 'protected internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P14 { protected internal get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("protected internal", "7.3", "8.0").WithLocation(18, 34), // (19,29): error CS8503: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P15 { get; internal set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("internal", "7.3", "8.0").WithLocation(19, 29), // (20,23): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P16 { private get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("private", "7.3", "8.0").WithLocation(20, 23), // (20,23): error CS0442: 'I1.P16.get': abstract properties cannot have private accessors // int P16 { private get; set;} Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I1.P16.get").WithLocation(20, 23), // (21,23): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P17 { private get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("private", "7.3", "8.0").WithLocation(21, 23), // (21,9): error CS0276: 'I1.P17': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int P17 { private get;} Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P17").WithArguments("I1.P17").WithLocation(21, 9), // (23,27): error CS8703: The modifier 'private protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private protected int P18 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P18").WithArguments("private protected", "7.3", "8.0").WithLocation(23, 27), // (24,38): error CS8703: The modifier 'private protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // int P19 { get; private protected set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("private protected", "7.3", "8.0").WithLocation(24, 38), // (14,21): warning CS0626: Method, operator, or accessor 'I1.P11.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.P11.get").WithLocation(14, 21), // (14,26): warning CS0626: Method, operator, or accessor 'I1.P11.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I1.P11.set").WithLocation(14, 26) ); ValidateSymbolsPropertyModifiers_01(compilation1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (5,19): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected int P02 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P02").WithLocation(5, 19), // (6,28): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal int P03 {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P03").WithLocation(6, 28), // (8,22): error CS0501: 'I1.P05.set' must declare a body because it is not marked abstract, extern, or partial // private int P05 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P05.set").WithLocation(8, 22), // (9,21): error CS8701: Target runtime doesn't support default interface implementation. // static int P06 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 21), // (10,22): error CS0501: 'I1.P07.set' must declare a body because it is not marked abstract, extern, or partial // virtual int P07 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.P07.set").WithLocation(10, 22), // (11,21): error CS0501: 'I1.P08.get' must declare a body because it is not marked abstract, extern, or partial // sealed int P08 {get;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P08.get").WithLocation(11, 21), // (12,18): error CS0106: The modifier 'override' is not valid for this item // override int P09 {set;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 18), // (14,21): error CS8701: Target runtime doesn't support default interface implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(14, 21), // (14,21): warning CS0626: Method, operator, or accessor 'I1.P11.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.P11.get").WithLocation(14, 21), // (14,26): error CS8701: Target runtime doesn't support default interface implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(14, 26), // (14,26): warning CS0626: Method, operator, or accessor 'I1.P11.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P11 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I1.P11.set").WithLocation(14, 26), // (16,22): error CS0273: The accessibility modifier of the 'I1.P12.get' accessor must be more restrictive than the property or indexer 'I1.P12' // int P12 { public get; set;} Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "get").WithArguments("I1.P12.get", "I1.P12").WithLocation(16, 22), // (17,30): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // int P13 { get; protected set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "set").WithLocation(17, 30), // (18,34): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // int P14 { protected internal get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "get").WithLocation(18, 34), // (20,23): error CS0442: 'I1.P16.get': abstract properties cannot have private accessors // int P16 { private get; set;} Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I1.P16.get").WithLocation(20, 23), // (21,9): error CS0276: 'I1.P17': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int P17 { private get;} Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P17").WithArguments("I1.P17").WithLocation(21, 9), // (23,27): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected int P18 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P18").WithLocation(23, 27), // (24,38): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // int P19 { get; private protected set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "set").WithLocation(24, 38) ); ValidateSymbolsPropertyModifiers_01(compilation2); } [Fact] public void PropertyModifiers_03() { ValidatePropertyImplementation_101(@" public interface I1 { public virtual int P1 { get { System.Console.WriteLine(""get P1""); return 0; } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "); ValidatePropertyImplementation_101(@" public interface I1 { public virtual int P1 { get => Test1.GetP1(); } } class Test1 : I1 { public static int GetP1() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "); ValidatePropertyImplementation_101(@" public interface I1 { public virtual int P1 => Test1.GetP1(); } class Test1 : I1 { public static int GetP1() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "); ValidatePropertyImplementation_102(@" public interface I1 { public virtual int P1 { get { System.Console.WriteLine(""get P1""); return 0; } set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.P1 = i1.P1; } } "); ValidatePropertyImplementation_102(@" public interface I1 { public virtual int P1 { get => Test1.GetP1(); set => System.Console.WriteLine(""set P1""); } } class Test1 : I1 { public static int GetP1() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); i1.P1 = i1.P1; } } "); ValidatePropertyImplementation_103(@" public interface I1 { public virtual int P1 { set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } } "); ValidatePropertyImplementation_103(@" public interface I1 { public virtual int P1 { set => System.Console.WriteLine(""set P1""); } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } } "); } [Fact] public void PropertyModifiers_04() { var source1 = @" public interface I1 { public virtual int P1 { get; } = 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( // (4,24): error CS8050: Only auto-implemented properties can have initializers. // public virtual int P1 { get; } = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 24), // (4,29): error CS0501: 'I1.P1.get' must declare a body because it is not marked abstract, extern, or partial // public virtual int P1 { get; } = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P1.get").WithLocation(4, 29) ); ValidatePropertyModifiers_04(compilation1, "P1"); } private static void ValidatePropertyModifiers_04(CSharpCompilation compilation1, string propertyName) { var i1 = compilation1.GlobalNamespace.GetTypeMember("I1"); var p1 = i1.GetMember(propertyName); var p1get = p1.GetMethod; Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.False(p1get.IsAbstract); Assert.True(p1get.IsVirtual); Assert.True(p1get.IsMetadataVirtual()); Assert.False(p1get.IsSealed); Assert.False(p1get.IsStatic); Assert.False(p1get.IsExtern); Assert.False(p1get.IsAsync); Assert.False(p1get.IsOverride); Assert.Equal(Accessibility.Public, p1get.DeclaredAccessibility); } [Fact] public void PropertyModifiers_05() { var source1 = @" public interface I1 { public abstract int P1 {get; set;} } public interface I2 { int P2 {get; set;} } class Test1 : I1 { public int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set => System.Console.WriteLine(""set_P1""); } } class Test2 : I2 { public int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } set => System.Console.WriteLine(""set_P2""); } static void Main() { I1 x = new Test1(); x.P1 = x.P1; I2 y = new Test2(); y.P2 = y.P2; } } "; ValidatePropertyModifiers_05(source1); } private void ValidatePropertyModifiers_05(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: @"get_P1 set_P1 get_P2 set_P2", symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { for (int i = 1; i <= 2; i++) { var test1 = m.GlobalNamespace.GetTypeMember("Test" + i); var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleProperty(i1); var test1P1 = GetSingleProperty(test1); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Same(test1P1, test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor(p1.GetMethod, test1P1.GetMethod); ValidateAccessor(p1.SetMethod, test1P1.SetMethod); void ValidateAccessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(implementation, test1.FindImplementationForInterfaceMember(accessor)); } } } } private static PropertySymbol GetSingleProperty(NamedTypeSymbol container) { return container.GetMembers().OfType().Single(); } private static PropertySymbol GetSingleProperty(CSharpCompilation compilation, string containerName) { return GetSingleProperty(compilation.GetTypeByMetadataName(containerName)); } private static PropertySymbol GetSingleProperty(ModuleSymbol m, string containerName) { return GetSingleProperty(m.GlobalNamespace.GetTypeMember(containerName)); } [Fact] public void PropertyModifiers_06() { var source1 = @" public interface I1 { public abstract int P1 {get; set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3); compilation1.VerifyDiagnostics( // (4,25): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract int P1 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P1").WithArguments("abstract", "7.3", "8.0").WithLocation(4, 25), // (4,25): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract int P1 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P1").WithArguments("public", "7.3", "8.0").WithLocation(4, 25) ); ValidatePropertyModifiers_06(compilation1, "P1"); } private static void ValidatePropertyModifiers_06(CSharpCompilation compilation1, string propertyName) { var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember(propertyName); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); ValidateAccessor(p1.GetMethod); ValidateAccessor(p1.SetMethod); void ValidateAccessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } } [Fact] public void PropertyModifiers_07() { var source1 = @" public interface I1 { public static int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } internal static int P2 { get { System.Console.WriteLine(""get_P2""); return P3; } set { System.Console.WriteLine(""set_P2""); P3 = value; } } private static int P3 { get => Test1.GetP3(); set => System.Console.WriteLine(""set_P3""); } internal static int P4 => Test1.GetP4(); internal static int P5 { get { System.Console.WriteLine(""get_P5""); return 0; } } internal static int P6 { get => Test1.GetP6(); } internal static int P7 { set { System.Console.WriteLine(""set_P7""); } } internal static int P8 { set => System.Console.WriteLine(""set_P8""); } } class Test1 : I1 { static void Main() { I1.P1 = I1.P1; I1.P2 = I1.P2; var x = I1.P4; x = I1.P5; x = I1.P6; I1.P7 = x; I1.P8 = x; } public static int GetP3() { System.Console.WriteLine(""get_P3""); return 0; } public static int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } public static int GetP6() { System.Console.WriteLine(""get_P6""); return 0; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 get_P3 set_P2 set_P3 get_P4 get_P5 get_P6 set_P7 set_P8", symbolValidator: Validate); Validate(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (6,9): error CS8701: Target runtime doesn't support default interface implementation. // get Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 9), // (11,9): error CS8701: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(11, 9), // (19,9): error CS8701: Target runtime doesn't support default interface implementation. // get Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(19, 9), // (24,9): error CS8701: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(24, 9), // (33,9): error CS8701: Target runtime doesn't support default interface implementation. // get => Test1.GetP3(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(33, 9), // (34,9): error CS8701: Target runtime doesn't support default interface implementation. // set => System.Console.WriteLine("set_P3"); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(34, 9), // (37,31): error CS8701: Target runtime doesn't support default interface implementation. // internal static int P4 => Test1.GetP4(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "Test1.GetP4()").WithLocation(37, 31), // (41,9): error CS8701: Target runtime doesn't support default interface implementation. // get Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(41, 9), // (50,9): error CS8701: Target runtime doesn't support default interface implementation. // get => Test1.GetP6(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(50, 9), // (55,9): error CS8701: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(55, 9), // (63,9): error CS8701: Target runtime doesn't support default interface implementation. // set => System.Console.WriteLine("set_P8"); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(63, 9) ); Validate(compilation2.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var tuple in new[] { (name: "P1", access: Accessibility.Public), (name: "P2", access: Accessibility.Internal), (name: "P3", access: Accessibility.Private), (name: "P4", access: Accessibility.Internal), (name: "P5", access: Accessibility.Internal), (name: "P6", access: Accessibility.Internal), (name: "P7", access: Accessibility.Internal), (name: "P8", access: Accessibility.Internal)}) { var p1 = i1.GetMember(tuple.name); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.True(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(tuple.access, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); switch (tuple.name) { case "P7": case "P8": Assert.Null(p1.GetMethod); ValidateAccessor(p1.SetMethod); break; case "P4": case "P5": case "P6": Assert.Null(p1.SetMethod); ValidateAccessor(p1.GetMethod); break; default: ValidateAccessor(p1.GetMethod); ValidateAccessor(p1.SetMethod); break; } void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(tuple.access, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } } [Fact] public void PropertyModifiers_08() { var source1 = @" public interface I1 { abstract static int P1 {get;} virtual static int P2 {set {}} sealed static int P3 => 0; static int P4 {get;} = 0; } class Test1 : I1 { int I1.P1 => 0; int I1.P2 {set {}} int I1.P3 => 0; int I1.P4 {set {}} } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,25): error CS0112: A static member 'I1.P1' cannot be marked as override, virtual, or abstract // abstract static int P1 {get;} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P1").WithArguments("I1.P1").WithLocation(4, 25), // (6,24): error CS0112: A static member 'I1.P2' cannot be marked as override, virtual, or abstract // virtual static int P2 {set {}} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P2").WithArguments("I1.P2").WithLocation(6, 24), // (8,23): error CS0238: 'I1.P3' cannot be sealed because it is not an override // sealed static int P3 => 0; Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I1.P3").WithLocation(8, 23), // (15,12): error CS0539: 'Test1.P1' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.P1 => 0; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("Test1.P1").WithLocation(15, 12), // (16,12): error CS0539: 'Test1.P2' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.P2 {set {}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P2").WithArguments("Test1.P2").WithLocation(16, 12), // (17,12): error CS0539: 'Test1.P3' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.P3 => 0; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test1.P3").WithLocation(17, 12), // (18,12): error CS0539: 'Test1.P4' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.P4 {set {}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P4").WithArguments("Test1.P4").WithLocation(18, 12) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember("P1"); var p1get = p1.GetMethod; Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.True(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.True(p1get.IsAbstract); Assert.False(p1get.IsVirtual); Assert.True(p1get.IsMetadataVirtual()); Assert.False(p1get.IsSealed); Assert.True(p1get.IsStatic); Assert.False(p1get.IsExtern); Assert.False(p1get.IsAsync); Assert.False(p1get.IsOverride); Assert.Equal(Accessibility.Public, p1get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1get)); var p2 = i1.GetMember("P2"); var p2set = p2.SetMethod; Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.True(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.False(p2set.IsAbstract); Assert.True(p2set.IsVirtual); Assert.True(p2set.IsMetadataVirtual()); Assert.False(p2set.IsSealed); Assert.True(p2set.IsStatic); Assert.False(p2set.IsExtern); Assert.False(p2set.IsAsync); Assert.False(p2set.IsOverride); Assert.Equal(Accessibility.Public, p2set.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2set)); var p3 = i1.GetMember("P3"); var p3get = p3.GetMethod; Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.True(p3.IsSealed); Assert.True(p3.IsStatic); Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.False(p3get.IsAbstract); Assert.False(p3get.IsVirtual); Assert.False(p3get.IsMetadataVirtual()); Assert.True(p3get.IsSealed); Assert.True(p3get.IsStatic); Assert.False(p3get.IsExtern); Assert.False(p3get.IsAsync); Assert.False(p3get.IsOverride); Assert.Equal(Accessibility.Public, p3get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3get)); } [Fact] public void PropertyModifiers_09() { var source1 = @" public interface I1 { private int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } } sealed void M() { var x = P1; } } public interface I2 { private int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } set { System.Console.WriteLine(""set_P2""); } } sealed void M() { P2 = P2; } } public interface I3 { private int P3 { set { System.Console.WriteLine(""set_P3""); } } sealed void M() { P3 = 0; } } public interface I4 { private int P4 { get => GetP4(); } private int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } sealed void M() { var x = P4; } } public interface I5 { private int P5 { get => GetP5(); set => System.Console.WriteLine(""set_P5""); } private int GetP5() { System.Console.WriteLine(""get_P5""); return 0; } sealed void M() { P5 = P5; } } public interface I6 { private int P6 { set => System.Console.WriteLine(""set_P6""); } sealed void M() { P6 = 0; } } public interface I7 { private int P7 => GetP7(); private int GetP7() { System.Console.WriteLine(""get_P7""); return 0; } sealed void M() { var x = P7; } } class Test1 : I1, I2, I3, I4, I5, I6, I7 { static void Main() { I1 x1 = new Test1(); x1.M(); I2 x2 = new Test1(); x2.M(); I3 x3 = new Test1(); x3.M(); I4 x4 = new Test1(); x4.M(); I5 x5 = new Test1(); x5.M(); I6 x6 = new Test1(); x6.M(); I7 x7 = new Test1(); x7.M(); } } "; ValidatePropertyModifiers_09(source1); } private void ValidatePropertyModifiers_09(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 get_P2 set_P2 set_P3 get_P4 get_P5 set_P5 set_P6 get_P7 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); for (int i = 1; i <= 7; i++) { var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleProperty(i1); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Private, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); switch (i) { case 3: case 6: Assert.Null(p1.GetMethod); ValidateAccessor(p1.SetMethod); break; case 1: case 4: case 7: Assert.Null(p1.SetMethod); ValidateAccessor(p1.GetMethod); break; default: ValidateAccessor(p1.GetMethod); ValidateAccessor(p1.SetMethod); break; } void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } } [Fact] public void PropertyModifiers_10() { var source1 = @" public interface I1 { abstract private int P1 { get; } virtual private int P2 => 0; sealed private int P3 { get => 0; set {} } private int P4 {get;} = 0; } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( // (4,26): error CS0621: 'I1.P1': virtual or abstract members cannot be private // abstract private int P1 { get; } Diagnostic(ErrorCode.ERR_VirtualPrivate, "P1").WithArguments("I1.P1").WithLocation(4, 26), // (6,25): error CS0621: 'I1.P2': virtual or abstract members cannot be private // virtual private int P2 => 0; Diagnostic(ErrorCode.ERR_VirtualPrivate, "P2").WithArguments("I1.P2").WithLocation(6, 25), // (8,24): error CS0238: 'I1.P3' cannot be sealed because it is not an override // sealed private int P3 Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I1.P3").WithLocation(8, 24), // (14,17): error CS8050: Only auto-implemented properties can have initializers. // private int P4 {get;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P4").WithArguments("I1.P4").WithLocation(14, 17), // (14,21): error CS0501: 'I1.P4.get' must declare a body because it is not marked abstract, extern, or partial // private int P4 {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P4.get").WithLocation(14, 21), // (17,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(17, 15) ); ValidatePropertyModifiers_10(compilation1); } private static void ValidatePropertyModifiers_10(CSharpCompilation compilation1) { var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMembers().OfType().ElementAt(0); var p1get = p1.GetMethod; Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Private, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.True(p1get.IsAbstract); Assert.False(p1get.IsVirtual); Assert.True(p1get.IsMetadataVirtual()); Assert.False(p1get.IsSealed); Assert.False(p1get.IsStatic); Assert.False(p1get.IsExtern); Assert.False(p1get.IsAsync); Assert.False(p1get.IsOverride); Assert.Equal(Accessibility.Private, p1get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1get)); var p2 = i1.GetMembers().OfType().ElementAt(1); var p2get = p2.GetMethod; Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Private, p2.DeclaredAccessibility); Assert.Same(p2, test1.FindImplementationForInterfaceMember(p2)); Assert.False(p2get.IsAbstract); Assert.True(p2get.IsVirtual); Assert.True(p2get.IsMetadataVirtual()); Assert.False(p2get.IsSealed); Assert.False(p2get.IsStatic); Assert.False(p2get.IsExtern); Assert.False(p2get.IsAsync); Assert.False(p2get.IsOverride); Assert.Equal(Accessibility.Private, p2get.DeclaredAccessibility); Assert.Same(p2get, test1.FindImplementationForInterfaceMember(p2get)); var p3 = i1.GetMembers().OfType().ElementAt(2); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.True(p3.IsSealed); Assert.False(p3.IsStatic); Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Private, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.GetMethod); ValidateP3Accessor(p3.SetMethod); void ValidateP3Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.True(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } var p4 = i1.GetMembers().OfType().ElementAt(3); var p4get = p4.GetMethod; Assert.False(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.False(p4.IsStatic); Assert.False(p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Private, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.False(p4get.IsAbstract); Assert.False(p4get.IsVirtual); Assert.False(p4get.IsMetadataVirtual()); Assert.False(p4get.IsSealed); Assert.False(p4get.IsStatic); Assert.False(p4get.IsExtern); Assert.False(p4get.IsAsync); Assert.False(p4get.IsOverride); Assert.Equal(Accessibility.Private, p4get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4get)); } [Fact] public void PropertyModifiers_11_01() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} sealed void Test() { P1 = P1; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.Test(); } public int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_01(source1, source2, Accessibility.Internal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } private void ValidatePropertyModifiers_11_01(string source1, string source2, Accessibility accessibility, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected1); ValidatePropertyModifiers_11(compilation1.SourceModule, accessibility); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var p1 = GetSingleProperty(i1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; ValidatePropertyModifiers_11(p1, accessibility); ValidatePropertyAccessorModifiers_11(p1get, accessibility); ValidatePropertyAccessorModifiers_11(p1set, accessibility); } var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected1); ValidatePropertyModifiers_11(compilation3.SourceModule, accessibility); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(expected1); ValidatePropertyModifiers_11(compilation4.SourceModule, accessibility); var source3 = @" class Test2 : I1 { } "; var compilation5 = CreateCompilation(source3, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics(expected2); ValidatePropertyNotImplemented_11(compilation5, "Test2"); var compilation6 = CreateCompilation(source3, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation6.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation6.VerifyDiagnostics(expected2); ValidatePropertyNotImplemented_11(compilation6, "Test2"); } private static void ValidatePropertyModifiers_11(ModuleSymbol m, Accessibility accessibility) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var p1 = GetSingleProperty(i1); var test1P1 = GetSingleProperty(test1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; ValidatePropertyModifiers_11(p1, accessibility); ValidatePropertyAccessorModifiers_11(p1get, accessibility); ValidatePropertyAccessorModifiers_11(p1set, accessibility); Assert.Same(test1P1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test1P1.GetMethod, test1.FindImplementationForInterfaceMember(p1get)); Assert.Same(test1P1.SetMethod, test1.FindImplementationForInterfaceMember(p1set)); } private static void ValidatePropertyModifiers_11(PropertySymbol p1, Accessibility accessibility) { Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(accessibility, p1.DeclaredAccessibility); } private static void ValidatePropertyAccessorModifiers_11(MethodSymbol m1, Accessibility accessibility) { Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(accessibility, m1.DeclaredAccessibility); } private static void ValidatePropertyNotImplemented_11(CSharpCompilation compilation, string className) { var test2 = compilation.GetTypeByMetadataName(className); var i1 = compilation.GetTypeByMetadataName("I1"); var p1 = GetSingleProperty(i1); Assert.Null(test2.FindImplementationForInterfaceMember(p1)); Assert.Null(test2.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p1.SetMethod)); } [Fact] public void PropertyModifiers_11_02() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) ); } private void ValidatePropertyModifiers_11_02(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); ValidatePropertyImplementation_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected); ValidatePropertyImplementation_11(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(expected); ValidatePropertyImplementation_11(compilation4.SourceModule); } private static void ValidatePropertyImplementation_11(ModuleSymbol m) { ValidatePropertyImplementation_11(m, implementedByBase: false); } private static void ValidatePropertyImplementationByBase_11(ModuleSymbol m) { ValidatePropertyImplementation_11(m, implementedByBase: true); } private static void ValidatePropertyImplementation_11(ModuleSymbol m, bool implementedByBase) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var p1 = GetSingleProperty(i1); var test1P1 = GetSingleProperty(implementedByBase ? test1.BaseTypeNoUseSiteDiagnostics : test1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; Assert.Same(test1P1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test1P1.GetMethod, test1.FindImplementationForInterfaceMember(p1get)); Assert.Same(test1P1.SetMethod, test1.FindImplementationForInterfaceMember(p1set)); var i2 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").SingleOrDefault(); bool isMetadataVirtual = test1P1.IsVirtual || test1P1.IsAbstract || test1P1.IsExplicitInterfaceImplementation || (!implementedByBase && (object)i2 != null && (object)test1P1 == test1.FindImplementationForInterfaceMember(GetSingleProperty(i2))); Assert.Equal(isMetadataVirtual, test1P1.GetMethod.IsMetadataVirtual()); Assert.Equal(isMetadataVirtual, test1P1.SetMethod.IsMetadataVirtual()); } [Fact] public void PropertyModifiers_11_03() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // int I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(9, 12) ); } private void ValidatePropertyModifiers_11_03(string source1, string source2, TargetFramework targetFramework, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, targetFramework: targetFramework, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: !(targetFramework == TargetFramework.Standard || ExecutionConditionUtil.IsMonoOrCoreClr) ? null : @"get_P1 set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementation_11); ValidatePropertyImplementation_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: targetFramework, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, targetFramework: targetFramework, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(expected); if (expected.Length == 0) { CompileAndVerify(compilation3, expectedOutput: !(targetFramework == TargetFramework.Standard || ExecutionConditionUtil.IsMonoOrCoreClr) ? null : @"get_P1 set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementation_11); } ValidatePropertyImplementation_11(compilation3.SourceModule); } } [Fact] public void PropertyModifiers_11_04() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_11_05() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_11_06() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract int P1 {get; set;} } class Test3 : Test1 { public override int P1 { get { System.Console.WriteLine(""Test3.get_P1""); return 0; } set { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_11_07() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { int P1 {get; set;} } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_11_08() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_08(source1, source2); } private void ValidatePropertyModifiers_11_08(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: @"Test2.get_P1 Test2.set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationByBase_11); ValidatePropertyImplementationByBase_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation3, expectedOutput: @"Test2.get_P1 Test2.set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationByBase_11); ValidatePropertyImplementationByBase_11(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation4, expectedOutput: @"Test2.get_P1 Test2.set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationByBase_11); ValidatePropertyImplementationByBase_11(compilation4.SourceModule); } [Fact] public void PropertyModifiers_11_09() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } private void ValidatePropertyModifiers_11_09(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(expected); ValidatePropertyNotImplemented_11(compilation1, "Test1"); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(expected); ValidatePropertyNotImplemented_11(compilation3, "Test1"); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics(expected); ValidatePropertyNotImplemented_11(compilation4, "Test1"); } [Fact] public void PropertyModifiers_11_10() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } "; var source2 = @" public class Test2 : I1 { public int P1 { get { return 0; } set {} } } class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.set'. 'Test2.P1.set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.set", "Test2.P1.set").WithLocation(2, 22), // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.get'. 'Test2.P1.get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.get", "Test2.P1.get").WithLocation(2, 22) ); } private void ValidatePropertyModifiers_11_10(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(expected); ValidatePropertyImplementationByBase_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(expected); ValidatePropertyImplementationByBase_11(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics(expected); ValidatePropertyImplementationByBase_11(compilation4.SourceModule); } [Fact] public void PropertyModifiers_11_11() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } public class Test2 : I1 { public int P1 { get { return 0; } set {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.set'. 'Test2.P1.set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.set", "Test2.P1.set").WithLocation(6, 22), // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.get'. 'Test2.P1.get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.get", "Test2.P1.get").WithLocation(6, 22) ); } private void ValidatePropertyModifiers_11_11(string source1, string source2, params DiagnosticDescription[] expected) { var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, assemblyName: "PropertyModifiers_11_11"); compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(); ValidatePropertyImplementationByBase_11(compilation3.SourceModule); var compilation3Ref = compilation3.EmitToImageReference(); var compilation4 = CreateCompilation("", new[] { compilation2.ToMetadataReference(), compilation3Ref }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); ValidatePropertyImplementationByBase_11(compilation4.GetReferencedAssemblySymbol(compilation3Ref).Modules[0]); } [Fact] public void PropertyModifiers_12() { var source1 = @" public interface I1 { internal abstract int P1 {get; set;} } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember("P1"); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Null(test1.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(p1.SetMethod)); } [Fact] public void PropertyModifiers_13() { var source1 = @" public interface I1 { public sealed int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } } } public interface I2 { public sealed int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } set { System.Console.WriteLine(""set_P2""); } } } public interface I3 { public sealed int P3 { set { System.Console.WriteLine(""set_P3""); } } } public interface I4 { public sealed int P4 { get => GetP4(); } private int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } public interface I5 { public sealed int P5 { get => GetP5(); set => System.Console.WriteLine(""set_P5""); } private int GetP5() { System.Console.WriteLine(""get_P5""); return 0; } } public interface I6 { public sealed int P6 { set => System.Console.WriteLine(""set_P6""); } } public interface I7 { public sealed int P7 => GetP7(); private int GetP7() { System.Console.WriteLine(""get_P7""); return 0; } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); var x = i1.P1; I2 i2 = new Test2(); i2.P2 = i2.P2; I3 i3 = new Test3(); i3.P3 = x; I4 i4 = new Test4(); x = i4.P4; I5 i5 = new Test5(); i5.P5 = i5.P5; I6 i6 = new Test6(); i6.P6 = x; I7 i7 = new Test7(); x = i7.P7; } public int P1 => throw null; } class Test2 : I2 { public int P2 { get => throw null; set => throw null; } } class Test3 : I3 { public int P3 { set => throw null; } } class Test4 : I4 { public int P4 { get => throw null; } } class Test5 : I5 { public int P5 { get => throw null; set => throw null; } } class Test6 : I6 { public int P6 { set => throw null; } } class Test7 : I7 { public int P7 => throw null; } "; ValidatePropertyModifiers_13(source1); } private void ValidatePropertyModifiers_13(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate(ModuleSymbol m) { for (int i = 1; i <= 7; i++) { var test1 = m.GlobalNamespace.GetTypeMember("Test" + i); var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleProperty(i1); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); switch (i) { case 3: case 6: Assert.Null(p1.GetMethod); ValidateAccessor(p1.SetMethod); break; case 1: case 4: case 7: Assert.Null(p1.SetMethod); ValidateAccessor(p1.GetMethod); break; default: ValidateAccessor(p1.GetMethod); ValidateAccessor(p1.SetMethod); break; } void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 get_P2 set_P2 set_P3 get_P4 get_P5 set_P5 set_P6 get_P7 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); } [Fact] public void PropertyModifiers_14() { var source1 = @" public interface I1 { public sealed int P1 {get;} = 0; } public interface I2 { abstract sealed int P2 {get;} } public interface I3 { virtual sealed int P3 { set {} } } class Test1 : I1, I2, I3 { int I1.P1 { get => throw null; } int I2.P2 { get => throw null; } int I3.P3 { set => throw null; } } class Test2 : I1, I2, I3 {} "; ValidatePropertyModifiers_14(source1, // (4,23): error CS8050: Only auto-implemented properties can have initializers. // public sealed int P1 {get;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I1.P1").WithLocation(4, 23), // (4,27): error CS0501: 'I1.P1.get' must declare a body because it is not marked abstract, extern, or partial // public sealed int P1 {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.P1.get").WithLocation(4, 27), // (8,25): error CS0238: 'I2.P2' cannot be sealed because it is not an override // abstract sealed int P2 {get;} Diagnostic(ErrorCode.ERR_SealedNonOverride, "P2").WithArguments("I2.P2").WithLocation(8, 25), // (12,24): error CS0238: 'I3.P3' cannot be sealed because it is not an override // virtual sealed int P3 Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I3.P3").WithLocation(12, 24), // (20,12): error CS0539: 'Test1.P1' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.P1 { get => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("Test1.P1").WithLocation(20, 12), // (21,12): error CS0539: 'Test1.P2' in explicit interface declaration is not found among members of the interface that can be implemented // int I2.P2 { get => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P2").WithArguments("Test1.P2").WithLocation(21, 12), // (22,12): error CS0539: 'Test1.P3' in explicit interface declaration is not found among members of the interface that can be implemented // int I3.P3 { set => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test1.P3").WithLocation(22, 12) ); } private void ValidatePropertyModifiers_14(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var p1 = GetSingleProperty(compilation1, "I1"); var p1get = p1.GetMethod; Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Null(test2.FindImplementationForInterfaceMember(p1)); Assert.False(p1get.IsAbstract); Assert.False(p1get.IsVirtual); Assert.False(p1get.IsMetadataVirtual()); Assert.False(p1get.IsSealed); Assert.False(p1get.IsStatic); Assert.False(p1get.IsExtern); Assert.False(p1get.IsAsync); Assert.False(p1get.IsOverride); Assert.Equal(Accessibility.Public, p1get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1get)); Assert.Null(test2.FindImplementationForInterfaceMember(p1get)); var p2 = GetSingleProperty(compilation1, "I2"); var test1P2 = test1.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); var p2get = p2.GetMethod; Assert.True(p2.IsAbstract); Assert.False(p2.IsVirtual); Assert.True(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.Null(test2.FindImplementationForInterfaceMember(p2)); Assert.True(p2get.IsAbstract); Assert.False(p2get.IsVirtual); Assert.True(p2get.IsMetadataVirtual()); Assert.True(p2get.IsSealed); Assert.False(p2get.IsStatic); Assert.False(p2get.IsExtern); Assert.False(p2get.IsAsync); Assert.False(p2get.IsOverride); Assert.Equal(Accessibility.Public, p2get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2get)); Assert.Null(test2.FindImplementationForInterfaceMember(p2get)); var p3 = GetSingleProperty(compilation1, "I3"); var test1P3 = test1.GetMembers().OfType().Where(p => p.Name.StartsWith("I3.")).Single(); var p3set = p3.SetMethod; Assert.False(p3.IsAbstract); Assert.True(p3.IsVirtual); Assert.True(p3.IsSealed); Assert.False(p3.IsStatic); Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); Assert.False(p3set.IsAbstract); Assert.True(p3set.IsVirtual); Assert.True(p3set.IsMetadataVirtual()); Assert.True(p3set.IsSealed); Assert.False(p3set.IsStatic); Assert.False(p3set.IsExtern); Assert.False(p3set.IsAsync); Assert.False(p3set.IsOverride); Assert.Equal(Accessibility.Public, p3set.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3set)); Assert.Null(test2.FindImplementationForInterfaceMember(p3set)); } [Fact] public void PropertyModifiers_15() { var source1 = @" public interface I0 { abstract virtual int P0 { get; set; } } public interface I1 { abstract virtual int P1 { get { throw null; } } } public interface I2 { virtual abstract int P2 { get { throw null; } set { throw null; } } } public interface I3 { abstract virtual int P3 { set { throw null; } } } public interface I4 { abstract virtual int P4 { get => throw null; } } public interface I5 { abstract virtual int P5 { get => throw null; set => throw null; } } public interface I6 { abstract virtual int P6 { set => throw null; } } public interface I7 { abstract virtual int P7 => throw null; } public interface I8 { abstract virtual int P8 {get;} = 0; } class Test1 : I0, I1, I2, I3, I4, I5, I6, I7, I8 { int I0.P0 { get { throw null; } set { throw null; } } int I1.P1 { get { throw null; } } int I2.P2 { get { throw null; } set { throw null; } } int I3.P3 { set { throw null; } } int I4.P4 { get { throw null; } } int I5.P5 { get { throw null; } set { throw null; } } int I6.P6 { set { throw null; } } int I7.P7 { get { throw null; } } int I8.P8 { get { throw null; } } } class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 {} "; ValidatePropertyModifiers_15(source1, // (4,26): error CS0503: The abstract property 'I0.P0' cannot be marked virtual // abstract virtual int P0 { get; set; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P0").WithArguments("property", "I0.P0").WithLocation(4, 26), // (8,26): error CS0503: The abstract property 'I1.P1' cannot be marked virtual // abstract virtual int P1 { get { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P1").WithArguments("property", "I1.P1").WithLocation(8, 26), // (8,31): error CS0500: 'I1.P1.get' cannot declare a body because it is marked abstract // abstract virtual int P1 { get { throw null; } } Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.P1.get").WithLocation(8, 31), // (12,26): error CS0503: The abstract property 'I2.P2' cannot be marked virtual // virtual abstract int P2 Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P2").WithArguments("property", "I2.P2").WithLocation(12, 26), // (14,9): error CS0500: 'I2.P2.get' cannot declare a body because it is marked abstract // get { throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.P2.get").WithLocation(14, 9), // (15,9): error CS0500: 'I2.P2.set' cannot declare a body because it is marked abstract // set { throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.P2.set").WithLocation(15, 9), // (20,26): error CS0503: The abstract property 'I3.P3' cannot be marked virtual // abstract virtual int P3 { set { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P3").WithArguments("property", "I3.P3").WithLocation(20, 26), // (20,31): error CS0500: 'I3.P3.set' cannot declare a body because it is marked abstract // abstract virtual int P3 { set { throw null; } } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I3.P3.set").WithLocation(20, 31), // (24,26): error CS0503: The abstract property 'I4.P4' cannot be marked virtual // abstract virtual int P4 { get => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P4").WithArguments("property", "I4.P4").WithLocation(24, 26), // (24,31): error CS0500: 'I4.P4.get' cannot declare a body because it is marked abstract // abstract virtual int P4 { get => throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I4.P4.get").WithLocation(24, 31), // (28,26): error CS0503: The abstract property 'I5.P5' cannot be marked virtual // abstract virtual int P5 Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P5").WithArguments("property", "I5.P5").WithLocation(28, 26), // (30,9): error CS0500: 'I5.P5.get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I5.P5.get").WithLocation(30, 9), // (31,9): error CS0500: 'I5.P5.set' cannot declare a body because it is marked abstract // set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I5.P5.set").WithLocation(31, 9), // (36,26): error CS0503: The abstract property 'I6.P6' cannot be marked virtual // abstract virtual int P6 { set => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P6").WithArguments("property", "I6.P6").WithLocation(36, 26), // (36,31): error CS0500: 'I6.P6.set' cannot declare a body because it is marked abstract // abstract virtual int P6 { set => throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I6.P6.set").WithLocation(36, 31), // (40,26): error CS0503: The abstract property 'I7.P7' cannot be marked virtual // abstract virtual int P7 => throw null; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P7").WithArguments("property", "I7.P7").WithLocation(40, 26), // (40,32): error CS0500: 'I7.P7.get' cannot declare a body because it is marked abstract // abstract virtual int P7 => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "throw null").WithArguments("I7.P7.get").WithLocation(40, 32), // (44,26): error CS0503: The abstract property 'I8.P8' cannot be marked virtual // abstract virtual int P8 {get;} = 0; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P8").WithArguments("property", "I8.P8").WithLocation(44, 26), // (44,26): error CS8050: Only auto-implemented properties can have initializers. // abstract virtual int P8 {get;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P8").WithArguments("I8.P8").WithLocation(44, 26), // (90,15): error CS0535: 'Test2' does not implement interface member 'I0.P0' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I0").WithArguments("Test2", "I0.P0").WithLocation(90, 15), // (90,19): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(90, 19), // (90,23): error CS0535: 'Test2' does not implement interface member 'I2.P2' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I2.P2").WithLocation(90, 23), // (90,27): error CS0535: 'Test2' does not implement interface member 'I3.P3' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test2", "I3.P3").WithLocation(90, 27), // (90,31): error CS0535: 'Test2' does not implement interface member 'I4.P4' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I4").WithArguments("Test2", "I4.P4").WithLocation(90, 31), // (90,35): error CS0535: 'Test2' does not implement interface member 'I5.P5' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test2", "I5.P5").WithLocation(90, 35), // (90,39): error CS0535: 'Test2' does not implement interface member 'I6.P6' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I6").WithArguments("Test2", "I6.P6").WithLocation(90, 39), // (90,43): error CS0535: 'Test2' does not implement interface member 'I7.P7' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I7").WithArguments("Test2", "I7.P7").WithLocation(90, 43), // (90,47): error CS0535: 'Test2' does not implement interface member 'I8.P8' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I8").WithArguments("Test2", "I8.P8").WithLocation(90, 47) ); } private void ValidatePropertyModifiers_15(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); for (int i = 0; i <= 8; i++) { var i1 = compilation1.GetTypeByMetadataName("I" + i); var p2 = GetSingleProperty(i1); var test1P2 = test1.GetMembers().OfType().Where(p => p.Name.StartsWith(i1.Name)).Single(); Assert.True(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Same(test1P2, test1.FindImplementationForInterfaceMember(p2)); Assert.Null(test2.FindImplementationForInterfaceMember(p2)); switch (i) { case 3: case 6: Assert.Null(p2.GetMethod); ValidateAccessor(p2.SetMethod, test1P2.SetMethod); break; case 1: case 4: case 7: case 8: Assert.Null(p2.SetMethod); ValidateAccessor(p2.GetMethod, test1P2.GetMethod); break; default: ValidateAccessor(p2.GetMethod, test1P2.GetMethod); ValidateAccessor(p2.SetMethod, test1P2.SetMethod); break; } void ValidateAccessor(MethodSymbol accessor, MethodSymbol implementedBy) { Assert.True(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(implementedBy, test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } } [Fact] public void PropertyModifiers_16() { var source1 = @" public interface I1 { extern int P1 {get;} } public interface I2 { virtual extern int P2 {set;} } public interface I3 { static extern int P3 {get; set;} } public interface I4 { private extern int P4 {get;} } public interface I5 { extern sealed int P5 {set;} } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { int I1.P1 => 0; int I2.P2 { set {} } } "; ValidatePropertyModifiers_16(source1, new DiagnosticDescription[] { // (4,16): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern int P1 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P1").WithArguments("extern", "7.3", "8.0").WithLocation(4, 16), // (8,24): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern int P2 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P2").WithArguments("extern", "7.3", "8.0").WithLocation(8, 24), // (8,24): error CS8503: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern int P2 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P2").WithArguments("virtual", "7.3", "8.0").WithLocation(8, 24), // (12,23): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static extern int P3 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P3").WithArguments("static", "7.3", "8.0").WithLocation(12, 23), // (12,23): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static extern int P3 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P3").WithArguments("extern", "7.3", "8.0").WithLocation(12, 23), // (16,24): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern int P4 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P4").WithArguments("private", "7.3", "8.0").WithLocation(16, 24), // (16,24): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern int P4 {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P4").WithArguments("extern", "7.3", "8.0").WithLocation(16, 24), // (20,23): error CS8503: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed int P5 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P5").WithArguments("sealed", "7.3", "8.0").WithLocation(20, 23), // (20,23): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed int P5 {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P5").WithArguments("extern", "7.3", "8.0").WithLocation(20, 23), // (8,28): warning CS0626: Method, operator, or accessor 'I2.P2.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern int P2 {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I2.P2.set").WithLocation(8, 28), // (12,27): warning CS0626: Method, operator, or accessor 'I3.P3.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I3.P3.get").WithLocation(12, 27), // (12,32): warning CS0626: Method, operator, or accessor 'I3.P3.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I3.P3.set").WithLocation(12, 32), // (16,28): warning CS0626: Method, operator, or accessor 'I4.P4.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern int P4 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I4.P4.get").WithLocation(16, 28), // (20,27): warning CS0626: Method, operator, or accessor 'I5.P5.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed int P5 {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I5.P5.set").WithLocation(20, 27), // (4,20): warning CS0626: Method, operator, or accessor 'I1.P1.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P1 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.P1.get").WithLocation(4, 20) }, // (4,20): error CS8501: Target runtime doesn't support default interface implementation. // extern int P1 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(4, 20), // (8,28): error CS8501: Target runtime doesn't support default interface implementation. // virtual extern int P2 {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(8, 28), // (16,28): error CS8501: Target runtime doesn't support default interface implementation. // private extern int P4 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(16, 28), // (20,27): error CS8501: Target runtime doesn't support default interface implementation. // extern sealed int P5 {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(20, 27), // (8,28): warning CS0626: Method, operator, or accessor 'I2.P2.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern int P2 {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I2.P2.set").WithLocation(8, 28), // (12,27): error CS8701: Target runtime doesn't support default interface implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(12, 27), // (12,27): warning CS0626: Method, operator, or accessor 'I3.P3.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I3.P3.get").WithLocation(12, 27), // (12,32): error CS8701: Target runtime doesn't support default interface implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(12, 32), // (12,32): warning CS0626: Method, operator, or accessor 'I3.P3.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I3.P3.set").WithLocation(12, 32), // (16,28): warning CS0626: Method, operator, or accessor 'I4.P4.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern int P4 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I4.P4.get").WithLocation(16, 28), // (20,27): warning CS0626: Method, operator, or accessor 'I5.P5.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed int P5 {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I5.P5.set").WithLocation(20, 27), // (4,20): warning CS0626: Method, operator, or accessor 'I1.P1.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int P1 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.P1.get").WithLocation(4, 20) ); } private void ValidatePropertyModifiers_16(string source1, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test2 = m.GlobalNamespace.GetTypeMember("Test2"); bool isSource = !(m is PEModuleSymbol); var p1 = GetSingleProperty(m, "I1"); var test2P1 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I1.")).Single(); var p1get = p1.GetMethod; Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.Equal(isSource, p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test2P1, test2.FindImplementationForInterfaceMember(p1)); Assert.False(p1get.IsAbstract); Assert.True(p1get.IsVirtual); Assert.True(p1get.IsMetadataVirtual()); Assert.False(p1get.IsSealed); Assert.False(p1get.IsStatic); Assert.Equal(isSource, p1get.IsExtern); Assert.False(p1get.IsAsync); Assert.False(p1get.IsOverride); Assert.Equal(Accessibility.Public, p1get.DeclaredAccessibility); Assert.Same(p1get, test1.FindImplementationForInterfaceMember(p1get)); Assert.Same(test2P1.GetMethod, test2.FindImplementationForInterfaceMember(p1get)); var p2 = GetSingleProperty(m, "I2"); var test2P2 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); var p2set = p2.SetMethod; Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.Equal(isSource, p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Same(p2, test1.FindImplementationForInterfaceMember(p2)); Assert.Same(test2P2, test2.FindImplementationForInterfaceMember(p2)); Assert.False(p2set.IsAbstract); Assert.True(p2set.IsVirtual); Assert.True(p2set.IsMetadataVirtual()); Assert.False(p2set.IsSealed); Assert.False(p2set.IsStatic); Assert.Equal(isSource, p2set.IsExtern); Assert.False(p2set.IsAsync); Assert.False(p2set.IsOverride); Assert.Equal(Accessibility.Public, p2set.DeclaredAccessibility); Assert.Same(p2set, test1.FindImplementationForInterfaceMember(p2set)); Assert.Same(test2P2.SetMethod, test2.FindImplementationForInterfaceMember(p2set)); var i3 = m.ContainingAssembly.GetTypeByMetadataName("I3"); if ((object)i3 != null) { var p3 = GetSingleProperty(i3); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.False(p3.IsSealed); Assert.True(p3.IsStatic); Assert.Equal(isSource, p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.GetMethod); ValidateP3Accessor(p3.SetMethod); void ValidateP3Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.Equal(isSource, accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } var p4 = GetSingleProperty(m, "I4"); var p4get = p4.GetMethod; Assert.False(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.False(p4.IsStatic); Assert.Equal(isSource, p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Private, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.Null(test2.FindImplementationForInterfaceMember(p4)); Assert.False(p4get.IsAbstract); Assert.False(p4get.IsVirtual); Assert.False(p4get.IsMetadataVirtual()); Assert.False(p4get.IsSealed); Assert.False(p4get.IsStatic); Assert.Equal(isSource, p4get.IsExtern); Assert.False(p4get.IsAsync); Assert.False(p4get.IsOverride); Assert.Equal(Accessibility.Private, p4get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4get)); Assert.Null(test2.FindImplementationForInterfaceMember(p4get)); var p5 = GetSingleProperty(m, "I5"); var p5set = p5.SetMethod; Assert.False(p5.IsAbstract); Assert.False(p5.IsVirtual); Assert.False(p5.IsSealed); Assert.False(p5.IsStatic); Assert.Equal(isSource, p5.IsExtern); Assert.False(p5.IsOverride); Assert.Equal(Accessibility.Public, p5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); Assert.False(p5set.IsAbstract); Assert.False(p5set.IsVirtual); Assert.False(p5set.IsMetadataVirtual()); Assert.False(p5set.IsSealed); Assert.False(p5set.IsStatic); Assert.Equal(isSource, p5set.IsExtern); Assert.False(p5set.IsAsync); Assert.False(p5set.IsOverride); Assert.Equal(Accessibility.Public, p5set.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5set)); Assert.Null(test2.FindImplementationForInterfaceMember(p5set)); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(expected1); Validate(compilation2.SourceModule); var compilation3 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected2); Validate(compilation3.SourceModule); } [Fact] public void PropertyModifiers_17() { var source1 = @" public interface I1 { abstract extern int P1 {get;} } public interface I2 { extern int P2 => 0; } public interface I3 { static extern int P3 {get => 0; set => throw null;} } public interface I4 { private extern int P4 { get {throw null;} set {throw null;}} } public interface I5 { extern sealed int P5 {get;} = 0; } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { int I1.P1 => 0; int I2.P2 => 0; int I3.P3 { get => 0; set => throw null;} int I4.P4 { get => 0; set => throw null;} int I5.P5 => 0; } "; ValidatePropertyModifiers_17(source1, // (4,25): error CS0180: 'I1.P1' cannot be both extern and abstract // abstract extern int P1 {get;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I1.P1").WithLocation(4, 25), // (8,22): error CS0179: 'I2.P2.get' cannot be extern and declare a body // extern int P2 => 0; Diagnostic(ErrorCode.ERR_ExternHasBody, "0").WithArguments("I2.P2.get").WithLocation(8, 22), // (12,27): error CS0179: 'I3.P3.get' cannot be extern and declare a body // static extern int P3 {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_ExternHasBody, "get").WithArguments("I3.P3.get").WithLocation(12, 27), // (12,37): error CS0179: 'I3.P3.set' cannot be extern and declare a body // static extern int P3 {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I3.P3.set").WithLocation(12, 37), // (16,29): error CS0179: 'I4.P4.get' cannot be extern and declare a body // private extern int P4 { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "get").WithArguments("I4.P4.get").WithLocation(16, 29), // (16,47): error CS0179: 'I4.P4.set' cannot be extern and declare a body // private extern int P4 { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I4.P4.set").WithLocation(16, 47), // (20,23): error CS8050: Only auto-implemented properties can have initializers. // extern sealed int P5 {get;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P5").WithArguments("I5.P5").WithLocation(20, 23), // (23,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(23, 15), // (31,12): error CS0539: 'Test2.P3' in explicit interface declaration is not found among members of the interface that can be implemented // int I3.P3 { get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test2.P3").WithLocation(31, 12), // (32,12): error CS0539: 'Test2.P4' in explicit interface declaration is not found among members of the interface that can be implemented // int I4.P4 { get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P4").WithArguments("Test2.P4").WithLocation(32, 12), // (33,12): error CS0539: 'Test2.P5' in explicit interface declaration is not found among members of the interface that can be implemented // int I5.P5 => 0; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P5").WithArguments("Test2.P5").WithLocation(33, 12), // (20,27): warning CS0626: Method, operator, or accessor 'I5.P5.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed int P5 {get;} = 0; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I5.P5.get").WithLocation(20, 27) ); } private void ValidatePropertyModifiers_17(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var p1 = GetSingleProperty(compilation1, "I1"); var test2P1 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I1.")).Single(); var p1get = p1.GetMethod; Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.True(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test2P1, test2.FindImplementationForInterfaceMember(p1)); Assert.True(p1get.IsAbstract); Assert.False(p1get.IsVirtual); Assert.True(p1get.IsMetadataVirtual()); Assert.False(p1get.IsSealed); Assert.False(p1get.IsStatic); Assert.True(p1get.IsExtern); Assert.False(p1get.IsAsync); Assert.False(p1get.IsOverride); Assert.Equal(Accessibility.Public, p1get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1get)); Assert.Same(test2P1.GetMethod, test2.FindImplementationForInterfaceMember(p1get)); var p2 = GetSingleProperty(compilation1, "I2"); var test2P2 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); var p2get = p2.GetMethod; Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.True(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Same(p2, test1.FindImplementationForInterfaceMember(p2)); Assert.Same(test2P2, test2.FindImplementationForInterfaceMember(p2)); Assert.False(p2get.IsAbstract); Assert.True(p2get.IsVirtual); Assert.True(p2get.IsMetadataVirtual()); Assert.False(p2get.IsSealed); Assert.False(p2get.IsStatic); Assert.True(p2get.IsExtern); Assert.False(p2get.IsAsync); Assert.False(p2get.IsOverride); Assert.Equal(Accessibility.Public, p2get.DeclaredAccessibility); Assert.Same(p2get, test1.FindImplementationForInterfaceMember(p2get)); Assert.Same(test2P2.GetMethod, test2.FindImplementationForInterfaceMember(p2get)); var p3 = GetSingleProperty(compilation1, "I3"); var test2P3 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I3.")).Single(); Assert.False(p3.IsAbstract); Assert.Equal(p3.IsIndexer, p3.IsVirtual); Assert.False(p3.IsSealed); Assert.Equal(!p3.IsIndexer, p3.IsStatic); Assert.True(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Same(p3.IsIndexer ? p3 : null, test1.FindImplementationForInterfaceMember(p3)); Assert.Same(p3.IsIndexer ? test2P3 : null, test2.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.GetMethod, p3.IsIndexer ? test2P3.GetMethod : null); ValidateP3Accessor(p3.SetMethod, p3.IsIndexer ? test2P3.SetMethod : null); void ValidateP3Accessor(MethodSymbol accessor, MethodSymbol test2Implementation) { Assert.False(accessor.IsAbstract); Assert.Equal(p3.IsIndexer, accessor.IsVirtual); Assert.Equal(p3.IsIndexer, accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.Equal(!p3.IsIndexer, accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(p3.IsIndexer ? accessor : null, test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(test2Implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p4 = GetSingleProperty(compilation1, "I4"); Assert.False(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.False(p4.IsStatic); Assert.True(p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Private, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.Null(test2.FindImplementationForInterfaceMember(p4)); ValidateP4Accessor(p4.GetMethod); ValidateP4Accessor(p4.SetMethod); void ValidateP4Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p5 = GetSingleProperty(compilation1, "I5"); var p5get = p5.GetMethod; Assert.False(p5.IsAbstract); Assert.False(p5.IsVirtual); Assert.False(p5.IsSealed); Assert.False(p5.IsStatic); Assert.True(p5.IsExtern); Assert.False(p5.IsOverride); Assert.Equal(Accessibility.Public, p5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); Assert.False(p5get.IsAbstract); Assert.False(p5get.IsVirtual); Assert.False(p5get.IsMetadataVirtual()); Assert.False(p5get.IsSealed); Assert.False(p5get.IsStatic); Assert.True(p5get.IsExtern); Assert.False(p5get.IsAsync); Assert.False(p5get.IsOverride); Assert.Equal(Accessibility.Public, p5get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5get)); Assert.Null(test2.FindImplementationForInterfaceMember(p5get)); } [Fact] public void PropertyModifiers_18() { var source1 = @" public interface I1 { abstract int P1 {get => 0; set => throw null;} } public interface I2 { abstract private int P2 => 0; } public interface I3 { static extern int P3 {get; set;} } public interface I4 { abstract static int P4 { get {throw null;} set {throw null;}} } public interface I5 { override sealed int P5 {get;} = 0; } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { int I1.P1 { get => 0; set => throw null;} int I2.P2 => 0; int I3.P3 { get => 0; set => throw null;} int I4.P4 { get => 0; set => throw null;} int I5.P5 => 0; } "; ValidatePropertyModifiers_18(source1, // (4,22): error CS0500: 'I1.P1.get' cannot declare a body because it is marked abstract // abstract int P1 {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.P1.get"), // (4,32): error CS0500: 'I1.P1.set' cannot declare a body because it is marked abstract // abstract int P1 {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I1.P1.set"), // (8,26): error CS0621: 'I2.P2': virtual or abstract members cannot be private // abstract private int P2 => 0; Diagnostic(ErrorCode.ERR_VirtualPrivate, "P2").WithArguments("I2.P2").WithLocation(8, 26), // (8,32): error CS0500: 'I2.P2.get' cannot declare a body because it is marked abstract // abstract private int P2 => 0; Diagnostic(ErrorCode.ERR_AbstractHasBody, "0").WithArguments("I2.P2.get").WithLocation(8, 32), // (16,25): error CS0112: A static member 'I4.P4' cannot be marked as override, virtual, or abstract // abstract static int P4 { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P4").WithArguments("I4.P4").WithLocation(16, 25), // (16,30): error CS0500: 'I4.P4.get' cannot declare a body because it is marked abstract // abstract static int P4 { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I4.P4.get").WithLocation(16, 30), // (16,48): error CS0500: 'I4.P4.set' cannot declare a body because it is marked abstract // abstract static int P4 { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I4.P4.set").WithLocation(16, 48), // (20,25): error CS0106: The modifier 'override' is not valid for this item // override sealed int P5 {get;} = 0; Diagnostic(ErrorCode.ERR_BadMemberFlag, "P5").WithArguments("override").WithLocation(20, 25), // (20,25): error CS8050: Only auto-implemented properties can have initializers. // override sealed int P5 {get;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P5").WithArguments("I5.P5").WithLocation(20, 25), // (20,29): error CS0501: 'I5.P5.get' must declare a body because it is not marked abstract, extern, or partial // override sealed int P5 {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I5.P5.get").WithLocation(20, 29), // (23,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(23, 15), // (23,19): error CS0535: 'Test1' does not implement interface member 'I2.P2' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I2.P2").WithLocation(23, 19), // (30,12): error CS0122: 'I2.P2' is inaccessible due to its protection level // int I2.P2 => 0; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I2.P2").WithLocation(30, 12), // (31,12): error CS0539: 'Test2.P3' in explicit interface declaration is not found among members of the interface that can be implemented // int I3.P3 { get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test2.P3").WithLocation(31, 12), // (32,12): error CS0539: 'Test2.P4' in explicit interface declaration is not found among members of the interface that can be implemented // int I4.P4 { get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P4").WithArguments("Test2.P4").WithLocation(32, 12), // (33,12): error CS0539: 'Test2.P5' in explicit interface declaration is not found among members of the interface that can be implemented // int I5.P5 => 0; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P5").WithArguments("Test2.P5").WithLocation(33, 12), // (12,27): warning CS0626: Method, operator, or accessor 'I3.P3.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I3.P3.get").WithLocation(12, 27), // (12,32): warning CS0626: Method, operator, or accessor 'I3.P3.set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int P3 {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I3.P3.set").WithLocation(12, 32) ); } private void ValidatePropertyModifiers_18(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var p1 = GetSingleProperty(compilation1, "I1"); var test2P1 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I1.")).Single(); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test2P1, test2.FindImplementationForInterfaceMember(p1)); ValidateP1Accessor(p1.GetMethod, test2P1.GetMethod); ValidateP1Accessor(p1.SetMethod, test2P1.SetMethod); void ValidateP1Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p2 = GetSingleProperty(compilation1, "I2"); var test2P2 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); var p2get = p2.GetMethod; Assert.True(p2.IsAbstract); Assert.False(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Private, p2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.Same(test2P2, test2.FindImplementationForInterfaceMember(p2)); Assert.True(p2get.IsAbstract); Assert.False(p2get.IsVirtual); Assert.True(p2get.IsMetadataVirtual()); Assert.False(p2get.IsSealed); Assert.False(p2get.IsStatic); Assert.False(p2get.IsExtern); Assert.False(p2get.IsAsync); Assert.False(p2get.IsOverride); Assert.Equal(Accessibility.Private, p2get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2get)); Assert.Same(test2P2.GetMethod, test2.FindImplementationForInterfaceMember(p2get)); var p3 = GetSingleProperty(compilation1, "I3"); var test2P3 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I3.")).Single(); Assert.False(p3.IsAbstract); Assert.Equal(p3.IsIndexer, p3.IsVirtual); Assert.False(p3.IsSealed); Assert.Equal(!p3.IsIndexer, p3.IsStatic); Assert.True(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Same(p3.IsIndexer ? p3 : null, test1.FindImplementationForInterfaceMember(p3)); Assert.Same(p3.IsIndexer ? test2P3 : null, test2.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.GetMethod, p3.IsIndexer ? test2P3.GetMethod : null); ValidateP3Accessor(p3.SetMethod, p3.IsIndexer ? test2P3.SetMethod : null); void ValidateP3Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.False(accessor.IsAbstract); Assert.Equal(p3.IsIndexer, accessor.IsVirtual); Assert.Equal(p3.IsIndexer, accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.Equal(!p3.IsIndexer, accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(p3.IsIndexer ? accessor : null, test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p4 = GetSingleProperty(compilation1, "I4"); var test2P4 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I4.")).Single(); Assert.True(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.Equal(!p4.IsIndexer, p4.IsStatic); Assert.False(p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Public, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.Same(p4.IsIndexer ? test2P4 : null, test2.FindImplementationForInterfaceMember(p4)); ValidateP4Accessor(p4.GetMethod, p4.IsIndexer ? test2P4.GetMethod : null); ValidateP4Accessor(p4.SetMethod, p4.IsIndexer ? test2P4.SetMethod : null); void ValidateP4Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.Equal(!p4.IsIndexer, accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p5 = GetSingleProperty(compilation1, "I5"); var p5get = p5.GetMethod; Assert.False(p5.IsAbstract); Assert.False(p5.IsVirtual); Assert.False(p5.IsSealed); Assert.False(p5.IsStatic); Assert.False(p5.IsExtern); Assert.False(p5.IsOverride); Assert.Equal(Accessibility.Public, p5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); Assert.False(p5get.IsAbstract); Assert.False(p5get.IsVirtual); Assert.False(p5get.IsMetadataVirtual()); Assert.False(p5get.IsSealed); Assert.False(p5get.IsStatic); Assert.False(p5get.IsExtern); Assert.False(p5get.IsAsync); Assert.False(p5get.IsOverride); Assert.Equal(Accessibility.Public, p5get.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5get)); Assert.Null(test2.FindImplementationForInterfaceMember(p5get)); } [Fact] public void PropertyModifiers_20() { var source1 = @" public interface I1 { internal int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } void M2() {P1 = P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_20(source1, source2, Accessibility.Internal); } private void ValidatePropertyModifiers_20(string source1, string source2, Accessibility accessibility) { var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var p1 = GetSingleProperty(i1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; ValidateProperty(p1); ValidateMethod(p1get); ValidateMethod(p1set); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(p1get, test1.FindImplementationForInterfaceMember(p1get)); Assert.Same(p1set, test1.FindImplementationForInterfaceMember(p1set)); } void ValidateProperty(PropertySymbol p1) { Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(accessibility, p1.DeclaredAccessibility); } void ValidateMethod(MethodSymbol m1) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(accessibility, m1.DeclaredAccessibility); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var p1 = GetSingleProperty(i1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; ValidateProperty(p1); ValidateMethod(p1get); ValidateMethod(p1set); } var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation4.SourceModule); } [Fact] public void PropertyModifiers_21() { var source1 = @" public interface I1 { private static int P1 { get => throw null; set => throw null; } internal static int P2 { get => throw null; set => throw null; } public static int P3 { get => throw null; set => throw null; } static int P4 { get => throw null; set => throw null; } } class Test1 { static void Main() { int x; x = I1.P1; I1.P1 = x; x = I1.P2; I1.P2 = x; x = I1.P3; I1.P3 = x; x = I1.P4; I1.P4 = x; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (18,16): error CS0122: 'I1.P1' is inaccessible due to its protection level // x = I1.P1; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(18, 16), // (19,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 = x; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(19, 12) ); var source2 = @" class Test2 { static void Main() { int x; x = I1.P1; I1.P1 = x; x = I1.P2; I1.P2 = x; x = I1.P3; I1.P3 = x; x = I1.P4; I1.P4 = x; } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (7,16): error CS0122: 'I1.P1' is inaccessible due to its protection level // x = I1.P1; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(7, 16), // (8,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 = x; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(8, 12), // (9,16): error CS0122: 'I1.P2' is inaccessible due to its protection level // x = I1.P2; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(9, 16), // (10,12): error CS0122: 'I1.P2' is inaccessible due to its protection level // I1.P2 = x; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(10, 12) ); } [Fact] public void PropertyModifiers_22() { var source1 = @" public interface I1 { public int P1 { internal get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } public interface I2 { int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } internal set { System.Console.WriteLine(""set_P2""); } } } public interface I3 { int P3 { internal get => Test1.GetP3(); set => System.Console.WriteLine(""set_P3""); } } public interface I4 { int P4 { get => Test1.GetP4(); internal set => System.Console.WriteLine(""set_P4""); } } class Test1 : I1, I2, I3, I4 { static void Main() { I1 i1 = new Test1(); I2 i2 = new Test1(); I3 i3 = new Test1(); I4 i4 = new Test1(); i1.P1 = i1.P1; i2.P2 = i2.P2; i3.P3 = i3.P3; i4.P4 = i4.P4; } public static int GetP3() { System.Console.WriteLine(""get_P3""); return 0; } public static int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } "; ValidatePropertyModifiers_22(source1, Accessibility.Internal); } private void ValidatePropertyModifiers_22(string source1, Accessibility accessibility) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2 get_P3 set_P3 get_P4 set_P4 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); for (int i = 1; i <= 4; i++) { var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleProperty(i1); Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); switch (i) { case 1: case 3: ValidateAccessor(p1.GetMethod, accessibility); ValidateAccessor(p1.SetMethod, Accessibility.Public); break; case 2: case 4: ValidateAccessor(p1.GetMethod, Accessibility.Public); ValidateAccessor(p1.SetMethod, accessibility); break; default: Assert.False(true); break; } void ValidateAccessor(MethodSymbol accessor, Accessibility access) { Assert.False(accessor.IsAbstract); Assert.Equal(accessor.DeclaredAccessibility != Accessibility.Private, accessor.IsVirtual); Assert.Equal(accessor.DeclaredAccessibility != Accessibility.Private, accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(access, accessor.DeclaredAccessibility); Assert.Same(accessor.DeclaredAccessibility == Accessibility.Private ? null : accessor, test1.FindImplementationForInterfaceMember(accessor)); } } } } [Fact] public void PropertyModifiers_23_00() { var source1 = @" public interface I1 {} public interface I3 { int P3 { private get { System.Console.WriteLine(""get_P3""); return 0; } set {System.Console.WriteLine(""set_P3"");} } void M2() { P3 = P3; } } public interface I4 { int P4 { get {System.Console.WriteLine(""get_P4""); return 0;} private set {System.Console.WriteLine(""set_P4"");} } void M2() { P4 = P4; } } public interface I5 { int P5 { private get => GetP5(); set => System.Console.WriteLine(""set_P5""); } private int GetP5() { System.Console.WriteLine(""get_P5""); return 0; } void M2() { P5 = P5; } } public interface I6 { int P6 { get => GetP6(); private set => System.Console.WriteLine(""set_P6""); } private int GetP6() { System.Console.WriteLine(""get_P6""); return 0; } void M2() { P6 = P6; } } "; var source2 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public int P3 { get { throw null; } set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public int P4 { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } set { throw null; } } } class Test5 : I5 { public int P5 { get { throw null; } set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public int P6 { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } set { throw null; } } } "; ValidatePropertyModifiers_23(source1, source2); var source3 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public int P3 { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public int P4 { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test5 : I5 { public int P5 { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public int P6 { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } "; ValidatePropertyModifiers_23(source1, source3); var source4 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public virtual int P3 { get { throw null; } set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public virtual int P4 { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } set { throw null; } } } class Test5 : I5 { public virtual int P5 { get { throw null; } set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public virtual int P6 { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } set { throw null; } } } "; ValidatePropertyModifiers_23(source1, source4); var source5 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public virtual int P3 { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public virtual int P4 { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test5 : I5 { public virtual int P5 { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public virtual int P6 { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } "; ValidatePropertyModifiers_23(source1, source5); var source6 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { int I3.P3 { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { int I4.P4 { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test5 : I5 { int I5.P5 { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { int I6.P6 { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } "; ValidatePropertyModifiers_23(source1, source6); var source7 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test33(); I4 i4 = new Test44(); I5 i5 = new Test55(); I6 i6 = new Test66(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } interface Test3 : I3 { int I3.P3 { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test33 : Test3 {} interface Test4 : I4 { int I4.P4 { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test44 : Test4 {} interface Test5 : I5 { int I5.P5 { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test55 : Test5 {} interface Test6 : I6 { int I6.P6 { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } class Test66 : Test6 {} "; ValidatePropertyModifiers_23(source1, source7); } private void ValidatePropertyModifiers_23(string source1, string source2) { foreach (var metadataImportOptions in new[] { MetadataImportOptions.All, MetadataImportOptions.Public }) { var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe.WithMetadataImportOptions(metadataImportOptions), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var im = test1.InterfacesNoUseSiteDiagnostics().Single().ContainingModule; ValidateProperty23(GetSingleProperty(im, "I3"), false, Accessibility.Private, Accessibility.Public, m.GlobalNamespace.GetTypeMember("Test3")); ValidateProperty23(GetSingleProperty(im, "I4"), false, Accessibility.Public, Accessibility.Private, m.GlobalNamespace.GetTypeMember("Test4")); ValidateProperty23(GetSingleProperty(im, "I5"), false, Accessibility.Private, Accessibility.Public, m.GlobalNamespace.GetTypeMember("Test5")); ValidateProperty23(GetSingleProperty(im, "I6"), false, Accessibility.Public, Accessibility.Private, m.GlobalNamespace.GetTypeMember("Test6")); } var expectedOutput = @" get_P3 Test3.set_P3 Test4.get_P4 set_P4 get_P5 Test5.set_P5 Test6.get_P6 set_P6 "; CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(metadataImportOptions), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateProperty23(GetSingleProperty(compilation2, "I3"), false, Accessibility.Private, Accessibility.Public); ValidateProperty23(GetSingleProperty(compilation2, "I4"), false, Accessibility.Public, Accessibility.Private); ValidateProperty23(GetSingleProperty(compilation2, "I5"), false, Accessibility.Private, Accessibility.Public); ValidateProperty23(GetSingleProperty(compilation2, "I6"), false, Accessibility.Public, Accessibility.Private); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe.WithMetadataImportOptions(metadataImportOptions), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(); Validate1(compilation3.SourceModule); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); } } } private static void ValidateProperty23(PropertySymbol p1, bool isAbstract, Accessibility getAccess, Accessibility setAccess, NamedTypeSymbol test1 = null) { Assert.Equal(isAbstract, p1.IsAbstract); Assert.NotEqual(isAbstract, p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); PropertySymbol implementingProperty = null; if ((object)test1 != null) { implementingProperty = GetSingleProperty(test1); Assert.Same(implementingProperty, test1.FindImplementationForInterfaceMember(p1)); if (implementingProperty.GetMethod?.ExplicitInterfaceImplementations.Length > 0 || implementingProperty.SetMethod?.ExplicitInterfaceImplementations.Length > 0) { Assert.Same(p1, implementingProperty.ExplicitInterfaceImplementations.Single()); } else { Assert.Empty(implementingProperty.ExplicitInterfaceImplementations); } } ValidateMethod23(p1, p1.GetMethod, isAbstract, getAccess, test1, implementingProperty?.GetMethod); ValidateMethod23(p1, p1.SetMethod, isAbstract, setAccess, test1, implementingProperty?.SetMethod); } private static void ValidateMethod23(PropertySymbol p1, MethodSymbol m1, bool isAbstract, Accessibility access, NamedTypeSymbol test1, MethodSymbol implementingMethod) { if (m1 is null) { Assert.Equal(Accessibility.Private, access); Assert.Equal(MetadataImportOptions.Public, ((PEModuleSymbol)p1.ContainingModule).ImportOptions); return; } Assert.Equal(isAbstract, m1.IsAbstract); Assert.NotEqual(isAbstract || access == Accessibility.Private, m1.IsVirtual); Assert.Equal(isAbstract || access != Accessibility.Private, m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(access, m1.DeclaredAccessibility); if ((object)test1 != null) { Assert.Same(access != Accessibility.Private ? implementingMethod : null, test1.FindImplementationForInterfaceMember(m1)); } } [Fact] public void PropertyModifiers_23_01() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} void M2() { P1 = P1; } } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.Internal, Accessibility.Public, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15) ); } private void ValidatePropertyModifiers_23(string source1, string source2, Accessibility getAccess, Accessibility setAccess, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var im = test1.InterfacesNoUseSiteDiagnostics().Single().ContainingModule; ValidateProperty23(GetSingleProperty(im, "I1"), true, getAccess, setAccess, test1); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); ValidateProperty23(GetSingleProperty(compilation2, "I1"), true, getAccess, setAccess); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(expected); Validate1(compilation4.SourceModule); } [Fact] public void PropertyModifiers_23_02() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_23_03() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,12): error CS0122: 'I1.P1.get' is inaccessible due to its protection level // int I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.get").WithLocation(9, 12) ); } [Fact] public void PropertyModifiers_23_04() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_05() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_06() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract int P1 {get; set;} } class Test3 : Test1 { public override int P1 { get { System.Console.WriteLine(""Test3.get_P1""); return 0; } set { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_07() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { int P1 {get; set;} } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_08() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_08(source1, source2); } [Fact] public void PropertyModifiers_23_09() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_23_10() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } "; var source2 = @" public class Test2 : I1 { public int P1 { get { return 0; } set {} } } class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.get'. 'Test2.P1.get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.get", "Test2.P1.get").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_11() { var source1 = @" public interface I1 { abstract int P1 {internal get; set;} } public class Test2 : I1 { public int P1 { get { return 0; } set {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.get'. 'Test2.P1.get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.get", "Test2.P1.get").WithLocation(6, 22) ); } [Fact] public void PropertyModifiers_23_51() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} void M2() { P1 = P1; } } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.Public, Accessibility.Internal, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_23_52() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_23_53() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,12): error CS0122: 'I1.P1.set' is inaccessible due to its protection level // int I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.set").WithLocation(9, 12) ); } [Fact] public void PropertyModifiers_23_54() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_55() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_56() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract int P1 {get; set;} } class Test3 : Test1 { public override int P1 { get { System.Console.WriteLine(""Test3.get_P1""); return 0; } set { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_57() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public int P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { int P1 {get; set;} } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1, I2 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_58() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } public class Test2 : I1 { int I1.P1 { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_08(source1, source2); } [Fact] public void PropertyModifiers_23_59() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_23_60() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } "; var source2 = @" public class Test2 : I1 { public int P1 { get { return 0; } set {} } } class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.set'. 'Test2.P1.set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.set", "Test2.P1.set").WithLocation(2, 22) ); } [Fact] public void PropertyModifiers_23_61() { var source1 = @" public interface I1 { abstract int P1 {get; internal set;} } public class Test2 : I1 { public int P1 { get { return 0; } set {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.set'. 'Test2.P1.set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.set", "Test2.P1.set").WithLocation(6, 22) ); } [Fact] public void PropertyModifiers_24() { var source1 = @" public interface I1 { int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } internal set { System.Console.WriteLine(""set_P1""); } } void M2() {P1 = P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_24(source1, source2); } private void ValidatePropertyModifiers_24(string source1, string source2) { var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var p1 = GetSingleProperty(i1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; ValidateProperty(p1); ValidateMethod(p1get, Accessibility.Public); ValidateMethod(p1set, Accessibility.Internal); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(p1get, test1.FindImplementationForInterfaceMember(p1get)); Assert.Same(p1set, test1.FindImplementationForInterfaceMember(p1set)); } void ValidateProperty(PropertySymbol p1) { Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); } void ValidateMethod(MethodSymbol m1, Accessibility access) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(access, m1.DeclaredAccessibility); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var p1 = GetSingleProperty(i1); var p1get = p1.GetMethod; var p1set = p1.SetMethod; ValidateProperty(p1); ValidateMethod(p1get, Accessibility.Public); ValidateMethod(p1set, Accessibility.Internal); } var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation4.SourceModule); } [Fact] public void PropertyModifiers_25() { var source1 = @" public interface I1 { static int P1 { private get => throw null; set => throw null; } static int P2 { internal get => throw null; set => throw null; } public static int P3 { get => throw null; private set => throw null; } static int P4 { get => throw null; internal set => throw null; } } class Test1 { static void Main() { int x; x = I1.P1; I1.P1 = x; x = I1.P2; I1.P2 = x; x = I1.P3; I1.P3 = x; x = I1.P4; I1.P4 = x; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (18,13): error CS0271: The property or indexer 'I1.P1' cannot be used in this context because the get accessor is inaccessible // x = I1.P1; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "I1.P1").WithArguments("I1.P1").WithLocation(18, 13), // (23,9): error CS0272: The property or indexer 'I1.P3' cannot be used in this context because the set accessor is inaccessible // I1.P3 = x; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "I1.P3").WithArguments("I1.P3").WithLocation(23, 9) ); var source2 = @" class Test2 { static void Main() { int x; x = I1.P1; I1.P1 = x; x = I1.P2; I1.P2 = x; x = I1.P3; I1.P3 = x; x = I1.P4; I1.P4 = x; } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (7,13): error CS0271: The property or indexer 'I1.P1' cannot be used in this context because the get accessor is inaccessible // x = I1.P1; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "I1.P1").WithArguments("I1.P1").WithLocation(7, 13), // (9,13): error CS0271: The property or indexer 'I1.P2' cannot be used in this context because the get accessor is inaccessible // x = I1.P2; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "I1.P2").WithArguments("I1.P2").WithLocation(9, 13), // (12,9): error CS0272: The property or indexer 'I1.P3' cannot be used in this context because the set accessor is inaccessible // I1.P3 = x; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "I1.P3").WithArguments("I1.P3").WithLocation(12, 9), // (14,9): error CS0272: The property or indexer 'I1.P4' cannot be used in this context because the set accessor is inaccessible // I1.P4 = x; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "I1.P4").WithArguments("I1.P4").WithLocation(14, 9) ); } [Fact] public void PropertyModifiers_26() { var source1 = @" public interface I1 { abstract int P1 { private get; set; } abstract int P2 { get; private set; } abstract int P3 { internal get; } static int P4 {internal get;} = 0; static int P5 { internal get {throw null;} } static int P6 { internal set {throw null;} } static int P7 { internal get => throw null; } static int P8 { internal set => throw null; } static int P9 { internal get {throw null;} private set {throw null;}} static int P10 { internal get => throw null; private set => throw null;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,31): error CS0442: 'I1.P1.get': abstract properties cannot have private accessors // abstract int P1 { private get; set; } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I1.P1.get").WithLocation(4, 31), // (5,36): error CS0442: 'I1.P2.set': abstract properties cannot have private accessors // abstract int P2 { get; private set; } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "set").WithArguments("I1.P2.set").WithLocation(5, 36), // (6,18): error CS0276: 'I1.P3': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // abstract int P3 { internal get; } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P3").WithArguments("I1.P3").WithLocation(6, 18), // (7,16): error CS0276: 'I1.P4': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // static int P4 {internal get;} = 0; Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P4").WithArguments("I1.P4").WithLocation(7, 16), // (8,16): error CS0276: 'I1.P5': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // static int P5 { internal get {throw null;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P5").WithArguments("I1.P5").WithLocation(8, 16), // (9,16): error CS0276: 'I1.P6': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // static int P6 { internal set {throw null;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P6").WithArguments("I1.P6").WithLocation(9, 16), // (10,16): error CS0276: 'I1.P7': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // static int P7 { internal get => throw null; } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P7").WithArguments("I1.P7").WithLocation(10, 16), // (11,16): error CS0276: 'I1.P8': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // static int P8 { internal set => throw null; } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "P8").WithArguments("I1.P8").WithLocation(11, 16), // (12,16): error CS0274: Cannot specify accessibility modifiers for both accessors of the property or indexer 'I1.P9' // static int P9 { internal get {throw null;} private set {throw null;}} Diagnostic(ErrorCode.ERR_DuplicatePropertyAccessMods, "P9").WithArguments("I1.P9").WithLocation(12, 16), // (13,16): error CS0274: Cannot specify accessibility modifiers for both accessors of the property or indexer 'I1.P10' // static int P10 { internal get => throw null; private set => throw null;} Diagnostic(ErrorCode.ERR_DuplicatePropertyAccessMods, "P10").WithArguments("I1.P10").WithLocation(13, 16) ); } [Fact] public void PropertyModifiers_27() { var source1 = @" public interface I1 { int P3 { private get {throw null;} set {} } int P4 { get {throw null;} private set {} } } class Test1 : I1 { int I1.P3 { get {throw null;} set {} } int I1.P4 { get {throw null;} set {} } } interface ITest1 : I1 { int I1.P3 { get {throw null;} set {} } int I1.P4 { get {throw null;} set {} } } public interface I2 { int P5 { private get {throw null;} set {} } int P6 { get {throw null;} private set {} } class Test3 : I2 { int I2.P5 { get {throw null;} set {} } int I2.P6 { get {throw null;} set {} } } interface ITest3 : I2 { int I2.P5 { get {throw null;} set {} } int I2.P6 { get {throw null;} set {} } } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // https://github.com/dotnet/roslyn/issues/34455: The wording "accessor not found in interface member" is somewhat misleading // in this scenario. The accessor is there, but cannot be implemented. Prehaps // the message should be adjusted. Should also check diagnostics for an attempt // to implement other sealed members. compilation1.VerifyDiagnostics( // (21,9): error CS0550: 'Test1.I1.P3.get' adds an accessor not found in interface member 'I1.P3' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("Test1.I1.P3.get", "I1.P3").WithLocation(21, 9), // (28,9): error CS0550: 'Test1.I1.P4.set' adds an accessor not found in interface member 'I1.P4' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("Test1.I1.P4.set", "I1.P4").WithLocation(28, 9), // (36,9): error CS0550: 'ITest1.I1.P3.get' adds an accessor not found in interface member 'I1.P3' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("ITest1.I1.P3.get", "I1.P3").WithLocation(36, 9), // (43,9): error CS0550: 'ITest1.I1.P4.set' adds an accessor not found in interface member 'I1.P4' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("ITest1.I1.P4.set", "I1.P4").WithLocation(43, 9), // (65,13): error CS0550: 'I2.Test3.I2.P5.get' adds an accessor not found in interface member 'I2.P5' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.Test3.I2.P5.get", "I2.P5").WithLocation(65, 13), // (72,13): error CS0550: 'I2.Test3.I2.P6.set' adds an accessor not found in interface member 'I2.P6' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.Test3.I2.P6.set", "I2.P6").WithLocation(72, 13), // (80,13): error CS0550: 'I2.ITest3.I2.P5.get' adds an accessor not found in interface member 'I2.P5' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.ITest3.I2.P5.get", "I2.P5").WithLocation(80, 13), // (87,13): error CS0550: 'I2.ITest3.I2.P6.set' adds an accessor not found in interface member 'I2.P6' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.ITest3.I2.P6.set", "I2.P6").WithLocation(87, 13) ); } [Fact] public void PropertyModifiers_28() { var source0 = @" public interface I1 { protected static int P1 { get { System.Console.WriteLine(""get_P1""); return 1; } set { System.Console.WriteLine(""set_P1""); } } protected internal static int P2 { get { System.Console.WriteLine(""get_P2""); return 2; } set { System.Console.WriteLine(""set_P2""); } } private protected static int P3 { get { System.Console.WriteLine(""get_P3""); return 3; } set { System.Console.WriteLine(""set_P3""); } } static int P4 { protected get { System.Console.WriteLine(""get_P4""); return 4; } set { System.Console.WriteLine(""set_P4""); } } static int P5 { get { System.Console.WriteLine(""get_P5""); return 5; } protected internal set { System.Console.WriteLine(""set_P5""); } } static int P6 { private protected get { System.Console.WriteLine(""get_P6""); return 6; } set { System.Console.WriteLine(""set_P6""); } } } "; var source1 = @" class Test1 : I1 { static void Main() { _ = I1.P1; I1.P1 = 11; _ = I1.P2; I1.P2 = 11; _ = I1.P3; I1.P3 = 11; _ = I1.P4; I1.P4 = 11; _ = I1.P5; I1.P5 = 11; _ = I1.P6; I1.P6 = 11; } } "; var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2 get_P3 set_P3 get_P4 set_P4 get_P5 set_P5 get_P6 set_P6", symbolValidator: validate, verify: VerifyOnMonoOrCoreClr); validate(compilation1.SourceModule); var source2 = @" class Test1 { static void Main() { _ = I1.P2; I1.P2 = 11; I1.P4 = 11; _ = I1.P5; I1.P5 = 11; I1.P6 = 11; } } "; var compilation2 = CreateCompilation(source0 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P2 set_P2 set_P4 get_P5 set_P5 set_P6 ", verify: VerifyOnMonoOrCoreClr); var compilation3 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); var source3 = @" class Test1 : I1 { static void Main() { _ = I1.P1; I1.P1 = 11; _ = I1.P2; I1.P2 = 11; _ = I1.P4; I1.P4 = 11; _ = I1.P5; I1.P5 = 11; I1.P6 = 11; } } "; var source4 = @" class Test1 { static void Main() { I1.P4 = 11; _ = I1.P5; I1.P6 = 11; } } "; var source5 = @" class Test1 { static void Main() { _ = I1.P1; I1.P1 = 11; _ = I1.P2; I1.P2 = 11; _ = I1.P3; I1.P3 = 11; _ = I1.P4; I1.P5 = 11; _ = I1.P6; } } "; foreach (var reference in new[] { compilation3.ToMetadataReference(), compilation3.EmitToImageReference() }) { var compilation4 = CreateCompilation(source3, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2 get_P4 set_P4 get_P5 set_P5 set_P6 ", verify: VerifyOnMonoOrCoreClr); var compilation5 = CreateCompilation(source4, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"set_P4 get_P5 set_P6 ", verify: VerifyOnMonoOrCoreClr); var compilation6 = CreateCompilation(source5, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation6.VerifyDiagnostics( // (6,16): error CS0122: 'I1.P1' is inaccessible due to its protection level // _ = I1.P1; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(6, 16), // (7,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 = 11; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(7, 12), // (8,16): error CS0122: 'I1.P2' is inaccessible due to its protection level // _ = I1.P2; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(8, 16), // (9,12): error CS0122: 'I1.P2' is inaccessible due to its protection level // I1.P2 = 11; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(9, 12), // (10,16): error CS0122: 'I1.P3' is inaccessible due to its protection level // _ = I1.P3; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(10, 16), // (11,12): error CS0122: 'I1.P3' is inaccessible due to its protection level // I1.P3 = 11; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(11, 12), // (12,13): error CS0271: The property or indexer 'I1.P4' cannot be used in this context because the get accessor is inaccessible // _ = I1.P4; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "I1.P4").WithArguments("I1.P4").WithLocation(12, 13), // (13,9): error CS0272: The property or indexer 'I1.P5' cannot be used in this context because the set accessor is inaccessible // I1.P5 = 11; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "I1.P5").WithArguments("I1.P5").WithLocation(13, 9), // (14,13): error CS0271: The property or indexer 'I1.P6' cannot be used in this context because the get accessor is inaccessible // _ = I1.P6; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "I1.P6").WithArguments("I1.P6").WithLocation(14, 13) ); var compilation7 = CreateCompilation(source1, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation7.VerifyDiagnostics( // (10,16): error CS0122: 'I1.P3' is inaccessible due to its protection level // _ = I1.P3; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(10, 16), // (11,12): error CS0122: 'I1.P3' is inaccessible due to its protection level // I1.P3 = 11; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(11, 12), // (16,13): error CS0271: The property or indexer 'I1.P6' cannot be used in this context because the get accessor is inaccessible // _ = I1.P6; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "I1.P6").WithArguments("I1.P6").WithLocation(16, 13) ); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var tuple in new[] { (name: "P1", access: Accessibility.Protected, getAccess: Accessibility.Protected, setAccess: Accessibility.Protected), (name: "P2", access: Accessibility.ProtectedOrInternal, getAccess: Accessibility.ProtectedOrInternal, setAccess: Accessibility.ProtectedOrInternal), (name: "P3", access: Accessibility.ProtectedAndInternal, getAccess: Accessibility.ProtectedAndInternal, setAccess: Accessibility.ProtectedAndInternal), (name: "P4", access: Accessibility.Public, getAccess: Accessibility.Protected, setAccess: Accessibility.Public), (name: "P5", access: Accessibility.Public, getAccess: Accessibility.Public, setAccess: Accessibility.ProtectedOrInternal), (name: "P6", access: Accessibility.Public, getAccess: Accessibility.ProtectedAndInternal, setAccess: Accessibility.Public)}) { var p1 = i1.GetMember(tuple.name); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.True(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(tuple.access, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); validateAccessor(p1.GetMethod, tuple.getAccess); validateAccessor(p1.SetMethod, tuple.setAccess); } void validateAccessor(MethodSymbol accessor, Accessibility accessibility) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } [Fact] public void PropertyModifiers_29() { var source1 = @" public interface I1 { protected abstract int P1 {get; set;} } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get => 0; set {} } } "; ValidatePropertyModifiers_11_01(source1, source2, Accessibility.Protected, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_30() { var source1 = @" public interface I1 { protected internal abstract int P1 {get; set;} } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get => 0; set {} } } "; ValidatePropertyModifiers_11_01(source1, source2, Accessibility.ProtectedOrInternal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_31() { var source1 = @" public interface I1 { private protected abstract int P1 {get; set;} } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get => 0; set {} } } "; ValidatePropertyModifiers_11_01(source1, source2, Accessibility.ProtectedAndInternal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_32() { var source1 = @" public interface I1 { abstract int P1 {protected get; set;} } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get => 0; set {} } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.Protected, Accessibility.Public, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_33() { var source1 = @" public interface I1 { abstract int P1 {protected internal get; set;} } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get => 0; set {} } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.ProtectedOrInternal, Accessibility.Public, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.get'. 'Test1.P1.get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.get", "Test1.P1.get").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_34() { var source1 = @" public interface I1 { abstract int P1 {get; private protected set;} } "; var source2 = @" class Test1 : I1 { static void Main() { } public int P1 { get => 0; set {} } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.Public, Accessibility.ProtectedAndInternal, // (2,15): error CS8704: 'Test1' does not implement interface member 'I1.P1.set'. 'Test1.P1.set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.set", "Test1.P1.set").WithLocation(2, 15) ); } [Fact] public void PropertyModifiers_35() { var source1 = @" public interface I1 { protected abstract int P1 {get; set;} public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest); } [Fact] public void PropertyModifiers_36() { var source1 = @" public interface I1 { protected internal abstract int P1 {get; set;} public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest); } [Fact] public void PropertyModifiers_37() { var source1 = @" public interface I1 { private protected abstract int P1 {get; set;} public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest, // (9,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // int I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(9, 12) ); } [Fact] public void PropertyModifiers_38() { var source1 = @" public interface I1 { abstract int P1 {protected get; set;} public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest); } [Fact] public void PropertyModifiers_39() { var source1 = @" public interface I1 { abstract int P1 {get; protected internal set;} public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest); } [Fact] public void PropertyModifiers_40() { var source1 = @" public interface I1 { abstract int P1 { private protected get; set;} public static void CallP1(I1 x) {x.P1 = x.P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } int I1.P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest, // (9,12): error CS0122: 'I1.P1.get' is inaccessible due to its protection level // int I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.get").WithLocation(9, 12) ); } [Fact] public void PropertyModifiers_41() { var source1 = @" public interface I1 { protected int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } void M2() {P1 = P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_20(source1, source2, Accessibility.Protected); } [Fact] public void PropertyModifiers_42() { var source1 = @" public interface I1 { protected internal int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } void M2() {P1 = P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_20(source1, source2, Accessibility.ProtectedOrInternal); } [Fact] public void PropertyModifiers_43() { var source1 = @" public interface I1 { private protected int P1 { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } void M2() {P1 = P1;} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_20(source1, source2, Accessibility.ProtectedAndInternal); } [Fact] public void PropertyModifiers_44() { var source1 = @" public interface I1 { public int P1 { protected get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } static void Test(I1 i1) { i1.P1 = i1.P1; } } public interface I2 { int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } protected set { System.Console.WriteLine(""set_P2""); } } static void Test(I2 i2) { i2.P2 = i2.P2; } } public interface I3 { int P3 { protected get => Test1.GetP3(); set => System.Console.WriteLine(""set_P3""); } static void Test(I3 i3) { i3.P3 = i3.P3; } } public interface I4 { int P4 { get => Test1.GetP4(); protected set => System.Console.WriteLine(""set_P4""); } static void Test(I4 i4) { i4.P4 = i4.P4; } } class Test1 : I1, I2, I3, I4 { static void Main() { I1.Test(new Test1()); I2.Test(new Test1()); I3.Test(new Test1()); I4.Test(new Test1()); } public static int GetP3() { System.Console.WriteLine(""get_P3""); return 0; } public static int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } "; ValidatePropertyModifiers_22(source1, Accessibility.Protected); } [Fact] public void PropertyModifiers_45() { var source1 = @" public interface I1 { public int P1 { protected internal get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } public interface I2 { int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } protected internal set { System.Console.WriteLine(""set_P2""); } } } public interface I3 { int P3 { protected internal get => Test1.GetP3(); set => System.Console.WriteLine(""set_P3""); } } public interface I4 { int P4 { get => Test1.GetP4(); protected internal set => System.Console.WriteLine(""set_P4""); } } class Test1 : I1, I2, I3, I4 { static void Main() { I1 i1 = new Test1(); I2 i2 = new Test1(); I3 i3 = new Test1(); I4 i4 = new Test1(); i1.P1 = i1.P1; i2.P2 = i2.P2; i3.P3 = i3.P3; i4.P4 = i4.P4; } public static int GetP3() { System.Console.WriteLine(""get_P3""); return 0; } public static int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } "; ValidatePropertyModifiers_22(source1, Accessibility.ProtectedOrInternal); } [Fact] public void PropertyModifiers_46() { var source1 = @" public interface I1 { public int P1 { private protected get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } static void Test(I1 i1) { i1.P1 = i1.P1; } } public interface I2 { int P2 { get { System.Console.WriteLine(""get_P2""); return 0; } private protected set { System.Console.WriteLine(""set_P2""); } } static void Test(I2 i2) { i2.P2 = i2.P2; } } public interface I3 { int P3 { private protected get => Test1.GetP3(); set => System.Console.WriteLine(""set_P3""); } static void Test(I3 i3) { i3.P3 = i3.P3; } } public interface I4 { int P4 { get => Test1.GetP4(); private protected set => System.Console.WriteLine(""set_P4""); } static void Test(I4 i4) { i4.P4 = i4.P4; } } class Test1 : I1, I2, I3, I4 { static void Main() { I1.Test(new Test1()); I2.Test(new Test1()); I3.Test(new Test1()); I4.Test(new Test1()); } public static int GetP3() { System.Console.WriteLine(""get_P3""); return 0; } public static int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } "; ValidatePropertyModifiers_22(source1, Accessibility.ProtectedAndInternal); } [Fact] public void IndexerModifiers_01() { var source1 = @" public interface I01{ public int this[int x] {get; set;} } public interface I02{ protected int this[int x] {get;} } public interface I03{ protected internal int this[int x] {set;} } public interface I04{ internal int this[int x] {get;} } public interface I05{ private int this[int x] {set;} } public interface I06{ static int this[int x] {get;} } public interface I07{ virtual int this[int x] {set;} } public interface I08{ sealed int this[int x] {get;} } public interface I09{ override int this[int x] {set;} } public interface I10{ abstract int this[int x] {get;} } public interface I11{ extern int this[int x] {get; set;} } public interface I12{ int this[int x] { public get; set;} } public interface I13{ int this[int x] { get; protected set;} } public interface I14{ int this[int x] { protected internal get; set;} } public interface I15{ int this[int x] { get; internal set;} } public interface I16{ int this[int x] { private get; set;} } public interface I17{ int this[int x] { private get;} } public interface I18{ private protected int this[int x] { get; } } public interface I19{ int this[int x] { get; private protected set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (6,48): error CS0501: 'I05.this[int].set' must declare a body because it is not marked abstract, extern, or partial // public interface I05{ private int this[int x] {set;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I05.this[int].set").WithLocation(6, 48), // (7,34): error CS0106: The modifier 'static' is not valid for this item // public interface I06{ static int this[int x] {get;} } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(7, 34), // (8,48): error CS0501: 'I07.this[int].set' must declare a body because it is not marked abstract, extern, or partial // public interface I07{ virtual int this[int x] {set;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I07.this[int].set").WithLocation(8, 48), // (9,47): error CS0501: 'I08.this[int].get' must declare a body because it is not marked abstract, extern, or partial // public interface I08{ sealed int this[int x] {get;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I08.this[int].get").WithLocation(9, 47), // (10,36): error CS0106: The modifier 'override' is not valid for this item // public interface I09{ override int this[int x] {set;} } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("override").WithLocation(10, 36), // (14,48): error CS0273: The accessibility modifier of the 'I12.this[int].get' accessor must be more restrictive than the property or indexer 'I12.this[int]' // public interface I12{ int this[int x] { public get; set;} } Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "get").WithArguments("I12.this[int].get", "I12.this[int]").WithLocation(14, 48), // (18,49): error CS0442: 'I16.this[int].get': abstract properties cannot have private accessors // public interface I16{ int this[int x] { private get; set;} } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I16.this[int].get").WithLocation(18, 49), // (19,27): error CS0276: 'I17.this[int]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // public interface I17{ int this[int x] { private get;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I17.this[int]").WithLocation(19, 27), // (12,47): warning CS0626: Method, operator, or accessor 'I11.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I11.this[int].get").WithLocation(12, 47), // (12,52): warning CS0626: Method, operator, or accessor 'I11.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I11.this[int].set").WithLocation(12, 52) ); ValidateSymbolsIndexerModifiers_01(compilation1); } private static void ValidateSymbolsIndexerModifiers_01(CSharpCompilation compilation1) { var p01 = compilation1.GetMember("I01.this[]"); Assert.True(p01.IsAbstract); Assert.False(p01.IsVirtual); Assert.False(p01.IsSealed); Assert.False(p01.IsStatic); Assert.False(p01.IsExtern); Assert.False(p01.IsOverride); Assert.Equal(Accessibility.Public, p01.DeclaredAccessibility); VaidateP01Accessor(p01.GetMethod); VaidateP01Accessor(p01.SetMethod); void VaidateP01Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p02 = compilation1.GetMember("I02.this[]"); var p02get = p02.GetMethod; Assert.True(p02.IsAbstract); Assert.False(p02.IsVirtual); Assert.False(p02.IsSealed); Assert.False(p02.IsStatic); Assert.False(p02.IsExtern); Assert.False(p02.IsOverride); Assert.Equal(Accessibility.Protected, p02.DeclaredAccessibility); Assert.True(p02get.IsAbstract); Assert.False(p02get.IsVirtual); Assert.True(p02get.IsMetadataVirtual()); Assert.False(p02get.IsSealed); Assert.False(p02get.IsStatic); Assert.False(p02get.IsExtern); Assert.False(p02get.IsAsync); Assert.False(p02get.IsOverride); Assert.Equal(Accessibility.Protected, p02get.DeclaredAccessibility); var p03 = compilation1.GetMember("I03.this[]"); var p03set = p03.SetMethod; Assert.True(p03.IsAbstract); Assert.False(p03.IsVirtual); Assert.False(p03.IsSealed); Assert.False(p03.IsStatic); Assert.False(p03.IsExtern); Assert.False(p03.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, p03.DeclaredAccessibility); Assert.True(p03set.IsAbstract); Assert.False(p03set.IsVirtual); Assert.True(p03set.IsMetadataVirtual()); Assert.False(p03set.IsSealed); Assert.False(p03set.IsStatic); Assert.False(p03set.IsExtern); Assert.False(p03set.IsAsync); Assert.False(p03set.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, p03set.DeclaredAccessibility); var p04 = compilation1.GetMember("I04.this[]"); var p04get = p04.GetMethod; Assert.True(p04.IsAbstract); Assert.False(p04.IsVirtual); Assert.False(p04.IsSealed); Assert.False(p04.IsStatic); Assert.False(p04.IsExtern); Assert.False(p04.IsOverride); Assert.Equal(Accessibility.Internal, p04.DeclaredAccessibility); Assert.True(p04get.IsAbstract); Assert.False(p04get.IsVirtual); Assert.True(p04get.IsMetadataVirtual()); Assert.False(p04get.IsSealed); Assert.False(p04get.IsStatic); Assert.False(p04get.IsExtern); Assert.False(p04get.IsAsync); Assert.False(p04get.IsOverride); Assert.Equal(Accessibility.Internal, p04get.DeclaredAccessibility); var p05 = compilation1.GetMember("I05.this[]"); var p05set = p05.SetMethod; Assert.False(p05.IsAbstract); Assert.False(p05.IsVirtual); Assert.False(p05.IsSealed); Assert.False(p05.IsStatic); Assert.False(p05.IsExtern); Assert.False(p05.IsOverride); Assert.Equal(Accessibility.Private, p05.DeclaredAccessibility); Assert.False(p05set.IsAbstract); Assert.False(p05set.IsVirtual); Assert.False(p05set.IsMetadataVirtual()); Assert.False(p05set.IsSealed); Assert.False(p05set.IsStatic); Assert.False(p05set.IsExtern); Assert.False(p05set.IsAsync); Assert.False(p05set.IsOverride); Assert.Equal(Accessibility.Private, p05set.DeclaredAccessibility); var p06 = compilation1.GetMember("I06.this[]"); var p06get = p06.GetMethod; Assert.True(p06.IsAbstract); Assert.False(p06.IsVirtual); Assert.False(p06.IsSealed); Assert.False(p06.IsStatic); Assert.False(p06.IsExtern); Assert.False(p06.IsOverride); Assert.Equal(Accessibility.Public, p06.DeclaredAccessibility); Assert.True(p06get.IsAbstract); Assert.False(p06get.IsVirtual); Assert.True(p06get.IsMetadataVirtual()); Assert.False(p06get.IsSealed); Assert.False(p06get.IsStatic); Assert.False(p06get.IsExtern); Assert.False(p06get.IsAsync); Assert.False(p06get.IsOverride); Assert.Equal(Accessibility.Public, p06get.DeclaredAccessibility); var p07 = compilation1.GetMember("I07.this[]"); var p07set = p07.SetMethod; Assert.False(p07.IsAbstract); Assert.True(p07.IsVirtual); Assert.False(p07.IsSealed); Assert.False(p07.IsStatic); Assert.False(p07.IsExtern); Assert.False(p07.IsOverride); Assert.Equal(Accessibility.Public, p07.DeclaredAccessibility); Assert.False(p07set.IsAbstract); Assert.True(p07set.IsVirtual); Assert.True(p07set.IsMetadataVirtual()); Assert.False(p07set.IsSealed); Assert.False(p07set.IsStatic); Assert.False(p07set.IsExtern); Assert.False(p07set.IsAsync); Assert.False(p07set.IsOverride); Assert.Equal(Accessibility.Public, p07set.DeclaredAccessibility); var p08 = compilation1.GetMember("I08.this[]"); var p08get = p08.GetMethod; Assert.False(p08.IsAbstract); Assert.False(p08.IsVirtual); Assert.False(p08.IsSealed); Assert.False(p08.IsStatic); Assert.False(p08.IsExtern); Assert.False(p08.IsOverride); Assert.Equal(Accessibility.Public, p08.DeclaredAccessibility); Assert.False(p08get.IsAbstract); Assert.False(p08get.IsVirtual); Assert.False(p08get.IsMetadataVirtual()); Assert.False(p08get.IsSealed); Assert.False(p08get.IsStatic); Assert.False(p08get.IsExtern); Assert.False(p08get.IsAsync); Assert.False(p08get.IsOverride); Assert.Equal(Accessibility.Public, p08get.DeclaredAccessibility); var p09 = compilation1.GetMember("I09.this[]"); var p09set = p09.SetMethod; Assert.True(p09.IsAbstract); Assert.False(p09.IsVirtual); Assert.False(p09.IsSealed); Assert.False(p09.IsStatic); Assert.False(p09.IsExtern); Assert.False(p09.IsOverride); Assert.Equal(Accessibility.Public, p09.DeclaredAccessibility); Assert.True(p09set.IsAbstract); Assert.False(p09set.IsVirtual); Assert.True(p09set.IsMetadataVirtual()); Assert.False(p09set.IsSealed); Assert.False(p09set.IsStatic); Assert.False(p09set.IsExtern); Assert.False(p09set.IsAsync); Assert.False(p09set.IsOverride); Assert.Equal(Accessibility.Public, p09set.DeclaredAccessibility); var p10 = compilation1.GetMember("I10.this[]"); var p10get = p10.GetMethod; Assert.True(p10.IsAbstract); Assert.False(p10.IsVirtual); Assert.False(p10.IsSealed); Assert.False(p10.IsStatic); Assert.False(p10.IsExtern); Assert.False(p10.IsOverride); Assert.Equal(Accessibility.Public, p10.DeclaredAccessibility); Assert.True(p10get.IsAbstract); Assert.False(p10get.IsVirtual); Assert.True(p10get.IsMetadataVirtual()); Assert.False(p10get.IsSealed); Assert.False(p10get.IsStatic); Assert.False(p10get.IsExtern); Assert.False(p10get.IsAsync); Assert.False(p10get.IsOverride); Assert.Equal(Accessibility.Public, p10get.DeclaredAccessibility); var p11 = compilation1.GetMember("I11.this[]"); Assert.False(p11.IsAbstract); Assert.True(p11.IsVirtual); Assert.False(p11.IsSealed); Assert.False(p11.IsStatic); Assert.True(p11.IsExtern); Assert.False(p11.IsOverride); Assert.Equal(Accessibility.Public, p11.DeclaredAccessibility); ValidateP11Accessor(p11.GetMethod); ValidateP11Accessor(p11.SetMethod); void ValidateP11Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p12 = compilation1.GetMember("I12.this[]"); Assert.True(p12.IsAbstract); Assert.False(p12.IsVirtual); Assert.False(p12.IsSealed); Assert.False(p12.IsStatic); Assert.False(p12.IsExtern); Assert.False(p12.IsOverride); Assert.Equal(Accessibility.Public, p12.DeclaredAccessibility); ValidateP12Accessor(p12.GetMethod); ValidateP12Accessor(p12.SetMethod); void ValidateP12Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p13 = compilation1.GetMember("I13.this[]"); Assert.True(p13.IsAbstract); Assert.False(p13.IsVirtual); Assert.False(p13.IsSealed); Assert.False(p13.IsStatic); Assert.False(p13.IsExtern); Assert.False(p13.IsOverride); Assert.Equal(Accessibility.Public, p13.DeclaredAccessibility); ValidateP13Accessor(p13.GetMethod, Accessibility.Public); ValidateP13Accessor(p13.SetMethod, Accessibility.Protected); void ValidateP13Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p14 = compilation1.GetMember("I14.this[]"); Assert.True(p14.IsAbstract); Assert.False(p14.IsVirtual); Assert.False(p14.IsSealed); Assert.False(p14.IsStatic); Assert.False(p14.IsExtern); Assert.False(p14.IsOverride); Assert.Equal(Accessibility.Public, p14.DeclaredAccessibility); ValidateP14Accessor(p14.GetMethod, Accessibility.ProtectedOrInternal); ValidateP14Accessor(p14.SetMethod, Accessibility.Public); void ValidateP14Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p15 = compilation1.GetMember("I15.this[]"); Assert.True(p15.IsAbstract); Assert.False(p15.IsVirtual); Assert.False(p15.IsSealed); Assert.False(p15.IsStatic); Assert.False(p15.IsExtern); Assert.False(p15.IsOverride); Assert.Equal(Accessibility.Public, p15.DeclaredAccessibility); ValidateP15Accessor(p15.GetMethod, Accessibility.Public); ValidateP15Accessor(p15.SetMethod, Accessibility.Internal); void ValidateP15Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p16 = compilation1.GetMember("I16.this[]"); Assert.True(p16.IsAbstract); Assert.False(p16.IsVirtual); Assert.False(p16.IsSealed); Assert.False(p16.IsStatic); Assert.False(p16.IsExtern); Assert.False(p16.IsOverride); Assert.Equal(Accessibility.Public, p16.DeclaredAccessibility); ValidateP16Accessor(p16.GetMethod, Accessibility.Private); ValidateP16Accessor(p16.SetMethod, Accessibility.Public); void ValidateP16Accessor(MethodSymbol accessor, Accessibility accessibility) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(accessibility, accessor.DeclaredAccessibility); } var p17 = compilation1.GetMember("I17.this[]"); var p17get = p17.GetMethod; Assert.True(p17.IsAbstract); Assert.False(p17.IsVirtual); Assert.False(p17.IsSealed); Assert.False(p17.IsStatic); Assert.False(p17.IsExtern); Assert.False(p17.IsOverride); Assert.Equal(Accessibility.Public, p17.DeclaredAccessibility); Assert.True(p17get.IsAbstract); Assert.False(p17get.IsVirtual); Assert.True(p17get.IsMetadataVirtual()); Assert.False(p17get.IsSealed); Assert.False(p17get.IsStatic); Assert.False(p17get.IsExtern); Assert.False(p17get.IsAsync); Assert.False(p17get.IsOverride); Assert.Equal(Accessibility.Private, p17get.DeclaredAccessibility); var p18 = compilation1.GetMember("I18.this[]"); var p18get = p18.GetMethod; Assert.True(p18.IsAbstract); Assert.False(p18.IsVirtual); Assert.False(p18.IsSealed); Assert.False(p18.IsStatic); Assert.False(p18.IsExtern); Assert.False(p18.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, p18.DeclaredAccessibility); Assert.True(p18get.IsAbstract); Assert.False(p18get.IsVirtual); Assert.True(p18get.IsMetadataVirtual()); Assert.False(p18get.IsSealed); Assert.False(p18get.IsStatic); Assert.False(p18get.IsExtern); Assert.False(p18get.IsAsync); Assert.False(p18get.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, p18get.DeclaredAccessibility); var p19 = compilation1.GetMember("I19.this[]"); Assert.True(p19.IsAbstract); Assert.False(p19.IsVirtual); Assert.False(p19.IsSealed); Assert.False(p19.IsStatic); Assert.False(p19.IsExtern); Assert.False(p19.IsOverride); Assert.Equal(Accessibility.Public, p19.DeclaredAccessibility); ValidateP13Accessor(p19.GetMethod, Accessibility.Public); ValidateP13Accessor(p19.SetMethod, Accessibility.ProtectedAndInternal); } [Fact] public void IndexerModifiers_02() { var source1 = @" public interface I01{ public int this[int x] {get; set;} } public interface I02{ protected int this[int x] {get;} } public interface I03{ protected internal int this[int x] {set;} } public interface I04{ internal int this[int x] {get;} } public interface I05{ private int this[int x] {set;} } public interface I06{ static int this[int x] {get;} } public interface I07{ virtual int this[int x] {set;} } public interface I08{ sealed int this[int x] {get;} } public interface I09{ override int this[int x] {set;} } public interface I10{ abstract int this[int x] {get;} } public interface I11{ extern int this[int x] {get; set;} } public interface I12{ int this[int x] { public get; set;} } public interface I13{ int this[int x] { get; protected set;} } public interface I14{ int this[int x] { protected internal get; set;} } public interface I15{ int this[int x] { get; internal set;} } public interface I16{ int this[int x] { private get; set;} } public interface I17{ int this[int x] { private get;} } public interface I18{ private protected int this[int x] { get; } } public interface I19{ int this[int x] { get; private protected set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (2,34): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I01{ public int this[int x] {get; set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("public", "7.3", "8.0").WithLocation(2, 34), // (3,37): error CS8703: The modifier 'protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I02{ protected int this[int x] {get;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("protected", "7.3", "8.0").WithLocation(3, 37), // (4,46): error CS8703: The modifier 'protected internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I03{ protected internal int this[int x] {set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("protected internal", "7.3", "8.0").WithLocation(4, 46), // (5,36): error CS8503: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I04{ internal int this[int x] {get;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("internal", "7.3", "8.0").WithLocation(5, 36), // (6,35): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I05{ private int this[int x] {set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("private", "7.3", "8.0").WithLocation(6, 35), // (6,48): error CS0501: 'I05.this[int].set' must declare a body because it is not marked abstract, extern, or partial // public interface I05{ private int this[int x] {set;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I05.this[int].set").WithLocation(6, 48), // (7,34): error CS0106: The modifier 'static' is not valid for this item // public interface I06{ static int this[int x] {get;} } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(7, 34), // (8,35): error CS8503: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I07{ virtual int this[int x] {set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("virtual", "7.3", "8.0").WithLocation(8, 35), // (8,48): error CS0501: 'I07.this[int].set' must declare a body because it is not marked abstract, extern, or partial // public interface I07{ virtual int this[int x] {set;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I07.this[int].set").WithLocation(8, 48), // (9,34): error CS8503: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I08{ sealed int this[int x] {get;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("sealed", "7.3", "8.0").WithLocation(9, 34), // (9,47): error CS0501: 'I08.this[int].get' must declare a body because it is not marked abstract, extern, or partial // public interface I08{ sealed int this[int x] {get;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I08.this[int].get").WithLocation(9, 47), // (10,36): error CS0106: The modifier 'override' is not valid for this item // public interface I09{ override int this[int x] {set;} } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("override").WithLocation(10, 36), // (11,36): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I10{ abstract int this[int x] {get;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("abstract", "7.3", "8.0").WithLocation(11, 36), // (12,34): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("extern", "7.3", "8.0").WithLocation(12, 34), // (14,48): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I12{ int this[int x] { public get; set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("public", "7.3", "8.0").WithLocation(14, 48), // (14,48): error CS0273: The accessibility modifier of the 'I12.this[int].get' accessor must be more restrictive than the property or indexer 'I12.this[int]' // public interface I12{ int this[int x] { public get; set;} } Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "get").WithArguments("I12.this[int].get", "I12.this[int]").WithLocation(14, 48), // (15,56): error CS8703: The modifier 'protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I13{ int this[int x] { get; protected set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("protected", "7.3", "8.0").WithLocation(15, 56), // (16,60): error CS8703: The modifier 'protected internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I14{ int this[int x] { protected internal get; set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("protected internal", "7.3", "8.0").WithLocation(16, 60), // (17,55): error CS8503: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I15{ int this[int x] { get; internal set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("internal", "7.3", "8.0").WithLocation(17, 55), // (18,49): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I16{ int this[int x] { private get; set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("private", "7.3", "8.0").WithLocation(18, 49), // (18,49): error CS0442: 'I16.this[int].get': abstract properties cannot have private accessors // public interface I16{ int this[int x] { private get; set;} } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I16.this[int].get").WithLocation(18, 49), // (19,49): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I17{ int this[int x] { private get;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "get").WithArguments("private", "7.3", "8.0").WithLocation(19, 49), // (19,27): error CS0276: 'I17.this[int]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // public interface I17{ int this[int x] { private get;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I17.this[int]").WithLocation(19, 27), // (21,45): error CS8703: The modifier 'private protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I18{ private protected int this[int x] { get; } } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("private protected", "7.3", "8.0").WithLocation(21, 45), // (22,64): error CS8703: The modifier 'private protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public interface I19{ int this[int x] { get; private protected set;} } Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("private protected", "7.3", "8.0").WithLocation(22, 64), // (12,47): warning CS0626: Method, operator, or accessor 'I11.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I11.this[int].get").WithLocation(12, 47), // (12,52): warning CS0626: Method, operator, or accessor 'I11.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I11.this[int].set").WithLocation(12, 52) ); ValidateSymbolsIndexerModifiers_01(compilation1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (3,37): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // public interface I02{ protected int this[int x] {get;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "this").WithLocation(3, 37), // (4,46): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // public interface I03{ protected internal int this[int x] {set;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "this").WithLocation(4, 46), // (6,48): error CS0501: 'I05.this[int].set' must declare a body because it is not marked abstract, extern, or partial // public interface I05{ private int this[int x] {set;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I05.this[int].set").WithLocation(6, 48), // (7,34): error CS0106: The modifier 'static' is not valid for this item // public interface I06{ static int this[int x] {get;} } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(7, 34), // (8,48): error CS0501: 'I07.this[int].set' must declare a body because it is not marked abstract, extern, or partial // public interface I07{ virtual int this[int x] {set;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I07.this[int].set").WithLocation(8, 48), // (9,47): error CS0501: 'I08.this[int].get' must declare a body because it is not marked abstract, extern, or partial // public interface I08{ sealed int this[int x] {get;} } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I08.this[int].get").WithLocation(9, 47), // (10,36): error CS0106: The modifier 'override' is not valid for this item // public interface I09{ override int this[int x] {set;} } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("override").WithLocation(10, 36), // (12,47): error CS8701: Target runtime doesn't support default interface implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(12, 47), // (12,47): warning CS0626: Method, operator, or accessor 'I11.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I11.this[int].get").WithLocation(12, 47), // (12,52): error CS8701: Target runtime doesn't support default interface implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(12, 52), // (12,52): warning CS0626: Method, operator, or accessor 'I11.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // public interface I11{ extern int this[int x] {get; set;} } Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I11.this[int].set").WithLocation(12, 52), // (14,48): error CS0273: The accessibility modifier of the 'I12.this[int].get' accessor must be more restrictive than the property or indexer 'I12.this[int]' // public interface I12{ int this[int x] { public get; set;} } Diagnostic(ErrorCode.ERR_InvalidPropertyAccessMod, "get").WithArguments("I12.this[int].get", "I12.this[int]").WithLocation(14, 48), // (15,56): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // public interface I13{ int this[int x] { get; protected set;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "set").WithLocation(15, 56), // (16,60): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // public interface I14{ int this[int x] { protected internal get; set;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "get").WithLocation(16, 60), // (18,49): error CS0442: 'I16.this[int].get': abstract properties cannot have private accessors // public interface I16{ int this[int x] { private get; set;} } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I16.this[int].get").WithLocation(18, 49), // (19,27): error CS0276: 'I17.this[int]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // public interface I17{ int this[int x] { private get;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I17.this[int]").WithLocation(19, 27), // (21,45): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // public interface I18{ private protected int this[int x] { get; } } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "this").WithLocation(21, 45), // (22,64): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // public interface I19{ int this[int x] { get; private protected set;} } Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "set").WithLocation(22, 64) ); ValidateSymbolsIndexerModifiers_01(compilation2); } [Fact] public void IndexerModifiers_03() { ValidateIndexerImplementation_101(@" public interface I1 { public virtual int this[int i] { get { System.Console.WriteLine(""get P1""); return 0; } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "); ValidateIndexerImplementation_101(@" public interface I1 { public virtual int this[int i] { get => Test1.GetP1(); } } class Test1 : I1 { public static int GetP1() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "); ValidateIndexerImplementation_101(@" public interface I1 { public virtual int this[int i] => Test1.GetP1(); } class Test1 : I1 { public static int GetP1() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "); ValidateIndexerImplementation_102(@" public interface I1 { public virtual int this[int i] { get { System.Console.WriteLine(""get P1""); return 0; } set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1[0] = i1[0]; } } "); ValidateIndexerImplementation_102(@" public interface I1 { public virtual int this[int i] { get => Test1.GetP1(); set => System.Console.WriteLine(""set P1""); } } class Test1 : I1 { public static int GetP1() { System.Console.WriteLine(""get P1""); return 0; } static void Main() { I1 i1 = new Test1(); i1[0] = i1[0]; } } "); ValidateIndexerImplementation_103(@" public interface I1 { public virtual int this[int i] { set { System.Console.WriteLine(""set P1""); } } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } } "); ValidateIndexerImplementation_103(@" public interface I1 { public virtual int this[int i] { set => System.Console.WriteLine(""set P1""); } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } } "); } [Fact] public void IndexerModifiers_04() { var source1 = @" public interface I1 { public virtual int this[int x] { get; } = 0; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (4,45): error CS1519: Invalid token '=' in class, struct, or interface member declaration // public virtual int this[int x] { get; } = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(4, 45), // (4,38): error CS0501: 'I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // public virtual int this[int x] { get; } = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.this[int].get").WithLocation(4, 38) ); ValidatePropertyModifiers_04(compilation1, "this[]"); } [Fact] public void IndexerModifiers_05() { var source1 = @" public interface I1 { public abstract int this[int x] {get; set;} } public interface I2 { int this[int x] {get; set;} } class Test1 : I1 { public int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set => System.Console.WriteLine(""set_P1""); } } class Test2 : I2 { public int this[int x] { get { System.Console.WriteLine(""get_P2""); return 0; } set => System.Console.WriteLine(""set_P2""); } static void Main() { I1 x = new Test1(); x[0] = x[0]; I2 y = new Test2(); y[0] = y[0]; } } "; ValidatePropertyModifiers_05(source1); } [Fact] public void IndexerModifiers_06() { var source1 = @" public interface I1 { public abstract int this[int x] {get; set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3); compilation1.VerifyDiagnostics( // (4,25): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract int this[int x] {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("abstract", "7.3", "8.0").WithLocation(4, 25), // (4,25): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract int this[int x] {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("public", "7.3", "8.0").WithLocation(4, 25) ); ValidatePropertyModifiers_06(compilation1, "this[]"); } [Fact] public void IndexerModifiers_09() { var source1 = @" public interface I1 { private int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } } sealed void M() { var x = this[0]; } } public interface I2 { private int this[int x] { get { System.Console.WriteLine(""get_P2""); return 0; } set { System.Console.WriteLine(""set_P2""); } } sealed void M() { this[0] = this[0]; } } public interface I3 { private int this[int x] { set { System.Console.WriteLine(""set_P3""); } } sealed void M() { this[0] = 0; } } public interface I4 { private int this[int x] { get => GetP4(); } private int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } sealed void M() { var x = this[0]; } } public interface I5 { private int this[int x] { get => GetP5(); set => System.Console.WriteLine(""set_P5""); } private int GetP5() { System.Console.WriteLine(""get_P5""); return 0; } sealed void M() { this[0] = this[0]; } } public interface I6 { private int this[int x] { set => System.Console.WriteLine(""set_P6""); } sealed void M() { this[0] = 0; } } public interface I7 { private int this[int x] => GetP7(); private int GetP7() { System.Console.WriteLine(""get_P7""); return 0; } sealed void M() { var x = this[0]; } } class Test1 : I1, I2, I3, I4, I5, I6, I7 { static void Main() { I1 x1 = new Test1(); x1.M(); I2 x2 = new Test1(); x2.M(); I3 x3 = new Test1(); x3.M(); I4 x4 = new Test1(); x4.M(); I5 x5 = new Test1(); x5.M(); I6 x6 = new Test1(); x6.M(); I7 x7 = new Test1(); x7.M(); } } "; ValidatePropertyModifiers_09(source1); } [Fact] public void IndexerModifiers_10() { var source1 = @" public interface I1 { abstract private int this[byte x] { get; } virtual private int this[int x] => 0; sealed private int this[short x] { get => 0; set {} } private int this[long x] {get;} = 0; } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,37): error CS1519: Invalid token '=' in class, struct, or interface member declaration // private int this[long x] {get;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(14, 37), // (4,26): error CS0621: 'I1.this[byte]': virtual or abstract members cannot be private // abstract private int this[byte x] { get; } Diagnostic(ErrorCode.ERR_VirtualPrivate, "this").WithArguments("I1.this[byte]").WithLocation(4, 26), // (6,25): error CS0621: 'I1.this[int]': virtual or abstract members cannot be private // virtual private int this[int x] => 0; Diagnostic(ErrorCode.ERR_VirtualPrivate, "this").WithArguments("I1.this[int]").WithLocation(6, 25), // (8,24): error CS0238: 'I1.this[short]' cannot be sealed because it is not an override // sealed private int this[short x] Diagnostic(ErrorCode.ERR_SealedNonOverride, "this").WithArguments("I1.this[short]").WithLocation(8, 24), // (14,31): error CS0501: 'I1.this[long].get' must declare a body because it is not marked abstract, extern, or partial // private int this[long x] {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.this[long].get").WithLocation(14, 31), // (17,15): error CS0535: 'Test1' does not implement interface member 'I1.this[byte]' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[byte]") ); ValidatePropertyModifiers_10(compilation1); } [Fact] public void IndexerModifiers_11_01() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} sealed void Test() { this[0] = this[0]; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.Test(); } public int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_01(source1, source2, Accessibility.Internal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.this[int]' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.this[int]") ); } [Fact] public void IndexerModifiers_11_02() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_11_03() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } int I1.this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,12): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // int I1.this[int x] Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(9, 12) ); } [Fact] public void IndexerModifiers_11_04() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_11_05() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_11_06() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract int this[int x] {get; set;} } class Test3 : Test1 { public override int this[int x] { get { System.Console.WriteLine(""Test3.get_P1""); return 0; } set { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_11_07() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { int this[int x] {get; set;} } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1, I2 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1, I2 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_11_08() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_08(source1, source2); } [Fact] public void IndexerModifiers_11_09() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_11_10() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } "; var source2 = @" public class Test2 : I1 { public int this[int x] { get { return 0; } set {} } } class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].set'. 'Test2.this[int].set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].set", "Test2.this[int].set").WithLocation(2, 22), // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].get'. 'Test2.this[int].get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].get", "Test2.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_11_11() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } public class Test2 : I1 { public int this[int x] { get { return 0; } set {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].set'. 'Test2.this[int].set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].set", "Test2.this[int].set").WithLocation(6, 22), // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].get'. 'Test2.this[int].get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].get", "Test2.this[int].get").WithLocation(6, 22) ); } [Fact] public void IndexerModifiers_12() { var source1 = @" public interface I1 { internal abstract int this[int x] {get; set;} } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[int]") ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember("this[]"); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Null(test1.FindImplementationForInterfaceMember(p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(p1.SetMethod)); } [Fact] public void IndexerModifiers_13() { var source1 = @" public interface I1 { public sealed int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } } } public interface I2 { public sealed int this[int x] { get { System.Console.WriteLine(""get_P2""); return 0; } set { System.Console.WriteLine(""set_P2""); } } } public interface I3 { public sealed int this[int x] { set { System.Console.WriteLine(""set_P3""); } } } public interface I4 { public sealed int this[int x] { get => GetP4(); } private int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } public interface I5 { public sealed int this[int x] { get => GetP5(); set => System.Console.WriteLine(""set_P5""); } private int GetP5() { System.Console.WriteLine(""get_P5""); return 0; } } public interface I6 { public sealed int this[int x] { set => System.Console.WriteLine(""set_P6""); } } public interface I7 { public sealed int this[int x] => GetP7(); private int GetP7() { System.Console.WriteLine(""get_P7""); return 0; } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); var x = i1[0]; I2 i2 = new Test2(); i2[0] = i2[0]; I3 i3 = new Test3(); i3[0] = x; I4 i4 = new Test4(); x = i4[0]; I5 i5 = new Test5(); i5[0] = i5[0]; I6 i6 = new Test6(); i6[0] = x; I7 i7 = new Test7(); x = i7[0]; } public int this[int x] => throw null; } class Test2 : I2 { public int this[int x] { get => throw null; set => throw null; } } class Test3 : I3 { public int this[int x] { set => throw null; } } class Test4 : I4 { public int this[int x] { get => throw null; } } class Test5 : I5 { public int this[int x] { get => throw null; set => throw null; } } class Test6 : I6 { public int this[int x] { set => throw null; } } class Test7 : I7 { public int this[int x] => throw null; } "; ValidatePropertyModifiers_13(source1); } [Fact] public void AccessModifiers_14() { var source1 = @" public interface I1 { public sealed int this[int x] {get;} = 0; } public interface I2 { abstract sealed int this[int x] {get;} } public interface I3 { virtual sealed int this[int x] { set {} } } class Test1 : I1, I2, I3 { int I1.this[int x] { get => throw null; } int I2.this[int x] { get => throw null; } int I3.this[int x] { set => throw null; } } class Test2 : I1, I2, I3 {} "; ValidatePropertyModifiers_14(source1, // (4,42): error CS1519: Invalid token '=' in class, struct, or interface member declaration // public sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(4, 42), // (4,36): error CS0501: 'I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // public sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.this[int].get").WithLocation(4, 36), // (8,25): error CS0238: 'I2.this[int]' cannot be sealed because it is not an override // abstract sealed int this[int x] {get;} Diagnostic(ErrorCode.ERR_SealedNonOverride, "this").WithArguments("I2.this[int]").WithLocation(8, 25), // (12,24): error CS0238: 'I3.this[int]' cannot be sealed because it is not an override // virtual sealed int this[int x] Diagnostic(ErrorCode.ERR_SealedNonOverride, "this").WithArguments("I3.this[int]").WithLocation(12, 24), // (20,12): error CS0539: 'Test1.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I1.this[int x] { get => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test1.this[int]").WithLocation(20, 12), // (21,12): error CS0539: 'Test1.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I2.this[int x] { get => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test1.this[int]").WithLocation(21, 12), // (22,12): error CS0539: 'Test1.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I3.this[int x] { set => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test1.this[int]").WithLocation(22, 12) ); } [Fact] public void IndexerModifiers_15() { var source1 = @" public interface I0 { abstract virtual int this[int x] { get; set; } } public interface I1 { abstract virtual int this[int x] { get { throw null; } } } public interface I2 { virtual abstract int this[int x] { get { throw null; } set { throw null; } } } public interface I3 { abstract virtual int this[int x] { set { throw null; } } } public interface I4 { abstract virtual int this[int x] { get => throw null; } } public interface I5 { abstract virtual int this[int x] { get => throw null; set => throw null; } } public interface I6 { abstract virtual int this[int x] { set => throw null; } } public interface I7 { abstract virtual int this[int x] => throw null; } public interface I8 { abstract virtual int this[int x] {get;} = 0; } class Test1 : I0, I1, I2, I3, I4, I5, I6, I7, I8 { int I0.this[int x] { get { throw null; } set { throw null; } } int I1.this[int x] { get { throw null; } } int I2.this[int x] { get { throw null; } set { throw null; } } int I3.this[int x] { set { throw null; } } int I4.this[int x] { get { throw null; } } int I5.this[int x] { get { throw null; } set { throw null; } } int I6.this[int x] { set { throw null; } } int I7.this[int x] { get { throw null; } } int I8.this[int x] { get { throw null; } } } class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 {} "; ValidatePropertyModifiers_15(source1, // (44,45): error CS1519: Invalid token '=' in class, struct, or interface member declaration // abstract virtual int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(44, 45), // (4,26): error CS0503: The abstract property 'I0.this[int]' cannot be marked virtual // abstract virtual int this[int x] { get; set; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I0.this[int]").WithLocation(4, 26), // (8,26): error CS0503: The abstract property 'I1.this[int]' cannot be marked virtual // abstract virtual int this[int x] { get { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I1.this[int]").WithLocation(8, 26), // (8,40): error CS0500: 'I1.this[int].get' cannot declare a body because it is marked abstract // abstract virtual int this[int x] { get { throw null; } } Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.this[int].get").WithLocation(8, 40), // (12,26): error CS0503: The abstract property 'I2.this[int]' cannot be marked virtual // virtual abstract int this[int x] Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I2.this[int]").WithLocation(12, 26), // (14,9): error CS0500: 'I2.this[int].get' cannot declare a body because it is marked abstract // get { throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.this[int].get").WithLocation(14, 9), // (15,9): error CS0500: 'I2.this[int].set' cannot declare a body because it is marked abstract // set { throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.this[int].set").WithLocation(15, 9), // (20,26): error CS0503: The abstract property 'I3.this[int]' cannot be marked virtual // abstract virtual int this[int x] { set { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I3.this[int]").WithLocation(20, 26), // (20,40): error CS0500: 'I3.this[int].set' cannot declare a body because it is marked abstract // abstract virtual int this[int x] { set { throw null; } } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I3.this[int].set").WithLocation(20, 40), // (24,26): error CS0503: The abstract property 'I4.this[int]' cannot be marked virtual // abstract virtual int this[int x] { get => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I4.this[int]").WithLocation(24, 26), // (24,40): error CS0500: 'I4.this[int].get' cannot declare a body because it is marked abstract // abstract virtual int this[int x] { get => throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I4.this[int].get").WithLocation(24, 40), // (28,26): error CS0503: The abstract property 'I5.this[int]' cannot be marked virtual // abstract virtual int this[int x] Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I5.this[int]").WithLocation(28, 26), // (30,9): error CS0500: 'I5.this[int].get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I5.this[int].get").WithLocation(30, 9), // (31,9): error CS0500: 'I5.this[int].set' cannot declare a body because it is marked abstract // set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I5.this[int].set").WithLocation(31, 9), // (36,26): error CS0503: The abstract property 'I6.this[int]' cannot be marked virtual // abstract virtual int this[int x] { set => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I6.this[int]").WithLocation(36, 26), // (36,40): error CS0500: 'I6.this[int].set' cannot declare a body because it is marked abstract // abstract virtual int this[int x] { set => throw null; } Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I6.this[int].set").WithLocation(36, 40), // (40,26): error CS0503: The abstract property 'I7.this[int]' cannot be marked virtual // abstract virtual int this[int x] => throw null; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I7.this[int]").WithLocation(40, 26), // (40,41): error CS0500: 'I7.this[int].get' cannot declare a body because it is marked abstract // abstract virtual int this[int x] => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "throw null").WithArguments("I7.this[int].get").WithLocation(40, 41), // (44,26): error CS0503: The abstract property 'I8.this[int]' cannot be marked virtual // abstract virtual int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "this").WithArguments("property", "I8.this[int]").WithLocation(44, 26), // (90,15): error CS0535: 'Test2' does not implement interface member 'I0.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I0").WithArguments("Test2", "I0.this[int]").WithLocation(90, 15), // (90,19): error CS0535: 'Test2' does not implement interface member 'I1.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.this[int]").WithLocation(90, 19), // (90,23): error CS0535: 'Test2' does not implement interface member 'I2.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I2.this[int]").WithLocation(90, 23), // (90,27): error CS0535: 'Test2' does not implement interface member 'I3.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test2", "I3.this[int]").WithLocation(90, 27), // (90,31): error CS0535: 'Test2' does not implement interface member 'I4.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I4").WithArguments("Test2", "I4.this[int]").WithLocation(90, 31), // (90,35): error CS0535: 'Test2' does not implement interface member 'I5.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test2", "I5.this[int]").WithLocation(90, 35), // (90,39): error CS0535: 'Test2' does not implement interface member 'I6.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I6").WithArguments("Test2", "I6.this[int]").WithLocation(90, 39), // (90,43): error CS0535: 'Test2' does not implement interface member 'I7.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I7").WithArguments("Test2", "I7.this[int]").WithLocation(90, 43), // (90,47): error CS0535: 'Test2' does not implement interface member 'I8.this[int]' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I8").WithArguments("Test2", "I8.this[int]").WithLocation(90, 47) ); } [Fact] public void IndexerModifiers_16() { var source1 = @" public interface I1 { extern int this[int x] {get;} } public interface I2 { virtual extern int this[int x] {set;} } public interface I4 { private extern int this[int x] {get;} } public interface I5 { extern sealed int this[int x] {set;} } class Test1 : I1, I2, I4, I5 { } class Test2 : I1, I2, I4, I5 { int I1.this[int x] => 0; int I2.this[int x] { set {} } } "; ValidatePropertyModifiers_16(source1, new DiagnosticDescription[] { // (4,16): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern int this[int x] {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("extern", "7.3", "8.0").WithLocation(4, 16), // (8,24): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern int this[int x] {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("extern", "7.3", "8.0").WithLocation(8, 24), // (8,24): error CS8503: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern int this[int x] {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("virtual", "7.3", "8.0").WithLocation(8, 24), // (12,24): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern int this[int x] {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("private", "7.3", "8.0").WithLocation(12, 24), // (12,24): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern int this[int x] {get;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("extern", "7.3", "8.0").WithLocation(12, 24), // (16,23): error CS8503: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed int this[int x] {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("sealed", "7.3", "8.0").WithLocation(16, 23), // (16,23): error CS8503: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed int this[int x] {set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "this").WithArguments("extern", "7.3", "8.0").WithLocation(16, 23), // (8,37): warning CS0626: Method, operator, or accessor 'I2.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern int this[int x] {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I2.this[int].set").WithLocation(8, 37), // (12,37): warning CS0626: Method, operator, or accessor 'I4.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern int this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I4.this[int].get").WithLocation(12, 37), // (16,36): warning CS0626: Method, operator, or accessor 'I5.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed int this[int x] {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I5.this[int].set").WithLocation(16, 36), // (4,29): warning CS0626: Method, operator, or accessor 'I1.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.this[int].get").WithLocation(4, 29) }, // (4,29): error CS8501: Target runtime doesn't support default interface implementation. // extern int this[int x] {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(4, 29), // (8,37): error CS8501: Target runtime doesn't support default interface implementation. // virtual extern int this[int x] {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(8, 37), // (12,37): error CS8501: Target runtime doesn't support default interface implementation. // private extern int this[int x] {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(12, 37), // (16,36): error CS8501: Target runtime doesn't support default interface implementation. // extern sealed int this[int x] {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(16, 36), // (8,37): warning CS0626: Method, operator, or accessor 'I2.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern int this[int x] {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I2.this[int].set").WithLocation(8, 37), // (12,37): warning CS0626: Method, operator, or accessor 'I4.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern int this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I4.this[int].get").WithLocation(12, 37), // (16,36): warning CS0626: Method, operator, or accessor 'I5.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed int this[int x] {set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I5.this[int].set").WithLocation(16, 36), // (4,29): warning CS0626: Method, operator, or accessor 'I1.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.this[int].get").WithLocation(4, 29) ); } [Fact] public void IndexerModifiers_17() { var source1 = @" public interface I1 { abstract extern int this[int x] {get;} } public interface I2 { extern int this[int x] => 0; } public interface I3 { static extern int this[int x] {get => 0; set => throw null;} } public interface I4 { private extern int this[int x] { get {throw null;} set {throw null;}} } public interface I5 { extern sealed int this[int x] {get;} = 0; } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { int I1.this[int x] => 0; int I2.this[int x] => 0; int I3.this[int x] { get => 0; set => throw null;} int I4.this[int x] { get => 0; set => throw null;} int I5.this[int x] => 0; } "; ValidatePropertyModifiers_17(source1, // (20,42): error CS1519: Invalid token '=' in class, struct, or interface member declaration // extern sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(20, 42), // (4,25): error CS0180: 'I1.this[int]' cannot be both extern and abstract // abstract extern int this[int x] {get;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I1.this[int]").WithLocation(4, 25), // (8,31): error CS0179: 'I2.this[int].get' cannot be extern and declare a body // extern int this[int x] => 0; Diagnostic(ErrorCode.ERR_ExternHasBody, "0").WithArguments("I2.this[int].get").WithLocation(8, 31), // (12,23): error CS0106: The modifier 'static' is not valid for this item // static extern int this[int x] {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(12, 23), // (12,36): error CS0179: 'I3.this[int].get' cannot be extern and declare a body // static extern int this[int x] {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_ExternHasBody, "get").WithArguments("I3.this[int].get").WithLocation(12, 36), // (12,46): error CS0179: 'I3.this[int].set' cannot be extern and declare a body // static extern int this[int x] {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I3.this[int].set").WithLocation(12, 46), // (16,38): error CS0179: 'I4.this[int].get' cannot be extern and declare a body // private extern int this[int x] { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "get").WithArguments("I4.this[int].get").WithLocation(16, 38), // (16,56): error CS0179: 'I4.this[int].set' cannot be extern and declare a body // private extern int this[int x] { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I4.this[int].set").WithLocation(16, 56), // (23,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[int]"), // (32,12): error CS0539: 'Test2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I4.this[int x] { get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test2.this[int]").WithLocation(32, 12), // (33,12): error CS0539: 'Test2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I5.this[int x] => 0; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test2.this[int]").WithLocation(33, 12), // (20,36): warning CS0626: Method, operator, or accessor 'I5.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I5.this[int].get").WithLocation(20, 36) ); } [Fact] public void IndexerModifiers_18() { var source1 = @" public interface I1 { abstract int this[int x] {get => 0; set => throw null;} } public interface I2 { abstract private int this[int x] => 0; } public interface I3 { static extern int this[int x] {get; set;} } public interface I4 { abstract static int this[int x] { get {throw null;} set {throw null;}} } public interface I5 { override sealed int this[int x] {get;} = 0; } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { int I1.this[int x] { get => 0; set => throw null;} int I2.this[int x] => 0; int I3.this[int x] { get => 0; set => throw null;} int I4.this[int x] { get => 0; set => throw null;} int I5.this[int x] => 0; } "; ValidatePropertyModifiers_18(source1, // (20,44): error CS1519: Invalid token '=' in class, struct, or interface member declaration // override sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(20, 44), // (4,31): error CS0500: 'I1.this[int].get' cannot declare a body because it is marked abstract // abstract int this[int x] {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.this[int].get").WithLocation(4, 31), // (4,41): error CS0500: 'I1.this[int].set' cannot declare a body because it is marked abstract // abstract int this[int x] {get => 0; set => throw null;} Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I1.this[int].set").WithLocation(4, 41), // (8,26): error CS0621: 'I2.this[int]': virtual or abstract members cannot be private // abstract private int this[int x] => 0; Diagnostic(ErrorCode.ERR_VirtualPrivate, "this").WithArguments("I2.this[int]").WithLocation(8, 26), // (8,41): error CS0500: 'I2.this[int].get' cannot declare a body because it is marked abstract // abstract private int this[int x] => 0; Diagnostic(ErrorCode.ERR_AbstractHasBody, "0").WithArguments("I2.this[int].get").WithLocation(8, 41), // (12,23): error CS0106: The modifier 'static' is not valid for this item // static extern int this[int x] {get; set;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(12, 23), // (16,25): error CS0106: The modifier 'static' is not valid for this item // abstract static int this[int x] { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(16, 25), // (16,39): error CS0500: 'I4.this[int].get' cannot declare a body because it is marked abstract // abstract static int this[int x] { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I4.this[int].get").WithLocation(16, 39), // (16,57): error CS0500: 'I4.this[int].set' cannot declare a body because it is marked abstract // abstract static int this[int x] { get {throw null;} set {throw null;}} Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I4.this[int].set").WithLocation(16, 57), // (20,25): error CS0106: The modifier 'override' is not valid for this item // override sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("override").WithLocation(20, 25), // (20,38): error CS0501: 'I5.this[int].get' must declare a body because it is not marked abstract, extern, or partial // override sealed int this[int x] {get;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I5.this[int].get").WithLocation(20, 38), // (23,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[int]"), // (23,19): error CS0535: 'Test1' does not implement interface member 'I2.this[int]' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I2.this[int]"), // (23,27): error CS0535: 'Test1' does not implement interface member 'I4.this[int]' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I4").WithArguments("Test1", "I4.this[int]").WithLocation(23, 27), // (30,12): error CS0122: 'I2.this[int]' is inaccessible due to its protection level // int I2.this[int x] => 0; Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I2.this[int]").WithLocation(30, 12), // (33,12): error CS0539: 'Test2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // int I5.this[int x] => 0; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("Test2.this[int]").WithLocation(33, 12), // (12,36): warning CS0626: Method, operator, or accessor 'I3.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int this[int x] {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I3.this[int].get").WithLocation(12, 36), // (12,41): warning CS0626: Method, operator, or accessor 'I3.this[int].set' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern int this[int x] {get; set;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "set").WithArguments("I3.this[int].set").WithLocation(12, 41) ); } [Fact] public void IndexerModifiers_20() { var source1 = @" public interface I1 { internal int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } void M2() {this[0] = this[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_20(source1, source2, Accessibility.Internal); } [Fact] public void IndexerModifiers_21() { var source1 = @" public interface I1 { private int this[int x] { get => throw null; set => throw null; } } public interface I2 { internal int this[int x] { get => throw null; set => throw null; } } public interface I3 { public int this[int x] { get => throw null; set => throw null; } } public interface I4 { int this[int x] { get => throw null; set => throw null; } } class Test1 { static void Test(I1 i1, I2 i2, I3 i3, I4 i4) { int x; x = i1[0]; i1[0] = x; x = i2[0]; i2[0] = x; x = i3[0]; i3[0] = x; x = i4[0]; i4[0] = x; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (24,13): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // x = i1[0]; Diagnostic(ErrorCode.ERR_BadAccess, "i1[0]").WithArguments("I1.this[int]").WithLocation(24, 13), // (25,9): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // i1[0] = x; Diagnostic(ErrorCode.ERR_BadAccess, "i1[0]").WithArguments("I1.this[int]").WithLocation(25, 9) ); var source2 = @" class Test2 { static void Test(I1 i1, I2 i2, I3 i3, I4 i4) { int x; x = i1[0]; i1[0] = x; x = i2[0]; i2[0] = x; x = i3[0]; i3[0] = x; x = i4[0]; i4[0] = x; } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (7,13): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // x = i1[0]; Diagnostic(ErrorCode.ERR_BadAccess, "i1[0]").WithArguments("I1.this[int]").WithLocation(7, 13), // (8,9): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // i1[0] = x; Diagnostic(ErrorCode.ERR_BadAccess, "i1[0]").WithArguments("I1.this[int]").WithLocation(8, 9), // (9,13): error CS0122: 'I2.this[int]' is inaccessible due to its protection level // x = i2[0]; Diagnostic(ErrorCode.ERR_BadAccess, "i2[0]").WithArguments("I2.this[int]").WithLocation(9, 13), // (10,9): error CS0122: 'I2.this[int]' is inaccessible due to its protection level // i2[0] = x; Diagnostic(ErrorCode.ERR_BadAccess, "i2[0]").WithArguments("I2.this[int]").WithLocation(10, 9) ); } [Fact] public void IndexerModifiers_22() { var source1 = @" public interface I1 { public int this[int x] { internal get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } public interface I2 { int this[int x] { get { System.Console.WriteLine(""get_P2""); return 0; } internal set { System.Console.WriteLine(""set_P2""); } } } public interface I3 { int this[int x] { internal get => Test1.GetP3(); set => System.Console.WriteLine(""set_P3""); } } public interface I4 { int this[int x] { get => Test1.GetP4(); internal set => System.Console.WriteLine(""set_P4""); } } class Test1 : I1, I2, I3, I4 { static void Main() { I1 i1 = new Test1(); I2 i2 = new Test1(); I3 i3 = new Test1(); I4 i4 = new Test1(); i1[0] = i1[0]; i2[0] = i2[0]; i3[0] = i3[0]; i4[0] = i4[0]; } public static int GetP3() { System.Console.WriteLine(""get_P3""); return 0; } public static int GetP4() { System.Console.WriteLine(""get_P4""); return 0; } } "; ValidatePropertyModifiers_22(source1, Accessibility.Internal); } [Fact] public void IndexerModifiers_23_00() { var source1 = @" public interface I1 { } public interface I3 { int this[int x] { private get { System.Console.WriteLine(""get_P3""); return 0; } set {System.Console.WriteLine(""set_P3"");} } void M2() { this[0] = this[1]; } } public interface I4 { int this[int x] { get {System.Console.WriteLine(""get_P4""); return 0;} private set {System.Console.WriteLine(""set_P4"");} } void M2() { this[0] = this[1]; } } public interface I5 { int this[int x] { private get => GetP5(); set => System.Console.WriteLine(""set_P5""); } private int GetP5() { System.Console.WriteLine(""get_P5""); return 0; } void M2() { this[0] = this[1]; } } public interface I6 { int this[int x] { get => GetP6(); private set => System.Console.WriteLine(""set_P6""); } private int GetP6() { System.Console.WriteLine(""get_P6""); return 0; } void M2() { this[0] = this[1]; } } "; var source2 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public int this[int x] { get { throw null; } set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public int this[int x] { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } set { throw null; } } } class Test5 : I5 { public int this[int x] { get { throw null; } set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public int this[int x] { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } set { throw null; } } } "; ValidatePropertyModifiers_23(source1, source2); var source3 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public int this[int x] { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public int this[int x] { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test5 : I5 { public int this[int x] { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public int this[int x] { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } "; ValidatePropertyModifiers_23(source1, source3); var source4 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public virtual int this[int x] { get { throw null; } set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public virtual int this[int x] { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } set { throw null; } } } class Test5 : I5 { public virtual int this[int x] { get { throw null; } set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public virtual int this[int x] { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } set { throw null; } } } "; ValidatePropertyModifiers_23(source1, source4); var source5 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { public virtual int this[int x] { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { public virtual int this[int x] { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test5 : I5 { public virtual int this[int x] { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { public virtual int this[int x] { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } "; ValidatePropertyModifiers_23(source1, source5); var source6 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test3(); I4 i4 = new Test4(); I5 i5 = new Test5(); I6 i6 = new Test6(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } class Test3 : I3 { int I3.this[int x] { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test4 : I4 { int I4.this[int x] { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test5 : I5 { int I5.this[int x] { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test6 : I6 { int I6.this[int x] { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } "; ValidatePropertyModifiers_23(source1, source6); var source7 = @" class Test1 : I1 { static void Main() { I3 i3 = new Test33(); I4 i4 = new Test44(); I5 i5 = new Test55(); I6 i6 = new Test66(); i3.M2(); i4.M2(); i5.M2(); i6.M2(); } } interface Test3 : I3 { int I3.this[int x] { set { System.Console.WriteLine(""Test3.set_P3""); } } } class Test33 : Test3 {} interface Test4 : I4 { int I4.this[int x] { get { System.Console.WriteLine(""Test4.get_P4""); return 0; } } } class Test44 : Test4 {} interface Test5 : I5 { int I5.this[int x] { set { System.Console.WriteLine(""Test5.set_P5""); } } } class Test55 : Test5 {} interface Test6 : I6 { int I6.this[int x] { get { System.Console.WriteLine(""Test6.get_P6""); return 0; } } } class Test66 : Test6 {} "; ValidatePropertyModifiers_23(source1, source7); } [Fact] public void IndexerModifiers_23_01() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} void M2() { this[0] = this[1]; } } "; var source2 = @" class Test1 : I1 { static void Main() { } public int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.Internal, Accessibility.Public, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_23_02() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_23_03() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } int I1.this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,12): error CS0122: 'I1.this[int].get' is inaccessible due to its protection level // int I1.this[int x] Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int].get").WithLocation(9, 12) ); } [Fact] public void IndexerModifiers_23_04() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_05() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_06() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract int this[int x] {get; set;} } class Test3 : Test1 { public override int this[int x] { get { System.Console.WriteLine(""Test3.get_P1""); return 0; } set { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_07() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { int this[int x] {get; set;} } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].get'. 'Test1.this[int].get' cannot implicitly implement a non-public member. // class Test1 : Test2, I1, I2 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].get", "Test1.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_08() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_08(source1, source2); } [Fact] public void IndexerModifiers_23_09() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_23_10() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } "; var source2 = @" public class Test2 : I1 { public int this[int x] { get { return 0; } set {} } } class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].get'. 'Test2.this[int].get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].get", "Test2.this[int].get").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_11() { var source1 = @" public interface I1 { abstract int this[int x] {internal get; set;} } public class Test2 : I1 { public int this[int x] { get { return 0; } set {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].get'. 'Test2.this[int].get' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].get", "Test2.this[int].get").WithLocation(6, 22) ); } [Fact] public void IndexerModifiers_23_51() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} void M2() { this[0] = this[0]; } } "; var source2 = @" class Test1 : I1 { static void Main() { } public int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_23(source1, source2, Accessibility.Public, Accessibility.Internal, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_23_52() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_23_53() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } int I1.this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } set { System.Console.WriteLine(""set_P1""); } } } "; ValidatePropertyModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,12): error CS0122: 'I1.this[int].set' is inaccessible due to its protection level // int I1.this[int x] Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int].set").WithLocation(9, 12) ); } [Fact] public void IndexerModifiers_23_54() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_55() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_56() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract int this[int x] {get; set;} } class Test3 : Test1 { public override int this[int x] { get { System.Console.WriteLine(""Test3.get_P1""); return 0; } set { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_57() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public int this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { int this[int x] {get; set;} } "; ValidatePropertyModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.this[int].set'. 'Test1.this[int].set' cannot implicitly implement a non-public member. // class Test1 : Test2, I1, I2 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.this[int].set", "Test1.this[int].set").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_58() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } public class Test2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""Test2.get_P1""); return 0; } set { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_08(source1, source2); } [Fact] public void IndexerModifiers_23_59() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class TestHelper { public static void CallP1(I1 x) {x[0] = x[0];} } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual long this[int x] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerModifiers_23_60() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } "; var source2 = @" public class Test2 : I1 { public int this[int x] { get { return 0; } set {} } } class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].set'. 'Test2.this[int].set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].set", "Test2.this[int].set").WithLocation(2, 22) ); } [Fact] public void IndexerModifiers_23_61() { var source1 = @" public interface I1 { abstract int this[int x] {get; internal set;} } public class Test2 : I1 { public int this[int x] { get { return 0; } set {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidatePropertyModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.this[int].set'. 'Test2.this[int].set' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.this[int].set", "Test2.this[int].set").WithLocation(6, 22) ); } [Fact] public void IndexerModifiers_24() { var source1 = @" public interface I1 { int this[int x] { get { System.Console.WriteLine(""get_P1""); return 0; } internal set { System.Console.WriteLine(""set_P1""); } } void M2() {this[0] = this[1];} } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidatePropertyModifiers_24(source1, source2); } [Fact] public void IndexerModifiers_25() { var source1 = @" public interface I1 { int this[int x] { private get => throw null; set => throw null; } } public interface I2 { int this[int x] { internal get => throw null; set => throw null; } } public interface I3 { public int this[int x] { get => throw null; private set => throw null; } } public interface I4 { int this[int x] { get => throw null; internal set => throw null; } } public class Test1 : I1, I2, I3, I4 { static void Main() { int x; I1 i1 = new Test1(); I2 i2 = new Test1(); I3 i3 = new Test1(); I4 i4 = new Test1(); x = i1[0]; i1[0] = x; x = i2[0]; i2[0] = x; x = i3[0]; i3[0] = x; x = i4[0]; i4[0] = x; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (29,13): error CS0271: The property or indexer 'I1.this[int]' cannot be used in this context because the get accessor is inaccessible // x = i1[0]; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "i1[0]").WithArguments("I1.this[int]").WithLocation(29, 13), // (34,9): error CS0272: The property or indexer 'I3.this[int]' cannot be used in this context because the set accessor is inaccessible // i3[0] = x; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "i3[0]").WithArguments("I3.this[int]").WithLocation(34, 9) ); var source2 = @" class Test2 { static void Main() { int x; I1 i1 = new Test1(); I2 i2 = new Test1(); I3 i3 = new Test1(); I4 i4 = new Test1(); x = i1[0]; i1[0] = x; x = i2[0]; i2[0] = x; x = i3[0]; i3[0] = x; x = i4[0]; i4[0] = x; } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (12,13): error CS0271: The property or indexer 'I1.this[int]' cannot be used in this context because the get accessor is inaccessible // x = i1[0]; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "i1[0]").WithArguments("I1.this[int]").WithLocation(12, 13), // (14,13): error CS0271: The property or indexer 'I2.this[int]' cannot be used in this context because the get accessor is inaccessible // x = i2[0]; Diagnostic(ErrorCode.ERR_InaccessibleGetter, "i2[0]").WithArguments("I2.this[int]").WithLocation(14, 13), // (17,9): error CS0272: The property or indexer 'I3.this[int]' cannot be used in this context because the set accessor is inaccessible // i3[0] = x; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "i3[0]").WithArguments("I3.this[int]").WithLocation(17, 9), // (19,9): error CS0272: The property or indexer 'I4.this[int]' cannot be used in this context because the set accessor is inaccessible // i4[0] = x; Diagnostic(ErrorCode.ERR_InaccessibleSetter, "i4[0]").WithArguments("I4.this[int]").WithLocation(19, 9) ); } [Fact] public void IndexerModifiers_26() { var source1 = @" public interface I1 { abstract int this[sbyte x] { private get; set; } abstract int this[byte x] { get; private set; } abstract int this[short x] { internal get; } int this[ushort x] {internal get;} = 0; int this[int x] { internal get {throw null;} } int this[uint x] { internal set {throw null;} } int this[long x] { internal get => throw null; } int this[ulong x] { internal set => throw null; } int this[float x] { internal get {throw null;} private set {throw null;}} int this[double x] { internal get => throw null; private set => throw null;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (7,40): error CS1519: Invalid token '=' in class, struct, or interface member declaration // int this[ushort x] {internal get;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(7, 40), // (4,42): error CS0442: 'I1.this[sbyte].get': abstract properties cannot have private accessors // abstract int this[sbyte x] { private get; set; } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "get").WithArguments("I1.this[sbyte].get").WithLocation(4, 42), // (5,46): error CS0442: 'I1.this[byte].set': abstract properties cannot have private accessors // abstract int this[byte x] { get; private set; } Diagnostic(ErrorCode.ERR_PrivateAbstractAccessor, "set").WithArguments("I1.this[byte].set").WithLocation(5, 46), // (6,18): error CS0276: 'I1.this[short]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // abstract int this[short x] { internal get; } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I1.this[short]").WithLocation(6, 18), // (7,9): error CS0276: 'I1.this[ushort]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int this[ushort x] {internal get;} = 0; Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I1.this[ushort]").WithLocation(7, 9), // (8,9): error CS0276: 'I1.this[int]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int this[int x] { internal get {throw null;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I1.this[int]").WithLocation(8, 9), // (9,9): error CS0276: 'I1.this[uint]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int this[uint x] { internal set {throw null;} } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I1.this[uint]").WithLocation(9, 9), // (10,9): error CS0276: 'I1.this[long]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int this[long x] { internal get => throw null; } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I1.this[long]").WithLocation(10, 9), // (11,9): error CS0276: 'I1.this[ulong]': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor // int this[ulong x] { internal set => throw null; } Diagnostic(ErrorCode.ERR_AccessModMissingAccessor, "this").WithArguments("I1.this[ulong]").WithLocation(11, 9), // (12,9): error CS0274: Cannot specify accessibility modifiers for both accessors of the property or indexer 'I1.this[float]' // int this[float x] { internal get {throw null;} private set {throw null;}} Diagnostic(ErrorCode.ERR_DuplicatePropertyAccessMods, "this").WithArguments("I1.this[float]").WithLocation(12, 9), // (13,9): error CS0274: Cannot specify accessibility modifiers for both accessors of the property or indexer 'I1.this[double]' // int this[double x] { internal get => throw null; private set => throw null;} Diagnostic(ErrorCode.ERR_DuplicatePropertyAccessMods, "this").WithArguments("I1.this[double]").WithLocation(13, 9) ); } [Fact] public void IndexerModifiers_27() { var source1 = @" public interface I1 { int this[short x] { private get {throw null;} set {} } int this[int x] { get {throw null;} private set {} } } class Test1 : I1 { int I1.this[short x] { get {throw null;} set {} } int I1.this[int x] { get {throw null;} set {} } } interface ITest1 : I1 { int I1.this[short x] { get {throw null;} set {} } int I1.this[int x] { get {throw null;} set {} } } public interface I2 { int this[short x] { private get {throw null;} set {} } int this[int x] { get {throw null;} private set {} } class Test3 : I2 { int I2.this[short x] { get {throw null;} set {} } int I2.this[int x] { get {throw null;} set {} } } interface ITest3 : I2 { int I2.this[short x] { get {throw null;} set {} } int I2.this[int x] { get {throw null;} set {} } } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (21,9): error CS0550: 'Test1.I1.this[short].get' adds an accessor not found in interface member 'I1.this[short]' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("Test1.I1.this[short].get", "I1.this[short]").WithLocation(21, 9), // (28,9): error CS0550: 'Test1.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("Test1.I1.this[int].set", "I1.this[int]").WithLocation(28, 9), // (36,9): error CS0550: 'ITest1.I1.this[short].get' adds an accessor not found in interface member 'I1.this[short]' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("ITest1.I1.this[short].get", "I1.this[short]").WithLocation(36, 9), // (43,9): error CS0550: 'ITest1.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("ITest1.I1.this[int].set", "I1.this[int]").WithLocation(43, 9), // (65,13): error CS0550: 'I2.Test3.I2.this[short].get' adds an accessor not found in interface member 'I2.this[short]' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.Test3.I2.this[short].get", "I2.this[short]").WithLocation(65, 13), // (72,13): error CS0550: 'I2.Test3.I2.this[int].set' adds an accessor not found in interface member 'I2.this[int]' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.Test3.I2.this[int].set", "I2.this[int]").WithLocation(72, 13), // (80,13): error CS0550: 'I2.ITest3.I2.this[short].get' adds an accessor not found in interface member 'I2.this[short]' // get {throw null;} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.ITest3.I2.this[short].get", "I2.this[short]").WithLocation(80, 13), // (87,13): error CS0550: 'I2.ITest3.I2.this[int].set' adds an accessor not found in interface member 'I2.this[int]' // set {} Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.ITest3.I2.this[int].set", "I2.this[int]").WithLocation(87, 13) ); } [Fact] public void EventModifiers_01() { var source1 = @" public interface I1 { public event System.Action P01; protected event System.Action P02 {add{}} protected internal event System.Action P03 {remove{}} internal event System.Action P04 {add{}} private event System.Action P05 {remove{}} static event System.Action P06 {add{}} virtual event System.Action P07 {remove{}} sealed event System.Action P08 {add{}} override event System.Action P09 {remove{}} abstract event System.Action P10 {add{}} extern event System.Action P11 {add{} remove{}} extern event System.Action P12 {add; remove;} extern event System.Action P13; private protected event System.Action P14; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.GetDiagnostics().Where(d => d.Code != (int)ErrorCode.ERR_EventNeedsBothAccessors).Verify( // (12,34): error CS0106: The modifier 'override' is not valid for this item // override event System.Action P09 {remove{}} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 34), // (13,38): error CS8712: 'I1.P10': abstract event cannot use event accessor syntax // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P10").WithLocation(13, 38), // (14,37): error CS0179: 'I1.P11.add' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "add").WithArguments("I1.P11.add").WithLocation(14, 37), // (14,43): error CS0179: 'I1.P11.remove' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "remove").WithArguments("I1.P11.remove").WithLocation(14, 43), // (15,37): warning CS0626: Method, operator, or accessor 'I1.P12.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "add").WithArguments("I1.P12.add").WithLocation(15, 37), // (15,40): error CS0073: An add or remove accessor must have a body // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(15, 40), // (15,42): warning CS0626: Method, operator, or accessor 'I1.P12.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "remove").WithArguments("I1.P12.remove").WithLocation(15, 42), // (15,48): error CS0073: An add or remove accessor must have a body // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(15, 48), // (16,32): warning CS0626: Method, operator, or accessor 'I1.P13.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P13; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P13").WithArguments("I1.P13.add").WithLocation(16, 32), // (16,32): warning CS0626: Method, operator, or accessor 'I1.P13.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P13; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P13").WithArguments("I1.P13.remove").WithLocation(16, 32) ); ValidateSymbolsEventModifiers_01(compilation1); } private static void ValidateSymbolsEventModifiers_01(CSharpCompilation compilation1) { var i1 = compilation1.GetTypeByMetadataName("I1"); var p01 = i1.GetMember("P01"); Assert.True(p01.IsAbstract); Assert.False(p01.IsVirtual); Assert.False(p01.IsSealed); Assert.False(p01.IsStatic); Assert.False(p01.IsExtern); Assert.False(p01.IsOverride); Assert.Equal(Accessibility.Public, p01.DeclaredAccessibility); VaidateP01Accessor(p01.AddMethod); VaidateP01Accessor(p01.RemoveMethod); void VaidateP01Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } var p02 = i1.GetMember("P02"); var p02get = p02.AddMethod; Assert.False(p02.IsAbstract); Assert.True(p02.IsVirtual); Assert.False(p02.IsSealed); Assert.False(p02.IsStatic); Assert.False(p02.IsExtern); Assert.False(p02.IsOverride); Assert.Equal(Accessibility.Protected, p02.DeclaredAccessibility); Assert.False(p02get.IsAbstract); Assert.True(p02get.IsVirtual); Assert.True(p02get.IsMetadataVirtual()); Assert.False(p02get.IsSealed); Assert.False(p02get.IsStatic); Assert.False(p02get.IsExtern); Assert.False(p02get.IsAsync); Assert.False(p02get.IsOverride); Assert.Equal(Accessibility.Protected, p02get.DeclaredAccessibility); var p03 = i1.GetMember("P03"); var p03set = p03.RemoveMethod; Assert.False(p03.IsAbstract); Assert.True(p03.IsVirtual); Assert.False(p03.IsSealed); Assert.False(p03.IsStatic); Assert.False(p03.IsExtern); Assert.False(p03.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, p03.DeclaredAccessibility); Assert.False(p03set.IsAbstract); Assert.True(p03set.IsVirtual); Assert.True(p03set.IsMetadataVirtual()); Assert.False(p03set.IsSealed); Assert.False(p03set.IsStatic); Assert.False(p03set.IsExtern); Assert.False(p03set.IsAsync); Assert.False(p03set.IsOverride); Assert.Equal(Accessibility.ProtectedOrInternal, p03set.DeclaredAccessibility); var p04 = i1.GetMember("P04"); var p04get = p04.AddMethod; Assert.False(p04.IsAbstract); Assert.True(p04.IsVirtual); Assert.False(p04.IsSealed); Assert.False(p04.IsStatic); Assert.False(p04.IsExtern); Assert.False(p04.IsOverride); Assert.Equal(Accessibility.Internal, p04.DeclaredAccessibility); Assert.False(p04get.IsAbstract); Assert.True(p04get.IsVirtual); Assert.True(p04get.IsMetadataVirtual()); Assert.False(p04get.IsSealed); Assert.False(p04get.IsStatic); Assert.False(p04get.IsExtern); Assert.False(p04get.IsAsync); Assert.False(p04get.IsOverride); Assert.Equal(Accessibility.Internal, p04get.DeclaredAccessibility); var p05 = i1.GetMember("P05"); var p05set = p05.RemoveMethod; Assert.False(p05.IsAbstract); Assert.False(p05.IsVirtual); Assert.False(p05.IsSealed); Assert.False(p05.IsStatic); Assert.False(p05.IsExtern); Assert.False(p05.IsOverride); Assert.Equal(Accessibility.Private, p05.DeclaredAccessibility); Assert.False(p05set.IsAbstract); Assert.False(p05set.IsVirtual); Assert.False(p05set.IsMetadataVirtual()); Assert.False(p05set.IsSealed); Assert.False(p05set.IsStatic); Assert.False(p05set.IsExtern); Assert.False(p05set.IsAsync); Assert.False(p05set.IsOverride); Assert.Equal(Accessibility.Private, p05set.DeclaredAccessibility); var p06 = i1.GetMember("P06"); var p06get = p06.AddMethod; Assert.False(p06.IsAbstract); Assert.False(p06.IsVirtual); Assert.False(p06.IsSealed); Assert.True(p06.IsStatic); Assert.False(p06.IsExtern); Assert.False(p06.IsOverride); Assert.Equal(Accessibility.Public, p06.DeclaredAccessibility); Assert.False(p06get.IsAbstract); Assert.False(p06get.IsVirtual); Assert.False(p06get.IsMetadataVirtual()); Assert.False(p06get.IsSealed); Assert.True(p06get.IsStatic); Assert.False(p06get.IsExtern); Assert.False(p06get.IsAsync); Assert.False(p06get.IsOverride); Assert.Equal(Accessibility.Public, p06get.DeclaredAccessibility); var p07 = i1.GetMember("P07"); var p07set = p07.RemoveMethod; Assert.False(p07.IsAbstract); Assert.True(p07.IsVirtual); Assert.False(p07.IsSealed); Assert.False(p07.IsStatic); Assert.False(p07.IsExtern); Assert.False(p07.IsOverride); Assert.Equal(Accessibility.Public, p07.DeclaredAccessibility); Assert.False(p07set.IsAbstract); Assert.True(p07set.IsVirtual); Assert.True(p07set.IsMetadataVirtual()); Assert.False(p07set.IsSealed); Assert.False(p07set.IsStatic); Assert.False(p07set.IsExtern); Assert.False(p07set.IsAsync); Assert.False(p07set.IsOverride); Assert.Equal(Accessibility.Public, p07set.DeclaredAccessibility); var p08 = i1.GetMember("P08"); var p08get = p08.AddMethod; Assert.False(p08.IsAbstract); Assert.False(p08.IsVirtual); Assert.False(p08.IsSealed); Assert.False(p08.IsStatic); Assert.False(p08.IsExtern); Assert.False(p08.IsOverride); Assert.Equal(Accessibility.Public, p08.DeclaredAccessibility); Assert.False(p08get.IsAbstract); Assert.False(p08get.IsVirtual); Assert.False(p08get.IsMetadataVirtual()); Assert.False(p08get.IsSealed); Assert.False(p08get.IsStatic); Assert.False(p08get.IsExtern); Assert.False(p08get.IsAsync); Assert.False(p08get.IsOverride); Assert.Equal(Accessibility.Public, p08get.DeclaredAccessibility); var p09 = i1.GetMember("P09"); var p09set = p09.RemoveMethod; Assert.False(p09.IsAbstract); Assert.True(p09.IsVirtual); Assert.False(p09.IsSealed); Assert.False(p09.IsStatic); Assert.False(p09.IsExtern); Assert.False(p09.IsOverride); Assert.Equal(Accessibility.Public, p09.DeclaredAccessibility); Assert.False(p09set.IsAbstract); Assert.True(p09set.IsVirtual); Assert.True(p09set.IsMetadataVirtual()); Assert.False(p09set.IsSealed); Assert.False(p09set.IsStatic); Assert.False(p09set.IsExtern); Assert.False(p09set.IsAsync); Assert.False(p09set.IsOverride); Assert.Equal(Accessibility.Public, p09set.DeclaredAccessibility); var p10 = i1.GetMember("P10"); var p10get = p10.AddMethod; Assert.True(p10.IsAbstract); Assert.False(p10.IsVirtual); Assert.False(p10.IsSealed); Assert.False(p10.IsStatic); Assert.False(p10.IsExtern); Assert.False(p10.IsOverride); Assert.Equal(Accessibility.Public, p10.DeclaredAccessibility); Assert.True(p10get.IsAbstract); Assert.False(p10get.IsVirtual); Assert.True(p10get.IsMetadataVirtual()); Assert.False(p10get.IsSealed); Assert.False(p10get.IsStatic); Assert.False(p10get.IsExtern); Assert.False(p10get.IsAsync); Assert.False(p10get.IsOverride); Assert.Equal(Accessibility.Public, p10get.DeclaredAccessibility); foreach (var name in new[] { "P11", "P12", "P13" }) { var p11 = i1.GetMember(name); Assert.False(p11.IsAbstract); Assert.True(p11.IsVirtual); Assert.False(p11.IsSealed); Assert.False(p11.IsStatic); Assert.True(p11.IsExtern); Assert.False(p11.IsOverride); Assert.Equal(Accessibility.Public, p11.DeclaredAccessibility); ValidateP11Accessor(p11.AddMethod); ValidateP11Accessor(p11.RemoveMethod); void ValidateP11Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } } var p14 = i1.GetMember("P14"); Assert.True(p14.IsAbstract); Assert.False(p14.IsVirtual); Assert.False(p14.IsSealed); Assert.False(p14.IsStatic); Assert.False(p14.IsExtern); Assert.False(p14.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, p14.DeclaredAccessibility); VaidateP14Accessor(p14.AddMethod); VaidateP14Accessor(p14.RemoveMethod); void VaidateP14Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.ProtectedAndInternal, accessor.DeclaredAccessibility); } } [Fact] public void EventModifiers_02() { var source1 = @" public interface I1 { public event System.Action P01; protected event System.Action P02 {add{}} protected internal event System.Action P03 {remove{}} internal event System.Action P04 {add{}} private event System.Action P05 {remove{}} static event System.Action P06 {add{}} virtual event System.Action P07 {remove{}} sealed event System.Action P08 {add{}} override event System.Action P09 {remove{}} abstract event System.Action P10 {add{}} extern event System.Action P11 {add{} remove{}} extern event System.Action P12 {add; remove;} extern event System.Action P13; private protected event System.Action P14; protected event System.Action P15; protected internal event System.Action P16; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.GetDiagnostics().Where(d => d.Code != (int)ErrorCode.ERR_EventNeedsBothAccessors).Verify( // (4,32): error CS8703: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public event System.Action P01; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P01").WithArguments("public", "7.3", "8.0").WithLocation(4, 32), // (5,40): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // protected event System.Action P02 {add{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(5, 40), // (6,49): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // protected internal event System.Action P03 {remove{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(6, 49), // (7,39): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal event System.Action P04 {add{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(7, 39), // (8,38): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private event System.Action P05 {remove{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(8, 38), // (9,37): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static event System.Action P06 {add{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(9, 37), // (10,38): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // virtual event System.Action P07 {remove{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(10, 38), // (11,37): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // sealed event System.Action P08 {add{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(11, 37), // (12,34): error CS0106: The modifier 'override' is not valid for this item // override event System.Action P09 {remove{}} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 34), // (12,39): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // override event System.Action P09 {remove{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(12, 39), // (13,39): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(13, 39), // (13,38): error CS8712: 'I1.P10': abstract event cannot use event accessor syntax // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P10").WithLocation(13, 38), // (14,37): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(14, 37), // (14,37): error CS0179: 'I1.P11.add' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "add").WithArguments("I1.P11.add").WithLocation(14, 37), // (14,43): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(14, 43), // (14,43): error CS0179: 'I1.P11.remove' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "remove").WithArguments("I1.P11.remove").WithLocation(14, 43), // (15,37): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(15, 37), // (15,37): warning CS0626: Method, operator, or accessor 'I1.P12.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "add").WithArguments("I1.P12.add").WithLocation(15, 37), // (15,40): error CS0073: An add or remove accessor must have a body // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(15, 40), // (15,42): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(15, 42), // (15,42): warning CS0626: Method, operator, or accessor 'I1.P12.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "remove").WithArguments("I1.P12.remove").WithLocation(15, 42), // (15,48): error CS0073: An add or remove accessor must have a body // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(15, 48), // (16,32): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern event System.Action P13; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P13").WithArguments("extern", "7.3", "8.0").WithLocation(16, 32), // (16,32): warning CS0626: Method, operator, or accessor 'I1.P13.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P13; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P13").WithArguments("I1.P13.add").WithLocation(16, 32), // (16,32): warning CS0626: Method, operator, or accessor 'I1.P13.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P13; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P13").WithArguments("I1.P13.remove").WithLocation(16, 32), // (17,43): error CS8703: The modifier 'private protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private protected event System.Action P14; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P14").WithArguments("private protected", "7.3", "8.0").WithLocation(17, 43), // (18,35): error CS8703: The modifier 'protected' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // protected event System.Action P15; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P15").WithArguments("protected", "7.3", "8.0").WithLocation(18, 35), // (19,44): error CS8703: The modifier 'protected internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // protected internal event System.Action P16; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P16").WithArguments("protected internal", "7.3", "8.0").WithLocation(19, 44) ); ValidateSymbolsEventModifiers_01(compilation1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.GetDiagnostics().Where(d => d.Code != (int)ErrorCode.ERR_EventNeedsBothAccessors).Verify( // (5,35): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected event System.Action P02 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P02").WithLocation(5, 35), // (5,40): error CS8701: Target runtime doesn't support default interface implementation. // protected event System.Action P02 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(5, 40), // (6,44): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal event System.Action P03 {remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P03").WithLocation(6, 44), // (6,49): error CS8701: Target runtime doesn't support default interface implementation. // protected internal event System.Action P03 {remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(6, 49), // (7,39): error CS8701: Target runtime doesn't support default interface implementation. // internal event System.Action P04 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(7, 39), // (8,38): error CS8701: Target runtime doesn't support default interface implementation. // private event System.Action P05 {remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(8, 38), // (9,37): error CS8701: Target runtime doesn't support default interface implementation. // static event System.Action P06 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(9, 37), // (10,38): error CS8701: Target runtime doesn't support default interface implementation. // virtual event System.Action P07 {remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(10, 38), // (11,37): error CS8701: Target runtime doesn't support default interface implementation. // sealed event System.Action P08 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(11, 37), // (12,34): error CS0106: The modifier 'override' is not valid for this item // override event System.Action P09 {remove{}} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P09").WithArguments("override").WithLocation(12, 34), // (12,39): error CS8701: Target runtime doesn't support default interface implementation. // override event System.Action P09 {remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(12, 39), // (13,39): error CS8701: Target runtime doesn't support default interface implementation. // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(13, 39), // (13,38): error CS8712: 'I1.P10': abstract event cannot use event accessor syntax // abstract event System.Action P10 {add{}} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P10").WithLocation(13, 38), // (14,37): error CS8701: Target runtime doesn't support default interface implementation. // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(14, 37), // (14,37): error CS0179: 'I1.P11.add' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "add").WithArguments("I1.P11.add").WithLocation(14, 37), // (14,43): error CS8701: Target runtime doesn't support default interface implementation. // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(14, 43), // (14,43): error CS0179: 'I1.P11.remove' cannot be extern and declare a body // extern event System.Action P11 {add{} remove{}} Diagnostic(ErrorCode.ERR_ExternHasBody, "remove").WithArguments("I1.P11.remove").WithLocation(14, 43), // (15,37): error CS8701: Target runtime doesn't support default interface implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(15, 37), // (15,37): warning CS0626: Method, operator, or accessor 'I1.P12.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "add").WithArguments("I1.P12.add").WithLocation(15, 37), // (15,40): error CS0073: An add or remove accessor must have a body // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(15, 40), // (15,42): error CS8701: Target runtime doesn't support default interface implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(15, 42), // (15,42): warning CS0626: Method, operator, or accessor 'I1.P12.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "remove").WithArguments("I1.P12.remove").WithLocation(15, 42), // (15,48): error CS0073: An add or remove accessor must have a body // extern event System.Action P12 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(15, 48), // (16,32): error CS8701: Target runtime doesn't support default interface implementation. // extern event System.Action P13; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P13").WithLocation(16, 32), // (16,32): warning CS0626: Method, operator, or accessor 'I1.P13.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P13; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P13").WithArguments("I1.P13.add").WithLocation(16, 32), // (16,32): warning CS0626: Method, operator, or accessor 'I1.P13.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P13; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P13").WithArguments("I1.P13.remove").WithLocation(16, 32), // (17,43): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected event System.Action P14; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P14").WithLocation(17, 43), // (18,35): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected event System.Action P15; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P15").WithLocation(18, 35), // (19,44): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal event System.Action P16; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "P16").WithLocation(19, 44) ); ValidateSymbolsEventModifiers_01(compilation2); } [Fact] public void EventModifiers_03() { ValidateEventImplementation_102(@" public interface I1 { public virtual event System.Action E1 { add => System.Console.WriteLine(""add E1""); remove => System.Console.WriteLine(""remove E1""); } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.E1 += null; i1.E1 -= null; } } "); ValidateEventImplementation_102(@" public interface I1 { public virtual event System.Action E1 { add {System.Console.WriteLine(""add E1"");} remove {System.Console.WriteLine(""remove E1"");} } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.E1 += null; i1.E1 -= null; } } "); } [Fact] public void EventModifiers_04() { ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 {} } class Test1 : I1 {} ", new[] { // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 {} Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: false, haveRemove: false); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { add; } } class Test1 : I1 {} ", new[] { // (6,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";"), // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: true, haveRemove: false); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { add {} } } class Test1 : I1 {} ", new[] { // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: true, haveRemove: false); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { add => throw null; } } class Test1 : I1 {} ", new[] { // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: true, haveRemove: false); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { remove; } } class Test1 : I1 {} ", new[] { // (6,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(6, 15), // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: false, haveRemove: true); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { remove {} } } class Test1 : I1 {} ", new[] { // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: false, haveRemove: true); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { remove => throw null; } } class Test1 : I1 {} ", new[] { // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: false, haveRemove: true); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 { add; remove; } } class Test1 : I1 {} ", new[] { // (6,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";"), // (7,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(7, 15) }, haveAdd: true, haveRemove: true); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1; } class Test1 : I1 {} ", new[] { // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40), // (4,40): warning CS0067: The event 'I1.E1' is never used // public virtual event System.Action E1; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: true, haveRemove: true); ValidateEventImplementation_101(@" public interface I1 { public virtual event System.Action E1 = null; } class Test1 : I1 {} ", new[] { // (4,40): error CS0068: 'I1.E1': instance event in interface cannot have initializer // public virtual event System.Action E1 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "E1").WithArguments("I1.E1").WithLocation(4, 40), // (4,40): error CS0065: 'I1.E1': event property must have both add and remove accessors // public virtual event System.Action E1 = null; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "E1").WithArguments("I1.E1").WithLocation(4, 40), // (4,40): warning CS0067: The event 'I1.E1' is never used // public virtual event System.Action E1 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "E1").WithArguments("I1.E1").WithLocation(4, 40) }, haveAdd: true, haveRemove: true); } [Fact] public void EventModifiers_05() { var source1 = @" public interface I1 { public abstract event System.Action P1; } public interface I2 { event System.Action P2; } class Test1 : I1 { public event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove => System.Console.WriteLine(""set_P1""); } } class Test2 : I2 { public event System.Action P2 { add { System.Console.WriteLine(""get_P2""); } remove => System.Console.WriteLine(""set_P2""); } static void Main() { I1 x = new Test1(); x.P1 += null; x.P1 -= null; I2 y = new Test2(); y.P2 += null; y.P2 -= null; } } "; ValidateEventModifiers_05(source1); } private void ValidateEventModifiers_05(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: @"get_P1 set_P1 get_P2 set_P2", symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { for (int i = 1; i <= 2; i++) { var test1 = m.GlobalNamespace.GetTypeMember("Test" + i); var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleEvent(i1); var test1P1 = GetSingleEvent(test1); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Same(test1P1, test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor(p1.AddMethod, test1P1.AddMethod); ValidateAccessor(p1.RemoveMethod, test1P1.RemoveMethod); void ValidateAccessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(implementation, test1.FindImplementationForInterfaceMember(accessor)); } } } } private static EventSymbol GetSingleEvent(NamedTypeSymbol container) { return container.GetMembers().OfType().Single(); } private static EventSymbol GetSingleEvent(CSharpCompilation compilation, string containerName) { return GetSingleEvent(compilation.GetTypeByMetadataName(containerName)); } private static EventSymbol GetSingleEvent(ModuleSymbol m, string containerName) { return GetSingleEvent(m.GlobalNamespace.GetTypeMember(containerName)); } [Fact] public void EventModifiers_06() { var source1 = @" public interface I1 { public abstract event System.Action P1; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3); compilation1.VerifyDiagnostics( // (4,41): error CS8503: The modifier 'abstract' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract event System.Action P1; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P1").WithArguments("abstract", "7.3", "8.0").WithLocation(4, 41), // (4,41): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public abstract event System.Action P1; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P1").WithArguments("public", "7.3", "8.0").WithLocation(4, 41) ); ValidateEventModifiers_06(compilation1); } private static void ValidateEventModifiers_06(CSharpCompilation compilation1) { var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember("P1"); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); ValidateAccessor(p1.AddMethod); ValidateAccessor(p1.RemoveMethod); void ValidateAccessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); } } [Fact] public void EventModifiers_07() { var source1 = @" public interface I1 { public static event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } internal static event System.Action P2 { add { System.Console.WriteLine(""get_P2""); P3 += value; } remove { System.Console.WriteLine(""set_P2""); P3 -= value; } } private static event System.Action P3 { add => System.Console.WriteLine(""get_P3""); remove => System.Console.WriteLine(""set_P3""); } } class Test1 : I1 { static void Main() { I1.P1 += null; I1.P1 -= null; I1.P2 += null; I1.P2 -= null; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 get_P3 set_P2 set_P3", symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var tuple in new[] { (name: "P1", access: Accessibility.Public), (name: "P2", access: Accessibility.Internal), (name: "P3", access: Accessibility.Private)}) { var p1 = i1.GetMember(tuple.name); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.True(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(tuple.access, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor(p1.AddMethod); ValidateAccessor(p1.RemoveMethod); void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(tuple.access, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } var source2 = @" public interface I1 { public static event System.Action P1; internal static event System.Action P2 { add; remove; } private static event System.Action P3 = null; } class Test1 : I1 { static void Main() { } } "; var compilation2 = CreateCompilation(source2, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyEmitDiagnostics( // (4,39): warning CS0067: The event 'I1.P1' is never used // public static event System.Action P1; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P1").WithArguments("I1.P1").WithLocation(4, 39), // (8,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(8, 12), // (9,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(9, 15), // (12,40): warning CS0414: The field 'I1.P3' is assigned but its value is never used // private static event System.Action P3 = null; Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "P3").WithArguments("I1.P3").WithLocation(12, 40) ); Validate(compilation2.SourceModule); var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation3.VerifyEmitDiagnostics( // (4,39): error CS8701: Target runtime doesn't support default interface implementation. // public static event System.Action P1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P1").WithLocation(4, 39), // (4,39): warning CS0067: The event 'I1.P1' is never used // public static event System.Action P1; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P1").WithArguments("I1.P1").WithLocation(4, 39), // (8,9): error CS8701: Target runtime doesn't support default interface implementation. // add; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(8, 9), // (8,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(8, 12), // (9,9): error CS8701: Target runtime doesn't support default interface implementation. // remove; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(9, 9), // (9,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(9, 15), // (12,40): error CS8701: Target runtime doesn't support default interface implementation. // private static event System.Action P3 = null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P3").WithLocation(12, 40), // (12,40): warning CS0414: The field 'I1.P3' is assigned but its value is never used // private static event System.Action P3 = null; Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "P3").WithArguments("I1.P3").WithLocation(12, 40) ); Validate(compilation3.SourceModule); } [Fact] public void EventModifiers_08() { var source1 = @" public interface I1 { abstract static event System.Action P1; virtual static event System.Action P2 {add {} remove{}} sealed static event System.Action P3 {add; remove;} } class Test1 : I1 { event System.Action I1.P1 {add {} remove{}} event System.Action I1.P2 {add {} remove{}} event System.Action I1.P3 {add {} remove{}} } class Test2 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (8,46): error CS0073: An add or remove accessor must have a body // sealed static event System.Action P3 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(8, 46), // (8,54): error CS0073: An add or remove accessor must have a body // sealed static event System.Action P3 {add; remove;} Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(8, 54), // (6,40): error CS0112: A static member 'I1.P2' cannot be marked as override, virtual, or abstract // virtual static event System.Action P2 {add {} remove{}} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P2").WithArguments("I1.P2").WithLocation(6, 40), // (8,39): error CS0238: 'I1.P3' cannot be sealed because it is not an override // sealed static event System.Action P3 {add; remove;} Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I1.P3").WithLocation(8, 39), // (4,41): error CS0112: A static member 'I1.P1' cannot be marked as override, virtual, or abstract // abstract static event System.Action P1; Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P1").WithArguments("I1.P1").WithLocation(4, 41), // (13,28): error CS0539: 'Test1.P1' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I1.P1 {add {} remove{}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("Test1.P1").WithLocation(13, 28), // (14,28): error CS0539: 'Test1.P2' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I1.P2 {add {} remove{}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P2").WithArguments("Test1.P2").WithLocation(14, 28), // (15,28): error CS0539: 'Test1.P3' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I1.P3 {add {} remove{}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test1.P3").WithLocation(15, 28) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember("P1"); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.True(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor1(p1.AddMethod); ValidateAccessor1(p1.RemoveMethod); void ValidateAccessor1(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } var p2 = i1.GetMember("P2"); Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.True(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2)); ValidateAccessor2(p2.AddMethod); ValidateAccessor2(p2.RemoveMethod); void ValidateAccessor2(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } var p3 = i1.GetMember("P3"); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.True(p3.IsSealed); Assert.True(p3.IsStatic); Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); ValidateAccessor3(p3.AddMethod); ValidateAccessor3(p3.RemoveMethod); void ValidateAccessor3(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.True(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } [Fact] public void EventModifiers_09() { var source1 = @" public interface I1 { private event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } sealed void M() { P1 += null; P1 -= null; } } public interface I2 { private event System.Action P2 { add => System.Console.WriteLine(""get_P2""); remove => System.Console.WriteLine(""set_P2""); } sealed void M() { P2 += null; P2 -= null; } } class Test1 : I1, I2 { static void Main() { I1 x1 = new Test1(); x1.M(); I2 x2 = new Test1(); x2.M(); } } "; ValidateEventModifiers_09(source1); } private void ValidateEventModifiers_09(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); for (int i = 1; i <= 2; i++) { var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleEvent(i1); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Private, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor(p1.AddMethod); ValidateAccessor(p1.RemoveMethod); void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } } [Fact] public void EventModifiers_10() { var source1 = @" public interface I1 { abstract private event System.Action P1; virtual private event System.Action P2; sealed private event System.Action P3 { add => throw null; remove {} } private event System.Action P4 = null; } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( // (4,42): error CS0621: 'I1.P1': virtual or abstract members cannot be private // abstract private event System.Action P1; Diagnostic(ErrorCode.ERR_VirtualPrivate, "P1").WithArguments("I1.P1").WithLocation(4, 42), // (6,41): error CS0065: 'I1.P2': event property must have both add and remove accessors // virtual private event System.Action P2; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P2").WithArguments("I1.P2").WithLocation(6, 41), // (6,41): error CS0621: 'I1.P2': virtual or abstract members cannot be private // virtual private event System.Action P2; Diagnostic(ErrorCode.ERR_VirtualPrivate, "P2").WithArguments("I1.P2").WithLocation(6, 41), // (6,41): warning CS0067: The event 'I1.P2' is never used // virtual private event System.Action P2; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P2").WithArguments("I1.P2").WithLocation(6, 41), // (8,40): error CS0238: 'I1.P3' cannot be sealed because it is not an override // sealed private event System.Action P3 Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I1.P3").WithLocation(8, 40), // (14,33): error CS0068: 'I1.P4': instance event in interface cannot have initializer // private event System.Action P4 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "P4").WithArguments("I1.P4").WithLocation(14, 33), // (14,33): error CS0065: 'I1.P4': event property must have both add and remove accessors // private event System.Action P4 = null; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P4").WithArguments("I1.P4").WithLocation(14, 33), // (17,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1"), // (14,33): warning CS0067: The event 'I1.P4' is never used // private event System.Action P4 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P4").WithArguments("I1.P4").WithLocation(14, 33) ); ValidateEventModifiers_10(compilation1); } private static void ValidateEventModifiers_10(CSharpCompilation compilation1) { var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMembers().OfType().ElementAt(0); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Private, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); ValidateP1Accessor(p1.AddMethod); ValidateP1Accessor(p1.RemoveMethod); void ValidateP1Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } var p2 = i1.GetMembers().OfType().ElementAt(1); Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Private, p2.DeclaredAccessibility); Assert.Same(p2, test1.FindImplementationForInterfaceMember(p2)); ValidateP2Accessor(p2.AddMethod); ValidateP2Accessor(p2.RemoveMethod); void ValidateP2Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Same(accessor, test1.FindImplementationForInterfaceMember(accessor)); } var p3 = i1.GetMembers().OfType().ElementAt(2); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.True(p3.IsSealed); Assert.False(p3.IsStatic); Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Private, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.AddMethod); ValidateP3Accessor(p3.RemoveMethod); void ValidateP3Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.True(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } var p4 = i1.GetMembers().OfType().ElementAt(3); Assert.False(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.False(p4.IsStatic); Assert.False(p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Private, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); ValidateP4Accessor(p4.AddMethod); ValidateP4Accessor(p4.RemoveMethod); void ValidateP4Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } [Fact] public void EventModifiers_11_01() { var source1 = @" public interface I1 { internal abstract event System.Action P1; sealed void Test() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.Test(); } public event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11(source1, source2, Accessibility.Internal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } private void ValidateEventModifiers_11(string source1, string source2, Accessibility accessibility, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected1); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var p1 = GetSingleEvent(i1); var test1P1 = GetSingleEvent(test1); var p1add = p1.AddMethod; var p1remove = p1.RemoveMethod; ValidateEvent(p1); ValidateMethod(p1add); ValidateMethod(p1remove); Assert.Same(test1P1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test1P1.AddMethod, test1.FindImplementationForInterfaceMember(p1add)); Assert.Same(test1P1.RemoveMethod, test1.FindImplementationForInterfaceMember(p1remove)); } void ValidateEvent(EventSymbol p1) { Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(accessibility, p1.DeclaredAccessibility); } void ValidateMethod(MethodSymbol m1) { Assert.True(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(accessibility, m1.DeclaredAccessibility); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var p1 = GetSingleEvent(i1); ValidateEvent(p1); ValidateMethod(p1.AddMethod); ValidateMethod(p1.RemoveMethod); } var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected1); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(expected1); Validate1(compilation4.SourceModule); var source3 = @" class Test2 : I1 { } "; var compilation5 = CreateCompilation(source3, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics(expected2); ValidateEventNotImplemented_11(compilation5, "Test2"); var compilation6 = CreateCompilation(source3, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation6.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation6.VerifyDiagnostics(expected2); ValidateEventNotImplemented_11(compilation6, "Test2"); } private static void ValidateEventNotImplemented_11(CSharpCompilation compilation, string className) { var test2 = compilation.GetTypeByMetadataName(className); var i1 = compilation.GetTypeByMetadataName("I1"); var p1 = GetSingleEvent(i1); Assert.Null(test2.FindImplementationForInterfaceMember(p1)); Assert.Null(test2.FindImplementationForInterfaceMember(p1.AddMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(p1.RemoveMethod)); } [Fact] public void EventModifiers_11_02() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11_02(source1, source2, // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 15) ); } private void ValidateEventModifiers_11_02(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(expected); ValidateEventImplementation_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(expected); ValidateEventImplementation_11(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics(expected); ValidateEventImplementation_11(compilation4.SourceModule); } private static void ValidateEventImplementation_11(ModuleSymbol m) { ValidateEventImplementation_11(m, implementedByBase: false); } private static void ValidateEventImplementationByBase_11(ModuleSymbol m) { ValidateEventImplementation_11(m, implementedByBase: true); } private static void ValidateEventImplementation_11(ModuleSymbol m, bool implementedByBase) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var p1 = GetSingleEvent(i1); var test1P1 = GetSingleEvent(implementedByBase ? test1.BaseTypeNoUseSiteDiagnostics : test1); var p1Add = p1.AddMethod; var p1Remove = p1.RemoveMethod; Assert.Same(test1P1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test1P1.AddMethod, test1.FindImplementationForInterfaceMember(p1Add)); Assert.Same(test1P1.RemoveMethod, test1.FindImplementationForInterfaceMember(p1Remove)); var i2 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").SingleOrDefault(); bool isMetadataVirtual = test1P1.IsVirtual || test1P1.IsAbstract || test1P1.IsExplicitInterfaceImplementation || (!implementedByBase && (object)i2 != null && (object)test1P1 == test1.FindImplementationForInterfaceMember(GetSingleEvent(i2))); Assert.Equal(isMetadataVirtual, test1P1.AddMethod.IsMetadataVirtual()); Assert.Equal(isMetadataVirtual, test1P1.RemoveMethod.IsMetadataVirtual()); } [Fact] public void EventModifiers_11_03() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } event System.Action I1.P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11_03(source1, source2, TargetFramework.Standard, // (9,28): error CS0122: 'I1.P1' is inaccessible due to its protection level // event System.Action I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(9, 28) ); } private void ValidateEventModifiers_11_03(string source1, string source2, TargetFramework targetFramework, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, targetFramework: targetFramework, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: !(targetFramework == TargetFramework.Standard || ExecutionConditionUtil.IsMonoOrCoreClr) ? null : @"get_P1 set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementation_11); ValidateEventImplementation_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: targetFramework, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: targetFramework); compilation3.VerifyDiagnostics(expected); if (expected.Length == 0) { CompileAndVerify(compilation3, expectedOutput: !(targetFramework == TargetFramework.Standard || ExecutionConditionUtil.IsMonoOrCoreClr) ? null : @"get_P1 set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementation_11); } ValidateEventImplementation_11(compilation3.SourceModule); } } [Fact] public void EventModifiers_11_04() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } public class Test2 : I1 { event System.Action I1.P1 { add { System.Console.WriteLine(""Test2.get_P1""); } remove { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public event System.Action P1 { add { System.Console.WriteLine(""Test1.get_P1""); } remove { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidateEventModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 22) ); } [Fact] public void EventModifiers_11_05() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } public class Test2 : I1 { event System.Action I1.P1 { add { System.Console.WriteLine(""Test2.get_P1""); } remove { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual event System.Action P1 { add { System.Console.WriteLine(""Test1.get_P1""); } remove { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidateEventModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 22) ); } [Fact] public void EventModifiers_11_06() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } public class Test2 : I1 { event System.Action I1.P1 { add { System.Console.WriteLine(""Test2.get_P1""); } remove { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @"abstract class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test3()); } public abstract event System.Action P1; } class Test3 : Test1 { public override event System.Action P1 { add { System.Console.WriteLine(""Test3.get_P1""); } remove { System.Console.WriteLine(""Test3.set_P1""); } } } "; ValidateEventModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 22) ); } [Fact] public void EventModifiers_11_07() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } public class Test2 : I1 { event System.Action I1.P1 { add { System.Console.WriteLine(""Test2.get_P1""); } remove { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1, I2 { static void Main() { TestHelper.CallP1(new Test1()); } public event System.Action P1 { add { System.Console.WriteLine(""Test1.get_P1""); } remove { System.Console.WriteLine(""Test1.set_P1""); } } } public interface I2 { event System.Action P1; } "; ValidateEventModifiers_11_02(source1, source2, // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 22), // (2,22): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : Test2, I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 22) ); } [Fact] public void EventModifiers_11_08() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } public class Test2 : I1 { event System.Action I1.P1 { add { System.Console.WriteLine(""Test2.get_P1""); } remove { System.Console.WriteLine(""Test2.set_P1""); } } } "; var source2 = @" class Test1 : Test2, I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual event System.Action P1 { add { System.Console.WriteLine(""Test1.get_P1""); } remove { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidateEventModifiers_11_08(source1, source2); } private void ValidateEventModifiers_11_08(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation1, expectedOutput: @"Test2.get_P1 Test2.set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationByBase_11); ValidateEventImplementationByBase_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation3, expectedOutput: @"Test2.get_P1 Test2.set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationByBase_11); ValidateEventImplementationByBase_11(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); CompileAndVerify(compilation4, expectedOutput: @"Test2.get_P1 Test2.set_P1", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationByBase_11); ValidateEventImplementationByBase_11(compilation4.SourceModule); } [Fact] public void EventModifiers_11_09() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class TestHelper { public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { TestHelper.CallP1(new Test1()); } public virtual event System.Action P1 { add { System.Console.WriteLine(""Test1.get_P1""); } remove { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidateEventModifiers_11_09(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } private void ValidateEventModifiers_11_09(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(expected); ValidateEventNotImplemented_11(compilation1, "Test1"); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(expected); ValidateEventNotImplemented_11(compilation3, "Test1"); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics(expected); ValidateEventNotImplemented_11(compilation4, "Test1"); } [Fact] public void EventModifiers_11_10() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } "; var source2 = @" public class Test2 : I1 { public event System.Action P1 { add {} remove {} } } class Test1 : Test2, I1 { } "; ValidateEventModifiers_11_10(source1, source2, // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.remove'. 'Test2.P1.remove' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.remove", "Test2.P1.remove").WithLocation(2, 22), // (2,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.add'. 'Test2.P1.add' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.add", "Test2.P1.add").WithLocation(2, 22) ); } private void ValidateEventModifiers_11_10(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(expected); ValidateEventImplementationByBase_11(compilation1.SourceModule); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(expected); ValidateEventImplementationByBase_11(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics(expected); ValidateEventImplementationByBase_11(compilation4.SourceModule); } [Fact] public void EventModifiers_11_11() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } public class Test2 : I1 { public event System.Action P1 { add {} remove {} } } "; var source2 = @" class Test1 : Test2, I1 { } "; ValidateEventModifiers_11_11(source1, source2, // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.remove'. 'Test2.P1.remove' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.remove", "Test2.P1.remove").WithLocation(6, 22), // (6,22): error CS8504: 'Test2' does not implement interface member 'I1.P1.add'. 'Test2.P1.add' cannot implicitly implement a non-public member. // public class Test2 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test2", "I1.P1.add", "Test2.P1.add").WithLocation(6, 22) ); } private void ValidateEventModifiers_11_11(string source1, string source2, params DiagnosticDescription[] expected) { var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, assemblyName: "EventModifiers_11_11"); compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(); ValidateEventImplementationByBase_11(compilation3.SourceModule); var compilation3Ref = compilation3.EmitToImageReference(); var compilation4 = CreateCompilation("", new[] { compilation2.ToMetadataReference(), compilation3Ref }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); ValidateEventImplementationByBase_11(compilation4.GetReferencedAssemblySymbol(compilation3Ref).Modules[0]); } [Fact] public void EventModifiers_12() { var source1 = @" public interface I1 { internal abstract event System.Action P1; } class Test1 : I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); var test1 = compilation1.GetTypeByMetadataName("Test1"); var i1 = compilation1.GetTypeByMetadataName("I1"); var p1 = i1.GetMember("P1"); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Null(test1.FindImplementationForInterfaceMember(p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(p1.RemoveMethod)); } [Fact] public void EventModifiers_13() { var source1 = @" public interface I1 { public sealed event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } public interface I2 { public sealed event System.Action P2 { add => System.Console.WriteLine(""get_P2""); remove => System.Console.WriteLine(""set_P2""); } } class Test1 : I1 { static void Main() { I1 i1 = new Test1(); i1.P1 += null; i1.P1 -= null; I2 i2 = new Test2(); i2.P2 += null; i2.P2 -= null; } public event System.Action P1 { add => throw null; remove => throw null; } } class Test2 : I2 { public event System.Action P2 { add => throw null; remove => throw null; } } "; ValidateEventModifiers_13(source1); } private void ValidateEventModifiers_13(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); void Validate(ModuleSymbol m) { for (int i = 1; i <= 2; i++) { var test1 = m.GlobalNamespace.GetTypeMember("Test" + i); var i1 = m.GlobalNamespace.GetTypeMember("I" + i); var p1 = GetSingleEvent(i1); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor(p1.AddMethod); ValidateAccessor(p1.RemoveMethod); void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); } [Fact] public void EventModifiers_14() { var source1 = @" public interface I1 { public sealed event System.Action P1 = null; } public interface I2 { abstract sealed event System.Action P2 {add; remove;} } public interface I3 { virtual sealed event System.Action P3 { add {} remove {} } } class Test1 : I1, I2, I3 { event System.Action I1.P1 { add => throw null; remove => throw null; } event System.Action I2.P2 { add => throw null; remove => throw null; } event System.Action I3.P3 { add => throw null; remove => throw null; } } class Test2 : I1, I2, I3 {} "; ValidateEventModifiers_14(source1, // (4,39): error CS0068: 'I1.P1': instance event in interface cannot have initializer // public sealed event System.Action P1 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "P1").WithArguments("I1.P1").WithLocation(4, 39), // (4,39): error CS0065: 'I1.P1': event property must have both add and remove accessors // public sealed event System.Action P1; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 39), // (8,41): error CS0238: 'I2.P2' cannot be sealed because it is not an override // abstract sealed event System.Action P2 {add; remove;} Diagnostic(ErrorCode.ERR_SealedNonOverride, "P2").WithArguments("I2.P2").WithLocation(8, 41), // (8,44): error CS8712: 'I2.P2': abstract event cannot use event accessor syntax // abstract sealed event System.Action P2 {add; remove;} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.P2").WithLocation(8, 44), // (12,40): error CS0238: 'I3.P3' cannot be sealed because it is not an override // virtual sealed event System.Action P3 Diagnostic(ErrorCode.ERR_SealedNonOverride, "P3").WithArguments("I3.P3").WithLocation(12, 40), // (21,28): error CS0539: 'Test1.P1' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I1.P1 { add => throw null; remove => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("Test1.P1").WithLocation(21, 28), // (22,28): error CS0539: 'Test1.P2' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I2.P2 { add => throw null; remove => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P2").WithArguments("Test1.P2").WithLocation(22, 28), // (23,28): error CS0539: 'Test1.P3' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I3.P3 { add => throw null; remove => throw null; } Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test1.P3").WithLocation(23, 28), // (4,39): warning CS0067: The event 'I1.P1' is never used // public sealed event System.Action P1 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P1").WithArguments("I1.P1").WithLocation(4, 39) ); } private void ValidateEventModifiers_14(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var p1 = GetSingleEvent(compilation1, "I1"); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Null(test2.FindImplementationForInterfaceMember(p1)); Validate1(p1.AddMethod); Validate1(p1.RemoveMethod); void Validate1(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p2 = GetSingleEvent(compilation1, "I2"); var test1P2 = test1.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); Assert.True(p2.IsAbstract); Assert.False(p2.IsVirtual); Assert.True(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.Null(test2.FindImplementationForInterfaceMember(p2)); Validate2(p2.AddMethod); Validate2(p2.RemoveMethod); void Validate2(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.True(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p3 = GetSingleEvent(compilation1, "I3"); var test1P3 = test1.GetMembers().OfType().Where(p => p.Name.StartsWith("I3.")).Single(); Assert.False(p3.IsAbstract); Assert.True(p3.IsVirtual); Assert.True(p3.IsSealed); Assert.False(p3.IsStatic); Assert.False(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); Validate3(p3.AddMethod); Validate3(p3.RemoveMethod); void Validate3(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.True(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } [Fact] public void EventModifiers_15() { var source1 = @" public interface I0 { abstract virtual event System.Action P0; } public interface I1 { abstract virtual event System.Action P1 { add { throw null; } } } public interface I2 { virtual abstract event System.Action P2 { add { throw null; } remove { throw null; } } } public interface I3 { abstract virtual event System.Action P3 { remove { throw null; } } } public interface I4 { abstract virtual event System.Action P4 { add => throw null; } } public interface I5 { abstract virtual event System.Action P5 { add => throw null; remove => throw null; } } public interface I6 { abstract virtual event System.Action P6 { remove => throw null; } } public interface I7 { abstract virtual event System.Action P7 { add; } } public interface I8 { abstract virtual event System.Action P8 { remove; } } class Test1 : I0, I1, I2, I3, I4, I5, I6, I7, I8 { event System.Action I0.P0 { add { throw null; } remove { throw null; } } event System.Action I1.P1 { add { throw null; } } event System.Action I2.P2 { add { throw null; } remove { throw null; } } event System.Action I3.P3 { remove { throw null; } } event System.Action I4.P4 { add { throw null; } } event System.Action I5.P5 { add { throw null; } remove { throw null; } } event System.Action I6.P6 { remove { throw null; } } event System.Action I7.P7 { add { throw null; } } event System.Action I8.P8 { remove { throw null; } } } class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 {} "; ValidateEventModifiers_15(source1, // (4,42): error CS0503: The abstract event 'I0.P0' cannot be marked virtual // abstract virtual event System.Action P0; Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P0").WithArguments("event", "I0.P0").WithLocation(4, 42), // (8,42): error CS0503: The abstract event 'I1.P1' cannot be marked virtual // abstract virtual event System.Action P1 { add { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P1").WithArguments("event", "I1.P1").WithLocation(8, 42), // (8,45): error CS8712: 'I1.P1': abstract event cannot use event accessor syntax // abstract virtual event System.Action P1 { add { throw null; } } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P1").WithLocation(8, 45), // (12,42): error CS0503: The abstract event 'I2.P2' cannot be marked virtual // virtual abstract event System.Action P2 Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P2").WithArguments("event", "I2.P2").WithLocation(12, 42), // (13,5): error CS8712: 'I2.P2': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.P2").WithLocation(13, 5), // (20,42): error CS0503: The abstract event 'I3.P3' cannot be marked virtual // abstract virtual event System.Action P3 { remove { throw null; } } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P3").WithArguments("event", "I3.P3").WithLocation(20, 42), // (20,45): error CS8712: 'I3.P3': abstract event cannot use event accessor syntax // abstract virtual event System.Action P3 { remove { throw null; } } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I3.P3").WithLocation(20, 45), // (24,42): error CS0503: The abstract event 'I4.P4' cannot be marked virtual // abstract virtual event System.Action P4 { add => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P4").WithArguments("event", "I4.P4").WithLocation(24, 42), // (24,45): error CS8712: 'I4.P4': abstract event cannot use event accessor syntax // abstract virtual event System.Action P4 { add => throw null; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I4.P4").WithLocation(24, 45), // (28,42): error CS0503: The abstract event 'I5.P5' cannot be marked virtual // abstract virtual event System.Action P5 Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P5").WithArguments("event", "I5.P5").WithLocation(28, 42), // (29,5): error CS8712: 'I5.P5': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I5.P5").WithLocation(29, 5), // (36,42): error CS0503: The abstract event 'I6.P6' cannot be marked virtual // abstract virtual event System.Action P6 { remove => throw null; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P6").WithArguments("event", "I6.P6").WithLocation(36, 42), // (36,45): error CS8712: 'I6.P6': abstract event cannot use event accessor syntax // abstract virtual event System.Action P6 { remove => throw null; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I6.P6").WithLocation(36, 45), // (40,42): error CS0503: The abstract event 'I7.P7' cannot be marked virtual // abstract virtual event System.Action P7 { add; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P7").WithArguments("event", "I7.P7").WithLocation(40, 42), // (40,45): error CS8712: 'I7.P7': abstract event cannot use event accessor syntax // abstract virtual event System.Action P7 { add; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I7.P7").WithLocation(40, 45), // (44,42): error CS0503: The abstract event 'I8.P8' cannot be marked virtual // abstract virtual event System.Action P8 { remove; } Diagnostic(ErrorCode.ERR_AbstractNotVirtual, "P8").WithArguments("event", "I8.P8").WithLocation(44, 42), // (44,45): error CS8712: 'I8.P8': abstract event cannot use event accessor syntax // abstract virtual event System.Action P8 { remove; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I8.P8").WithLocation(44, 45), // (54,28): error CS0065: 'Test1.I1.P1': event property must have both add and remove accessors // event System.Action I1.P1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("Test1.I1.P1").WithLocation(54, 28), // (63,28): error CS0065: 'Test1.I3.P3': event property must have both add and remove accessors // event System.Action I3.P3 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P3").WithArguments("Test1.I3.P3").WithLocation(63, 28), // (67,28): error CS0065: 'Test1.I4.P4': event property must have both add and remove accessors // event System.Action I4.P4 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P4").WithArguments("Test1.I4.P4").WithLocation(67, 28), // (76,28): error CS0065: 'Test1.I6.P6': event property must have both add and remove accessors // event System.Action I6.P6 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P6").WithArguments("Test1.I6.P6").WithLocation(76, 28), // (80,28): error CS0065: 'Test1.I7.P7': event property must have both add and remove accessors // event System.Action I7.P7 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P7").WithArguments("Test1.I7.P7").WithLocation(80, 28), // (84,28): error CS0065: 'Test1.I8.P8': event property must have both add and remove accessors // event System.Action I8.P8 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P8").WithArguments("Test1.I8.P8").WithLocation(84, 28), // (90,15): error CS0535: 'Test2' does not implement interface member 'I0.P0' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I0").WithArguments("Test2", "I0.P0").WithLocation(90, 15), // (90,19): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(90, 19), // (90,23): error CS0535: 'Test2' does not implement interface member 'I2.P2' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I2.P2").WithLocation(90, 23), // (90,27): error CS0535: 'Test2' does not implement interface member 'I3.P3' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test2", "I3.P3").WithLocation(90, 27), // (90,31): error CS0535: 'Test2' does not implement interface member 'I4.P4' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I4").WithArguments("Test2", "I4.P4").WithLocation(90, 31), // (90,35): error CS0535: 'Test2' does not implement interface member 'I5.P5' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test2", "I5.P5").WithLocation(90, 35), // (90,39): error CS0535: 'Test2' does not implement interface member 'I6.P6' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I6").WithArguments("Test2", "I6.P6").WithLocation(90, 39), // (90,43): error CS0535: 'Test2' does not implement interface member 'I7.P7' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I7").WithArguments("Test2", "I7.P7").WithLocation(90, 43), // (90,47): error CS0535: 'Test2' does not implement interface member 'I8.P8' // class Test2 : I0, I1, I2, I3, I4, I5, I6, I7, I8 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I8").WithArguments("Test2", "I8.P8").WithLocation(90, 47) ); } private void ValidateEventModifiers_15(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); for (int i = 0; i <= 8; i++) { var i1 = compilation1.GetTypeByMetadataName("I" + i); var p2 = GetSingleEvent(i1); var test1P2 = test1.GetMembers().OfType().Where(p => p.Name.StartsWith(i1.Name)).Single(); Assert.True(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Same(test1P2, test1.FindImplementationForInterfaceMember(p2)); Assert.Null(test2.FindImplementationForInterfaceMember(p2)); switch (i) { case 3: case 6: case 8: Assert.Null(p2.AddMethod); ValidateAccessor(p2.RemoveMethod, test1P2.RemoveMethod); break; case 1: case 4: case 7: Assert.Null(p2.RemoveMethod); ValidateAccessor(p2.AddMethod, test1P2.AddMethod); break; default: ValidateAccessor(p2.AddMethod, test1P2.AddMethod); ValidateAccessor(p2.RemoveMethod, test1P2.RemoveMethod); break; } void ValidateAccessor(MethodSymbol accessor, MethodSymbol implementedBy) { Assert.True(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(implementedBy, test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } } [Fact] public void EventModifiers_16() { var source1 = @" public interface I1 { extern event System.Action P1; } public interface I2 { virtual extern event System.Action P2; } public interface I3 { static extern event System.Action P3; } public interface I4 { private extern event System.Action P4; } public interface I5 { extern sealed event System.Action P5; } public interface I6 { static event System.Action P6 { add => throw null; remove => throw null; } } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { event System.Action I1.P1 { add{} remove{} } event System.Action I2.P2 { add{} remove{} } } "; ValidateEventModifiers_16(source1); } private void ValidateEventModifiers_16(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test2 = m.GlobalNamespace.GetTypeMember("Test2"); bool isSource = !(m is PEModuleSymbol); var p1 = GetSingleEvent(m, "I1"); var test2P1 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I1.")).Single(); Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.Equal(isSource, p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test2P1, test2.FindImplementationForInterfaceMember(p1)); ValidateP1Accessor(p1.AddMethod, test2P1.AddMethod); ValidateP1Accessor(p1.RemoveMethod, test2P1.RemoveMethod); void ValidateP1Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.Equal(isSource, accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(accessor, test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p2 = GetSingleEvent(m, "I2"); var test2P2 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.Equal(isSource, p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Same(p2, test1.FindImplementationForInterfaceMember(p2)); Assert.Same(test2P2, test2.FindImplementationForInterfaceMember(p2)); ValidateP2Accessor(p2.AddMethod, test2P2.AddMethod); ValidateP2Accessor(p2.RemoveMethod, test2P2.RemoveMethod); void ValidateP2Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.Equal(isSource, accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(accessor, test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var i3 = m.ContainingAssembly.GetTypeByMetadataName("I3"); var p3 = GetSingleEvent(i3); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.False(p3.IsSealed); Assert.True(p3.IsStatic); Assert.Equal(isSource, p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.AddMethod); ValidateP3Accessor(p3.RemoveMethod); void ValidateP3Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.Equal(isSource, accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p4 = GetSingleEvent(m, "I4"); Assert.False(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.False(p4.IsStatic); Assert.Equal(isSource, p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Private, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.Null(test2.FindImplementationForInterfaceMember(p4)); ValidateP4Accessor(p4.AddMethod); ValidateP4Accessor(p4.RemoveMethod); void ValidateP4Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.Equal(isSource, accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p5 = GetSingleEvent(m, "I5"); Assert.False(p5.IsAbstract); Assert.False(p5.IsVirtual); Assert.False(p5.IsSealed); Assert.False(p5.IsStatic); Assert.Equal(isSource, p5.IsExtern); Assert.False(p5.IsOverride); Assert.Equal(Accessibility.Public, p5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); ValidateP5Accessor(p5.AddMethod); ValidateP5Accessor(p5.RemoveMethod); void ValidateP5Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.Equal(isSource, accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (4,32): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern event System.Action P1; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P1").WithArguments("extern", "7.3", "8.0").WithLocation(4, 32), // (8,40): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern event System.Action P2; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P2").WithArguments("extern", "7.3", "8.0").WithLocation(8, 40), // (8,40): error CS8703: The modifier 'virtual' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // virtual extern event System.Action P2; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P2").WithArguments("virtual", "7.3", "8.0").WithLocation(8, 40), // (12,39): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static extern event System.Action P3; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P3").WithArguments("static", "7.3", "8.0").WithLocation(12, 39), // (12,39): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static extern event System.Action P3; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P3").WithArguments("extern", "7.3", "8.0").WithLocation(12, 39), // (16,40): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern event System.Action P4; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P4").WithArguments("private", "7.3", "8.0").WithLocation(16, 40), // (16,40): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private extern event System.Action P4; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P4").WithArguments("extern", "7.3", "8.0").WithLocation(16, 40), // (20,39): error CS8703: The modifier 'sealed' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed event System.Action P5; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P5").WithArguments("sealed", "7.3", "8.0").WithLocation(20, 39), // (20,39): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern sealed event System.Action P5; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "P5").WithArguments("extern", "7.3", "8.0").WithLocation(20, 39), // (26,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // add => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(26, 9), // (27,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // remove => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(27, 9), // (8,40): warning CS0626: Method, operator, or accessor 'I2.P2.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern event System.Action P2; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P2").WithArguments("I2.P2.add").WithLocation(8, 40), // (8,40): warning CS0626: Method, operator, or accessor 'I2.P2.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern event System.Action P2; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P2").WithArguments("I2.P2.remove").WithLocation(8, 40), // (12,39): warning CS0626: Method, operator, or accessor 'I3.P3.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P3").WithArguments("I3.P3.add").WithLocation(12, 39), // (12,39): warning CS0626: Method, operator, or accessor 'I3.P3.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P3").WithArguments("I3.P3.remove").WithLocation(12, 39), // (16,40): warning CS0626: Method, operator, or accessor 'I4.P4.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern event System.Action P4; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P4").WithArguments("I4.P4.add").WithLocation(16, 40), // (16,40): warning CS0626: Method, operator, or accessor 'I4.P4.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern event System.Action P4; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P4").WithArguments("I4.P4.remove").WithLocation(16, 40), // (20,39): warning CS0626: Method, operator, or accessor 'I5.P5.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed event System.Action P5; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P5").WithArguments("I5.P5.add").WithLocation(20, 39), // (20,39): warning CS0626: Method, operator, or accessor 'I5.P5.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed event System.Action P5; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P5").WithArguments("I5.P5.remove").WithLocation(20, 39), // (4,32): warning CS0626: Method, operator, or accessor 'I1.P1.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P1; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P1").WithArguments("I1.P1.add").WithLocation(4, 32), // (4,32): warning CS0626: Method, operator, or accessor 'I1.P1.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P1; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P1").WithArguments("I1.P1.remove").WithLocation(4, 32) ); Validate(compilation2.SourceModule); var compilation3 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (4,32): error CS8501: Target runtime doesn't support default interface implementation. // extern event System.Action P1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P1").WithLocation(4, 32), // (8,40): error CS8501: Target runtime doesn't support default interface implementation. // virtual extern event System.Action P2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P2").WithLocation(8, 40), // (16,40): error CS8501: Target runtime doesn't support default interface implementation. // private extern event System.Action P4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P4").WithLocation(16, 40), // (20,39): error CS8501: Target runtime doesn't support default interface implementation. // extern sealed event System.Action P5; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P5").WithLocation(20, 39), // (8,40): warning CS0626: Method, operator, or accessor 'I2.P2.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern event System.Action P2; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P2").WithArguments("I2.P2.add").WithLocation(8, 40), // (8,40): warning CS0626: Method, operator, or accessor 'I2.P2.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // virtual extern event System.Action P2; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P2").WithArguments("I2.P2.remove").WithLocation(8, 40), // (12,39): error CS8701: Target runtime doesn't support default interface implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P3").WithLocation(12, 39), // (12,39): warning CS0626: Method, operator, or accessor 'I3.P3.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P3").WithArguments("I3.P3.add").WithLocation(12, 39), // (12,39): warning CS0626: Method, operator, or accessor 'I3.P3.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P3").WithArguments("I3.P3.remove").WithLocation(12, 39), // (16,40): warning CS0626: Method, operator, or accessor 'I4.P4.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern event System.Action P4; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P4").WithArguments("I4.P4.add").WithLocation(16, 40), // (16,40): warning CS0626: Method, operator, or accessor 'I4.P4.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // private extern event System.Action P4; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P4").WithArguments("I4.P4.remove").WithLocation(16, 40), // (20,39): warning CS0626: Method, operator, or accessor 'I5.P5.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed event System.Action P5; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P5").WithArguments("I5.P5.add").WithLocation(20, 39), // (20,39): warning CS0626: Method, operator, or accessor 'I5.P5.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern sealed event System.Action P5; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P5").WithArguments("I5.P5.remove").WithLocation(20, 39), // (4,32): warning CS0626: Method, operator, or accessor 'I1.P1.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P1; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P1").WithArguments("I1.P1.add").WithLocation(4, 32), // (4,32): warning CS0626: Method, operator, or accessor 'I1.P1.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern event System.Action P1; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P1").WithArguments("I1.P1.remove").WithLocation(4, 32), // (26,9): error CS8701: Target runtime doesn't support default interface implementation. // add => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(26, 9), // (27,9): error CS8701: Target runtime doesn't support default interface implementation. // remove => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(27, 9) ); Validate(compilation3.SourceModule); } [Fact] public void EventModifiers_17() { var source1 = @" public interface I1 { abstract extern event System.Action P1; } public interface I2 { extern event System.Action P2 = null; } public interface I3 { static extern event System.Action P3 {add => throw null; remove => throw null;} } public interface I4 { private extern event System.Action P4 { add {throw null;} remove {throw null;}} } class Test1 : I1, I2, I3, I4 { } class Test2 : I1, I2, I3, I4 { event System.Action I1.P1 { add => throw null; remove => throw null;} event System.Action I2.P2 { add => throw null; remove => throw null;} event System.Action I3.P3 { add => throw null; remove => throw null;} event System.Action I4.P4 { add => throw null; remove => throw null;} } "; ValidateEventModifiers_17(source1, // (4,41): error CS0180: 'I1.P1' cannot be both extern and abstract // abstract extern event System.Action P1; Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I1.P1").WithLocation(4, 41), // (8,32): error CS0068: 'I2.P2': instance event in interface cannot have initializer // extern event System.Action P2 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "P2").WithArguments("I2.P2").WithLocation(8, 32), // (12,43): error CS0179: 'I3.P3.add' cannot be extern and declare a body // static extern event System.Action P3 {add => throw null; remove => throw null;} Diagnostic(ErrorCode.ERR_ExternHasBody, "add").WithArguments("I3.P3.add").WithLocation(12, 43), // (12,62): error CS0179: 'I3.P3.remove' cannot be extern and declare a body // static extern event System.Action P3 {add => throw null; remove => throw null;} Diagnostic(ErrorCode.ERR_ExternHasBody, "remove").WithArguments("I3.P3.remove").WithLocation(12, 62), // (16,45): error CS0179: 'I4.P4.add' cannot be extern and declare a body // private extern event System.Action P4 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "add").WithArguments("I4.P4.add").WithLocation(16, 45), // (16,63): error CS0179: 'I4.P4.remove' cannot be extern and declare a body // private extern event System.Action P4 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_ExternHasBody, "remove").WithArguments("I4.P4.remove").WithLocation(16, 63), // (19,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1, I2, I3, I4 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(19, 15), // (27,28): error CS0539: 'Test2.P3' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I3.P3 { add => throw null; remove => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test2.P3").WithLocation(27, 28), // (28,28): error CS0539: 'Test2.P4' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I4.P4 { add => throw null; remove => throw null;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P4").WithArguments("Test2.P4").WithLocation(28, 28), // (8,32): warning CS0067: The event 'I2.P2' is never used // extern event System.Action P2 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P2").WithArguments("I2.P2").WithLocation(8, 32) ); } private void ValidateEventModifiers_17(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var p1 = GetSingleEvent(compilation1, "I1"); var test2P1 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I1.")).Single(); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.True(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test2P1, test2.FindImplementationForInterfaceMember(p1)); ValidateP1Accessor(p1.AddMethod, test2P1.AddMethod); ValidateP1Accessor(p1.RemoveMethod, test2P1.RemoveMethod); void ValidateP1Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p2 = GetSingleEvent(compilation1, "I2"); var test2P2 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); Assert.False(p2.IsAbstract); Assert.True(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.True(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Public, p2.DeclaredAccessibility); Assert.Same(p2, test1.FindImplementationForInterfaceMember(p2)); Assert.Same(test2P2, test2.FindImplementationForInterfaceMember(p2)); ValidateP2Accessor(p2.AddMethod, test2P2.AddMethod); ValidateP2Accessor(p2.RemoveMethod, test2P2.RemoveMethod); void ValidateP2Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.False(accessor.IsAbstract); Assert.True(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Same(accessor, test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p3 = GetSingleEvent(compilation1, "I3"); var test2P3 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I3.")).Single(); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.False(p3.IsSealed); Assert.True(p3.IsStatic); Assert.True(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.AddMethod); ValidateP3Accessor(p3.RemoveMethod); void ValidateP3Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p4 = GetSingleEvent(compilation1, "I4"); Assert.False(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.False(p4.IsStatic); Assert.True(p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Private, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.Null(test2.FindImplementationForInterfaceMember(p4)); ValidateP4Accessor(p4.AddMethod); ValidateP4Accessor(p4.RemoveMethod); void ValidateP4Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } [Fact] public void EventModifiers_18() { var source1 = @" public interface I1 { abstract event System.Action P1 {add => throw null; remove => throw null;} } public interface I2 { abstract private event System.Action P2 = null; } public interface I3 { static extern event System.Action P3; } public interface I4 { abstract static event System.Action P4 { add {throw null;} remove {throw null;}} } public interface I5 { override sealed event System.Action P5 { add {throw null;} remove {throw null;}} } class Test1 : I1, I2, I3, I4, I5 { } class Test2 : I1, I2, I3, I4, I5 { event System.Action I1.P1 { add {throw null;} remove {throw null;}} event System.Action I2.P2 { add {throw null;} remove {throw null;}} event System.Action I3.P3 { add {throw null;} remove {throw null;}} event System.Action I4.P4 { add {throw null;} remove {throw null;}} event System.Action I5.P5 { add {throw null;} remove {throw null;}} } "; ValidateEventModifiers_18(source1, // (4,37): error CS8712: 'I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action P1 {add => throw null; remove => throw null;} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.P1").WithLocation(4, 37), // (8,42): error CS0068: 'I2.P2': instance event in interface cannot have initializer // abstract private event System.Action P2 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "P2").WithArguments("I2.P2").WithLocation(8, 42), // (8,42): error CS0621: 'I2.P2': virtual or abstract members cannot be private // abstract private event System.Action P2 = null; Diagnostic(ErrorCode.ERR_VirtualPrivate, "P2").WithArguments("I2.P2").WithLocation(8, 42), // (16,44): error CS8712: 'I4.P4': abstract event cannot use event accessor syntax // abstract static event System.Action P4 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I4.P4").WithLocation(16, 44), // (16,41): error CS0112: A static member 'I4.P4' cannot be marked as override, virtual, or abstract // abstract static event System.Action P4 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_StaticNotVirtual, "P4").WithArguments("I4.P4").WithLocation(16, 41), // (20,41): error CS0106: The modifier 'override' is not valid for this item // override sealed event System.Action P5 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_BadMemberFlag, "P5").WithArguments("override").WithLocation(20, 41), // (23,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.P1").WithLocation(23, 15), // (23,19): error CS0535: 'Test1' does not implement interface member 'I2.P2' // class Test1 : I1, I2, I3, I4, I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I2.P2").WithLocation(23, 19), // (30,28): error CS0122: 'I2.P2' is inaccessible due to its protection level // event System.Action I2.P2 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I2.P2").WithLocation(30, 28), // (31,28): error CS0539: 'Test2.P3' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I3.P3 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P3").WithArguments("Test2.P3").WithLocation(31, 28), // (32,28): error CS0539: 'Test2.P4' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I4.P4 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P4").WithArguments("Test2.P4").WithLocation(32, 28), // (33,28): error CS0539: 'Test2.P5' in explicit interface declaration is not found among members of the interface that can be implemented // event System.Action I5.P5 { add {throw null;} remove {throw null;}} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P5").WithArguments("Test2.P5").WithLocation(33, 28), // (12,39): warning CS0626: Method, operator, or accessor 'I3.P3.add' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P3").WithArguments("I3.P3.add").WithLocation(12, 39), // (12,39): warning CS0626: Method, operator, or accessor 'I3.P3.remove' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // static extern event System.Action P3; Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "P3").WithArguments("I3.P3.remove").WithLocation(12, 39), // (8,42): warning CS0067: The event 'I2.P2' is never used // abstract private event System.Action P2 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "P2").WithArguments("I2.P2").WithLocation(8, 42) ); } private void ValidateEventModifiers_18(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); var test1 = compilation1.GetTypeByMetadataName("Test1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); var p1 = GetSingleEvent(compilation1, "I1"); var test2P1 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I1.")).Single(); Assert.True(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(Accessibility.Public, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); Assert.Same(test2P1, test2.FindImplementationForInterfaceMember(p1)); ValidateP1Accessor(p1.AddMethod, test2P1.AddMethod); ValidateP1Accessor(p1.RemoveMethod, test2P1.RemoveMethod); void ValidateP1Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p2 = GetSingleEvent(compilation1, "I2"); var test2P2 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); Assert.True(p2.IsAbstract); Assert.False(p2.IsVirtual); Assert.False(p2.IsSealed); Assert.False(p2.IsStatic); Assert.False(p2.IsExtern); Assert.False(p2.IsOverride); Assert.Equal(Accessibility.Private, p2.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p2)); Assert.Same(test2P2, test2.FindImplementationForInterfaceMember(p2)); ValidateP2Accessor(p2.AddMethod, test2P2.AddMethod); ValidateP2Accessor(p2.RemoveMethod, test2P2.RemoveMethod); void ValidateP2Accessor(MethodSymbol accessor, MethodSymbol implementation) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Private, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Same(implementation, test2.FindImplementationForInterfaceMember(accessor)); } var p3 = GetSingleEvent(compilation1, "I3"); var test2P3 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I3.")).Single(); Assert.False(p3.IsAbstract); Assert.False(p3.IsVirtual); Assert.False(p3.IsSealed); Assert.True(p3.IsStatic); Assert.True(p3.IsExtern); Assert.False(p3.IsOverride); Assert.Equal(Accessibility.Public, p3.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p3)); Assert.Null(test2.FindImplementationForInterfaceMember(p3)); ValidateP3Accessor(p3.AddMethod); ValidateP3Accessor(p3.RemoveMethod); void ValidateP3Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.True(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p4 = GetSingleEvent(compilation1, "I4"); var test2P4 = test2.GetMembers().OfType().Where(p => p.Name.StartsWith("I4.")).Single(); Assert.True(p4.IsAbstract); Assert.False(p4.IsVirtual); Assert.False(p4.IsSealed); Assert.True(p4.IsStatic); Assert.False(p4.IsExtern); Assert.False(p4.IsOverride); Assert.Equal(Accessibility.Public, p4.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p4)); Assert.Null(test2.FindImplementationForInterfaceMember(p4)); ValidateP4Accessor(p4.AddMethod); ValidateP4Accessor(p4.RemoveMethod); void ValidateP4Accessor(MethodSymbol accessor) { Assert.True(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.True(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } var p5 = GetSingleEvent(compilation1, "I5"); Assert.False(p5.IsAbstract); Assert.False(p5.IsVirtual); Assert.False(p5.IsSealed); Assert.False(p5.IsStatic); Assert.False(p5.IsExtern); Assert.False(p5.IsOverride); Assert.Equal(Accessibility.Public, p5.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p5)); Assert.Null(test2.FindImplementationForInterfaceMember(p5)); ValidateP5Accessor(p5.AddMethod); ValidateP5Accessor(p5.RemoveMethod); void ValidateP5Accessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.False(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(Accessibility.Public, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); Assert.Null(test2.FindImplementationForInterfaceMember(accessor)); } } [Fact] public void EventModifiers_20() { var source1 = @" public interface I1 { internal event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } void M2() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidateEventModifiers_20(source1, source2, Accessibility.Internal); } private void ValidateEventModifiers_20(string source1, string source2, Accessibility accessibility) { var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Single(); var p1 = GetSingleEvent(i1); var p1add = p1.AddMethod; var p1remove = p1.RemoveMethod; ValidateEvent(p1); ValidateMethod(p1add); ValidateMethod(p1remove); Assert.Same(p1, test1.FindImplementationForInterfaceMember(p1)); Assert.Same(p1add, test1.FindImplementationForInterfaceMember(p1add)); Assert.Same(p1remove, test1.FindImplementationForInterfaceMember(p1remove)); } void ValidateEvent(EventSymbol p1) { Assert.False(p1.IsAbstract); Assert.True(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.False(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(accessibility, p1.DeclaredAccessibility); } void ValidateMethod(MethodSymbol m1) { Assert.False(m1.IsAbstract); Assert.True(m1.IsVirtual); Assert.True(m1.IsMetadataVirtual()); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(accessibility, m1.DeclaredAccessibility); } var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); { var i1 = compilation2.GetTypeByMetadataName("I1"); var p1 = GetSingleEvent(i1); ValidateEvent(p1); ValidateMethod(p1.AddMethod); ValidateMethod(p1.RemoveMethod); } var compilation3 = CreateCompilation(source2, new[] { compilation2.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, new[] { compilation2.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); Validate1(compilation4.SourceModule); } [Fact] public void EventModifiers_21() { var source1 = @" public interface I1 { private static event System.Action P1 { add => throw null; remove => throw null; } internal static event System.Action P2 { add => throw null; remove => throw null; } public static event System.Action P3 { add => throw null; remove => throw null; } static event System.Action P4 { add => throw null; remove => throw null; } } class Test1 { static void Main() { I1.P1 += null; I1.P1 -= null; I1.P2 += null; I1.P2 -= null; I1.P3 += null; I1.P3 -= null; I1.P4 += null; I1.P4 -= null; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (17,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(17, 12), // (18,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(18, 12) ); var source2 = @" class Test2 { static void Main() { I1.P1 += null; I1.P1 -= null; I1.P2 += null; I1.P2 -= null; I1.P3 += null; I1.P3 -= null; I1.P4 += null; I1.P4 -= null; } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (6,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(6, 12), // (7,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(7, 12), // (8,12): error CS0122: 'I1.P2' is inaccessible due to its protection level // I1.P2 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(8, 12), // (9,12): error CS0122: 'I1.P2' is inaccessible due to its protection level // I1.P2 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(9, 12) ); } [Fact] public void EventModifiers_22() { var source0 = @" public interface I1 { protected static event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } protected internal static event System.Action P2 { add { System.Console.WriteLine(""get_P2""); } remove { System.Console.WriteLine(""set_P2""); } } private protected static event System.Action P3 { add => System.Console.WriteLine(""get_P3""); remove => System.Console.WriteLine(""set_P3""); } } "; var source1 = @" class Test1 : I1 { static void Main() { I1.P1 += null; I1.P1 -= null; I1.P2 += null; I1.P2 -= null; I1.P3 += null; I1.P3 -= null; } } "; var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2 get_P3 set_P3", symbolValidator: validate, verify: VerifyOnMonoOrCoreClr); validate(compilation1.SourceModule); var source2 = @" class Test1 { static void Main() { I1.P2 += null; I1.P2 -= null; } } "; var compilation2 = CreateCompilation(source0 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P2 set_P2", verify: VerifyOnMonoOrCoreClr); var compilation3 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); var source3 = @" class Test1 : I1 { static void Main() { I1.P1 += null; I1.P1 -= null; I1.P2 += null; I1.P2 -= null; } } "; var source4 = @" class Test1 { static void Main() { I1.P1 += null; I1.P1 -= null; I1.P2 += null; I1.P2 -= null; I1.P3 += null; I1.P3 -= null; } } "; foreach (var reference in new[] { compilation3.ToMetadataReference(), compilation3.EmitToImageReference() }) { var compilation4 = CreateCompilation(source3, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"get_P1 set_P1 get_P2 set_P2", verify: VerifyOnMonoOrCoreClr); var compilation5 = CreateCompilation(source4, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics( // (6,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(6, 12), // (7,12): error CS0122: 'I1.P1' is inaccessible due to its protection level // I1.P1 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(7, 12), // (8,12): error CS0122: 'I1.P2' is inaccessible due to its protection level // I1.P2 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(8, 12), // (9,12): error CS0122: 'I1.P2' is inaccessible due to its protection level // I1.P2 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P2").WithArguments("I1.P2").WithLocation(9, 12), // (10,12): error CS0122: 'I1.P3' is inaccessible due to its protection level // I1.P3 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(10, 12), // (11,12): error CS0122: 'I1.P3' is inaccessible due to its protection level // I1.P3 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(11, 12) ); var compilation6 = CreateCompilation(source1, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation6.VerifyDiagnostics( // (10,12): error CS0122: 'I1.P3' is inaccessible due to its protection level // I1.P3 += null; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(10, 12), // (11,12): error CS0122: 'I1.P3' is inaccessible due to its protection level // I1.P3 -= null; Diagnostic(ErrorCode.ERR_BadAccess, "P3").WithArguments("I1.P3").WithLocation(11, 12) ); } void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = m.GlobalNamespace.GetTypeMember("I1"); foreach (var tuple in new[] { (name: "P1", access: Accessibility.Protected), (name: "P2", access: Accessibility.ProtectedOrInternal), (name: "P3", access: Accessibility.ProtectedAndInternal)}) { var p1 = i1.GetMember(tuple.name); Assert.False(p1.IsAbstract); Assert.False(p1.IsVirtual); Assert.False(p1.IsSealed); Assert.True(p1.IsStatic); Assert.False(p1.IsExtern); Assert.False(p1.IsOverride); Assert.Equal(tuple.access, p1.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(p1)); ValidateAccessor(p1.AddMethod); ValidateAccessor(p1.RemoveMethod); void ValidateAccessor(MethodSymbol accessor) { Assert.False(accessor.IsAbstract); Assert.False(accessor.IsVirtual); Assert.False(accessor.IsMetadataVirtual()); Assert.False(accessor.IsSealed); Assert.True(accessor.IsStatic); Assert.False(accessor.IsExtern); Assert.False(accessor.IsAsync); Assert.False(accessor.IsOverride); Assert.Equal(tuple.access, accessor.DeclaredAccessibility); Assert.Null(test1.FindImplementationForInterfaceMember(accessor)); } } } } [Fact] public void EventModifiers_23() { var source1 = @" public interface I1 { protected abstract event System.Action P1; sealed void Test() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.Test(); } public event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11(source1, source2, Accessibility.Protected, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } [Fact] public void EventModifiers_24() { var source1 = @" public interface I1 { protected internal abstract event System.Action P1; sealed void Test() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.Test(); } public event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11(source1, source2, Accessibility.ProtectedOrInternal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } [Fact] public void EventModifiers_25() { var source1 = @" public interface I1 { private protected abstract event System.Action P1; sealed void Test() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.Test(); } public event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11(source1, source2, Accessibility.ProtectedAndInternal, new DiagnosticDescription[] { // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.remove'. 'Test1.P1.remove' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.remove", "Test1.P1.remove").WithLocation(2, 15), // (2,15): error CS8504: 'Test1' does not implement interface member 'I1.P1.add'. 'Test1.P1.add' cannot implicitly implement a non-public member. // class Test1 : I1 Diagnostic(ErrorCode.ERR_ImplicitImplementationOfNonPublicInterfaceMember, "I1").WithArguments("Test1", "I1.P1.add", "Test1.P1.add").WithLocation(2, 15) }, // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.P1' // class Test2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test2", "I1.P1").WithLocation(2, 15) ); } [Fact] public void EventModifiers_26() { var source1 = @" public interface I1 { protected abstract event System.Action P1; public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } event System.Action I1.P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest); } [Fact] public void EventModifiers_27() { var source1 = @" public interface I1 { protected internal abstract event System.Action P1; public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } event System.Action I1.P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest); } [Fact] public void EventModifiers_28() { var source1 = @" public interface I1 { private protected abstract event System.Action P1; public static void CallP1(I1 x) { x.P1 += null; x.P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1.CallP1(new Test1()); } event System.Action I1.P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } } "; ValidateEventModifiers_11_03(source1, source2, TargetFramework.NetStandardLatest, // (9,28): error CS0122: 'I1.P1' is inaccessible due to its protection level // event System.Action I1.P1 Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(9, 28) ); } [Fact] public void EventModifiers_29() { var source1 = @" public interface I1 { protected event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } void M2() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidateEventModifiers_20(source1, source2, Accessibility.Protected); } [Fact] public void EventModifiers_30() { var source1 = @" public interface I1 { protected internal event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } void M2() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidateEventModifiers_20(source1, source2, Accessibility.ProtectedOrInternal); } [Fact] public void EventModifiers_31() { var source1 = @" public interface I1 { private protected event System.Action P1 { add { System.Console.WriteLine(""get_P1""); } remove { System.Console.WriteLine(""set_P1""); } } void M2() { P1 += null; P1 -= null; } } "; var source2 = @" class Test1 : I1 { static void Main() { I1 x = new Test1(); x.M2(); } } "; ValidateEventModifiers_20(source1, source2, Accessibility.ProtectedAndInternal); } [Fact] public void NestedTypes_01() { var source1 = @" public interface I1 { interface T1 { void M1(); } class T2 {} struct T3 {} enum T4 { B } delegate void T5(); } class Test1 : I1.T1 { static void Main() { I1.T1 a = new Test1(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } public void M1() { System.Console.WriteLine(""M1""); } } "; ValidateNestedTypes_01(source1); } private void ValidateNestedTypes_01(string source1, Accessibility expected = Accessibility.Public, TargetFramework targetFramework = TargetFramework.Standard, bool execute = true, Verification verify = Verification.Passes) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: targetFramework); for (int i = 1; i <= 5; i++) { Assert.Equal(expected, compilation1.GetMember("I1.T" + i).DeclaredAccessibility); } CompileAndVerify(compilation1, expectedOutput: !execute ? null : @"M1 I1+T2 I1+T3 B I1+T5", verify: verify); } [Fact] public void NestedTypes_02() { var source1 = @" public interface I1 { interface T1 { void M1(); } class T2 {} struct T3 {} enum T4 { B } } class Test1 : I1.T1 { static void Main() { I1.T1 a = new Test1(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); } public void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3); for (int i = 1; i <= 4; i++) { Assert.Equal(Accessibility.Public, compilation1.GetMember("I1.T" + i).DeclaredAccessibility); } compilation1.VerifyDiagnostics( // (4,15): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // interface T1 Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "T1").WithArguments("default interface implementation", "8.0").WithLocation(4, 15), // (9,11): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // class T2 Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "T2").WithArguments("default interface implementation", "8.0").WithLocation(9, 11), // (12,12): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // struct T3 Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "T3").WithArguments("default interface implementation", "8.0").WithLocation(12, 12), // (15,10): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // enum T4 Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "T4").WithArguments("default interface implementation", "8.0").WithLocation(15, 10) ); } [Fact] public void NestedTypes_03() { var source1 = @" public interface I1 { public interface T1 { void M1(); } public class T2 {} public struct T3 {} public enum T4 { B } public delegate void T5(); } class Test1 : I1.T1 { static void Main() { I1.T1 a = new Test1(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } public void M1() { System.Console.WriteLine(""M1""); } } "; ValidateNestedTypes_01(source1); } [Fact] public void NestedTypes_04() { var source0 = @" public interface I1 { protected interface T1 { void M1(); } protected class T2 {} protected struct T3 {} protected enum T4 { B } protected delegate void T5(); } "; var source1 = @" class Test1 : I1 { static void Main() { I1.T1 a = new Test2(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } class Test2 : I1.T1 { public void M1() { System.Console.WriteLine(""M1""); } } } "; ValidateNestedTypes_01(source0 + source1, Accessibility.Protected, targetFramework: TargetFramework.NetStandardLatest, execute: ExecutionConditionUtil.IsMonoOrCoreClr, verify: VerifyOnMonoOrCoreClr); var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); for (int i = 1; i <= 5; i++) { Assert.Equal(Accessibility.Protected, compilation1.GetMember("I1.T" + i).DeclaredAccessibility); } compilation1.VerifyDiagnostics( // (4,25): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected interface T1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T1").WithLocation(4, 25), // (9,21): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected class T2 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T2").WithLocation(9, 21), // (12,22): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected struct T3 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T3").WithLocation(12, 22), // (15,20): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected enum T4 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T4").WithLocation(15, 20), // (20,29): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected delegate void T5(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T5").WithLocation(20, 29) ); var source2 = @" class Test1 { static void Main() { I1.T1 a = new Test2(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } class Test2 : I1.T1 { public void M1() { System.Console.WriteLine(""M1""); } } } "; var compilation2 = CreateCompilation(source2 + source0, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var expected = new DiagnosticDescription[] { // (6,12): error CS0122: 'I1.T1' is inaccessible due to its protection level // I1.T1 a = new Test2(); Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(6, 12), // (7,11): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // a.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(7, 11), // (8,41): error CS0122: 'I1.T2' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T2()); Diagnostic(ErrorCode.ERR_BadAccess, "T2").WithArguments("I1.T2").WithLocation(8, 41), // (9,41): error CS0122: 'I1.T3' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T3()); Diagnostic(ErrorCode.ERR_BadAccess, "T3").WithArguments("I1.T3").WithLocation(9, 41), // (10,37): error CS0122: 'I1.T4' is inaccessible due to its protection level // System.Console.WriteLine(I1.T4.B); Diagnostic(ErrorCode.ERR_BadAccess, "T4").WithArguments("I1.T4").WithLocation(10, 37), // (11,41): error CS0122: 'I1.T5' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "T5").WithArguments("I1.T5").WithLocation(11, 41), // (11,46): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(11, 46), // (14,22): error CS0122: 'I1.T1' is inaccessible due to its protection level // class Test2 : I1.T1 Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(14, 22) }; compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); foreach (var reference in new[] { compilation3.ToMetadataReference(), compilation3.EmitToImageReference() }) { var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics(); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 I1+T2 I1+T3 B I1+T5", verify: VerifyOnMonoOrCoreClr); var compilation5 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics(expected); } } [Fact] public void NestedTypes_05() { var source0 = @" public interface I1 { protected internal interface T1 { void M1(); } protected internal class T2 {} protected internal struct T3 {} protected internal enum T4 { B } protected internal delegate void T5(); } "; var source1 = @" class Test1 : I1 { static void Main() { I1.T1 a = new Test2(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } class Test2 : I1.T1 { public void M1() { System.Console.WriteLine(""M1""); } } } "; var source2 = @" class Test1 { static void Main() { I1.T1 a = new Test2(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } class Test2 : I1.T1 { public void M1() { System.Console.WriteLine(""M1""); } } } "; ValidateNestedTypes_01(source0 + source1, Accessibility.ProtectedOrInternal, targetFramework: TargetFramework.NetStandardLatest, execute: ExecutionConditionUtil.IsMonoOrCoreClr, verify: VerifyOnMonoOrCoreClr); ValidateNestedTypes_01(source0 + source2, Accessibility.ProtectedOrInternal, targetFramework: TargetFramework.NetStandardLatest, execute: ExecutionConditionUtil.IsMonoOrCoreClr, verify: VerifyOnMonoOrCoreClr); var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); for (int i = 1; i <= 5; i++) { Assert.Equal(Accessibility.ProtectedOrInternal, compilation1.GetMember("I1.T" + i).DeclaredAccessibility); } compilation1.VerifyDiagnostics( // (4,34): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal interface T1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T1").WithLocation(4, 34), // (9,30): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal class T2 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T2").WithLocation(9, 30), // (12,31): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal struct T3 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T3").WithLocation(12, 31), // (15,29): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal enum T4 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T4").WithLocation(15, 29), // (20,38): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // protected internal delegate void T5(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T5").WithLocation(20, 38) ); var compilation3 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); foreach (var reference in new[] { compilation3.ToMetadataReference(), compilation3.EmitToImageReference() }) { var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics(); CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1 I1+T2 I1+T3 B I1+T5", verify: VerifyOnMonoOrCoreClr); var compilation5 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics( // (6,12): error CS0122: 'I1.T1' is inaccessible due to its protection level // I1.T1 a = new Test2(); Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(6, 12), // (7,11): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // a.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(7, 11), // (8,41): error CS0122: 'I1.T2' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T2()); Diagnostic(ErrorCode.ERR_BadAccess, "T2").WithArguments("I1.T2").WithLocation(8, 41), // (9,41): error CS0122: 'I1.T3' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T3()); Diagnostic(ErrorCode.ERR_BadAccess, "T3").WithArguments("I1.T3").WithLocation(9, 41), // (10,37): error CS0122: 'I1.T4' is inaccessible due to its protection level // System.Console.WriteLine(I1.T4.B); Diagnostic(ErrorCode.ERR_BadAccess, "T4").WithArguments("I1.T4").WithLocation(10, 37), // (11,41): error CS0122: 'I1.T5' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "T5").WithArguments("I1.T5").WithLocation(11, 41), // (11,46): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(11, 46), // (14,22): error CS0122: 'I1.T1' is inaccessible due to its protection level // class Test2 : I1.T1 Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(14, 22) ); } } [Fact] public void NestedTypes_06() { var source1 = @" public interface I1 { internal interface T1 { void M1(); } internal class T2 {} internal struct T3 {} internal enum T4 { B } internal delegate void T5(); } "; var source2 = @" class Test1 : I1.T1 { static void Main() { I1.T1 a = new Test1(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } public void M1() { System.Console.WriteLine(""M1""); } } "; ValidateNestedTypes_01(source1 + source2, Accessibility.Internal); var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe); var expected = new[] { // (2,18): error CS0122: 'I1.T1' is inaccessible due to its protection level // class Test1 : I1.T1 Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(2, 18), // (6,12): error CS0122: 'I1.T1' is inaccessible due to its protection level // I1.T1 a = new Test1(); Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(6, 12), // (7,11): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // a.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(7, 11), // (8,41): error CS0122: 'I1.T2' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T2()); Diagnostic(ErrorCode.ERR_BadAccess, "T2").WithArguments("I1.T2").WithLocation(8, 41), // (9,41): error CS0122: 'I1.T3' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T3()); Diagnostic(ErrorCode.ERR_BadAccess, "T3").WithArguments("I1.T3").WithLocation(9, 41), // (10,37): error CS0122: 'I1.T4' is inaccessible due to its protection level // System.Console.WriteLine(I1.T4.B); Diagnostic(ErrorCode.ERR_BadAccess, "T4").WithArguments("I1.T4").WithLocation(10, 37), // (11,41): error CS0122: 'I1.T5' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "T5").WithArguments("I1.T5").WithLocation(11, 41), // (11,46): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(11, 46) }; compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe); compilation3.VerifyDiagnostics(expected); } [Fact] public void NestedTypes_07() { var source1 = @" public interface I1 { private interface T1 { void M1(); } private class T2 {} private struct T3 {} private enum T4 { B } private delegate void T5(); class Test1 : I1.T1 { static void Main() { I1.T1 a = new Test1(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } public void M1() { System.Console.WriteLine(""M1""); } } } "; ValidateNestedTypes_01(source1, Accessibility.Private); } [Fact] public void NestedTypes_08() { var source1 = @" public interface I1 { private interface T1 { void M1(); } private class T2 {} private struct T3 {} private enum T4 { B } } class Test1 : I1.T1 { static void Main() { I1.T1 a = new Test1(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); } public void M1() { System.Console.WriteLine(""M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (21,18): error CS0122: 'I1.T1' is inaccessible due to its protection level // class Test1 : I1.T1 Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(21, 18), // (25,12): error CS0122: 'I1.T1' is inaccessible due to its protection level // I1.T1 a = new Test1(); Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(25, 12), // (26,11): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // a.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(26, 11), // (27,41): error CS0122: 'I1.T2' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T2()); Diagnostic(ErrorCode.ERR_BadAccess, "T2").WithArguments("I1.T2").WithLocation(27, 41), // (28,41): error CS0122: 'I1.T3' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T3()); Diagnostic(ErrorCode.ERR_BadAccess, "T3").WithArguments("I1.T3").WithLocation(28, 41), // (29,37): error CS0122: 'I1.T4' is inaccessible due to its protection level // System.Console.WriteLine(I1.T4.B); Diagnostic(ErrorCode.ERR_BadAccess, "T4").WithArguments("I1.T4").WithLocation(29, 37) ); } [Fact] public void NestedTypes_09() { var source0 = @" public interface I1 { private protected interface T1 { void M1(); } private protected class T2 {} private protected struct T3 {} private protected enum T4 { B } private protected delegate void T5(); } "; var source1 = @" class Test1 : I1 { static void Main() { I1.T1 a = new Test2(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } class Test2 : I1.T1 { public void M1() { System.Console.WriteLine(""M1""); } } } "; var source2 = @" class Test1 { static void Main() { I1.T1 a = new Test2(); a.M1(); System.Console.WriteLine(new I1.T2()); System.Console.WriteLine(new I1.T3()); System.Console.WriteLine(I1.T4.B); System.Console.WriteLine(new I1.T5(a.M1)); } class Test2 : I1.T1 { public void M1() { System.Console.WriteLine(""M1""); } } } "; ValidateNestedTypes_01(source0 + source1, Accessibility.ProtectedAndInternal, targetFramework: TargetFramework.NetStandardLatest, execute: ExecutionConditionUtil.IsMonoOrCoreClr, verify: VerifyOnMonoOrCoreClr); var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); for (int i = 1; i <= 5; i++) { Assert.Equal(Accessibility.ProtectedAndInternal, compilation1.GetMember("I1.T" + i).DeclaredAccessibility); } compilation1.VerifyDiagnostics( // (4,33): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected interface T1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T1").WithLocation(4, 33), // (9,29): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected class T2 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T2").WithLocation(9, 29), // (12,30): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected struct T3 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T3").WithLocation(12, 30), // (15,28): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected enum T4 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T4").WithLocation(15, 28), // (20,37): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // private protected delegate void T5(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "T5").WithLocation(20, 37) ); var compilation2 = CreateCompilation(source2 + source0, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var expected = new DiagnosticDescription[] { // (6,12): error CS0122: 'I1.T1' is inaccessible due to its protection level // I1.T1 a = new Test2(); Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(6, 12), // (7,11): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // a.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(7, 11), // (8,41): error CS0122: 'I1.T2' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T2()); Diagnostic(ErrorCode.ERR_BadAccess, "T2").WithArguments("I1.T2").WithLocation(8, 41), // (9,41): error CS0122: 'I1.T3' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T3()); Diagnostic(ErrorCode.ERR_BadAccess, "T3").WithArguments("I1.T3").WithLocation(9, 41), // (10,37): error CS0122: 'I1.T4' is inaccessible due to its protection level // System.Console.WriteLine(I1.T4.B); Diagnostic(ErrorCode.ERR_BadAccess, "T4").WithArguments("I1.T4").WithLocation(10, 37), // (11,41): error CS0122: 'I1.T5' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "T5").WithArguments("I1.T5").WithLocation(11, 41), // (11,46): error CS0122: 'I1.T1.M1()' is inaccessible due to its protection level // System.Console.WriteLine(new I1.T5(a.M1)); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.T1.M1()").WithLocation(11, 46), // (14,22): error CS0122: 'I1.T1' is inaccessible due to its protection level // class Test2 : I1.T1 Diagnostic(ErrorCode.ERR_BadAccess, "T1").WithArguments("I1.T1").WithLocation(14, 22) }; compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); foreach (var reference in new[] { compilation3.ToMetadataReference(), compilation3.EmitToImageReference() }) { var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics(expected); var compilation5 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics(expected); } } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void MethodImplementationInDerived_01() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I5 : I4 { } public interface I1 : I2, I5 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source2 = @" class Test1 : I1 { static void Main() { I2 i2 = new Test1(); i2.M1(); I4 i4 = new Test1(); i4.M1(); } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); } private static void ValidateMethodImplementationInDerived_01(ModuleSymbol m) { ValidateMethodImplementationInDerived_01(m, i4M1IsAbstract: false); } private static void ValidateMethodImplementationInDerived_01(ModuleSymbol m, bool i4M1IsAbstract) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var i1i2m1 = i1.GetMember("I2.M1"); var i1i4m1 = i1.GetMember("I4.M1"); var i2 = i1.AllInterfacesNoUseSiteDiagnostics.Where(i => i.Name == "I2").Single(); var i2m1 = i2.GetMembers().OfType().Single(); var i4 = i1.AllInterfacesNoUseSiteDiagnostics.Where(i => i.Name == "I4").Single(); var i4m1 = i4.GetMembers().OfType().Single(); var i3 = i1.ContainingNamespace.GetTypeMember("I3"); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); ValidateExplicitImplementation(i1i2m1); ValidateExplicitImplementation(i1i4m1, i4M1IsAbstract); Assert.Null(test1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1i4m1)); Assert.Same(i1i2m1, test1.FindImplementationForInterfaceMember(i2m1)); Assert.Same(i4M1IsAbstract ? null : i1i4m1, test1.FindImplementationForInterfaceMember(i4m1)); Assert.Null(i1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Null(i1.FindImplementationForInterfaceMember(i1i4m1)); Assert.Same(i1i2m1, i1.FindImplementationForInterfaceMember(i2m1)); Assert.Same(i4M1IsAbstract ? null : i1i4m1, i1.FindImplementationForInterfaceMember(i4m1)); Assert.Null(i2.FindImplementationForInterfaceMember(i2m1)); Assert.Null(i4.FindImplementationForInterfaceMember(i4m1)); Assert.Same(i1i2m1, i3.FindImplementationForInterfaceMember(i2m1)); Assert.Same(i4M1IsAbstract ? null : i1i4m1, i3.FindImplementationForInterfaceMember(i4m1)); } private static void ValidateExplicitImplementation(MethodSymbol m1, bool isAbstract = false) { Assert.True(m1.IsMetadataVirtual()); Assert.True(m1.IsMetadataFinal); Assert.False(m1.IsMetadataNewSlot()); Assert.Equal(isAbstract, m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.Equal(isAbstract, m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); if (m1.ContainingModule is PEModuleSymbol peModule) { int rva; peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)m1.OriginalDefinition).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } } [Fact] public void MethodImplementationInDerived_02() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 : I2, I4 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // void I2.M1() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(14, 13), // (18,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // void I4.M1() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(18, 13) ); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); var source2 = @" public interface I3 : I1 { } class Test1 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (6,15): error CS8506: 'I1.I2.M1()' cannot implement interface member 'I2.M1()' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1()", "I2.M1()", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15), // (6,15): error CS8506: 'I1.I4.M1()' cannot implement interface member 'I4.M1()' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1()", "I4.M1()", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15) ); ValidateMethodImplementationInDerived_01(compilation2.SourceModule); } [Fact] public void MethodImplementationInDerived_03() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 : I2, I4 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,13): error CS8501: Target runtime doesn't support default interface implementation. // void I2.M1() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(14, 13), // (18,13): error CS8501: Target runtime doesn't support default interface implementation. // void I4.M1() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(18, 13) ); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); var source2 = @" public interface I3 : I1 { } class Test1 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (6,15): error CS8502: 'I1.I2.M1()' cannot implement interface member 'I2.M1()' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1()", "I2.M1()", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I4.M1()' cannot implement interface member 'I4.M1()' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1()", "I4.M1()", "Test1").WithLocation(6, 15) ); } [Fact] public void MethodImplementationInDerived_04() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 : I2, I4 { void I2.M1(); void I4.M1(); } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (15,13): error CS0501: 'I1.I4.M1()' must declare a body because it is not marked abstract, extern, or partial // void I4.M1(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M1").WithArguments("I1.I4.M1()").WithLocation(15, 13), // (14,13): error CS0501: 'I1.I2.M1()' must declare a body because it is not marked abstract, extern, or partial // void I2.M1(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M1").WithArguments("I1.I2.M1()").WithLocation(14, 13) ); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); } [Fact] public void MethodImplementationInDerived_05() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I2.M1""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (18,10): error CS0540: 'I1.I4.M1()': containing type does not implement interface 'I4' // void I4.M1() Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I4").WithArguments("I1.I4.M1()", "I4").WithLocation(18, 10), // (14,10): error CS0540: 'I1.I2.M1()': containing type does not implement interface 'I2' // void I2.M1() Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I2").WithArguments("I1.I2.M1()", "I2").WithLocation(14, 10) ); } [Fact] public void MethodImplementationInDerived_06() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 : I2, I4 { public static void I2.M1() { System.Console.WriteLine(""I2.M1""); } internal virtual void I4.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,27): error CS0106: The modifier 'static' is not valid for this item // public static void I2.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("static").WithLocation(14, 27), // (14,27): error CS0106: The modifier 'public' is not valid for this item // public static void I2.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("public").WithLocation(14, 27), // (18,30): error CS0106: The modifier 'internal' is not valid for this item // internal virtual void I4.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("internal").WithLocation(18, 30), // (18,30): error CS0106: The modifier 'virtual' is not valid for this item // internal virtual void I4.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("virtual").WithLocation(18, 30) ); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); } [Fact] public void MethodImplementationInDerived_07() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 : I2, I4 { private sealed void I2.M1() { System.Console.WriteLine(""I2.M1""); } protected abstract void I4.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,28): error CS0106: The modifier 'sealed' is not valid for this item // private sealed void I2.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("sealed").WithLocation(14, 28), // (14,28): error CS0106: The modifier 'private' is not valid for this item // private sealed void I2.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private").WithLocation(14, 28), // (18,32): error CS0106: The modifier 'protected' is not valid for this item // protected abstract void I4.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(18, 32), // (18,32): error CS0500: 'I1.I4.M1()' cannot declare a body because it is marked abstract // protected abstract void I4.M1() Diagnostic(ErrorCode.ERR_AbstractHasBody, "M1").WithArguments("I1.I4.M1()").WithLocation(18, 32), // (28,15): error CS0535: 'Test1' does not implement interface member 'I4.M1()' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.M1()").WithLocation(28, 15) ); ValidateMethodImplementationInDerived_01(compilation1.SourceModule, i4M1IsAbstract: true); } [Fact] public void MethodImplementationInDerived_08() { var source1 = @" public interface I2 { void M1(); } public interface I4 { void M1(); } public interface I1 : I2, I4 { private protected void I2.M1() { System.Console.WriteLine(""I2.M1""); } internal protected override void I4.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,31): error CS0106: The modifier 'private protected' is not valid for this item // private protected void I2.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private protected").WithLocation(14, 31), // (18,41): error CS0106: The modifier 'protected internal' is not valid for this item // internal protected override void I4.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected internal").WithLocation(18, 41), // (18,41): error CS0106: The modifier 'override' is not valid for this item // internal protected override void I4.M1() Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("override").WithLocation(18, 41) ); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); } [Fact] public void MethodImplementationInDerived_09() { var source1 = @" public interface I2 { void M1(); } public interface I1 : I2 { extern void I2.M1(); } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (9,20): warning CS0626: Method, operator, or accessor 'I1.I2.M1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void I2.M1(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M1").WithArguments("I1.I2.M1()").WithLocation(9, 20) ); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var i1i2m1 = i1.GetMember("I2.M1"); var i2 = i1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").Single(); var i2m1 = i2.GetMembers().OfType().Single(); var i3 = i1.ContainingNamespace.GetTypeMember("I3"); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); ValidateExplicitExternImplementation(i1i2m1); Assert.Null(test1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Same(i1i2m1, test1.FindImplementationForInterfaceMember(i2m1)); Assert.Null(i1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Same(i1i2m1, i1.FindImplementationForInterfaceMember(i2m1)); Assert.Null(i2.FindImplementationForInterfaceMember(i2m1)); Assert.Same(i1i2m1, i3.FindImplementationForInterfaceMember(i2m1)); } CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (9,20): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern void I2.M1(); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(9, 20), // (9,20): warning CS0626: Method, operator, or accessor 'I1.I2.M1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void I2.M1(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M1").WithArguments("I1.I2.M1()").WithLocation(9, 20) ); Validate1(compilation2.SourceModule); var compilation3 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (9,20): error CS8501: Target runtime doesn't support default interface implementation. // extern void I2.M1(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(9, 20), // (9,20): warning CS0626: Method, operator, or accessor 'I1.I2.M1()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern void I2.M1(); Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "M1").WithArguments("I1.I2.M1()").WithLocation(9, 20) ); Validate1(compilation3.SourceModule); var source2 = @" public interface I2 { void M1(); } public interface I1 : I2 { extern void I2.M1() {} } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation4 = CreateCompilation(source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics( // (9,20): error CS0179: 'I1.I2.M1()' cannot be extern and declare a body // extern void I2.M1() Diagnostic(ErrorCode.ERR_ExternHasBody, "M1").WithArguments("I1.I2.M1()").WithLocation(9, 20) ); Validate1(compilation4.SourceModule); } private static void ValidateExplicitExternImplementation(MethodSymbol m1) { Assert.True(m1.IsMetadataVirtual()); Assert.True(m1.IsMetadataFinal); Assert.False(m1.IsMetadataNewSlot()); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.NotEqual(m1.OriginalDefinition is PEMethodSymbol, m1.IsExtern); Assert.False(m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); if (m1.ContainingModule is PEModuleSymbol peModule) { int rva; peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)m1).Handle, out _, out _, out _, out rva); Assert.Equal(0, rva); } } [Fact] public void MethodImplementationInDerived_10() { var source1 = @" using System.Threading.Tasks; public interface I2 { Task M1(); } public interface I1 : I2 { async Task I2.M1() { await Task.Factory.StartNew(() => System.Console.WriteLine(""I2.M1"")); } } public interface I3 : I1 { } class Test1 : I1 { static void Main() { I2 i2 = new Test1(); i2.M1().Wait(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest, references: new[] { TestReferences.NetCoreApp30.SystemThreadingTasksRef }); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var i1i2m1 = i1.GetMember("I2.M1"); var i2 = i1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").Single(); var i2m1 = i2.GetMembers().OfType().Single(); var i3 = i1.ContainingNamespace.GetTypeMember("I3"); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); Validate2(i1i2m1); Assert.Null(test1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Equal("System.Threading.Tasks.Task I1.I2.M1()", test1.FindImplementationForInterfaceMember(i2m1).ToTestDisplayString()); Assert.Null(i1.FindImplementationForInterfaceMember(i1i2m1)); Assert.Equal("System.Threading.Tasks.Task I1.I2.M1()", i1.FindImplementationForInterfaceMember(i2m1).ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i2m1)); Assert.Equal("System.Threading.Tasks.Task I1.I2.M1()", i3.FindImplementationForInterfaceMember(i2m1).ToTestDisplayString()); } void Validate2(MethodSymbol m1) { Assert.True(m1.IsMetadataVirtual()); Assert.True(m1.IsMetadataFinal); Assert.False(m1.IsMetadataNewSlot()); Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.NotEqual(m1 is PEMethodSymbol, m1.IsAsync); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); if (m1.ContainingModule is PEModuleSymbol peModule) { int rva; peModule.Module.GetMethodDefPropsOrThrow(((PEMethodSymbol)m1).Handle, out _, out _, out _, out rva); Assert.NotEqual(0, rva); } } CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "I2.M1", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void MethodImplementationInDerived_11() { var source1 = @" public interface I2 { internal void M1(); } public interface I4 { internal void M1(); } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { i2.M1(); i4.M1(); } } "; var source2 = @" public interface I1 : I2, I5 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { TestHelper.Test(new Test1(), new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); var compilation2 = CreateCompilation(source3, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); var compilation3 = CreateCompilation(source3, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); var compilation5 = CreateCompilation(source2 + source3, new[] { compilation4.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics( // (8,13): error CS0122: 'I4.M1()' is inaccessible due to its protection level // void I4.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I4.M1()").WithLocation(8, 13), // (4,13): error CS0122: 'I2.M1()' is inaccessible due to its protection level // void I2.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1()").WithLocation(4, 13) ); var compilation6 = CreateCompilation(source2 + source3, new[] { compilation4.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation6.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation6.SourceModule); compilation6.VerifyDiagnostics( // (8,13): error CS0122: 'I4.M1()' is inaccessible due to its protection level // void I4.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I4.M1()").WithLocation(8, 13), // (4,13): error CS0122: 'I2.M1()' is inaccessible due to its protection level // void I2.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1()").WithLocation(4, 13) ); } [Fact] [WorkItem(20083, "https://github.com/dotnet/roslyn/issues/20083")] public void MethodImplementationInDerived_12() { var source1 = @" public interface I1 { void M1(){ System.Console.WriteLine(""Unexpected!!!""); } } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.I1.M1""); } } public interface I3 : I1 { void I1.M1() { System.Console.WriteLine(""I3.I1.M1""); } } public interface I4 : I1 { void I1.M1() { System.Console.WriteLine(""I4.I1.M1""); } } public interface I5 : I2, I3 { void I1.M1() { System.Console.WriteLine(""I5.I1.M1""); } } public interface I6 : I1, I2, I3, I5 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = i1.GetMember("M1"); var i2 = FindType(m, "I2"); var i2m1 = i2.GetMember("I1.M1"); var i5 = FindType(m, "I5"); var i5m1 = i5.GetMember("I1.M1"); var i6 = FindType(m, "I6"); ValidateExplicitImplementation(i2m1); ValidateExplicitImplementation(i5m1); Assert.Same(i1m1, i1.FindImplementationForInterfaceMember(i1m1)); Assert.Same(i2m1, i2.FindImplementationForInterfaceMember(i1m1)); Assert.Same(i5m1, i5.FindImplementationForInterfaceMember(i1m1)); Assert.Same(i5m1, i6.FindImplementationForInterfaceMember(i1m1)); } CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var refs1 = new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }; var source2 = @" public interface I7 : I2, I3 {} public interface I8 : I1, I2, I3, I5, I4 {} "; var source3 = @" class Test1 : I2, I3 {} class Test2 : I7 {} class Test3 : I1, I2, I3, I4 {} class Test4 : I1, I2, I3, I5, I4 {} class Test5 : I8 {} "; var source4 = @" class Test5 : I2 {} class Test6 : I1, I2, I3, I5 {} class Test7 : I6 { static void Main() { I1 i1 = new Test5(); i1.M1(); i1 = new Test6(); i1.M1(); i1 = new Test7(); i1.M1(); } } "; var source5 = @" class Test8 : I2, I3 { void I1.M1() { System.Console.WriteLine(""Test8.I1.M1""); } static void Main() { I1 i1 = new Test8(); i1.M1(); i1 = new Test9(); i1.M1(); i1 = new Test10(); i1.M1(); i1 = new Test11(); i1.M1(); i1 = new Test12(); i1.M1(); } } class Test9 : I7 { void I1.M1() { System.Console.WriteLine(""Test9.I1.M1""); } } class Test10 : I1, I2, I3, I4 { public void M1() { System.Console.WriteLine(""Test10.M1""); } } class Test11 : I1, I2, I3, I5, I4 { public void M1() { System.Console.WriteLine(""Test11.M1""); } } class Test12 : I8 { public virtual void M1() { System.Console.WriteLine(""Test12.M1""); } } "; foreach (var ref1 in refs1) { var compilation2 = CreateCompilation(source2, new[] { ref1 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-06-14.md, // we do not require interfaces to have a most specific implementation of all members. Therefore, there are no // errors in this compilation. compilation2.VerifyDiagnostics(); Validate2(compilation2.SourceModule); void Validate2(ModuleSymbol m) { Validate1(m); var i1 = FindType(m, "I1"); var i1m1 = i1.GetMember("M1"); var i7 = FindType(m, "I7"); var i8 = FindType(m, "I8"); Assert.Null(i7.FindImplementationForInterfaceMember(i1m1)); Assert.Null(i8.FindImplementationForInterfaceMember(i1m1)); } CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); compilation2 = CreateCompilation(source2, new[] { ref1 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); Validate2(compilation2.SourceModule); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var refs2 = new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }; var compilation4 = CreateCompilation(source4, new[] { ref1 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); Validate4(compilation4.SourceModule); void Validate4(ModuleSymbol m) { Validate1(m); var i1 = FindType(m, "I1"); var i1m1 = i1.GetMember("M1"); var i2 = FindType(m, "I2"); var i2m1 = i2.GetMember("I1.M1"); var i5 = FindType(m, "I5"); var i5m1 = i5.GetMember("I1.M1"); var test5 = FindType(m, "Test5"); var test6 = FindType(m, "Test6"); var test7 = FindType(m, "Test7"); Assert.Same(i2m1, test5.FindImplementationForInterfaceMember(i1m1)); Assert.Same(i5m1, test6.FindImplementationForInterfaceMember(i1m1)); Assert.Same(i5m1, test7.FindImplementationForInterfaceMember(i1m1)); } CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.I1.M1 I5.I1.M1 I5.I1.M1 " , verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate4); foreach (var ref2 in refs2) { var compilation3 = CreateCompilation(source3, new[] { ref1, ref2 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (5,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test2 : I7 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I7").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(5, 15), // (8,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test3 : I1, I2, I3, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(8, 15), // (11,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I5.I1.M1()', nor 'I4.I1.M1()' are most specific. // class Test4 : I1, I2, I3, I5, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I5.I1.M1()", "I4.I1.M1()").WithLocation(11, 15), // (14,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I5.I1.M1()', nor 'I4.I1.M1()' are most specific. // class Test5 : I8 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I8").WithArguments("I1.M1()", "I5.I1.M1()", "I4.I1.M1()").WithLocation(14, 15) ); Validate3(compilation3.SourceModule); void Validate3(ModuleSymbol m) { Validate1(m); Validate2(m); var i1 = FindType(m, "I1"); var i1m1 = i1.GetMember("M1"); var test1 = FindType(m, "Test1"); var test2 = FindType(m, "Test2"); var test3 = FindType(m, "Test3"); var test4 = FindType(m, "Test4"); var test5 = FindType(m, "Test5"); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test3.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test4.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test5.FindImplementationForInterfaceMember(i1m1)); } var compilation5 = CreateCompilation(source5, new[] { ref1, ref2 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics(); Validate5(compilation5.SourceModule); void Validate5(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = i1.GetMember("M1"); var test8 = FindType(m, "Test8"); var test9 = FindType(m, "Test9"); var test10 = FindType(m, "Test10"); var test11 = FindType(m, "Test11"); var test12 = FindType(m, "Test12"); Assert.Same(test8.GetMember("I1.M1"), test8.FindImplementationForInterfaceMember(i1m1)); Assert.Same(test9.GetMember("I1.M1"), test9.FindImplementationForInterfaceMember(i1m1)); Assert.Same(test10.GetMember("M1"), test10.FindImplementationForInterfaceMember(i1m1)); Assert.Same(test11.GetMember("M1"), test11.FindImplementationForInterfaceMember(i1m1)); Assert.Same(test12.GetMember("M1"), test12.FindImplementationForInterfaceMember(i1m1)); } CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test8.I1.M1 Test9.I1.M1 Test10.M1 Test11.M1 Test12.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate5); } } } private static NamedTypeSymbol FindType(ModuleSymbol m, string name) { var result = m.GlobalNamespace.GetMember(name); if ((object)result != null) { return result; } foreach (var assembly in m.ReferencedAssemblySymbols) { result = assembly.Modules[0].GlobalNamespace.GetMember(name); if ((object)result != null) { return result; } } Assert.NotNull(result); return result; } [Fact] public void MethodImplementationInDerived_13() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { } } public interface I3 : I1 { void I1.M1() { } } "; var source2 = @" class Test1 : I2, I3 { public int M1() => 1; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (2,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implement 'I1.M1()' because it does not have the matching return type of 'void'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.M1()", "Test1.M1()", "void").WithLocation(2, 15) ); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8505: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.M1()'. 'Test1.M1()' cannot implement 'I1.M1()' because it does not have the matching return type of 'void'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.M1()", "Test1.M1()", "void").WithLocation(2, 15) ); } [Fact] [WorkItem(20084, "https://github.com/dotnet/roslyn/issues/20084")] public void MethodImplementationInDerived_14() { var source1 = @" public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } void M2() { System.Console.WriteLine(""I1.M2""); } } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.I1.M1""); } void I1.M2() { System.Console.WriteLine(""I2.I1.M2""); } } public interface I3 : I1 {} "; var source2 = @" class Test1 : I1 { static void Main() { I1 i1Int = new Test1(); i1Int.M1(); i1Int.M2(); I1 i1Long = new Test2(); i1Long.M1(); i1Long.M2(); } } class Test2 : I2 {} "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = i1.GetMember("M1"); var i1m2 = i1.GetMember("M2"); var i2 = FindType(m, "I2"); var i2m1 = i2.GetMember("I1.M1"); var i2m2 = i2.GetMember("I1.M2"); var i2i1 = i2.InterfacesNoUseSiteDiagnostics().Single(); var i2i1m1 = i2i1.GetMember("M1"); var i2i1m2 = i2i1.GetMember("M2"); var i3 = FindType(m, "I3"); var i3i1 = i3.InterfacesNoUseSiteDiagnostics().Single(); var i3i1m1 = i3i1.GetMember("M1"); var i3i1m2 = i3i1.GetMember("M2"); Assert.Same(i1m1, i1.FindImplementationForInterfaceMember(i1m1)); Assert.Same(i1m2, i1.FindImplementationForInterfaceMember(i1m2)); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(i2.FindImplementationForInterfaceMember(i1m2)); Assert.Null(i2.FindImplementationForInterfaceMember(i3i1m1)); Assert.Null(i2.FindImplementationForInterfaceMember(i3i1m2)); Assert.Same(i2m1, i2.FindImplementationForInterfaceMember(i2i1m1)); Assert.Same(i2m2, i2.FindImplementationForInterfaceMember(i2i1m2)); Assert.Null(i3.FindImplementationForInterfaceMember(i1m1)); Assert.Null(i3.FindImplementationForInterfaceMember(i1m2)); Assert.Null(i3.FindImplementationForInterfaceMember(i2i1m1)); Assert.Null(i3.FindImplementationForInterfaceMember(i2i1m2)); Assert.Same(i3i1m1, i3.FindImplementationForInterfaceMember(i3i1m1)); Assert.Same(i3i1m2, i3.FindImplementationForInterfaceMember(i3i1m2)); ValidateExplicitImplementation(i2m1); ValidateExplicitImplementation(i2m2); var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test1i1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32)); var test1i1m1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32)).GetMember("M1"); var test1i1m2 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32)).GetMember("M2"); var test2 = m.GlobalNamespace.GetTypeMember("Test2"); var test2i1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)); var test2i1m1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)).GetMember("M1"); var test2i1m2 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)).GetMember("M2"); var test2i2 = i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)); var test2i2m1 = i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)).GetMember("I1.M1"); var test2i2m2 = i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)).GetMember("I1.M2"); Assert.NotSame(test1i1, test1i1m1.ContainingType); Assert.NotSame(test1i1, test1i1m2.ContainingType); Assert.NotSame(test2i1, test2i1m1.ContainingType); Assert.NotSame(test2i1, test2i1m2.ContainingType); Assert.NotSame(test2i2, test2i2m1.ContainingType); Assert.NotSame(test2i2, test2i2m2.ContainingType); Assert.Null(test1i1.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1i1.FindImplementationForInterfaceMember(i1m2)); Assert.Equal(test1i1m1, test1i1.FindImplementationForInterfaceMember(test1i1m1)); Assert.Equal(test1i1m2, test1i1.FindImplementationForInterfaceMember(test1i1m2)); Assert.Equal(test2i1m1, test2i1.FindImplementationForInterfaceMember(test2i1m1)); Assert.Equal(test2i1m2, test2i1.FindImplementationForInterfaceMember(test2i1m2)); Assert.Null(test2i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test2i2.FindImplementationForInterfaceMember(i1m2)); Assert.Equal(test2i2m1, test2i2.FindImplementationForInterfaceMember(test2i1m1)); Assert.Equal(test2i2m2, test2i2.FindImplementationForInterfaceMember(test2i1m2)); ValidateExplicitImplementation(test2i2m1); ValidateExplicitImplementation(test2i2m2); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m2)); Assert.Equal(test1i1m1, test1.FindImplementationForInterfaceMember(test1i1m1)); Assert.Equal(test1i1m2, test1.FindImplementationForInterfaceMember(test1i1m2)); Assert.Null(test2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1m2)); Assert.Equal(test2i2m1, test2.FindImplementationForInterfaceMember(test2i1m1)); Assert.Equal(test2i2m2, test2.FindImplementationForInterfaceMember(test2i1m2)); } CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1 I1.M2 I2.I1.M1 I2.I1.M2 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1 I1.M2 I2.I1.M1 I2.I1.M2 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1 I1.M2 I2.I1.M1 I2.I1.M2 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); } [Fact] public void MethodImplementationInDerived_15() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { } } public interface I3 : I1 { void I1.M1() { } } "; var source2 = @"#nullable enable warnings class Test1 : I2, I3 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (2,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(2, 7), // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (2,19): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I3").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 19) ); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics( // (2,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(2, 7), // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (2,19): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I3").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 19) ); test1 = compilation3.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); } [Fact] public void MethodImplementationInDerived_16() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { } } public interface I3 : I1 { void I1.M1() { } } "; var source2 = @"#nullable enable warnings class Test1 : I2, I3, I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (2,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(2, 7), // (2,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(2, 7), // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (2,19): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I3").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 19), // (2,23): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 23) ); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[4].GetMember("M1"))); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics( // (2,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(2, 7), // (2,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(2, 7), // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15), // (2,19): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I3").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 19), // (2,23): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 23) ); test1 = compilation3.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[4].GetMember("M1"))); } [Fact] public void MethodImplementationInDerived_17() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { } } #nullable enable public interface I3 : I1 { void I1.M1() { } } "; var source2 = @" #nullable enable class Test1 : I2, I3, I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (3,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(3, 7), // (3,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(3, 7), // (3,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(3, 15), // (3,19): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I3").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(3, 19), // (3,23): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(3, 23) ); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[4].GetMember("M1"))); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics( // (3,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(3, 7), // (3,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(3, 7), // (3,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(3, 15), // (3,19): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I3").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(3, 19), // (3,23): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(3, 23) ); test1 = compilation3.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[4].GetMember("M1"))); } [Fact] public void MethodImplementationInDerived_18() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { } } public interface I3 : I1 { void I1.M1() { } } "; var source2 = @" #nullable enable class Test1 : I2, I3, I1 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(4, 15), // (4,23): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(4, 23) ); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(4, 15), // (4,23): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3, I1 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(4, 23) ); test1 = compilation3.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); } [Fact] public void MethodImplementationInDerived_19() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { } public interface I3 : I2, I1 { void I1.M1() { } void I1.M1() { } } "; var source2 = @" #nullable enable class Test1 : I3 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (13,18): warning CS8645: 'I1' is already listed in the interface list on type 'I3' with different nullability of reference types. // public interface I3 : I2, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "I3").WithArguments("I1", "I3").WithLocation(13, 18), // (13,18): error CS8646: 'I1.M1()' is explicitly implemented more than once. // public interface I3 : I2, I1 Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "I3").WithArguments("I1.M1()").WithLocation(13, 18), // (13,18): error CS8646: 'I1.M1()' is explicitly implemented more than once. // public interface I3 : I2, I1 Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "I3").WithArguments("I1.M1()").WithLocation(13, 18) ); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.M1()").WithLocation(4, 15), // (4,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.M1()").WithLocation(4, 15) ); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I3", "I2", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); } [Fact] public void MethodImplementationInDerived_20() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { } public interface I3 : I1 { void I1.M1() { System.Console.WriteLine(""I3.M1""); } } "; var source2 = @" #nullable enable class Test1 : I2, I3 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I3.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I3.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,15): warning CS8644: 'Test1' does not implement interface member 'I1.M1()'. Nullability of reference types in interface implemented by the base type doesn't match. // class Test1 : I2, I3 Diagnostic(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase, "I2").WithArguments("Test1", "I1.M1()").WithLocation(4, 15) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I3.M1 I3.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_21() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { } public interface I3 : I1 { void I1.M1() { System.Console.WriteLine(""I3.M1""); } } "; var source2 = @" #nullable enable class Test1 : I3, I2 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I3", "I1", "I2", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I3.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I3.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I3, I2 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,19): warning CS8644: 'Test1' does not implement interface member 'I1.M1()'. Nullability of reference types in interface implemented by the base type doesn't match. // class Test1 : I3, I2 Diagnostic(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase, "I2").WithArguments("Test1", "I1.M1()").WithLocation(4, 19) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I3.M1 I3.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_22() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I2 { } public interface I4 : I2 { } "; var source2 = @" #nullable enable class Test1 : I3, I4 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I3", "I2", "I1", "I4", "I2", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I2.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I2.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[5].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I2' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I3, I4 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I2", "Test1").WithLocation(4, 7), // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I3, I4 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I2.M1 I2.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_23() { var source1 = @" #nullable enable public interface I1 { void M1() { System.Console.WriteLine(""I1.M1""); } } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I2 { } public interface I4 : I2 { } "; var source2 = @" #nullable enable class Test1 : I4, I3 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I4", "I2", "I1", "I3", "I2", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I2.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I2.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[5].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I2' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I4, I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I2", "Test1").WithLocation(4, 7), // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I4, I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I2.M1 I2.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_24() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.M1""); } } "; var source2 = @" #nullable enable class Test1 : I2 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (11,10): warning CS8643: Nullability of reference types in explicit interface specifier doesn't match interface implemented by the type. // void I1.M1() Diagnostic(ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface, "I1").WithLocation(11, 10) ); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I2.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[1].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I2.M1 I2.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_25() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.M1""); } } "; var source2 = @" #nullable enable class Test1 : I2, I1 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,19): warning CS8644: 'Test1' does not implement interface member 'I1.M1()'. Nullability of reference types in interface implemented by the base type doesn't match. // class Test1 : I2, I1 Diagnostic(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase, "I1").WithArguments("Test1", "I1.M1()").WithLocation(4, 19) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I2.M1 I2.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_26() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2 : I1 { void I1.M1() { System.Console.WriteLine(""I2.M1""); } } "; var source2 = @" #nullable enable class Test1 : I2, I1 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (11,10): warning CS8643: Nullability of reference types in explicit interface specifier doesn't match interface implemented by the type. // void I1.M1() Diagnostic(ErrorCode.WRN_NullabilityMismatchInExplicitlyImplementedInterface, "I1").WithLocation(11, 10) ); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I2.M1 I2.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_27() { var source1 = @" #nullable enable public interface I1 { void M1(); } public interface I2: I1 { void I1.M1() { System.Console.WriteLine(""I2.M1""); } } public interface I3 : I1 { void I1.M1() { System.Console.WriteLine(""I3.M1""); } } public interface I4 : I2, I3 { void I1.M1() { System.Console.WriteLine(""I4.M1""); } } "; var source2 = @" #nullable enable class Test1 : I2, I3, I4 { static void Main() { ((I1)new Test1()).M1(); ((I1)new Test1()).M1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I2", "I3", "I1", "I4", "I2", "I3", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Equal("void I4.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1")).ToTestDisplayString()); Assert.Equal("void I4.I1.M1()", test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[6].GetMember("M1")).ToTestDisplayString()); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I2' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I4 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I2", "Test1").WithLocation(4, 7), // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I4 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,7): warning CS8645: 'I3' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I2, I3, I4 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I3", "Test1").WithLocation(4, 7), // (4,15): warning CS8644: 'Test1' does not implement interface member 'I1.M1()'. Nullability of reference types in interface implemented by the base type doesn't match. // class Test1 : I2, I3, I4 Diagnostic(ErrorCode.WRN_NullabilityMismatchInInterfaceImplementedByBase, "I2").WithArguments("Test1", "I1.M1()").WithLocation(4, 15) ); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" I4.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr); } } [Fact] public void MethodImplementationInDerived_28() { var source1 = @" public interface I2 { protected void M1(); } public interface I4 { protected void M1(); } public interface I5 : I4 { static void Test(I5 i4) { i4.M1(); } } public interface I6 : I2 { static void Test(I6 i2) { i2.M1(); } } "; var source2 = @" public interface I1 : I6, I5 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { I6.Test(new Test1()); I5.Test(new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics(); CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); } } [Fact] public void MethodImplementationInDerived_29() { var source1 = @" public interface I2 { protected internal void M1(); } public interface I4 { protected internal void M1(); } public interface I5 : I4 { static void Test(I5 i4) { i4.M1(); } } public interface I6 : I2 { static void Test(I6 i2) { i2.M1(); } } "; var source2 = @" public interface I1 : I6, I5 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { I6.Test(new Test1()); I5.Test(new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics(); CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); } } [Fact] public void MethodImplementationInDerived_30() { var source1 = @" public interface I2 { private protected void M1(); } public interface I4 { private protected void M1(); } public interface I5 : I4 { static void Test(I5 i4) { i4.M1(); } } public interface I6 : I2 { static void Test(I6 i2) { i2.M1(); } } "; var source2 = @" public interface I1 : I6, I5 { void I2.M1() { System.Console.WriteLine(""I2.M1""); } void I4.M1() { System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { I6.Test(new Test1()); I5.Test(new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateMethodImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateMethodImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateMethodImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics( // (4,13): error CS0122: 'I2.M1()' is inaccessible due to its protection level // void I2.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1()").WithLocation(4, 13), // (8,13): error CS0122: 'I4.M1()' is inaccessible due to its protection level // void I4.M1() Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I4.M1()").WithLocation(8, 13) ); } } [Fact] public void MethodImplementationInDerived_31() { var source1 = @" public interface I1 { void M1(); void M2(); } public interface I2 : I1 { public virtual void M1() {} new public virtual void M2() {} } public interface I3 : I1, I2 { } class Test1 : I1, I2 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (10,25): warning CS0108: 'I2.M1()' hides inherited member 'I1.M1()'. Use the new keyword if hiding was intended. // public virtual void M1() Diagnostic(ErrorCode.WRN_NewRequired, "M1").WithArguments("I2.M1()", "I1.M1()").WithLocation(10, 25), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M2()' // class Test1 : I1, I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M2()").WithLocation(20, 15), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I1, I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I1.M1()").WithLocation(20, 15) ); } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void PropertyImplementationInDerived_01() { var source1 = @" public interface I2 { int M1 {get;} } public interface I4 { int M1 {set;} } public interface I5 : I4 { } public interface I1 : I2, I5 { int I2.M1 { get { System.Console.WriteLine(""I2.M1""); return 1; } } int I4.M1 { set => System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source2 = @" class Test1 : I1 { static void Main() { I2 i2 = new Test1(); _ = i2.M1; I4 i4 = new Test1(); i4.M1 = 0; } } "; ValidatePropertyImplementationInDerived_01(source1, source2); } private void ValidatePropertyImplementationInDerived_01(string source1, string source2) { foreach (var options in new[] { TestOptions.DebugExe, TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All) }) { var compilation1 = CreateCompilation(source1 + source2, options: options, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidatePropertyImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationInDerived_01); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: options, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidatePropertyImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationInDerived_01); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: options, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidatePropertyImplementationInDerived_01(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationInDerived_01); } } private static void ValidatePropertyImplementationInDerived_01(ModuleSymbol m) { ValidatePropertyImplementationInDerived_01(m, i4M1IsAbstract: false); } private static void ValidatePropertyImplementationInDerived_01(ModuleSymbol m, bool i4M1IsAbstract) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var i1i2m1 = i1.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); var i1i4m1 = i1.GetMembers().OfType().Where(p => p.Name.StartsWith("I4.")).Single(); var i2 = i1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").Single(); var i2m1 = i2.GetMembers().OfType().Single(); var i4 = i1.AllInterfacesNoUseSiteDiagnostics.Where(i => i.Name == "I4").Single(); var i4m1 = i4.GetMembers().OfType().Single(); var i3 = i1.ContainingNamespace.GetTypeMember("I3"); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); ValidateExplicitImplementation(i1i2m1); ValidateExplicitImplementation(i1i4m1, i4M1IsAbstract); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, test1, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, test1, i4m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i1, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i1, i4m1); VerifyFindImplementationForInterfaceMemberSame(i2m1.IsAbstract ? null : i2m1, i2, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4m1.IsAbstract ? null : i4m1, i4, i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i3, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i3, i4m1); } private static void VerifyFindImplementationForInterfaceMemberSame(PropertySymbol expected, NamedTypeSymbol implementingType, PropertySymbol interfaceProperty) { Assert.Same(expected, implementingType.FindImplementationForInterfaceMember(interfaceProperty)); ValidateAccessor(expected?.GetMethod, interfaceProperty.GetMethod); ValidateAccessor(expected?.SetMethod, interfaceProperty.SetMethod); void ValidateAccessor(MethodSymbol accessor, MethodSymbol interfaceAccessor) { if ((object)interfaceAccessor != null) { Assert.Same(interfaceAccessor.DeclaredAccessibility == Accessibility.Private ? null : accessor, implementingType.FindImplementationForInterfaceMember(interfaceAccessor)); } else { Assert.Null(accessor); } } } private static void VerifyFindImplementationForInterfaceMemberEqual(PropertySymbol expected, NamedTypeSymbol implementingType, PropertySymbol interfaceProperty) { Assert.Equal(expected, implementingType.FindImplementationForInterfaceMember(interfaceProperty)); ValidateAccessor(expected?.GetMethod, interfaceProperty.GetMethod); ValidateAccessor(expected?.SetMethod, interfaceProperty.SetMethod); void ValidateAccessor(MethodSymbol accessor, MethodSymbol interfaceAccessor) { if ((object)interfaceAccessor != null) { Assert.Equal(accessor, implementingType.FindImplementationForInterfaceMember(interfaceAccessor)); } else { Assert.Null(accessor); } } } private static void ValidateExplicitImplementation(PropertySymbol m1, bool isAbstract = false) { Assert.Equal(isAbstract, m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.Equal(isAbstract, m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); ValidateAccessor(m1.GetMethod, isAbstract); ValidateAccessor(m1.SetMethod, isAbstract); static void ValidateAccessor(MethodSymbol accessor, bool isAbstract) { if ((object)accessor != null) { ValidateExplicitImplementation(accessor, isAbstract); } } } [Fact] public void PropertyImplementationInDerived_02() { var source1 = @" public interface I2 { int M1 {get;} } public interface I4 { int M1 {set;} } public interface I1 : I2, I4 { int I2.M1 => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.M1 { set { System.Console.WriteLine(""I2.M1""); } } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_02(source1, new DiagnosticDescription[] { // (14,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int I2.M1 => Getter(); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "Getter()").WithArguments("default interface implementation", "8.0").WithLocation(14, 18), // (16,17): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private int Getter() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "Getter").WithArguments("default interface implementation", "8.0").WithLocation(16, 17), // (24,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // set Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(24, 9) }, // (6,15): error CS8506: 'I1.I2.M1.get' cannot implement interface member 'I2.M1.get' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.get", "I2.M1.get", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15), // (6,15): error CS8506: 'I1.I4.M1.set' cannot implement interface member 'I4.M1.set' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1.set", "I4.M1.set", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15) ); } private void ValidatePropertyImplementationInDerived_02(string source1, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected1); ValidatePropertyImplementationInDerived_01(compilation1.SourceModule); var source2 = @" public interface I3 : I1 { } class Test1 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(expected2); ValidatePropertyImplementationInDerived_01(compilation2.SourceModule); } [Fact] public void PropertyImplementationInDerived_03() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {set;} } public interface I1 : I2, I4 { int I2.M1 { get { System.Console.WriteLine(""I2.M1""); return 1; } set { System.Console.WriteLine(""I2.M1""); } } int I4.M1 { set { System.Console.WriteLine(""I2.M1""); } } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_03(source1, new DiagnosticDescription[] { // (16,9): error CS8501: Target runtime doesn't support default interface implementation. // get Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(16, 9), // (21,9): error CS8501: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(21, 9), // (29,9): error CS8501: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(29, 9) }, // (6,15): error CS8502: 'I1.I2.M1.set' cannot implement interface member 'I2.M1.set' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.set", "I2.M1.set", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I2.M1.get' cannot implement interface member 'I2.M1.get' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.get", "I2.M1.get", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I4.M1.set' cannot implement interface member 'I4.M1.set' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1.set", "I4.M1.set", "Test1").WithLocation(6, 15) ); } private void ValidatePropertyImplementationInDerived_03(string source1, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected1); ValidatePropertyImplementationInDerived_01(compilation1.SourceModule); var source2 = @" public interface I3 : I1 { } class Test1 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(expected2); } [Fact] public void PropertyImplementationInDerived_04() { var source1 = @" public interface I2 { int M1 {get;} } public interface I4 { int M1 {set;} } public interface I1 : I2, I4 { int I2.M1 {get;} int I4.M1 {set;} } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (14,16): error CS0501: 'I1.I2.M1.get' must declare a body because it is not marked abstract, extern, or partial // int I2.M1 {get;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.I2.M1.get").WithLocation(14, 16), // (15,16): error CS0501: 'I1.I4.M1.set' must declare a body because it is not marked abstract, extern, or partial // int I4.M1 {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.I4.M1.set").WithLocation(15, 16) ); } private void ValidatePropertyImplementationInDerived_04(string source1, params DiagnosticDescription[] expected) { ValidatePropertyImplementationInDerived_04(source1, i4M1IsAbstract: false, expected); } private void ValidatePropertyImplementationInDerived_04(string source1, bool i4M1IsAbstract, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); ValidatePropertyImplementationInDerived_01(compilation1.SourceModule, i4M1IsAbstract); } [Fact] public void PropertyImplementationInDerived_05() { var source1 = @" public interface I2 { int M1 {get;} } public interface I4 { int M1 {set;} } public interface I1 { int I2.M1 {get => throw null;} int I4.M1 {set => throw null;} } "; ValidatePropertyImplementationInDerived_05(source1, // (14,9): error CS0540: 'I1.I2.M1': containing type does not implement interface 'I2' // int I2.M1 {get => throw null;} Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I2").WithArguments("I1.I2.M1", "I2").WithLocation(14, 9), // (15,9): error CS0540: 'I1.I4.M1': containing type does not implement interface 'I4' // int I4.M1 {set => throw null;} Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I4").WithArguments("I1.I4.M1", "I4").WithLocation(15, 9) ); } private void ValidatePropertyImplementationInDerived_05(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected); } [Fact] public void PropertyImplementationInDerived_06() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {get; set;} } public interface I1 : I2, I4 { public static int I2.M1 { internal get => throw null; set => throw null; } internal virtual int I4.M1 { public get => throw null; set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (14,26): error CS0106: The modifier 'static' is not valid for this item // public static int I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("static").WithLocation(14, 26), // (14,26): error CS0106: The modifier 'public' is not valid for this item // public static int I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("public").WithLocation(14, 26), // (16,18): error CS0106: The modifier 'internal' is not valid for this item // internal get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("internal").WithLocation(16, 18), // (19,29): error CS0106: The modifier 'internal' is not valid for this item // internal virtual int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("internal").WithLocation(19, 29), // (19,29): error CS0106: The modifier 'virtual' is not valid for this item // internal virtual int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("virtual").WithLocation(19, 29), // (21,16): error CS0106: The modifier 'public' is not valid for this item // public get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("public").WithLocation(21, 16) ); } [Fact] public void PropertyImplementationInDerived_07() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {get; set;} } public interface I1 : I2, I4 { private sealed int I2.M1 { private get => throw null; set => throw null; } protected abstract int I4.M1 { get => throw null; protected set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, i4M1IsAbstract: true, // (14,27): error CS0106: The modifier 'sealed' is not valid for this item // private sealed int I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("sealed").WithLocation(14, 27), // (14,27): error CS0106: The modifier 'private' is not valid for this item // private sealed int I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private").WithLocation(14, 27), // (16,17): error CS0106: The modifier 'private' is not valid for this item // private get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private").WithLocation(16, 17), // (19,31): error CS0106: The modifier 'protected' is not valid for this item // protected abstract int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(19, 31), // (21,9): error CS0500: 'I1.I4.M1.get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.I4.M1.get").WithLocation(21, 9), // (22,19): error CS0106: The modifier 'protected' is not valid for this item // protected set => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected").WithLocation(22, 19), // (22,19): error CS0500: 'I1.I4.M1.set' cannot declare a body because it is marked abstract // protected set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I1.I4.M1.set").WithLocation(22, 19), // (30,15): error CS0535: 'Test1' does not implement interface member 'I4.M1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.M1").WithLocation(30, 15) ); } [Fact] public void PropertyImplementationInDerived_08() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {get; set;} } public interface I1 : I2, I4 { private protected int I2.M1 { private protected get => throw null; set => throw null; } internal protected override int I4.M1 { get => throw null; internal protected set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (14,30): error CS0106: The modifier 'private protected' is not valid for this item // private protected int I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private protected").WithLocation(14, 30), // (16,27): error CS0106: The modifier 'private protected' is not valid for this item // private protected get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private protected").WithLocation(16, 27), // (19,40): error CS0106: The modifier 'protected internal' is not valid for this item // internal protected override int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected internal").WithLocation(19, 40), // (19,40): error CS0106: The modifier 'override' is not valid for this item // internal protected override int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("override").WithLocation(19, 40), // (22,28): error CS0106: The modifier 'protected internal' is not valid for this item // internal protected set => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected internal").WithLocation(22, 28) ); } [Fact] public void PropertyImplementationInDerived_09() { var source1 = @" public interface I2 { int M1 {get;} } public interface I1 : I2 { extern int I2.M1 {get;} } public interface I3 : I1 { } class Test1 : I1 {} "; var source2 = @" public interface I2 { int M1 {set;} } public interface I1 : I2 { extern int I2.M1 { set {}} } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_09(source1, source2, new DiagnosticDescription[] { // (9,23): warning CS0626: Method, operator, or accessor 'I1.I2.M1.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int I2.M1 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.I2.M1.get").WithLocation(9, 23) }, new DiagnosticDescription[] { // (9,23): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern int I2.M1 {get;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 23), // (9,23): warning CS0626: Method, operator, or accessor 'I1.I2.M1.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int I2.M1 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.I2.M1.get").WithLocation(9, 23) }, new DiagnosticDescription[] { // (9,23): error CS8501: Target runtime doesn't support default interface implementation. // extern int I2.M1 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 23), // (9,23): warning CS0626: Method, operator, or accessor 'I1.I2.M1.get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int I2.M1 {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.I2.M1.get").WithLocation(9, 23) }, // (10,7): error CS0179: 'I1.I2.M1.set' cannot be extern and declare a body // { set {}} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I1.I2.M1.set").WithLocation(10, 7) ); } private void ValidatePropertyImplementationInDerived_09(string source1, string source2, DiagnosticDescription[] expected1, DiagnosticDescription[] expected2, DiagnosticDescription[] expected3, params DiagnosticDescription[] expected4) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(expected1); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var i1i2m1 = GetSingleProperty(i1); var i2 = i1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").Single(); var i2m1 = GetSingleProperty(i2); var i3 = i1.ContainingNamespace.GetTypeMember("I3"); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); ValidateExplicitExternImplementation(i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, test1, i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i1, i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i2m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i3, i2m1); } CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(expected2); Validate1(compilation2.SourceModule); var compilation3 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected3); Validate1(compilation3.SourceModule); var compilation4 = CreateCompilation(source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(expected4); Validate1(compilation4.SourceModule); } private static void ValidateExplicitExternImplementation(PropertySymbol m1) { Assert.False(m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.False(m1.IsSealed); Assert.False(m1.IsStatic); Assert.NotEqual(m1.OriginalDefinition is PEPropertySymbol, m1.IsExtern); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); ValidateAccessor(m1.GetMethod); ValidateAccessor(m1.SetMethod); void ValidateAccessor(MethodSymbol accessor) { if ((object)accessor != null) { ValidateExplicitExternImplementation(accessor); } } } [Fact] public void PropertyImplementationInDerived_10() { var source1 = @" public interface I1 { int M1 {get;set;} int M2 {get;set;} } public interface I2 : I1 { int I1.M1 { get => throw null; } int I1.M2 { set => throw null; } } class Test1 : I2 {} public interface I3 { int M1 {get;} int M2 {set;} int M3 {get;set;} int M4 {get;set;} } public interface I4 : I3 { int I3.M1 { get => throw null; set => throw null; } int I3.M2 { get => throw null; set => throw null; } int I3.M3 {get; set;} int I3.M4 {get; set;} = 0; } class Test2 : I4 {} "; ValidatePropertyImplementationInDerived_05(source1, // (10,12): error CS0551: Explicit interface implementation 'I2.I1.M1' is missing accessor 'I1.M1.set' // int I1.M1 Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "M1").WithArguments("I2.I1.M1", "I1.M1.set").WithLocation(10, 12), // (14,12): error CS0551: Explicit interface implementation 'I2.I1.M2' is missing accessor 'I1.M2.get' // int I1.M2 Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "M2").WithArguments("I2.I1.M2", "I1.M2.get").WithLocation(14, 12), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M1.set' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1.set").WithLocation(20, 15), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M2.get' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M2.get").WithLocation(20, 15), // (36,9): error CS0550: 'I4.I3.M1.set' adds an accessor not found in interface member 'I3.M1' // set => throw null; Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I4.I3.M1.set", "I3.M1").WithLocation(36, 9), // (40,9): error CS0550: 'I4.I3.M2.get' adds an accessor not found in interface member 'I3.M2' // get => throw null; Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I4.I3.M2.get", "I3.M2").WithLocation(40, 9), // (43,16): error CS0501: 'I4.I3.M3.get' must declare a body because it is not marked abstract, extern, or partial // int I3.M3 {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I4.I3.M3.get").WithLocation(43, 16), // (43,21): error CS0501: 'I4.I3.M3.set' must declare a body because it is not marked abstract, extern, or partial // int I3.M3 {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I4.I3.M3.set").WithLocation(43, 21), // (44,12): error CS8050: Only auto-implemented properties can have initializers. // int I3.M4 {get; set;} = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "M4").WithArguments("I4.I3.M4").WithLocation(44, 12), // (44,16): error CS0501: 'I4.I3.M4.get' must declare a body because it is not marked abstract, extern, or partial // int I3.M4 {get; set;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I4.I3.M4.get").WithLocation(44, 16), // (44,21): error CS0501: 'I4.I3.M4.set' must declare a body because it is not marked abstract, extern, or partial // int I3.M4 {get; set;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I4.I3.M4.set").WithLocation(44, 21) ); } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void PropertyImplementationInDerived_11() { var source1 = @" public interface I2 { internal int M1 {get;} } public interface I4 { int M1 {get; internal set;} } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { _ = i2.M1; i4.M1 = i4.M1; } } "; var source2 = @" public interface I1 : I2, I5 { int I2.M1 => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.M1 { get { System.Console.WriteLine(""I4.M1""); return 1; } set => System.Console.WriteLine(""I4.M1.set""); } } public interface I3 : I1 { } "; ValidatePropertyImplementationInDerived_11(source1, source2, // (4,12): error CS0122: 'I2.M1' is inaccessible due to its protection level // int I2.M1 => Getter(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1").WithLocation(4, 12), // (11,12): error CS0122: 'I4.M1.set' is inaccessible due to its protection level // int I4.M1 Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I4.M1.set").WithLocation(11, 12) ); } private void ValidatePropertyImplementationInDerived_11(string source1, string source2, params DiagnosticDescription[] expected) { var source3 = @" class Test1 : I1 { static void Main() { TestHelper.Test(new Test1(), new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidatePropertyImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 I4.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidatePropertyImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 I4.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidatePropertyImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics(expected); if (expected.Length == 0) { CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1 I4.M1 I4.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidatePropertyImplementationInDerived_01); } } } [Fact] [WorkItem(20083, "https://github.com/dotnet/roslyn/issues/20083")] public void PropertyImplementationInDerived_12() { var source1 = @" public interface I1 { int M1 { get => throw null; set => throw null;} } public interface I2 : I1 { int I1.M1 { get { System.Console.WriteLine(""I2.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I2.I1.M1.set""); } } } public interface I3 : I1 { int I1.M1 { get { System.Console.WriteLine(""I3.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I3.I1.M1.set""); } } } public interface I4 : I1 { int I1.M1 { get { System.Console.WriteLine(""I4.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I4.I1.M1.set""); } } } public interface I5 : I2, I3 { int I1.M1 { get { System.Console.WriteLine(""I5.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I5.I1.M1.set""); } } } public interface I6 : I1, I2, I3, I5 {} "; var source4 = @" class Test5 : I2 {} class Test6 : I1, I2, I3, I5 {} class Test7 : I6 { static void Main() { I1 i1 = new Test5(); i1.M1 = i1.M1; i1 = new Test6(); i1.M1 = i1.M1; i1 = new Test7(); i1.M1 = i1.M1; } } "; var source5 = @" class Test8 : I2, I3 { int I1.M1 { get { System.Console.WriteLine(""Test8.I1.M1.get""); return 1; } set { System.Console.WriteLine(""Test8.I1.M1.set""); } } static void Main() { I1 i1 = new Test8(); i1.M1 = i1.M1; i1 = new Test9(); i1.M1 = i1.M1; i1 = new Test10(); i1.M1 = i1.M1; i1 = new Test11(); i1.M1 = i1.M1; i1 = new Test12(); i1.M1 = i1.M1; } } class Test9 : I7 { int I1.M1 { get { System.Console.WriteLine(""Test9.I1.M1.get""); return 1; } set { System.Console.WriteLine(""Test9.I1.M1.set""); } } } class Test10 : I1, I2, I3, I4 { public int M1 { get { System.Console.WriteLine(""Test10.M1.get""); return 1; } set { System.Console.WriteLine(""Test10.M1.set""); } } } class Test11 : I1, I2, I3, I5, I4 { public int M1 { get { System.Console.WriteLine(""Test11.M1.get""); return 1; } set { System.Console.WriteLine(""Test11.M1.set""); } } } class Test12 : I8 { public virtual int M1 { get { System.Console.WriteLine(""Test12.M1.get""); return 1; } set { System.Console.WriteLine(""Test12.M1.set""); } } } "; ValidatePropertyImplementationInDerived_12(source1, source4, source5, new DiagnosticDescription[] { // (2,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(2, 15), // (5,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test2 : I7 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I7").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(5, 15), // (8,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test3 : I1, I2, I3, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(8, 15), // (11,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I5.I1.M1', nor 'I4.I1.M1' are most specific. // class Test4 : I1, I2, I3, I5, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1", "I5.I1.M1", "I4.I1.M1").WithLocation(11, 15), // (14,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I5.I1.M1', nor 'I4.I1.M1' are most specific. // class Test5 : I8 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I8").WithArguments("I1.M1", "I5.I1.M1", "I4.I1.M1").WithLocation(14, 15) } ); } private void ValidatePropertyImplementationInDerived_12(string source1, string source4, string source5, DiagnosticDescription[] expected1, DiagnosticDescription[] expected2 = null) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = GetSingleProperty(i1); var i2 = FindType(m, "I2"); var i2m1 = GetSingleProperty(i2); var i5 = FindType(m, "I5"); var i5m1 = GetSingleProperty(i5); var i6 = FindType(m, "I6"); ValidateExplicitImplementation(i2m1); ValidateExplicitImplementation(i5m1); VerifyFindImplementationForInterfaceMemberSame(i1m1, i1, i1m1); VerifyFindImplementationForInterfaceMemberSame(i2m1, i2, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, i5, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, i6, i1m1); } CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var refs1 = new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }; var source2 = @" public interface I7 : I2, I3 {} public interface I8 : I1, I2, I3, I5, I4 {} "; var source3 = @" class Test1 : I2, I3 {} class Test2 : I7 {} class Test3 : I1, I2, I3, I4 {} class Test4 : I1, I2, I3, I5, I4 {} class Test5 : I8 {} "; foreach (var ref1 in refs1) { var compilation2 = CreateCompilation(source2, new[] { ref1 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-06-14.md, // we do not require interfaces to have a most specific implementation of all members. Therefore, there are no // errors in this compilation. compilation2.VerifyDiagnostics(); Validate2(compilation2.SourceModule); void Validate2(ModuleSymbol m) { Validate1(m); var i1 = FindType(m, "I1"); var i1m1 = GetSingleProperty(i1); var i7 = FindType(m, "I7"); var i8 = FindType(m, "I8"); VerifyFindImplementationForInterfaceMemberSame(null, i7, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i8, i1m1); } CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); compilation2 = CreateCompilation(source2, new[] { ref1 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); Validate2(compilation2.SourceModule); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var refs2 = new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }; var compilation4 = CreateCompilation(source4, new[] { ref1 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); Validate4(compilation4.SourceModule); void Validate4(ModuleSymbol m) { Validate1(m); var i1 = FindType(m, "I1"); var i1m1 = GetSingleProperty(i1); var i2 = FindType(m, "I2"); var i2m1 = GetSingleProperty(i2); var i5 = FindType(m, "I5"); var i5m1 = GetSingleProperty(i5); var test5 = FindType(m, "Test5"); var test6 = FindType(m, "Test6"); var test7 = FindType(m, "Test7"); VerifyFindImplementationForInterfaceMemberSame(i2m1, test5, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, test6, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, test7, i1m1); } CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.I1.M1.get I2.I1.M1.set I5.I1.M1.get I5.I1.M1.set I5.I1.M1.get I5.I1.M1.set " , verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate4); foreach (var ref2 in refs2) { var compilation3 = CreateCompilation(source3, new[] { ref1, ref2 }, options: TestOptions.DebugDll.WithConcurrentBuild(false), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(ref1 is CompilationReference ? expected1 : expected2 ?? expected1); Validate3(compilation3.SourceModule); void Validate3(ModuleSymbol m) { Validate1(m); Validate2(m); var i1 = FindType(m, "I1"); var i1m1 = GetSingleProperty(i1); var test1 = FindType(m, "Test1"); var test2 = FindType(m, "Test2"); var test3 = FindType(m, "Test3"); var test4 = FindType(m, "Test4"); var test5 = FindType(m, "Test5"); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test2, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test3, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test4, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test5, i1m1); } var compilation5 = CreateCompilation(source5, new[] { ref1, ref2 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics(); Validate5(compilation5.SourceModule); void Validate5(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = GetSingleProperty(i1); var test8 = FindType(m, "Test8"); var test9 = FindType(m, "Test9"); var test10 = FindType(m, "Test10"); var test11 = FindType(m, "Test11"); var test12 = FindType(m, "Test12"); VerifyFindImplementationForInterfaceMemberSame(GetSingleProperty(test8), test8, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleProperty(test9), test9, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleProperty(test10), test10, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleProperty(test11), test11, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleProperty(test12), test12, i1m1); } CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test8.I1.M1.get Test8.I1.M1.set Test9.I1.M1.get Test9.I1.M1.set Test10.M1.get Test10.M1.set Test11.M1.get Test11.M1.set Test12.M1.get Test12.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate5); } } } [Fact] public void PropertyImplementationInDerived_13() { var source1 = @" public interface I1 { int M1 {get;} } public interface I2 : I1 { int I1.M1 => throw null; } public interface I3 : I1 { int I1.M1 => throw null; } "; var source2 = @" class Test1 : I2, I3 { public long M1 => 1; } "; ValidatePropertyImplementationInDerived_13(source1, source2, new DiagnosticDescription[] { // (2,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.M1'. 'Test1.M1' cannot implement 'I1.M1' because it does not have the matching return type of 'int'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.M1", "Test1.M1", "int").WithLocation(2, 15) } ); } private void ValidatePropertyImplementationInDerived_13(string source1, string source2, DiagnosticDescription[] expected1, DiagnosticDescription[] expected2 = null) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(expected1); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics(expected2 ?? expected1); } [Fact] [WorkItem(20084, "https://github.com/dotnet/roslyn/issues/20084")] public void PropertyImplementationInDerived_14() { var source1 = @" public interface I1 { int M1 { get { System.Console.WriteLine(""I1.M1.get""); return 1; } set => System.Console.WriteLine(""I1.M1.set""); } } public interface I2 : I1 { int I1.M1 { get { System.Console.WriteLine(""I2.I1.M1.get""); return 1; } set => System.Console.WriteLine(""I2.I1.M1.set""); } } public interface I3 : I1 {} "; var source2 = @" class Test1 : I1 { static void Main() { I1 i1Int = new Test1(); i1Int.M1 = i1Int.M1; I1 i1Long = new Test2(); i1Long.M1 = i1Long.M1; } } class Test2 : I2 {} "; ValidatePropertyImplementationInDerived_14(source1, source2); } private void ValidatePropertyImplementationInDerived_14(string source1, string source2) { var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = GetSingleProperty(i1); var i2 = FindType(m, "I2"); var i2m1 = GetSingleProperty(i2); var i2i1 = i2.InterfacesNoUseSiteDiagnostics().Single(); var i2i1m1 = GetSingleProperty(i2i1); var i3 = FindType(m, "I3"); var i3i1 = i3.InterfacesNoUseSiteDiagnostics().Single(); var i3i1m1 = GetSingleProperty(i3i1); VerifyFindImplementationForInterfaceMemberSame(i1m1, i1, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i3i1m1); VerifyFindImplementationForInterfaceMemberSame(i2m1, i2, i2i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i3, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i3, i2i1m1); VerifyFindImplementationForInterfaceMemberEqual(i3i1m1, i3, i3i1m1); ValidateExplicitImplementation(i2m1); var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test1i1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32)); var test1i1m1 = GetSingleProperty(i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32))); var test2 = m.GlobalNamespace.GetTypeMember("Test2"); var test2i1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)); var test2i1m1 = GetSingleProperty(i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64))); var test2i2 = i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)); var test2i2m1 = GetSingleProperty(i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64))); Assert.NotSame(test1i1, test1i1m1.ContainingType); Assert.NotSame(test2i1, test2i1m1.ContainingType); Assert.NotSame(test2i2, test2i2m1.ContainingType); VerifyFindImplementationForInterfaceMemberSame(null, test1i1, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test1i1m1, test1i1, test1i1m1); VerifyFindImplementationForInterfaceMemberEqual(test2i1m1, test2i1, test2i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test2i2, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test2i2m1, test2i2, test2i1m1); ValidateExplicitImplementation(test2i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test1i1m1, test1, test1i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test2, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test2i2m1, test2, test2i1m1); } CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1.get I1.M1.set I2.I1.M1.get I2.I1.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1.get I1.M1.set I2.I1.M1.get I2.I1.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1.get I1.M1.set I2.I1.M1.get I2.I1.M1.set ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); } [Fact] public void PropertyImplementationInDerived_15() { var source1 = @" public interface I2 { virtual int M1 {get => throw null; private set => throw null;} } public interface I4 { int M1 {set => throw null; private get => throw null;} } public interface I5 : I4 { } public interface I1 : I2, I5 { int I2.M1 { get { System.Console.WriteLine(""I2.M1""); return 1; } } int I4.M1 { set => System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source2 = @" class Test1 : I1 { static void Main() { I2 i2 = new Test1(); _ = i2.M1; I4 i4 = new Test1(); i4.M1 = 0; } } "; ValidatePropertyImplementationInDerived_01(source1, source2); } [Fact] public void PropertyImplementationInDerived_16() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {get; set;} } public interface I1 : I2, I4 { int I2.M1 { protected get => throw null; set => throw null; } protected int I4.M1 { get => throw null; set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (16,19): error CS0106: The modifier 'protected' is not valid for this item // protected get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("protected").WithLocation(16, 19), // (19,22): error CS0106: The modifier 'protected' is not valid for this item // protected int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(19, 22) ); } [Fact] public void PropertyImplementationInDerived_17() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {get; set;} } public interface I1 : I2, I4 { int I2.M1 { get => throw null; protected internal set => throw null; } protected internal int I4.M1 { get => throw null; set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (17,28): error CS0106: The modifier 'protected internal' is not valid for this item // protected internal set => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected internal").WithLocation(17, 28), // (19,31): error CS0106: The modifier 'protected internal' is not valid for this item // protected internal int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected internal").WithLocation(19, 31) ); } [Fact] public void PropertyImplementationInDerived_18() { var source1 = @" public interface I2 { int M1 {get; set;} } public interface I4 { int M1 {get; set;} } public interface I1 : I2, I4 { int I2.M1 { private protected get => throw null; set => throw null; } private protected int I4.M1 { get => throw null; set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (16,27): error CS0106: The modifier 'private protected' is not valid for this item // private protected get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private protected").WithLocation(16, 27), // (19,30): error CS0106: The modifier 'private protected' is not valid for this item // private protected int I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private protected").WithLocation(19, 30) ); } [Fact] public void PropertyImplementationInDerived_19() { var source1 = @" #nullable enable public interface I1 { int M1 {get; set;} } public interface I2 : I1 { } public interface I3 : I2, I1 { int I1.M1 { get => throw null!; set => throw null!; } int I1.M1 { get => throw null!; set => throw null!; } } "; var source2 = @" #nullable enable class Test1 : I3 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (13,18): warning CS8645: 'I1' is already listed in the interface list on type 'I3' with different nullability of reference types. // public interface I3 : I2, I1 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "I3").WithArguments("I1", "I3").WithLocation(13, 18), // (13,18): error CS8646: 'I1.M1' is explicitly implemented more than once. // public interface I3 : I2, I1 Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "I3").WithArguments("I1.M1").WithLocation(13, 18), // (13,18): error CS8646: 'I1.M1' is explicitly implemented more than once. // public interface I3 : I2, I1 Diagnostic(ErrorCode.ERR_DuplicateExplicitImpl, "I3").WithArguments("I1.M1").WithLocation(13, 18), // (21,21): error CS0102: The type 'I3' already contains a definition for 'I1.M1' // int I1.M1 Diagnostic(ErrorCode.ERR_DuplicateNameInClass, "M1").WithArguments("I3", "I1.M1").WithLocation(21, 21) ); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (4,7): warning CS8645: 'I1' is already listed in the interface list on type 'Test1' with different nullability of reference types. // class Test1 : I3 Diagnostic(ErrorCode.WRN_DuplicateInterfaceWithNullabilityMismatchInBaseList, "Test1").WithArguments("I1", "Test1").WithLocation(4, 7), // (4,15): error CS0535: 'Test1' does not implement interface member 'I1.M1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.M1").WithLocation(4, 15), // (4,15): error CS0535: 'Test1' does not implement interface member 'I1.M1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.M1").WithLocation(4, 15) ); var test1 = compilation2.GetTypeByMetadataName("Test1"); Assert.Equal(new[] { "I3", "I2", "I1", "I1" }, test1.AllInterfacesNoUseSiteDiagnostics.Select(i => i.ToTestDisplayString())); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[2].GetMember("M1"))); Assert.Null(test1.FindImplementationForInterfaceMember(test1.AllInterfacesNoUseSiteDiagnostics[3].GetMember("M1"))); } [Fact] public void PropertyImplementationInDerived_20() { var source1 = @" public interface I2 { protected int M1 {get;} public static void Test(I2 i2) { _ = i2.M1; } } public interface I4 { int M1 {get; protected set;} public static void Test(I4 i4) { i4.M1 = i4.M1; } } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { I2.Test(i2); I4.Test(i4); } } "; var source2 = @" public interface I1 : I2, I5 { int I2.M1 => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.M1 { get { System.Console.WriteLine(""I4.M1""); return 1; } set => System.Console.WriteLine(""I4.M1.set""); } } public interface I3 : I1 { } "; ValidatePropertyImplementationInDerived_11(source1, source2); } [Fact] public void PropertyImplementationInDerived_21() { var source1 = @" public interface I2 { protected internal int M1 {get;} public static void Test(I2 i2) { _ = i2.M1; } } public interface I4 { int M1 {get; protected internal set;} public static void Test(I4 i4) { i4.M1 = i4.M1; } } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { I2.Test(i2); I4.Test(i4); } } "; var source2 = @" public interface I1 : I2, I5 { int I2.M1 => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.M1 { get { System.Console.WriteLine(""I4.M1""); return 1; } set => System.Console.WriteLine(""I4.M1.set""); } } public interface I3 : I1 { } "; ValidatePropertyImplementationInDerived_11(source1, source2); } [Fact] public void PropertyImplementationInDerived_22() { var source1 = @" public interface I2 { private protected int M1 {get;} public static void Test(I2 i2) { _ = i2.M1; } } public interface I4 { int M1 {get; private protected set;} public static void Test(I4 i4) { i4.M1 = i4.M1; } } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { I2.Test(i2); I4.Test(i4); } } "; var source2 = @" public interface I1 : I2, I5 { int I2.M1 => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.M1 { get { System.Console.WriteLine(""I4.M1""); return 1; } set => System.Console.WriteLine(""I4.M1.set""); } } public interface I3 : I1 { } "; ValidatePropertyImplementationInDerived_11(source1, source2, // (4,12): error CS0122: 'I2.M1' is inaccessible due to its protection level // int I2.M1 => Getter(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1").WithLocation(4, 12), // (11,12): error CS0122: 'I4.M1.set' is inaccessible due to its protection level // int I4.M1 Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I4.M1.set").WithLocation(11, 12) ); } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void EventImplementationInDerived_01() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I5 : I4 { } public interface I1 : I2, I5 { event System.Action I2.M1 { add { System.Console.WriteLine(""I2.M1.add""); } remove { System.Console.WriteLine(""I2.M1.remove""); } } event System.Action I4.M1 { add => System.Console.WriteLine(""I4.M1.add""); remove => System.Console.WriteLine(""I4.M1.remove""); } } public interface I3 : I1 { } "; var source2 = @" class Test1 : I1 { static void Main() { I2 i2 = new Test1(); i2.M1 += null; i2.M1 -= null; I4 i4 = new Test1(); i4.M1 += null; i4.M1 -= null; } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateEventImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); } private static void ValidateEventImplementationInDerived_01(ModuleSymbol m) { ValidateEventImplementationInDerived_01(m, i4M1IsAbstract: false); } private static void ValidateEventImplementationInDerived_01(ModuleSymbol m, bool i4M1IsAbstract) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1 = test1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I1").Single(); var i1i2m1 = i1.GetMembers().OfType().Where(p => p.Name.StartsWith("I2.")).Single(); var i1i4m1 = i1.GetMembers().OfType().Where(p => p.Name.StartsWith("I4.")).Single(); var i2 = i1.InterfacesNoUseSiteDiagnostics().Where(i => i.Name == "I2").Single(); var i2m1 = i2.GetMembers().OfType().Single(); var i4 = i1.AllInterfacesNoUseSiteDiagnostics.Where(i => i.Name == "I4").Single(); var i4m1 = i4.GetMembers().OfType().Single(); var i3 = i1.ContainingNamespace.GetTypeMember("I3"); Assert.True(i1.IsAbstract); Assert.True(i1.IsMetadataAbstract); ValidateExplicitImplementation(i1i2m1); ValidateExplicitImplementation(i1i4m1, i4M1IsAbstract); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, test1, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, test1, i4m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i1, i1i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i1, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i1, i4m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i2m1); VerifyFindImplementationForInterfaceMemberSame(null, i4, i4m1); VerifyFindImplementationForInterfaceMemberSame(i1i2m1, i3, i2m1); VerifyFindImplementationForInterfaceMemberSame(i4M1IsAbstract ? null : i1i4m1, i3, i4m1); } private static void VerifyFindImplementationForInterfaceMemberSame(EventSymbol expected, NamedTypeSymbol implementingType, EventSymbol interfaceEvent) { Assert.Same(expected, implementingType.FindImplementationForInterfaceMember(interfaceEvent)); ValidateAccessor(expected?.AddMethod, interfaceEvent.AddMethod); ValidateAccessor(expected?.RemoveMethod, interfaceEvent.RemoveMethod); void ValidateAccessor(MethodSymbol accessor, MethodSymbol interfaceAccessor) { if ((object)interfaceAccessor != null) { Assert.Same(accessor, implementingType.FindImplementationForInterfaceMember(interfaceAccessor)); } else { Assert.Null(accessor); } } } private static void VerifyFindImplementationForInterfaceMemberEqual(EventSymbol expected, NamedTypeSymbol implementingType, EventSymbol interfaceEvent) { Assert.Equal(expected, implementingType.FindImplementationForInterfaceMember(interfaceEvent)); ValidateAccessor(expected?.AddMethod, interfaceEvent.AddMethod); ValidateAccessor(expected?.RemoveMethod, interfaceEvent.RemoveMethod); void ValidateAccessor(MethodSymbol accessor, MethodSymbol interfaceAccessor) { if ((object)interfaceAccessor != null) { Assert.Equal(accessor, implementingType.FindImplementationForInterfaceMember(interfaceAccessor)); } else { Assert.Null(accessor); } } } private static void ValidateExplicitImplementation(EventSymbol m1, bool isAbstract = false) { Assert.Equal(isAbstract, m1.IsAbstract); Assert.False(m1.IsVirtual); Assert.Equal(isAbstract, m1.IsSealed); Assert.False(m1.IsStatic); Assert.False(m1.IsExtern); Assert.False(m1.IsOverride); Assert.Equal(Accessibility.Private, m1.DeclaredAccessibility); ValidateAccessor(m1.AddMethod, isAbstract); ValidateAccessor(m1.RemoveMethod, isAbstract); static void ValidateAccessor(MethodSymbol accessor, bool isAbstract) { if ((object)accessor != null) { ValidateExplicitImplementation(accessor, isAbstract); } } } [Fact] public void EventImplementationInDerived_02() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I1 : I2, I4 { event System.Action I2.M1 { add => throw null; remove => throw null; } event System.Action I4.M1 { add => throw null; remove => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (16,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // add => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(16, 9), // (17,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // remove => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(17, 9), // (22,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // add => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "add").WithArguments("default interface implementation", "8.0").WithLocation(22, 9), // (23,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // remove => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "remove").WithArguments("default interface implementation", "8.0").WithLocation(23, 9) ); ValidateEventImplementationInDerived_01(compilation1.SourceModule); var source2 = @" public interface I3 : I1 { } class Test1 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (6,15): error CS8506: 'I1.I2.M1.remove' cannot implement interface member 'I2.M1.remove' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.remove", "I2.M1.remove", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15), // (6,15): error CS8506: 'I1.I2.M1.add' cannot implement interface member 'I2.M1.add' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.add", "I2.M1.add", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15), // (6,15): error CS8506: 'I1.I4.M1.remove' cannot implement interface member 'I4.M1.remove' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1.remove", "I4.M1.remove", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15), // (6,15): error CS8506: 'I1.I4.M1.add' cannot implement interface member 'I4.M1.add' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1.add", "I4.M1.add", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15) ); ValidateEventImplementationInDerived_01(compilation2.SourceModule); } [Fact] public void EventImplementationInDerived_03() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I1 : I2, I4 { event System.Action I2.M1 { add => throw null; remove => throw null; } event System.Action I4.M1 { add => throw null; remove => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular, skipUsesIsNullable: true); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (16,9): error CS8501: Target runtime doesn't support default interface implementation. // add => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(16, 9), // (17,9): error CS8501: Target runtime doesn't support default interface implementation. // remove => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(17, 9), // (22,9): error CS8501: Target runtime doesn't support default interface implementation. // add => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "add").WithLocation(22, 9), // (23,9): error CS8501: Target runtime doesn't support default interface implementation. // remove => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "remove").WithLocation(23, 9) ); ValidateEventImplementationInDerived_01(compilation1.SourceModule); var source2 = @" public interface I3 : I1 { } class Test1 : I1 {} "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (6,15): error CS8502: 'I1.I2.M1.remove' cannot implement interface member 'I2.M1.remove' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.remove", "I2.M1.remove", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I2.M1.add' cannot implement interface member 'I2.M1.add' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.M1.add", "I2.M1.add", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I4.M1.remove' cannot implement interface member 'I4.M1.remove' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1.remove", "I4.M1.remove", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I4.M1.add' cannot implement interface member 'I4.M1.add' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.M1.add", "I4.M1.add", "Test1").WithLocation(6, 15) ); } [Fact] public void EventImplementationInDerived_04() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I1 : I2, I4 { event System.Action I2.M1 { add; remove; } event System.Action I4.M1 { add; remove {} } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (16,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(16, 12), // (17,15): error CS0073: An add or remove accessor must have a body // remove; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(17, 15), // (21,12): error CS0073: An add or remove accessor must have a body // add; Diagnostic(ErrorCode.ERR_AddRemoveMustHaveBody, ";").WithLocation(21, 12) ); ValidateEventImplementationInDerived_01(compilation1.SourceModule); } [Fact] public void EventImplementationInDerived_05() { var source1 = @" public interface I2 { event System.Action M1; } public interface I1 { event System.Action I2.M1 { add => throw null; remove => throw null; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (9,25): error CS0540: 'I1.I2.M1': containing type does not implement interface 'I2' // event System.Action I2.M1 Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I2").WithArguments("I1.I2.M1", "I2").WithLocation(9, 25) ); } [Fact] public void EventImplementationInDerived_06() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I1 : I2, I4 { public static event System.Action I2.M1 { add => throw null; remove => throw null; } internal virtual event System.Action I4.M1 { add => throw null; remove => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,42): error CS0106: The modifier 'static' is not valid for this item // public static event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("static").WithLocation(14, 42), // (14,42): error CS0106: The modifier 'public' is not valid for this item // public static event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("public").WithLocation(14, 42), // (19,45): error CS0106: The modifier 'internal' is not valid for this item // internal virtual event System.Action I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("internal").WithLocation(19, 45), // (19,45): error CS0106: The modifier 'virtual' is not valid for this item // internal virtual event System.Action I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("virtual").WithLocation(19, 45) ); ValidateEventImplementationInDerived_01(compilation1.SourceModule); } [Fact] public void EventImplementationInDerived_07() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I1 : I2, I4 { private sealed event System.Action I2.M1 { add => throw null; remove => throw null; } protected abstract event System.Action I4.M1 { add => throw null; remove => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,43): error CS0106: The modifier 'sealed' is not valid for this item // private sealed event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("sealed").WithLocation(14, 43), // (14,43): error CS0106: The modifier 'private' is not valid for this item // private sealed event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private").WithLocation(14, 43), // (19,47): error CS0106: The modifier 'protected' is not valid for this item // protected abstract event System.Action I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected").WithLocation(19, 47), // (20,5): error CS8712: 'I1.I4.M1': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I1.I4.M1").WithLocation(20, 5), // (30,15): error CS0535: 'Test1' does not implement interface member 'I4.M1' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.M1").WithLocation(30, 15) ); ValidateEventImplementationInDerived_01(compilation1.SourceModule, i4M1IsAbstract: true); } [Fact] public void EventImplementationInDerived_08() { var source1 = @" public interface I2 { event System.Action M1; } public interface I4 { event System.Action M1; } public interface I1 : I2, I4 { private protected extern event System.Action I2.M1 { add => throw null; remove => throw null; } internal protected override event System.Action I4.M1 { add => throw null; remove => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (14,53): error CS0106: The modifier 'private protected' is not valid for this item // private protected extern event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("private protected").WithLocation(14, 53), // (14,53): error CS0106: The modifier 'extern' is not valid for this item // private protected extern event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("extern").WithLocation(14, 53), // (19,56): error CS0106: The modifier 'protected internal' is not valid for this item // internal protected override event System.Action I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("protected internal").WithLocation(19, 56), // (19,56): error CS0106: The modifier 'override' is not valid for this item // internal protected override event System.Action I4.M1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("override").WithLocation(19, 56) ); ValidateEventImplementationInDerived_01(compilation1.SourceModule); } [Fact] public void EventImplementationInDerived_10() { var source1 = @" public interface I1 { event System.Action M1; event System.Action M2; } public interface I2 : I1 { event System.Action I1.M1 { add => throw null; } event System.Action I1.M2 { remove => throw null; } } class Test1 : I2 {} public interface I3 { event System.Action M1; } public interface I4 : I3 { event System.Action I3.M1; } class Test2 : I4 {} public interface I5 : I3 { event System.Action I3.M1 } class Test3 : I5 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics( // (30,28): error CS0071: An explicit interface implementation of an event must use event accessor syntax // event System.Action I3.M1; Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "M1").WithLocation(30, 28), // (10,28): error CS0065: 'I2.I1.M1': event property must have both add and remove accessors // event System.Action I1.M1 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "M1").WithArguments("I2.I1.M1").WithLocation(10, 28), // (14,28): error CS0065: 'I2.I1.M2': event property must have both add and remove accessors // event System.Action I1.M2 Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "M2").WithArguments("I2.I1.M2").WithLocation(14, 28), // (33,15): error CS0535: 'Test2' does not implement interface member 'I3.M1.remove' // class Test2 : I4 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I4").WithArguments("Test2", "I3.M1.remove").WithLocation(33, 15), // (33,15): error CS0535: 'Test2' does not implement interface member 'I3.M1.add' // class Test2 : I4 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I4").WithArguments("Test2", "I3.M1.add").WithLocation(33, 15), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M1.remove' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1.remove").WithLocation(20, 15), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.M2.add' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M2.add").WithLocation(20, 15), // (38,27): error CS0071: An explicit interface implementation of an event must use event accessor syntax // event System.Action I3.M1 Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(38, 27), // (41,15): error CS0535: 'Test3' does not implement interface member 'I3.M1.remove' // class Test3 : I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test3", "I3.M1.remove").WithLocation(41, 15), // (41,15): error CS0535: 'Test3' does not implement interface member 'I3.M1.add' // class Test3 : I5 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I5").WithArguments("Test3", "I3.M1.add").WithLocation(41, 15) ); } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void EventImplementationInDerived_11() { var source1 = @" public interface I2 { internal event System.Action M1; } public interface I4 { event System.Action M1; } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { i2.M1 += null; i2.M1 -= null; i4.M1 += null; i4.M1 -= null; } } "; var source2 = @" public interface I1 : I2, I5 { event System.Action I2.M1 { add { System.Console.WriteLine(""I2.M1.add""); } remove => System.Console.WriteLine(""I2.M1.remove""); } event System.Action I4.M1 { add { System.Console.WriteLine(""I4.M1.add""); } remove => System.Console.WriteLine(""I4.M1.remove""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { TestHelper.Test(new Test1(), new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateEventImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); var compilation2 = CreateCompilation(source3, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); var compilation3 = CreateCompilation(source3, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); var compilation5 = CreateCompilation(source2 + source3, new[] { compilation4.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics( // (4,28): error CS0122: 'I2.M1' is inaccessible due to its protection level // event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1").WithLocation(4, 28) ); var compilation6 = CreateCompilation(source2 + source3, new[] { compilation4.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation6.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation6.SourceModule); compilation6.VerifyDiagnostics( // (4,28): error CS0122: 'I2.M1' is inaccessible due to its protection level // event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1").WithLocation(4, 28) ); } [Fact] [WorkItem(20083, "https://github.com/dotnet/roslyn/issues/20083")] public void EventImplementationInDerived_12() { var source1 = @" public interface I1 { event System.Action M1 { add => throw null; remove => throw null;} } public interface I2 : I1 { event System.Action I1.M1 { add { System.Console.WriteLine(""I2.I1.M1.add""); } remove { System.Console.WriteLine(""I2.I1.M1.remove""); } } } public interface I3 : I1 { event System.Action I1.M1 { add { System.Console.WriteLine(""I3.I1.M1.add""); } remove { System.Console.WriteLine(""I3.I1.M1.remove""); } } } public interface I4 : I1 { event System.Action I1.M1 { add { System.Console.WriteLine(""I4.I1.M1.add""); } remove { System.Console.WriteLine(""I4.I1.M1.remove""); } } } public interface I5 : I2, I3 { event System.Action I1.M1 { add { System.Console.WriteLine(""I5.I1.M1.add""); } remove { System.Console.WriteLine(""I5.I1.M1.remove""); } } } public interface I6 : I1, I2, I3, I5 {} "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate1(compilation1.SourceModule); void Validate1(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = GetSingleEvent(i1); var i2 = FindType(m, "I2"); var i2m1 = GetSingleEvent(i2); var i5 = FindType(m, "I5"); var i5m1 = GetSingleEvent(i5); var i6 = FindType(m, "I6"); ValidateExplicitImplementation(i2m1); ValidateExplicitImplementation(i5m1); VerifyFindImplementationForInterfaceMemberSame(i1m1, i1, i1m1); VerifyFindImplementationForInterfaceMemberSame(i2m1, i2, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, i5, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, i6, i1m1); } CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate1); var refs1 = new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }; var source2 = @" public interface I7 : I2, I3 {} public interface I8 : I1, I2, I3, I5, I4 {} "; var source3 = @" class Test1 : I2, I3 {} class Test2 : I7 {} class Test3 : I1, I2, I3, I4 {} class Test4 : I1, I2, I3, I5, I4 {} class Test5 : I8 {} "; var source4 = @" class Test5 : I2 {} class Test6 : I1, I2, I3, I5 {} class Test7 : I6 { static void Main() { I1 i1 = new Test5(); i1.M1 += null; i1.M1 -= null; i1 = new Test6(); i1.M1 += null; i1.M1 -= null; i1 = new Test7(); i1.M1 += null; i1.M1 -= null; } } "; var source5 = @" class Test8 : I2, I3 { event System.Action I1.M1 { add { System.Console.WriteLine(""Test8.I1.M1.add""); } remove { System.Console.WriteLine(""Test8.I1.M1.remove""); } } static void Main() { I1 i1 = new Test8(); i1.M1 += null; i1.M1 -= null; i1 = new Test9(); i1.M1 += null; i1.M1 -= null; i1 = new Test10(); i1.M1 += null; i1.M1 -= null; i1 = new Test11(); i1.M1 += null; i1.M1 -= null; i1 = new Test12(); i1.M1 += null; i1.M1 -= null; } } class Test9 : I7 { event System.Action I1.M1 { add { System.Console.WriteLine(""Test9.I1.M1.add""); } remove { System.Console.WriteLine(""Test9.I1.M1.remove""); } } } class Test10 : I1, I2, I3, I4 { public event System.Action M1 { add { System.Console.WriteLine(""Test10.M1.add""); } remove { System.Console.WriteLine(""Test10.M1.remove""); } } } class Test11 : I1, I2, I3, I5, I4 { public event System.Action M1 { add { System.Console.WriteLine(""Test11.M1.add""); } remove { System.Console.WriteLine(""Test11.M1.remove""); } } } class Test12 : I8 { public virtual event System.Action M1 { add { System.Console.WriteLine(""Test12.M1.add""); } remove { System.Console.WriteLine(""Test12.M1.remove""); } } } "; foreach (var ref1 in refs1) { var compilation2 = CreateCompilation(source2, new[] { ref1 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); // According to LDM decision captured at https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-06-14.md, // we do not require interfaces to have a most specific implementation of all members. Therefore, there are no // errors in this compilation. compilation2.VerifyDiagnostics(); Validate2(compilation2.SourceModule); void Validate2(ModuleSymbol m) { Validate1(m); var i1 = FindType(m, "I1"); var i1m1 = GetSingleEvent(i1); var i7 = FindType(m, "I7"); var i8 = FindType(m, "I8"); VerifyFindImplementationForInterfaceMemberSame(null, i7, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i8, i1m1); } CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); compilation2 = CreateCompilation(source2, new[] { ref1 }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics(); Validate2(compilation2.SourceModule); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate2); var refs2 = new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }; var compilation4 = CreateCompilation(source4, new[] { ref1 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); Validate4(compilation4.SourceModule); void Validate4(ModuleSymbol m) { Validate1(m); var i1 = FindType(m, "I1"); var i1m1 = GetSingleEvent(i1); var i2 = FindType(m, "I2"); var i2m1 = GetSingleEvent(i2); var i5 = FindType(m, "I5"); var i5m1 = GetSingleEvent(i5); var test5 = FindType(m, "Test5"); var test6 = FindType(m, "Test6"); var test7 = FindType(m, "Test7"); VerifyFindImplementationForInterfaceMemberSame(i2m1, test5, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, test6, i1m1); VerifyFindImplementationForInterfaceMemberSame(i5m1, test7, i1m1); } CompileAndVerify(compilation4, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.I1.M1.add I2.I1.M1.remove I5.I1.M1.add I5.I1.M1.remove I5.I1.M1.add I5.I1.M1.remove " , verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate4); foreach (var ref2 in refs2) { var compilation3 = CreateCompilation(source3, new[] { ref1, ref2 }, options: TestOptions.DebugDll.WithConcurrentBuild(false), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(2, 15), // (5,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test2 : I7 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I7").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(5, 15), // (8,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test3 : I1, I2, I3, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(8, 15), // (11,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I5.I1.M1', nor 'I4.I1.M1' are most specific. // class Test4 : I1, I2, I3, I5, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.M1", "I5.I1.M1", "I4.I1.M1").WithLocation(11, 15), // (14,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I5.I1.M1', nor 'I4.I1.M1' are most specific. // class Test5 : I8 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I8").WithArguments("I1.M1", "I5.I1.M1", "I4.I1.M1").WithLocation(14, 15) ); Validate3(compilation3.SourceModule); void Validate3(ModuleSymbol m) { Validate1(m); Validate2(m); var i1 = FindType(m, "I1"); var i1m1 = GetSingleEvent(i1); var test1 = FindType(m, "Test1"); var test2 = FindType(m, "Test2"); var test3 = FindType(m, "Test3"); var test4 = FindType(m, "Test4"); var test5 = FindType(m, "Test5"); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test2, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test3, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test4, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test5, i1m1); } var compilation5 = CreateCompilation(source5, new[] { ref1, ref2 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation5.VerifyDiagnostics(); Validate5(compilation5.SourceModule); void Validate5(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = GetSingleEvent(i1); var test8 = FindType(m, "Test8"); var test9 = FindType(m, "Test9"); var test10 = FindType(m, "Test10"); var test11 = FindType(m, "Test11"); var test12 = FindType(m, "Test12"); VerifyFindImplementationForInterfaceMemberSame(GetSingleEvent(test8), test8, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleEvent(test9), test9, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleEvent(test10), test10, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleEvent(test11), test11, i1m1); VerifyFindImplementationForInterfaceMemberSame(GetSingleEvent(test12), test12, i1m1); } CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"Test8.I1.M1.add Test8.I1.M1.remove Test9.I1.M1.add Test9.I1.M1.remove Test10.M1.add Test10.M1.remove Test11.M1.add Test11.M1.remove Test12.M1.add Test12.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate5); } } } [Fact] public void EventImplementationInDerived_13() { var source1 = @" public interface I1 { event System.Action M1; } public interface I2 : I1 { event System.Action I1.M1 { add => throw null; remove => throw null;} } public interface I3 : I1 { event System.Action I1.M1 { add => throw null; remove => throw null;} } "; var source2 = @" class Test1 : I2, I3 { public event System.Action M1 { add => throw null; remove => throw null;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation2.VerifyDiagnostics( // (2,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.M1'. 'Test1.M1' cannot implement 'I1.M1' because it does not have the matching return type of 'Action'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.M1", "Test1.M1", "System.Action").WithLocation(2, 15) ); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation3.VerifyDiagnostics( // (2,15): error CS8505: Interface member 'I1.M1' does not have a most specific implementation. Neither 'I2.I1.M1', nor 'I3.I1.M1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1", "I2.I1.M1", "I3.I1.M1").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.M1'. 'Test1.M1' cannot implement 'I1.M1' because it does not have the matching return type of 'Action'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.M1", "Test1.M1", "System.Action").WithLocation(2, 15) ); } [Fact] [WorkItem(20084, "https://github.com/dotnet/roslyn/issues/20084")] public void EventImplementationInDerived_14() { var source1 = @" public interface I1 { event System.Action M1 { add { System.Console.WriteLine(""I1.M1.add""); } remove => System.Console.WriteLine(""I1.M1.remove""); } } public interface I2 : I1 { event System.Action I1.M1 { add { System.Console.WriteLine(""I2.I1.M1.add""); } remove => System.Console.WriteLine(""I2.I1.M1.remove""); } } public interface I3 : I1 {} "; var source2 = @" class Test1 : I1 { static void Main() { I1 i1Int = new Test1(); i1Int.M1 += null; i1Int.M1 -= null; I1 i1Long = new Test2(); i1Long.M1 += null; i1Long.M1 -= null; } } class Test2 : I2 {} "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); Validate(compilation1.SourceModule); void Validate(ModuleSymbol m) { var i1 = FindType(m, "I1"); var i1m1 = GetSingleEvent(i1); var i2 = FindType(m, "I2"); var i2m1 = GetSingleEvent(i2); var i2i1 = i2.InterfacesNoUseSiteDiagnostics().Single(); var i2i1m1 = GetSingleEvent(i2i1); var i3 = FindType(m, "I3"); var i3i1 = i3.InterfacesNoUseSiteDiagnostics().Single(); var i3i1m1 = GetSingleEvent(i3i1); VerifyFindImplementationForInterfaceMemberSame(i1m1, i1, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i2, i3i1m1); VerifyFindImplementationForInterfaceMemberSame(i2m1, i2, i2i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i3, i1m1); VerifyFindImplementationForInterfaceMemberSame(null, i3, i2i1m1); VerifyFindImplementationForInterfaceMemberEqual(i3i1m1, i3, i3i1m1); ValidateExplicitImplementation(i2m1); var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test1i1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32)); var test1i1m1 = GetSingleEvent(i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int32))); var test2 = m.GlobalNamespace.GetTypeMember("Test2"); var test2i1 = i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)); var test2i1m1 = GetSingleEvent(i1.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64))); var test2i2 = i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64)); var test2i2m1 = GetSingleEvent(i2.Construct(m.ContainingAssembly.GetSpecialType(SpecialType.System_Int64))); Assert.NotSame(test1i1, test1i1m1.ContainingType); Assert.NotSame(test2i1, test2i1m1.ContainingType); Assert.NotSame(test2i2, test2i2m1.ContainingType); VerifyFindImplementationForInterfaceMemberSame(null, test1i1, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test1i1m1, test1i1, test1i1m1); VerifyFindImplementationForInterfaceMemberEqual(test2i1m1, test2i1, test2i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test2i2, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test2i2m1, test2i2, test2i1m1); ValidateExplicitImplementation(test2i2m1); VerifyFindImplementationForInterfaceMemberSame(null, test1, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test1i1m1, test1, test1i1m1); VerifyFindImplementationForInterfaceMemberSame(null, test2, i1m1); VerifyFindImplementationForInterfaceMemberEqual(test2i2m1, test2, test2i1m1); } CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1.add I1.M1.remove I2.I1.M1.add I2.I1.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1.add I1.M1.remove I2.I1.M1.add I2.I1.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation3.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1.M1.add I1.M1.remove I2.I1.M1.add I2.I1.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: Validate); } [Fact] public void EventImplementationInDerived_15() { var source1 = @" public interface I2 { protected event System.Action M1; public static void Test(I2 i2) { i2.M1 += null; i2.M1 -= null; } } public interface I4 { event System.Action M1; } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { I2.Test(i2); i4.M1 += null; i4.M1 -= null; } } "; var source2 = @" public interface I1 : I2, I5 { event System.Action I2.M1 { add { System.Console.WriteLine(""I2.M1.add""); } remove => System.Console.WriteLine(""I2.M1.remove""); } event System.Action I4.M1 { add { System.Console.WriteLine(""I4.M1.add""); } remove => System.Console.WriteLine(""I4.M1.remove""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { TestHelper.Test(new Test1(), new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateEventImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics(); CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); } } [Fact] public void EventImplementationInDerived_16() { var source1 = @" public interface I2 { protected internal event System.Action M1; public static void Test(I2 i2) { i2.M1 += null; i2.M1 -= null; } } public interface I4 { event System.Action M1; } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { I2.Test(i2); i4.M1 += null; i4.M1 -= null; } } "; var source2 = @" public interface I1 : I2, I5 { event System.Action I2.M1 { add { System.Console.WriteLine(""I2.M1.add""); } remove => System.Console.WriteLine(""I2.M1.remove""); } event System.Action I4.M1 { add { System.Console.WriteLine(""I4.M1.add""); } remove => System.Console.WriteLine(""I4.M1.remove""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { TestHelper.Test(new Test1(), new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateEventImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics(); CompileAndVerify(compilation5, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); } } [Fact] public void EventImplementationInDerived_17() { var source1 = @" public interface I2 { private protected event System.Action M1; public static void Test(I2 i2) { i2.M1 += null; i2.M1 -= null; } } public interface I4 { event System.Action M1; } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { I2.Test(i2); i4.M1 += null; i4.M1 -= null; } } "; var source2 = @" public interface I1 : I2, I5 { event System.Action I2.M1 { add { System.Console.WriteLine(""I2.M1.add""); } remove => System.Console.WriteLine(""I2.M1.remove""); } event System.Action I4.M1 { add { System.Console.WriteLine(""I4.M1.add""); } remove => System.Console.WriteLine(""I4.M1.remove""); } } public interface I3 : I1 { } "; var source3 = @" class Test1 : I1 { static void Main() { TestHelper.Test(new Test1(), new Test1()); } } "; var compilation1 = CreateCompilation(source1 + source2 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); ValidateEventImplementationInDerived_01(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source3, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation2.SourceModule); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I2.M1.add I2.M1.remove I4.M1.add I4.M1.remove ", verify: VerifyOnMonoOrCoreClr, symbolValidator: ValidateEventImplementationInDerived_01); } var compilation4 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics(); foreach (var reference in new[] { compilation4.ToMetadataReference(), compilation4.EmitToImageReference() }) { var compilation5 = CreateCompilation(source2 + source3, new[] { reference }, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation5.Assembly.RuntimeSupportsDefaultInterfaceImplementation); ValidateEventImplementationInDerived_01(compilation5.SourceModule); compilation5.VerifyDiagnostics( // (4,28): error CS0122: 'I2.M1' is inaccessible due to its protection level // event System.Action I2.M1 Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I2.M1").WithLocation(4, 28) ); } } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void IndexerImplementationInDerived_01() { var source1 = @" public interface I2 { int this[int x] {get;} } public interface I4 { int this[int x] {set;} } public interface I5 : I4 { } public interface I1 : I2, I5 { int I2.this[int x] { get { System.Console.WriteLine(""I2.M1""); return 1; } } int I4.this[int x] { set => System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source2 = @" class Test1 : I1 { static void Main() { I2 i2 = new Test1(); _ = i2[0]; I4 i4 = new Test1(); i4[0] = 0; } } "; ValidatePropertyImplementationInDerived_01(source1, source2); } [Fact] public void IndexerImplementationInDerived_02() { var source1 = @" public interface I2 { int this[int x] {get;} } public interface I4 { int this[int x] {set;} } public interface I1 : I2, I4 { int I2.this[int x] => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.this[int x] { set { System.Console.WriteLine(""I2.M1""); } } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_02(source1, new DiagnosticDescription[] { // (16,17): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private int Getter() Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "Getter").WithArguments("default interface implementation", "8.0").WithLocation(16, 17), // (14,27): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // int I2.this[int x] => Getter(); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "Getter()").WithArguments("default interface implementation", "8.0").WithLocation(14, 27), // (24,9): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // set Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(24, 9) }, // (6,15): error CS8506: 'I1.I2.this[int].get' cannot implement interface member 'I2.this[int].get' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.this[int].get", "I2.this[int].get", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15), // (6,15): error CS8506: 'I1.I4.this[int].set' cannot implement interface member 'I4.this[int].set' in type 'Test1' because feature 'default interface implementation' is not available in C# 7.3. Please use language version '8.0' or greater. // class Test1 : I1 Diagnostic(ErrorCode.ERR_LanguageVersionDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.this[int].set", "I4.this[int].set", "Test1", "default interface implementation", "7.3", "8.0").WithLocation(6, 15) ); } [Fact] public void IndexerImplementationInDerived_03() { var source1 = @" public interface I2 { int this[int x] {get; set;} } public interface I4 { int this[int x] {set;} } public interface I1 : I2, I4 { int I2.this[int x] { get { System.Console.WriteLine(""I2.M1""); return 1; } set { System.Console.WriteLine(""I2.M1""); } } int I4.this[int x] { set { System.Console.WriteLine(""I2.M1""); } } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_03(source1, new DiagnosticDescription[] { // (16,9): error CS8501: Target runtime doesn't support default interface implementation. // get Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(16, 9), // (21,9): error CS8501: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(21, 9), // (29,9): error CS8501: Target runtime doesn't support default interface implementation. // set Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(29, 9) }, // (6,15): error CS8502: 'I1.I2.this[int].set' cannot implement interface member 'I2.this[int].set' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.this[int].set", "I2.this[int].set", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I2.this[int].get' cannot implement interface member 'I2.this[int].get' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I2.this[int].get", "I2.this[int].get", "Test1").WithLocation(6, 15), // (6,15): error CS8502: 'I1.I4.this[int].set' cannot implement interface member 'I4.this[int].set' in type 'Test1' because the target runtime doesn't support default interface implementation. // class Test1 : I1 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementationForMember, "I1").WithArguments("I1.I4.this[int].set", "I4.this[int].set", "Test1").WithLocation(6, 15) ); } [Fact] public void IndexerImplementationInDerived_04() { var source1 = @" public interface I2 { int this[int x] {get;} } public interface I4 { int this[int x] {set;} } public interface I1 : I2, I4 { int I2.this[int x] {get;} int I4.this[int x] {set;} } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (14,25): error CS0501: 'I1.I2.this[int].get' must declare a body because it is not marked abstract, extern, or partial // int I2.this[int x] {get;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.I2.this[int].get").WithLocation(14, 25), // (15,25): error CS0501: 'I1.I4.this[int].set' must declare a body because it is not marked abstract, extern, or partial // int I4.this[int x] {set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.I4.this[int].set").WithLocation(15, 25) ); } [Fact] public void IndexerImplementationInDerived_05() { var source1 = @" public interface I2 { int this[int x] {get;} } public interface I4 { int this[int x] {set;} } public interface I1 { int I2.this[int x] {get => throw null;} int I4.this[int x] {set => throw null;} } "; ValidatePropertyImplementationInDerived_05(source1, // (14,9): error CS0540: 'I1.I2.this[int]': containing type does not implement interface 'I2' // int I2.this[int x] {get => throw null;} Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I2").WithArguments("I1.I2.this[int]", "I2").WithLocation(14, 9), // (15,9): error CS0540: 'I1.I4.this[int]': containing type does not implement interface 'I4' // int I4.this[int x] {set => throw null;} Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I4").WithArguments("I1.I4.this[int]", "I4").WithLocation(15, 9) ); } [Fact] public void IndexerImplementationInDerived_06() { var source1 = @" public interface I2 { int this[int x] {get; set;} } public interface I4 { int this[int x] {get; set;} } public interface I1 : I2, I4 { public static int I2.this[int x] { internal get => throw null; set => throw null; } internal virtual int I4.this[int x] { public get => throw null; set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (14,26): error CS0106: The modifier 'static' is not valid for this item // public static int I2.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("static").WithLocation(14, 26), // (14,26): error CS0106: The modifier 'public' is not valid for this item // public static int I2.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(14, 26), // (16,18): error CS0106: The modifier 'internal' is not valid for this item // internal get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("internal").WithLocation(16, 18), // (19,29): error CS0106: The modifier 'internal' is not valid for this item // internal virtual int I4.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("internal").WithLocation(19, 29), // (19,29): error CS0106: The modifier 'virtual' is not valid for this item // internal virtual int I4.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("virtual").WithLocation(19, 29), // (21,16): error CS0106: The modifier 'public' is not valid for this item // public get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("public").WithLocation(21, 16) ); } [Fact] public void IndexerImplementationInDerived_07() { var source1 = @" public interface I2 { int this[int x] {get; set;} } public interface I4 { int this[int x] {get; set;} } public interface I1 : I2, I4 { private sealed int I2.this[int x] { private get => throw null; set => throw null; } protected abstract int I4.this[int x] { get => throw null; protected set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, i4M1IsAbstract: true, // (14,27): error CS0106: The modifier 'sealed' is not valid for this item // private sealed int I2.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("sealed").WithLocation(14, 27), // (14,27): error CS0106: The modifier 'private' is not valid for this item // private sealed int I2.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("private").WithLocation(14, 27), // (16,17): error CS0106: The modifier 'private' is not valid for this item // private get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private").WithLocation(16, 17), // (19,31): error CS0106: The modifier 'protected' is not valid for this item // protected abstract int I4.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("protected").WithLocation(19, 31), // (21,9): error CS0500: 'I1.I4.this[int].get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I1.I4.this[int].get").WithLocation(21, 9), // (22,19): error CS0106: The modifier 'protected' is not valid for this item // protected set => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected").WithLocation(22, 19), // (22,19): error CS0500: 'I1.I4.this[int].set' cannot declare a body because it is marked abstract // protected set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I1.I4.this[int].set").WithLocation(22, 19), // (30,15): error CS0535: 'Test1' does not implement interface member 'I4.this[int]' // class Test1 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("Test1", "I4.this[int]").WithLocation(30, 15) ); } [Fact] public void IndexerImplementationInDerived_08() { var source1 = @" public interface I2 { int this[int x] {get; set;} } public interface I4 { int this[int x] {get; set;} } public interface I1 : I2, I4 { private protected int I2.this[int x] { private protected get => throw null; set => throw null; } internal protected override int I4.this[int x] { get => throw null; internal protected set => throw null; } } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_04(source1, // (14,30): error CS0106: The modifier 'private protected' is not valid for this item // private protected int I2.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("private protected").WithLocation(14, 30), // (16,27): error CS0106: The modifier 'private protected' is not valid for this item // private protected get => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "get").WithArguments("private protected").WithLocation(16, 27), // (19,40): error CS0106: The modifier 'protected internal' is not valid for this item // internal protected override int I4.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("protected internal").WithLocation(19, 40), // (19,40): error CS0106: The modifier 'override' is not valid for this item // internal protected override int I4.this[int x] Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("override").WithLocation(19, 40), // (22,28): error CS0106: The modifier 'protected internal' is not valid for this item // internal protected set => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "set").WithArguments("protected internal").WithLocation(22, 28) ); } [Fact] public void IndexerImplementationInDerived_09() { var source1 = @" public interface I2 { int this[int x] {get;} } public interface I1 : I2 { extern int I2.this[int x] {get;} } public interface I3 : I1 { } class Test1 : I1 {} "; var source2 = @" public interface I2 { int this[int x] {set;} } public interface I1 : I2 { extern int I2.this[int x] { set {}} } public interface I3 : I1 { } class Test1 : I1 {} "; ValidatePropertyImplementationInDerived_09(source1, source2, new DiagnosticDescription[] { // (9,32): warning CS0626: Method, operator, or accessor 'I1.I2.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int I2.this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.I2.this[int].get").WithLocation(9, 32) }, new DiagnosticDescription[] { // (9,32): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // extern int I2.this[int x] {get;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 32), // (9,32): warning CS0626: Method, operator, or accessor 'I1.I2.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int I2.this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.I2.this[int].get").WithLocation(9, 32) }, new DiagnosticDescription[] { // (9,32): error CS8501: Target runtime doesn't support default interface implementation. // extern int I2.this[int x] {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 32), // (9,32): warning CS0626: Method, operator, or accessor 'I1.I2.this[int].get' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation. // extern int I2.this[int x] {get;} Diagnostic(ErrorCode.WRN_ExternMethodNoImplementation, "get").WithArguments("I1.I2.this[int].get").WithLocation(9, 32) }, // (10,7): error CS0179: 'I1.I2.this[int].set' cannot be extern and declare a body // { set {}} Diagnostic(ErrorCode.ERR_ExternHasBody, "set").WithArguments("I1.I2.this[int].set").WithLocation(10, 7) ); } [Fact] public void IndexerImplementationInDerived_10() { var source1 = @" public interface I1 { int this[int x] {get;set;} int this[long x] {get;set;} } public interface I2 : I1 { int I1.this[int x] { get => throw null; } int I1.this[long x] { set => throw null; } } class Test1 : I2 {} public interface I3 { int this[int x] {get;} int this[long x] {set;} int this[byte x] {get;set;} int this[short x] {get;set;} } public interface I4 : I3 { int I3.this[int x] { get => throw null; set => throw null; } int I3.this[long x] { get => throw null; set => throw null; } int I3.this[byte x] {get; set;} int I3.this[short x] {get; set;} = 0; } class Test2 : I4 {} "; ValidatePropertyImplementationInDerived_05(source1, // (44,38): error CS1519: Invalid token '=' in class, struct, or interface member declaration // int I3.this[short x] {get; set;} = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(44, 38), // (10,12): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].set' // int I1.this[int x] Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].set").WithLocation(10, 12), // (14,12): error CS0551: Explicit interface implementation 'I2.I1.this[long]' is missing accessor 'I1.this[long].get' // int I1.this[long x] Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[long]", "I1.this[long].get").WithLocation(14, 12), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.this[long].get' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[long].get").WithLocation(20, 15), // (20,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int].set' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int].set").WithLocation(20, 15), // (36,9): error CS0550: 'I4.I3.this[int].set' adds an accessor not found in interface member 'I3.this[int]' // set => throw null; Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I4.I3.this[int].set", "I3.this[int]").WithLocation(36, 9), // (40,9): error CS0550: 'I4.I3.this[long].get' adds an accessor not found in interface member 'I3.this[long]' // get => throw null; Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I4.I3.this[long].get", "I3.this[long]").WithLocation(40, 9), // (43,26): error CS0501: 'I4.I3.this[byte].get' must declare a body because it is not marked abstract, extern, or partial // int I3.this[byte x] {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I4.I3.this[byte].get").WithLocation(43, 26), // (43,31): error CS0501: 'I4.I3.this[byte].set' must declare a body because it is not marked abstract, extern, or partial // int I3.this[byte x] {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I4.I3.this[byte].set").WithLocation(43, 31), // (44,27): error CS0501: 'I4.I3.this[short].get' must declare a body because it is not marked abstract, extern, or partial // int I3.this[short x] {get; set;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I4.I3.this[short].get").WithLocation(44, 27), // (44,32): error CS0501: 'I4.I3.this[short].set' must declare a body because it is not marked abstract, extern, or partial // int I3.this[short x] {get; set;} = 0; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I4.I3.this[short].set").WithLocation(44, 32) ); } [Fact] [WorkItem(32540, "https://github.com/dotnet/roslyn/issues/32540")] public void IndexerImplementationInDerived_11() { var source1 = @" public interface I2 { internal int this[int x] {get;} } public interface I4 { int this[int x] {get; internal set;} } public interface I5 : I4 { } public class TestHelper { public static void Test(I2 i2, I4 i4) { _ = i2[0]; i4[0] = i4[0]; } } "; var source2 = @" public interface I1 : I2, I5 { int I2.this[int x] => Getter(); private int Getter() { System.Console.WriteLine(""I2.M1""); return 1; } int I4.this[int x] { get { System.Console.WriteLine(""I4.M1""); return 1; } set => System.Console.WriteLine(""I4.M1.set""); } } public interface I3 : I1 { } "; ValidatePropertyImplementationInDerived_11(source1, source2, // (4,12): error CS0122: 'I2.this[int]' is inaccessible due to its protection level // int I2.this[int x] => Getter(); Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I2.this[int]").WithLocation(4, 12), // (11,12): error CS0122: 'I4.this[int].set' is inaccessible due to its protection level // int I4.this[int x] Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I4.this[int].set").WithLocation(11, 12) ); } [Fact] [WorkItem(20083, "https://github.com/dotnet/roslyn/issues/20083")] public void IndexerImplementationInDerived_12() { var source1 = @" public interface I1 { int this[int x] { get => throw null; set => throw null;} } public interface I2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""I2.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I2.I1.M1.set""); } } } public interface I3 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""I3.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I3.I1.M1.set""); } } } public interface I4 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""I4.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I4.I1.M1.set""); } } } public interface I5 : I2, I3 { int I1.this[int x] { get { System.Console.WriteLine(""I5.I1.M1.get""); return 1; } set { System.Console.WriteLine(""I5.I1.M1.set""); } } } public interface I6 : I1, I2, I3, I5 {} "; var source4 = @" class Test5 : I2 {} class Test6 : I1, I2, I3, I5 {} class Test7 : I6 { static void Main() { I1 i1 = new Test5(); i1[0] = i1[0]; i1 = new Test6(); i1[0] = i1[0]; i1 = new Test7(); i1[0] = i1[0]; } } "; var source5 = @" class Test8 : I2, I3 { int I1.this[int x] { get { System.Console.WriteLine(""Test8.I1.M1.get""); return 1; } set { System.Console.WriteLine(""Test8.I1.M1.set""); } } static void Main() { I1 i1 = new Test8(); i1[0] = i1[0]; i1 = new Test9(); i1[0] = i1[0]; i1 = new Test10(); i1[0] = i1[0]; i1 = new Test11(); i1[0] = i1[0]; i1 = new Test12(); i1[0] = i1[0]; } } class Test9 : I7 { int I1.this[int x] { get { System.Console.WriteLine(""Test9.I1.M1.get""); return 1; } set { System.Console.WriteLine(""Test9.I1.M1.set""); } } } class Test10 : I1, I2, I3, I4 { public int this[int x] { get { System.Console.WriteLine(""Test10.M1.get""); return 1; } set { System.Console.WriteLine(""Test10.M1.set""); } } } class Test11 : I1, I2, I3, I5, I4 { public int this[int x] { get { System.Console.WriteLine(""Test11.M1.get""); return 1; } set { System.Console.WriteLine(""Test11.M1.set""); } } } class Test12 : I8 { public virtual int this[int x] { get { System.Console.WriteLine(""Test12.M1.get""); return 1; } set { System.Console.WriteLine(""Test12.M1.set""); } } } "; ValidatePropertyImplementationInDerived_12(source1, source4, source5, new DiagnosticDescription[] { // (2,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15), // (5,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test2 : I7 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I7").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(5, 15), // (8,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test3 : I1, I2, I3, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(8, 15), // (11,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I5.I1.this[int]', nor 'I4.I1.this[int]' are most specific. // class Test4 : I1, I2, I3, I5, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.this[int]", "I5.I1.this[int]", "I4.I1.this[int]").WithLocation(11, 15), // (14,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I5.I1.this[int]', nor 'I4.I1.this[int]' are most specific. // class Test5 : I8 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I8").WithArguments("I1.this[int]", "I5.I1.this[int]", "I4.I1.this[int]").WithLocation(14, 15) }, new DiagnosticDescription[] { // (2,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15), // (5,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test2 : I7 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I7").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(5, 15), // (8,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test3 : I1, I2, I3, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(8, 15), // (11,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I5.I1.Item[int]', nor 'I4.I1.Item[int]' are most specific. // class Test4 : I1, I2, I3, I5, I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I1").WithArguments("I1.this[int]", "I5.I1.Item[int]", "I4.I1.Item[int]").WithLocation(11, 15), // (14,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I5.I1.Item[int]', nor 'I4.I1.Item[int]' are most specific. // class Test5 : I8 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I8").WithArguments("I1.this[int]", "I5.I1.Item[int]", "I4.I1.Item[int]").WithLocation(14, 15) } ); } [Fact] public void IndexerImplementationInDerived_13() { var source1 = @" public interface I1 { int this[int x] {get;} } public interface I2 : I1 { int I1.this[int x] => throw null; } public interface I3 : I1 { int I1.this[int x] => throw null; } "; var source2 = @" class Test1 : I2, I3 { public long this[int x] => 1; } "; ValidatePropertyImplementationInDerived_13(source1, source2, new DiagnosticDescription[] { // (2,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.this[int]'. 'Test1.this[int]' cannot implement 'I1.this[int]' because it does not have the matching return type of 'int'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.this[int]", "Test1.this[int]", "int").WithLocation(2, 15) }, new DiagnosticDescription[] { // (2,15): error CS8505: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15), // (2,15): error CS0738: 'Test1' does not implement interface member 'I1.this[int]'. 'Test1.this[int]' cannot implement 'I1.this[int]' because it does not have the matching return type of 'int'. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_CloseUnimplementedInterfaceMemberWrongReturnType, "I2").WithArguments("Test1", "I1.this[int]", "Test1.this[int]", "int").WithLocation(2, 15) } ); } [Fact] [WorkItem(20084, "https://github.com/dotnet/roslyn/issues/20084")] public void IndexerImplementationInDerived_14() { var source1 = @" public interface I1 { int this[int x] { get { System.Console.WriteLine(""I1.M1.get""); return 1; } set => System.Console.WriteLine(""I1.M1.set""); } } public interface I2 : I1 { int I1.this[int x] { get { System.Console.WriteLine(""I2.I1.M1.get""); return 1; } set => System.Console.WriteLine(""I2.I1.M1.set""); } } public interface I3 : I1 {} "; var source2 = @" class Test1 : I1 { static void Main() { I1 i1Int = new Test1(); i1Int[0] = i1Int[0]; I1 i1Long = new Test2(); i1Long[0] = i1Long[0]; } } class Test2 : I2 {} "; ValidatePropertyImplementationInDerived_14(source1, source2); } [Fact] public void IndexerImplementationInDerived_15() { var source1 = @" public interface I2 { int this[int x] {get => throw null; private set => throw null;} } public interface I4 { int this[int x] {set => throw null; private get => throw null;} } public interface I5 : I4 { } public interface I1 : I2, I5 { int I2.this[int x] { get { System.Console.WriteLine(""I2.M1""); return 1; } } int I4.this[int x] { set => System.Console.WriteLine(""I4.M1""); } } public interface I3 : I1 { } "; var source2 = @" class Test1 : I1 { static void Main() { I2 i2 = new Test1(); _ = i2[0]; I4 i4 = new Test1(); i4[0] = 0; } } "; ValidatePropertyImplementationInDerived_01(source1, source2); } [Fact] public void Field_01() { var source1 = @" public interface I1 { int F1; protected static int F2; protected internal static int F3; private protected static int F4; int F5 = 5; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation1.VerifyEmitDiagnostics( // (4,9): error CS0525: Interfaces cannot contain instance fields // int F1; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 9), // (5,26): error CS8701: Target runtime doesn't support default interface implementation. // protected static int F2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F2").WithLocation(5, 26), // (6,35): error CS8701: Target runtime doesn't support default interface implementation. // protected internal static int F3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F3").WithLocation(6, 35), // (7,34): error CS8701: Target runtime doesn't support default interface implementation. // private protected static int F4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F4").WithLocation(7, 34), // (8,9): error CS0525: Interfaces cannot contain instance fields // int F5 = 5; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F5").WithLocation(8, 9) ); validate(compilation1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyEmitDiagnostics( // (4,9): error CS0525: Interfaces cannot contain instance fields // int F1; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F1").WithLocation(4, 9), // (8,9): error CS0525: Interfaces cannot contain instance fields // int F5 = 5; Diagnostic(ErrorCode.ERR_InterfacesCantContainFields, "F5").WithLocation(8, 9) ); validate(compilation2); static void validate(CSharpCompilation compilation) { var i1 = compilation.GetTypeByMetadataName("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.False(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Protected, f2.DeclaredAccessibility); Assert.Equal(Accessibility.ProtectedOrInternal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.ProtectedAndInternal, f4.DeclaredAccessibility); } } [Fact] public void Field_02() { var source1 = @" public interface I1 { static int F1; public static int F2; internal static int F3; private static int F4; public class TestHelper { public static int F4Proxy { get => I1.F4; set => I1.F4 = value; } } } class Test1 : I1 { static void Main() { I1.F1 = 1; I1.F2 = 2; I1.F3 = 3; I1.TestHelper.F4Proxy = 4; System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}{I1.TestHelper.F4Proxy}""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Null(cctor); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1.F1 = 11; I1.F2 = 22; I1.TestHelper.F4Proxy = 44; System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.TestHelper.F4Proxy}""); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "112244"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "112244"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,16): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int F1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F1").WithArguments("default interface implementation", "8.0").WithLocation(4, 16), // (5,23): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static int F2; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F2").WithArguments("default interface implementation", "8.0").WithLocation(5, 23), // (6,25): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static int F3; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F3").WithArguments("default interface implementation", "8.0").WithLocation(6, 25), // (7,24): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private static int F4; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F4").WithArguments("default interface implementation", "8.0").WithLocation(7, 24), // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,16): error CS8701: Target runtime doesn't support default interface implementation. // static int F1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F1").WithLocation(4, 16), // (5,23): error CS8701: Target runtime doesn't support default interface implementation. // public static int F2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F2").WithLocation(5, 23), // (6,25): error CS8701: Target runtime doesn't support default interface implementation. // internal static int F3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F3").WithLocation(6, 25), // (7,24): error CS8701: Target runtime doesn't support default interface implementation. // private static int F4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F4").WithLocation(7, 24) ); Validate1(compilation5.SourceModule); } [Fact] public void Field_03() { var source1 = @" public interface I1 { static readonly int F1 = 1; public static readonly int F2 = 2; internal static readonly int F3 = 3; private static readonly int F4 = 4; public class TestHelper { public static int F4Proxy { get => I1.F4; } } } class Test1 : I1 { static void Main() { System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}{I1.TestHelper.F4Proxy}""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.True(f1.IsReadOnly); Assert.True(f2.IsReadOnly); Assert.True(f3.IsReadOnly); Assert.True(f4.IsReadOnly); Assert.False(f1.IsConst); Assert.False(f2.IsConst); Assert.False(f3.IsConst); Assert.False(f4.IsConst); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Equal(MethodKind.StaticConstructor, cctor.MethodKind); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.TestHelper.F4Proxy}""); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "124"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "124"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,25): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static readonly int F1 = 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F1").WithArguments("default interface implementation", "8.0").WithLocation(4, 25), // (5,32): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static readonly int F2 = 2; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F2").WithArguments("default interface implementation", "8.0").WithLocation(5, 32), // (6,34): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static readonly int F3 = 3; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F3").WithArguments("default interface implementation", "8.0").WithLocation(6, 34), // (7,33): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private static readonly int F4 = 4; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F4").WithArguments("default interface implementation", "8.0").WithLocation(7, 33), // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,25): error CS8701: Target runtime doesn't support default interface implementation. // static readonly int F1 = 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F1").WithLocation(4, 25), // (5,32): error CS8701: Target runtime doesn't support default interface implementation. // public static readonly int F2 = 2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F2").WithLocation(5, 32), // (6,34): error CS8701: Target runtime doesn't support default interface implementation. // internal static readonly int F3 = 3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F3").WithLocation(6, 34), // (7,33): error CS8701: Target runtime doesn't support default interface implementation. // private static readonly int F4 = 4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F4").WithLocation(7, 33) ); Validate1(compilation5.SourceModule); } [Fact] public void Field_04() { var source1 = @" public interface I1 { const int F1 = 1; public const int F2 = 2; internal const int F3 = 3; private const int F4 = 4; public class TestHelper { public static int F4Proxy { get => I1.F4; } } } class Test1 : I1 { static void Main() { System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}{I1.TestHelper.F4Proxy}""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.True(f1.IsConst); Assert.True(f2.IsConst); Assert.True(f3.IsConst); Assert.True(f4.IsConst); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Null(cctor); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.TestHelper.F4Proxy}""); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "124"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "124"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,15): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // const int F1 = 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F1").WithArguments("default interface implementation", "8.0").WithLocation(4, 15), // (5,22): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public const int F2 = 2; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F2").WithArguments("default interface implementation", "8.0").WithLocation(5, 22), // (6,24): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal const int F3 = 3; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F3").WithArguments("default interface implementation", "8.0").WithLocation(6, 24), // (7,23): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private const int F4 = 4; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F4").WithArguments("default interface implementation", "8.0").WithLocation(7, 23), // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,15): error CS8701: Target runtime doesn't support default interface implementation. // const int F1 = 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F1").WithLocation(4, 15), // (5,22): error CS8701: Target runtime doesn't support default interface implementation. // public const int F2 = 2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F2").WithLocation(5, 22), // (6,24): error CS8701: Target runtime doesn't support default interface implementation. // internal const int F3 = 3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F3").WithLocation(6, 24), // (7,23): error CS8701: Target runtime doesn't support default interface implementation. // private const int F4 = 4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F4").WithLocation(7, 23) ); Validate1(compilation5.SourceModule); } [Fact] public void Field_05() { var source0 = @" public interface I1 { static protected int F1; static protected internal int F2; static private protected int F3; } "; var source1 = @" class Test1 : I1 { static void Main() { I1.F1 = 1; I1.F2 = 2; I1.F3 = 3; System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}""); Test2.Test(); } } class Test2 { public static void Test() { I1.F2 = -2; System.Console.WriteLine(I1.F2); } } "; var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); validate(compilation1.SourceModule); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"123 -2 ", verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var source2 = @" class Test2 : I1 { static void Main() { I1.F1 = 11; I1.F2 = 22; System.Console.WriteLine($""{I1.F1}{I1.F2}""); } } "; var references = new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }; foreach (var reference in references) { var compilation2 = CreateCompilation(source2, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "1122" : null, verify: VerifyOnMonoOrCoreClr); } var source3 = @" class Test1 { static void Main() { I1.F1 = 1; I1.F2 = 2; I1.F3 = 3; } } "; var compilation3 = CreateCompilation(source0 + source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics( // (13,12): error CS0122: 'I1.F1' is inaccessible due to its protection level // I1.F1 = 1; Diagnostic(ErrorCode.ERR_BadAccess, "F1").WithArguments("I1.F1").WithLocation(13, 12), // (15,12): error CS0122: 'I1.F3' is inaccessible due to its protection level // I1.F3 = 3; Diagnostic(ErrorCode.ERR_BadAccess, "F3").WithArguments("I1.F3").WithLocation(15, 12) ); var source4 = @" class Test2 : I1 { static void Test() { I1.F3 = -3; } } "; foreach (var reference in references) { var compilation2 = CreateCompilation(source3 + source4, new[] { reference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (6,12): error CS0122: 'I1.F1' is inaccessible due to its protection level // I1.F1 = 1; Diagnostic(ErrorCode.ERR_BadAccess, "F1").WithArguments("I1.F1").WithLocation(6, 12), // (7,12): error CS0122: 'I1.F2' is inaccessible due to its protection level // I1.F2 = 2; Diagnostic(ErrorCode.ERR_BadAccess, "F2").WithArguments("I1.F2").WithLocation(7, 12), // (8,12): error CS0122: 'I1.F3' is inaccessible due to its protection level // I1.F3 = 3; Diagnostic(ErrorCode.ERR_BadAccess, "F3").WithArguments("I1.F3").WithLocation(8, 12), // (16,12): error CS0122: 'I1.F3' is inaccessible due to its protection level // I1.F3 = -3; Diagnostic(ErrorCode.ERR_BadAccess, "F3").WithArguments("I1.F3").WithLocation(16, 12) ); } var compilation4 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,26): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static protected int F1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F1").WithArguments("default interface implementation", "8.0").WithLocation(4, 26), // (5,35): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static protected internal int F2; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F2").WithArguments("default interface implementation", "8.0").WithLocation(5, 35), // (6,34): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static private protected int F3; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "F3").WithArguments("default interface implementation", "8.0").WithLocation(6, 34) ); validate(compilation4.SourceModule); void validate(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.Equal(Accessibility.Protected, f1.DeclaredAccessibility); Assert.Equal(Accessibility.ProtectedOrInternal, f2.DeclaredAccessibility); Assert.Equal(Accessibility.ProtectedAndInternal, f3.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Null(cctor); } } [Fact] public void Constructors_01() { var source1 = @" public interface I1 { I1(){} static I1() {} } interface I2 { I2(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,5): error CS0526: Interfaces cannot contain instance constructors // I1(){} Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I1").WithLocation(4, 5), // (10,5): error CS0501: 'I2.I2()' must declare a body because it is not marked abstract, extern, or partial // I2(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "I2").WithArguments("I2.I2()").WithLocation(10, 5), // (10,5): error CS0526: Interfaces cannot contain instance constructors // I2(); Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I2").WithLocation(10, 5) ); } [Fact] public void Constructors_02() { var source1 = @" interface I1 { static I1() {} } interface I2 { static I2() => throw null; } interface I3 { I3() {} } interface I4 { I4() => throw null; } interface I5 { I5(); } interface I6 { extern static I6(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,12): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static I1() {} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "I1").WithArguments("default interface implementation", "8.0").WithLocation(4, 12), // (8,12): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static I2() => throw null; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "I2").WithArguments("default interface implementation", "8.0").WithLocation(8, 12), // (12,5): error CS0526: Interfaces cannot contain instance constructors // I3() {} Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I3").WithLocation(12, 5), // (16,5): error CS0526: Interfaces cannot contain instance constructors // I4() => throw null; Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I4").WithLocation(16, 5), // (20,5): error CS0501: 'I5.I5()' must declare a body because it is not marked abstract, extern, or partial // I5(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "I5").WithArguments("I5.I5()").WithLocation(20, 5), // (20,5): error CS0526: Interfaces cannot contain instance constructors // I5(); Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I5").WithLocation(20, 5), // (24,19): error CS8703: The modifier 'extern' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // extern static I6(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "I6").WithArguments("extern", "7.3", "8.0").WithLocation(24, 19), // (24,19): warning CS0824: Constructor 'I6.I6()' is marked external // extern static I6(); Diagnostic(ErrorCode.WRN_ExternCtorNoImplementation, "I6").WithArguments("I6.I6()").WithLocation(24, 19) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (4,12): error CS8701: Target runtime doesn't support default interface implementation. // static I1() {} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "I1").WithLocation(4, 12), // (8,12): error CS8701: Target runtime doesn't support default interface implementation. // static I2() => throw null; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "I2").WithLocation(8, 12), // (12,5): error CS0526: Interfaces cannot contain instance constructors // I3() {} Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I3").WithLocation(12, 5), // (16,5): error CS0526: Interfaces cannot contain instance constructors // I4() => throw null; Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I4").WithLocation(16, 5), // (20,5): error CS0501: 'I5.I5()' must declare a body because it is not marked abstract, extern, or partial // I5(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "I5").WithArguments("I5.I5()").WithLocation(20, 5), // (20,5): error CS0526: Interfaces cannot contain instance constructors // I5(); Diagnostic(ErrorCode.ERR_InterfacesCantContainConstructors, "I5").WithLocation(20, 5), // (24,19): error CS8701: Target runtime doesn't support default interface implementation. // extern static I6(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "I6").WithLocation(24, 19), // (24,19): warning CS0824: Constructor 'I6.I6()' is marked external // extern static I6(); Diagnostic(ErrorCode.WRN_ExternCtorNoImplementation, "I6").WithArguments("I6.I6()").WithLocation(24, 19) ); } [Fact] public void Constructors_03() { var source1 = @" interface I1 { static I1(int i) {} } interface I2 { static void I2() {} } interface I3 { void I3() {} } interface I4 { public static I4() {} } interface I5 { internal static I5() {} } interface I6 { private static I6() {} } interface I7 { static I7(); } interface I8 { static I8(){} static void M1() { I8(); } void M2() { I8.I8(); } } interface I9 { static I9() {} => throw null; } interface I10 { abstract static I10(); } interface I11 { virtual static I11(); } interface I12 { abstract static I12() {} } interface I13 { virtual static I13() => throw null; } interface I14 { partial static I14(); } interface I15 { static partial I15(); } interface I16 { partial static I16() {} } interface I17 { static partial I17() => throw null; } interface I18 { extern static I18() {} } interface I19 { static extern I19() => throw null; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,12): error CS0132: 'I1.I1(int)': a static constructor must be parameterless // static I1(int i) {} Diagnostic(ErrorCode.ERR_StaticConstParam, "I1").WithArguments("I1.I1(int)").WithLocation(4, 12), // (8,17): error CS0542: 'I2': member names cannot be the same as their enclosing type // static void I2() {} Diagnostic(ErrorCode.ERR_MemberNameSameAsType, "I2").WithArguments("I2").WithLocation(8, 17), // (16,19): error CS0515: 'I4.I4()': access modifiers are not allowed on static constructors // public static I4() {} Diagnostic(ErrorCode.ERR_StaticConstructorWithAccessModifiers, "I4").WithArguments("I4.I4()").WithLocation(16, 19), // (20,21): error CS0515: 'I5.I5()': access modifiers are not allowed on static constructors // internal static I5() {} Diagnostic(ErrorCode.ERR_StaticConstructorWithAccessModifiers, "I5").WithArguments("I5.I5()").WithLocation(20, 21), // (24,20): error CS0515: 'I6.I6()': access modifiers are not allowed on static constructors // private static I6() {} Diagnostic(ErrorCode.ERR_StaticConstructorWithAccessModifiers, "I6").WithArguments("I6.I6()").WithLocation(24, 20), // (28,12): error CS0501: 'I7.I7()' must declare a body because it is not marked abstract, extern, or partial // static I7(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "I7").WithArguments("I7.I7()").WithLocation(28, 12), // (36,9): error CS1955: Non-invocable member 'I8' cannot be used like a method. // I8(); Diagnostic(ErrorCode.ERR_NonInvocableMemberCalled, "I8").WithArguments("I8").WithLocation(36, 9), // (41,12): error CS0117: 'I8' does not contain a definition for 'I8' // I8.I8(); Diagnostic(ErrorCode.ERR_NoSuchMember, "I8").WithArguments("I8", "I8").WithLocation(41, 12), // (46,5): error CS8057: Block bodies and expression bodies cannot both be provided. // static I9() {} => throw null; Diagnostic(ErrorCode.ERR_BlockBodyAndExpressionBody, "static I9() {} => throw null;").WithLocation(46, 5), // (50,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract static I10(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "I10").WithArguments("abstract").WithLocation(50, 21), // (54,20): error CS0106: The modifier 'virtual' is not valid for this item // virtual static I11(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "I11").WithArguments("virtual").WithLocation(54, 20), // (58,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract static I12() {} Diagnostic(ErrorCode.ERR_BadMemberFlag, "I12").WithArguments("abstract").WithLocation(58, 21), // (62,20): error CS0106: The modifier 'virtual' is not valid for this item // virtual static I13() => throw null; Diagnostic(ErrorCode.ERR_BadMemberFlag, "I13").WithArguments("virtual").WithLocation(62, 20), // (66,5): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void' // partial static I14(); Diagnostic(ErrorCode.ERR_PartialMisplaced, "partial").WithLocation(66, 5), // (66,5): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void' // partial static I14(); Diagnostic(ErrorCode.ERR_PartialMisplaced, "partial").WithLocation(66, 5), // (70,12): error CS0246: The type or namespace name 'partial' could not be found (are you missing a using directive or an assembly reference?) // static partial I15(); Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "partial").WithArguments("partial").WithLocation(70, 12), // (70,20): error CS0501: 'I15.I15()' must declare a body because it is not marked abstract, extern, or partial // static partial I15(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "I15").WithArguments("I15.I15()").WithLocation(70, 20), // (70,20): error CS0542: 'I15': member names cannot be the same as their enclosing type // static partial I15(); Diagnostic(ErrorCode.ERR_MemberNameSameAsType, "I15").WithArguments("I15").WithLocation(70, 20), // (74,5): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void' // partial static I16() {} Diagnostic(ErrorCode.ERR_PartialMisplaced, "partial").WithLocation(74, 5), // (74,5): error CS0267: The 'partial' modifier can only appear immediately before 'class', 'struct', 'interface', or 'void' // partial static I16() {} Diagnostic(ErrorCode.ERR_PartialMisplaced, "partial").WithLocation(74, 5), // (78,12): error CS0246: The type or namespace name 'partial' could not be found (are you missing a using directive or an assembly reference?) // static partial I17() => throw null; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "partial").WithArguments("partial").WithLocation(78, 12), // (78,20): error CS0542: 'I17': member names cannot be the same as their enclosing type // static partial I17() => throw null; Diagnostic(ErrorCode.ERR_MemberNameSameAsType, "I17").WithArguments("I17").WithLocation(78, 20), // (82,19): error CS0179: 'I18.I18()' cannot be extern and declare a body // extern static I18() {} Diagnostic(ErrorCode.ERR_ExternHasBody, "I18").WithArguments("I18.I18()").WithLocation(82, 19), // (86,19): error CS0179: 'I19.I19()' cannot be extern and declare a body // static extern I19() => throw null; Diagnostic(ErrorCode.ERR_ExternHasBody, "I19").WithArguments("I19.I19()").WithLocation(86, 19) ); } [Fact] public void Constructors_04() { var source1 = @" interface I1 { static I1() { System.Console.WriteLine(""I1""); } static void Main() { System.Console.WriteLine(""Main""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); ValidateConstructor(compilation1.SourceModule); Assert.Empty(compilation1.GetTypeByMetadataName("I1").GetMembers("I1")); CompileAndVerify(compilation1, symbolValidator: ValidateConstructor, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1 Main "); } private static void ValidateConstructor(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var cctor = i1.GetMember(".cctor"); Assert.False(cctor.IsAbstract); Assert.False(cctor.IsVirtual); Assert.False(cctor.IsMetadataVirtual()); Assert.False(cctor.IsSealed); Assert.True(cctor.IsStatic); Assert.False(cctor.IsExtern); Assert.False(cctor.IsAsync); Assert.False(cctor.IsOverride); Assert.Equal(Accessibility.Private, cctor.DeclaredAccessibility); Assert.Equal(MethodKind.StaticConstructor, cctor.MethodKind); } [Fact] public void Constructors_05() { var source1 = @" interface I1 { static string F = ""F""; static void Main() { System.Console.WriteLine(F); System.Console.WriteLine(""Main""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); ValidateConstructor(compilation1.SourceModule); CompileAndVerify(compilation1, symbolValidator: ValidateConstructor, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"F Main "); } [Fact] public void Constructors_06() { var source1 = @" interface I1 { static string F = ""F""; static I1() { System.Console.WriteLine(F); System.Console.WriteLine(""I1""); } static void Main() { System.Console.WriteLine(""Main""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); ValidateConstructor(compilation1.SourceModule); CompileAndVerify(compilation1, symbolValidator: ValidateConstructor, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"F I1 Main "); } [Fact] public void Constructors_07() { var source1 = @" interface I1 { extern static I1(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,19): warning CS0824: Constructor 'I1.I1()' is marked external // extern static I1(); Diagnostic(ErrorCode.WRN_ExternCtorNoImplementation, "I1").WithArguments("I1.I1()").WithLocation(4, 19) ); var i1 = compilation1.SourceModule.GlobalNamespace.GetTypeMember("I1"); var cctor = i1.GetMember(".cctor"); Assert.False(cctor.IsAbstract); Assert.False(cctor.IsVirtual); Assert.False(cctor.IsMetadataVirtual()); Assert.False(cctor.IsSealed); Assert.True(cctor.IsStatic); Assert.True(cctor.IsExtern); Assert.False(cctor.IsAsync); Assert.False(cctor.IsOverride); Assert.Equal(Accessibility.Private, cctor.DeclaredAccessibility); Assert.Equal(MethodKind.StaticConstructor, cctor.MethodKind); CompileAndVerify(compilation1, symbolValidator: ValidateConstructor, verify: Verification.Skipped); } [Fact] public void Constructors_08() { var source1 = @" interface I1 { void I1(); } class Test : I1 { void I1.I1() { System.Console.WriteLine(""Test.I1""); } static void Main() { I1 x = new Test(); x.I1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: "Test.I1"); } [Fact] public void Constructors_09() { var source1 = @" interface I1 { void I1(); static I1() { System.Console.WriteLine(""I1..cctor""); } static void M1() { System.Console.WriteLine(""I1.M1""); } } class Test : I1 { void I1.I1() { System.Console.WriteLine(""Test.I1""); } static void Main() { I1.M1(); I1 x = new Test(); x.I1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1..cctor I1.M1 Test.I1 "); } [Fact] public void Constructors_10() { var source1 = @" interface I1 { void I1() { System.Console.WriteLine(""I1.I1""); } static I1() { System.Console.WriteLine(""I1..cctor""); } static void M1() { System.Console.WriteLine(""I1.M1""); } } class Test : I1 { static void Main() { I1.M1(); I1 x = new Test(); x.I1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"I1..cctor I1.M1 I1.I1 ", verify: VerifyOnMonoOrCoreClr); } [Fact] public void Constructors_11() { var source1 = @" interface I1 { void I1() { System.Console.WriteLine(""I1.I1""); } } class Test : I1 { static void Main() { I1 x = new Test(); x.I1(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "I1.I1", verify: VerifyOnMonoOrCoreClr); } /// /// Make sure runtime handles cycles in static constructors. /// [Fact] public void Constructors_12() { var source0 = @" interface I1 { public static int F1; static I1() { F1 = I2.F2; } } interface I2 { public static int F2; static I2() { F2 = I1.F1 + 1; } } "; var source1 = @" class Test { static void Main() { System.Console.WriteLine(I1.F1 + I2.F2); } } "; var compilation1 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "2"); var source2 = @" class Test { static void Main() { System.Console.WriteLine(I2.F2 + I1.F1); } } "; var compilation2 = CreateCompilation(source0 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1"); } [Fact] public void AutoProperty_01() { var source1 = @" public interface I1 { private int F1 {get; set;} private int F5 {get;} = 5; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyEmitDiagnostics( // (4,21): error CS0501: 'I1.F1.get' must declare a body because it is not marked abstract, extern, or partial // private int F1 {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.F1.get").WithLocation(4, 21), // (4,26): error CS0501: 'I1.F1.set' must declare a body because it is not marked abstract, extern, or partial // private int F1 {get; set;} Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("I1.F1.set").WithLocation(4, 26), // (5,17): error CS8050: Only auto-implemented properties can have initializers. // private int F5 {get;} = 5; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "F5").WithArguments("I1.F5").WithLocation(5, 17), // (5,21): error CS0501: 'I1.F5.get' must declare a body because it is not marked abstract, extern, or partial // private int F5 {get;} = 5; Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("I1.F5.get").WithLocation(5, 21) ); } [Fact] public void AutoProperty_02() { var source1 = @" public interface I1 { static int F1 {get; set;} public static int F2 {get; set;} internal static int F3 {get; set;} private static int F4 {get; set;} public class TestHelper { public static int F4Proxy { get => I1.F4; set => I1.F4 = value; } } } class Test1 : I1 { static void Main() { I1.F1 = 1; I1.F2 = 2; I1.F3 = 3; I1.TestHelper.F4Proxy = 4; System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}{I1.TestHelper.F4Proxy}""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Null(cctor); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1.F1 = 11; I1.F2 = 22; I1.TestHelper.F4Proxy = 44; System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.TestHelper.F4Proxy}""); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "112244"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "112244"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,16): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static int F1 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F1").WithArguments("static", "7.3", "8.0").WithLocation(4, 16), // (4,20): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int F1 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(4, 20), // (4,25): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int F1 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(4, 25), // (5,23): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("static", "7.3", "8.0").WithLocation(5, 23), // (5,23): error CS8703: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("public", "7.3", "8.0").WithLocation(5, 23), // (5,27): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static int F2 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(5, 27), // (5,32): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static int F2 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(5, 32), // (6,25): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("static", "7.3", "8.0").WithLocation(6, 25), // (6,25): error CS8703: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("internal", "7.3", "8.0").WithLocation(6, 25), // (6,29): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static int F3 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(6, 29), // (6,34): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static int F3 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(6, 34), // (7,24): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static int F4 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("static", "7.3", "8.0").WithLocation(7, 24), // (7,24): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static int F4 {get; set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("private", "7.3", "8.0").WithLocation(7, 24), // (7,28): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private static int F4 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(7, 28), // (7,33): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private static int F4 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(7, 33), // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,20): error CS8701: Target runtime doesn't support default interface implementation. // static int F1 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(4, 20), // (4,25): error CS8701: Target runtime doesn't support default interface implementation. // static int F1 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(4, 25), // (5,27): error CS8701: Target runtime doesn't support default interface implementation. // public static int F2 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(5, 27), // (5,32): error CS8701: Target runtime doesn't support default interface implementation. // public static int F2 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(5, 32), // (6,29): error CS8701: Target runtime doesn't support default interface implementation. // internal static int F3 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 29), // (6,34): error CS8701: Target runtime doesn't support default interface implementation. // internal static int F3 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(6, 34), // (7,28): error CS8701: Target runtime doesn't support default interface implementation. // private static int F4 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(7, 28), // (7,33): error CS8701: Target runtime doesn't support default interface implementation. // private static int F4 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(7, 33) ); Validate1(compilation5.SourceModule); } [Fact] public void AutoProperty_03() { var source1 = @" public interface I1 { static int F1 {get;} = 1; public static int F2 {get;} = 2; internal static int F3 {get;} = 3; private static int F4 {get;} = 4; public class TestHelper { public static int F4Proxy { get => I1.F4; } } } class Test1 : I1 { static void Main() { System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}{I1.TestHelper.F4Proxy}""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.True(f1.IsReadOnly); Assert.True(f2.IsReadOnly); Assert.True(f3.IsReadOnly); Assert.True(f4.IsReadOnly); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Equal(MethodKind.StaticConstructor, cctor.MethodKind); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.TestHelper.F4Proxy}""); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "124"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "124"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,16): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static int F1 {get;} = 1; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F1").WithArguments("static", "7.3", "8.0").WithLocation(4, 16), // (4,20): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int F1 {get;} = 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(4, 20), // (5,23): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get;} = 2; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("static", "7.3", "8.0").WithLocation(5, 23), // (5,23): error CS8703: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get;} = 2; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("public", "7.3", "8.0").WithLocation(5, 23), // (5,27): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static int F2 {get;} = 2; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(5, 27), // (6,25): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get;} = 3; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("static", "7.3", "8.0").WithLocation(6, 25), // (6,25): error CS8703: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get;} = 3; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("internal", "7.3", "8.0").WithLocation(6, 25), // (6,29): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static int F3 {get;} = 3; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(6, 29), // (7,24): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static int F4 {get;} = 4; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("static", "7.3", "8.0").WithLocation(7, 24), // (7,24): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static int F4 {get;} = 4; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("private", "7.3", "8.0").WithLocation(7, 24), // (7,28): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // private static int F4 {get;} = 4; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(7, 28), // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,20): error CS8701: Target runtime doesn't support default interface implementation. // static int F1 {get;} = 1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(4, 20), // (5,27): error CS8701: Target runtime doesn't support default interface implementation. // public static int F2 {get;} = 2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(5, 27), // (6,29): error CS8701: Target runtime doesn't support default interface implementation. // internal static int F3 {get;} = 3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 29), // (7,28): error CS8701: Target runtime doesn't support default interface implementation. // private static int F4 {get;} = 4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(7, 28) ); Validate1(compilation5.SourceModule); } [Fact] public void AutoProperty_04() { var source1 = @" public interface I1 { static int F1 {get; private set;} public static int F2 {get; private set;} internal static int F3 {get; private set;} public class TestHelper { public static void F4Proxy(int f1, int f2, int f3) { F1 = f1; F2 = f2; F3 = f3; } } } class Test1 : I1 { static void Main() { I1.TestHelper.F4Proxy(1,2,3); System.Console.WriteLine($""{I1.F1}{I1.F2}{I1.F3}""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f1.SetMethod.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f2.SetMethod.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f3.SetMethod.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Null(cctor); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "123", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1.TestHelper.F4Proxy(11,22,3); System.Console.WriteLine($""{I1.F1}{I1.F2}""); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1122"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1122"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (4,16): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static int F1 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F1").WithArguments("static", "7.3", "8.0").WithLocation(4, 16), // (4,20): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int F1 {get; private set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(4, 20), // (4,33): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static int F1 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("private", "7.3", "8.0").WithLocation(4, 33), // (4,33): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // static int F1 {get; private set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(4, 33), // (5,23): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("static", "7.3", "8.0").WithLocation(5, 23), // (5,23): error CS8703: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("public", "7.3", "8.0").WithLocation(5, 23), // (5,27): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(5, 27), // (5,40): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("private", "7.3", "8.0").WithLocation(5, 40), // (5,40): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(5, 40), // (6,25): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("static", "7.3", "8.0").WithLocation(6, 25), // (6,25): error CS8703: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("internal", "7.3", "8.0").WithLocation(6, 25), // (6,29): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(6, 29), // (6,42): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "set").WithArguments("private", "7.3", "8.0").WithLocation(6, 42), // (6,42): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(6, 42), // (8,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(8, 18) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,20): error CS8701: Target runtime doesn't support default interface implementation. // static int F1 {get; private set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(4, 20), // (4,33): error CS8701: Target runtime doesn't support default interface implementation. // static int F1 {get; private set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(4, 33), // (5,27): error CS8701: Target runtime doesn't support default interface implementation. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(5, 27), // (5,40): error CS8701: Target runtime doesn't support default interface implementation. // public static int F2 {get; private set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(5, 40), // (6,29): error CS8701: Target runtime doesn't support default interface implementation. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(6, 29), // (6,42): error CS8701: Target runtime doesn't support default interface implementation. // internal static int F3 {get; private set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(6, 42) ); Validate1(compilation5.SourceModule); } [Fact] public void FieldLikeEvent_01() { var source1 = @" public interface I1 { private event System.Action F1; private event System.Action F5 = null; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular); compilation1.VerifyEmitDiagnostics( // (4,33): error CS0065: 'I1.F1': event property must have both add and remove accessors // private event System.Action F1; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "F1").WithArguments("I1.F1").WithLocation(4, 33), // (5,33): error CS0068: 'I1.F5': instance event in interface cannot have initializer // private event System.Action F5 = null; Diagnostic(ErrorCode.ERR_InterfaceEventInitializer, "F5").WithArguments("I1.F5").WithLocation(5, 33), // (5,33): error CS0065: 'I1.F5': event property must have both add and remove accessors // private event System.Action F5 = null; Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "F5").WithArguments("I1.F5").WithLocation(5, 33), // (5,33): warning CS0067: The event 'I1.F5' is never used // private event System.Action F5 = null; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "F5").WithArguments("I1.F5").WithLocation(5, 33), // (4,33): warning CS0067: The event 'I1.F1' is never used // private event System.Action F1; Diagnostic(ErrorCode.WRN_UnreferencedEvent, "F1").WithArguments("I1.F1").WithLocation(4, 33) ); } [Fact] public void FieldLikeEvent_02() { var source1 = @" public interface I1 { static event System.Action F1; public static event System.Action F2; internal static event System.Action F3; private static event System.Action F4; public class TestHelper { public static System.Action F4Proxy { set => I1.F4 += value; } public static void Raise() { F1(); F2(); F3?.Invoke(); F4(); } } } class Test1 : I1 { static void Main() { I1.F1 += () => System.Console.Write(1); I1.F2 += () => System.Console.Write(2); I1.F3 += () => System.Console.Write(3); I1.TestHelper.F4Proxy = () => System.Console.Write(4); I1.TestHelper.Raise(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Null(cctor); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1.F1 += () => System.Console.Write(11); I1.F2 += () => System.Console.Write(22); I1.TestHelper.F4Proxy = () => System.Console.Write(44); I1.TestHelper.Raise(); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "112244"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "112244"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18), // (4,32): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static event System.Action F1; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F1").WithArguments("static", "7.3", "8.0").WithLocation(4, 32), // (5,39): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static event System.Action F2; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("static", "7.3", "8.0").WithLocation(5, 39), // (5,39): error CS8503: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static event System.Action F2; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("public", "7.3", "8.0").WithLocation(5, 39), // (6,41): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static event System.Action F3; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("static", "7.3", "8.0").WithLocation(6, 41), // (6,41): error CS8503: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static event System.Action F3; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("internal", "7.3", "8.0").WithLocation(6, 41), // (7,40): error CS8503: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static event System.Action F4; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("static", "7.3", "8.0").WithLocation(7, 40), // (7,40): error CS8503: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static event System.Action F4; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("private", "7.3", "8.0").WithLocation(7, 40) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,32): error CS8701: Target runtime doesn't support default interface implementation. // static event System.Action F1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F1").WithLocation(4, 32), // (5,39): error CS8701: Target runtime doesn't support default interface implementation. // public static event System.Action F2; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F2").WithLocation(5, 39), // (6,41): error CS8701: Target runtime doesn't support default interface implementation. // internal static event System.Action F3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F3").WithLocation(6, 41), // (7,40): error CS8701: Target runtime doesn't support default interface implementation. // private static event System.Action F4; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F4").WithLocation(7, 40) ); Validate1(compilation5.SourceModule); } [Fact] public void FieldLikeEvent_03() { var source1 = @" public interface I1 { static event System.Action F1 = () => System.Console.Write(1); public static event System.Action F2 = () => System.Console.Write(2); internal static event System.Action F3 = () => System.Console.Write(3); private static event System.Action F4 = () => System.Console.Write(4); public class TestHelper { public static void Raise() { F1(); F2(); F3(); F4(); } } } class Test1 : I1 { static void Main() { I1.TestHelper.Raise(); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); void Validate1(ModuleSymbol m) { var i1 = m.GlobalNamespace.GetTypeMember("I1"); var f1 = i1.GetMember("F1"); var f2 = i1.GetMember("F2"); var f3 = i1.GetMember("F3"); var f4 = i1.GetMember("F4"); Assert.True(f1.IsStatic); Assert.True(f2.IsStatic); Assert.True(f3.IsStatic); Assert.True(f4.IsStatic); Assert.Equal(Accessibility.Public, f1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, f2.DeclaredAccessibility); Assert.Equal(Accessibility.Internal, f3.DeclaredAccessibility); Assert.Equal(Accessibility.Private, f4.DeclaredAccessibility); var cctor = i1.GetMember(".cctor"); Assert.Equal(MethodKind.StaticConstructor, cctor.MethodKind); } Validate1(compilation1.SourceModule); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234", symbolValidator: Validate1); var source2 = @" class Test2 : I1 { static void Main() { I1.TestHelper.Raise(); } } "; var compilation2 = CreateCompilation(source2, new[] { compilation1.ToMetadataReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234"); var compilation3 = CreateCompilation(source2, new[] { compilation1.EmitToImageReference() }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "1234"); var compilation4 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics( // (9,18): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public class TestHelper Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "TestHelper").WithArguments("default interface implementation", "8.0").WithLocation(9, 18), // (4,32): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // static event System.Action F1 = () => System.Console.Write(1); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F1").WithArguments("static", "7.3", "8.0").WithLocation(4, 32), // (5,39): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static event System.Action F2 = () => System.Console.Write(2); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("static", "7.3", "8.0").WithLocation(5, 39), // (5,39): error CS8703: The modifier 'public' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // public static event System.Action F2 = () => System.Console.Write(2); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F2").WithArguments("public", "7.3", "8.0").WithLocation(5, 39), // (6,41): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static event System.Action F3 = () => System.Console.Write(3); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("static", "7.3", "8.0").WithLocation(6, 41), // (6,41): error CS8703: The modifier 'internal' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // internal static event System.Action F3 = () => System.Console.Write(3); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F3").WithArguments("internal", "7.3", "8.0").WithLocation(6, 41), // (7,40): error CS8703: The modifier 'static' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static event System.Action F4 = () => System.Console.Write(4); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("static", "7.3", "8.0").WithLocation(7, 40), // (7,40): error CS8703: The modifier 'private' is not valid for this item in C# 7.3. Please use language version '8.0' or greater. // private static event System.Action F4 = () => System.Console.Write(4); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationModifier, "F4").WithArguments("private", "7.3", "8.0").WithLocation(7, 40) ); Validate1(compilation4.SourceModule); var compilation5 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation5.VerifyDiagnostics( // (4,32): error CS8701: Target runtime doesn't support default interface implementation. // static event System.Action F1 = () => System.Console.Write(1); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F1").WithLocation(4, 32), // (5,39): error CS8701: Target runtime doesn't support default interface implementation. // public static event System.Action F2 = () => System.Console.Write(2); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F2").WithLocation(5, 39), // (6,41): error CS8701: Target runtime doesn't support default interface implementation. // internal static event System.Action F3 = () => System.Console.Write(3); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F3").WithLocation(6, 41), // (7,40): error CS8701: Target runtime doesn't support default interface implementation. // private static event System.Action F4 = () => System.Console.Write(4); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "F4").WithLocation(7, 40) ); Validate1(compilation5.SourceModule); } [Fact] public void UnsupportedMemberAccess_01() { var source0 = @" public delegate void D0(); public interface I0 { static readonly int F1 = 1; static int P2 {get {System.Console.WriteLine(""P2""); return 2;} set {System.Console.WriteLine(""set_P2"");}} static void M3() {System.Console.WriteLine(""M3"");} static event D0 E4 { add {System.Console.WriteLine(""add E4"");value();} remove {System.Console.WriteLine(""remove E4"");value();} } class C6 { public static void M() {System.Console.WriteLine(""C6.M"");} } } "; var source1 = @" public delegate void D1(); public interface I1 { int P20 {get {System.Console.WriteLine(""P20""); return 20;}} int this[int P50] {set {System.Console.WriteLine(""P50"");}} void M30() {System.Console.WriteLine(""M30"");} event D1 E40 { add {System.Console.WriteLine(""add E40"");value();} remove {System.Console.WriteLine(""remove E40"");value();} } sealed int P200 {get {System.Console.WriteLine(""P200""); return 200;}} sealed int this[string P500] {set {System.Console.WriteLine(""P500"");}} sealed void M300() {System.Console.WriteLine(""M300"");} sealed event D1 E400 { add {System.Console.WriteLine(""add E400"");value();} remove {System.Console.WriteLine(""remove E400"");value();} } } public class Test1 : I1 { } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source2 = @" class Test2 { static void Main() { System.Console.WriteLine(I0.F1); System.Console.WriteLine(I0.P2); I0.M3(); I0.E4 += I0.M3; I0.E4 -= new D0(I0.M3); I0.P2 = 3; I0.C6.M(); } } "; var source3 = @" class Test3 { static void Main() { I1 i1 = new Test1(); System.Console.WriteLine(i1.P20); i1.M30(); i1.E40 += i1.M30; i1.E40 -= new D1(i1.M30); i1[50] = default; } } "; var source4 = @" class Test4 : Test1 { static void Main() { I1 i1 = new Test1(); System.Console.WriteLine(i1.P200); i1.M300(); i1.E400 += i1.M300; i1.E400 -= new D1(i1.M300); i1[""500""] = default; } } "; foreach (var refs in new[] { (comp0:compilation0.ToMetadataReference(), comp1:compilation1.ToMetadataReference()), (comp0:compilation0.EmitToImageReference(), comp1:compilation1.EmitToImageReference()) }) { var compilation2 = CreateCompilation(source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.StandardLatest); compilation2 = compilation2.AddReferences(refs.comp0); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"1 P2 2 M3 add E4 M3 remove E4 M3 set_P2 C6.M "); var compilation3 = CreateCompilation(source3, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.StandardLatest); compilation3 = compilation3.AddReferences(refs.comp1); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"P20 20 M30 add E40 M30 remove E40 M30 P50 "); var compilation4 = CreateCompilation(source4, options: TestOptions.DebugExe, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); compilation4 = compilation4.AddReferences(refs.comp1); Assert.False(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics( // (7,34): error CS8501: Target runtime doesn't support default interface implementation. // System.Console.WriteLine(i1.P200); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.P200").WithLocation(7, 34), // (8,9): error CS8501: Target runtime doesn't support default interface implementation. // i1.M300(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.M300").WithLocation(8, 9), // (9,9): error CS8501: Target runtime doesn't support default interface implementation. // i1.E400 += i1.M300; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.E400 += i1.M300").WithLocation(9, 9), // (9,20): error CS8501: Target runtime doesn't support default interface implementation. // i1.E400 += i1.M300; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.M300").WithLocation(9, 20), // (10,9): error CS8501: Target runtime doesn't support default interface implementation. // i1.E400 -= new D1(i1.M300); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.E400 -= new D1(i1.M300)").WithLocation(10, 9), // (10,27): error CS8501: Target runtime doesn't support default interface implementation. // i1.E400 -= new D1(i1.M300); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.M300").WithLocation(10, 27), // (11,9): error CS8701: Target runtime doesn't support default interface implementation. // i1["500"] = default; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, @"i1[""500""]").WithLocation(11, 9) ); } } [Fact] public void UnsupportedMemberAccess_02() { var source0 = @" public delegate void D0(); public interface I0 { static protected readonly int F1 = 1; static protected internal int P2 {get {System.Console.WriteLine(""P2""); return 2;} set {System.Console.WriteLine(""set_P2"");}} static protected void M3() {System.Console.WriteLine(""M3"");} static protected internal event D0 E4 { add {System.Console.WriteLine(""add E4"");value();} remove {System.Console.WriteLine(""remove E4"");value();} } protected internal class C6 { public static void M() {System.Console.WriteLine(""C6.M"");} } protected class C7 { } static int P8 {protected internal get {System.Console.WriteLine(""P8""); return 8;} set {System.Console.WriteLine(""set_P8"");}} static int P9 {get {System.Console.WriteLine(""P9""); return 9;} protected set {System.Console.WriteLine(""set_P9"");}} } public class Test1 : I0 { } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); var source2 = @" using static I0; class Test2 : Test1 { static void Main() { System.Console.WriteLine(I0.F1); System.Console.WriteLine(I0.P2); I0.M3(); I0.E4 += I0.M3; I0.E4 -= new D0(I0.M3); I0.P2 = 3; I0.C6.M(); _ = new C7(); _ = I0.P8; _ = I0.P9; I0.P8 = 12; I0.P9 = 13; } } "; foreach (var reference in new[] { compilation0.ToMetadataReference(), compilation0.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.DesktopLatestExtended, references: new[] { reference }, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics( // (9,34): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // System.Console.WriteLine(I0.F1); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.F1").WithLocation(9, 34), // (10,34): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // System.Console.WriteLine(I0.P2); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.P2").WithLocation(10, 34), // (11,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.M3(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.M3").WithLocation(11, 9), // (12,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.E4 += I0.M3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.E4 += I0.M3").WithLocation(12, 9), // (12,18): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.E4 += I0.M3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.M3").WithLocation(12, 18), // (13,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.E4 -= new D0(I0.M3); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.E4 -= new D0(I0.M3)").WithLocation(13, 9), // (13,25): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.E4 -= new D0(I0.M3); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.M3").WithLocation(13, 25), // (14,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.P2 = 3; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.P2").WithLocation(14, 9), // (15,12): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.C6.M(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "C6").WithLocation(15, 12), // (16,17): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // _ = new C7(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "C7").WithLocation(16, 17), // (17,13): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // _ = I0.P8; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.P8").WithLocation(17, 13), // (20,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // I0.P9 = 13; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I0.P9").WithLocation(20, 9) ); } } [Fact] public void UnsupportedMemberAccess_03() { var source1 = @" public delegate void D1(); public interface I1 { protected int P20 {get {System.Console.WriteLine(""P20""); return 20;}} protected internal int this[int P50] {set {System.Console.WriteLine(""P50"");}} protected void M30() {System.Console.WriteLine(""M30"");} protected internal event D1 E40 { add {System.Console.WriteLine(""add E40"");value();} remove {System.Console.WriteLine(""remove E40"");value();} } int P50 {protected get {System.Console.WriteLine(""P50""); return 50;} set {}} int P60 {get {System.Console.WriteLine(""P60""); return 60;} protected internal set {}} protected internal sealed int P200 {get {System.Console.WriteLine(""P200""); return 200;}} protected sealed int this[string P500] {set {System.Console.WriteLine(""P500"");}} protected internal sealed void M300() {System.Console.WriteLine(""M300"");} protected sealed event D1 E400 { add {System.Console.WriteLine(""add E400"");value();} remove {System.Console.WriteLine(""remove E400"");value();} } sealed int P500 {protected get {System.Console.WriteLine(""P500""); return 500;} set {}} sealed int P600 {get {System.Console.WriteLine(""P600""); return 600;} protected internal set {}} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source3 = @" interface Test3 : I1 { static void Main() { Test3 i1 = null; System.Console.WriteLine(i1.P20); i1.M30(); i1.E40 += i1.M30; i1.E40 -= new D1(i1.M30); i1[50] = default; _ = i1.P50; _ = i1.P60; i1.P50 = 12; i1.P60 = 13; } } "; var source4 = @" interface Test4 : I1 { static void Main() { Test4 i1 = null; System.Console.WriteLine(i1.P200); i1.M300(); i1.E400 += i1.M300; i1.E400 -= new D1(i1.M300); i1[""500""] = default; _ = i1.P500; _ = i1.P600; i1.P500 = 12; i1.P600 = 13; } } "; foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation3 = CreateCompilation(source3, options: TestOptions.DebugExe, targetFramework: TargetFramework.DesktopLatestExtended, references: new[] { reference }, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics( // (4,17): error CS8701: Target runtime doesn't support default interface implementation. // static void Main() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "Main").WithLocation(4, 17), // (7,34): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // System.Console.WriteLine(i1.P20); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.P20").WithLocation(7, 34), // (8,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1.M30(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.M30").WithLocation(8, 9), // (9,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1.E40 += i1.M30; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.E40 += i1.M30").WithLocation(9, 9), // (9,19): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1.E40 += i1.M30; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.M30").WithLocation(9, 19), // (10,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1.E40 -= new D1(i1.M30); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.E40 -= new D1(i1.M30)").WithLocation(10, 9), // (10,26): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1.E40 -= new D1(i1.M30); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.M30").WithLocation(10, 26), // (11,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1[50] = default; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1[50]").WithLocation(11, 9), // (12,13): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // _ = i1.P50; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.P50").WithLocation(12, 13), // (15,9): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // i1.P60 = 13; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "i1.P60").WithLocation(15, 9) ); var compilation4 = CreateCompilation(source4, options: TestOptions.DebugExe, targetFramework: TargetFramework.DesktopLatestExtended, references: new[] { reference }, parseOptions: TestOptions.Regular); Assert.False(compilation4.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation4.VerifyDiagnostics( // (4,17): error CS8701: Target runtime doesn't support default interface implementation. // static void Main() Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "Main").WithLocation(4, 17), // (7,34): error CS8701: Target runtime doesn't support default interface implementation. // System.Console.WriteLine(i1.P200); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.P200").WithLocation(7, 34), // (8,9): error CS8701: Target runtime doesn't support default interface implementation. // i1.M300(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.M300").WithLocation(8, 9), // (9,9): error CS8701: Target runtime doesn't support default interface implementation. // i1.E400 += i1.M300; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.E400 += i1.M300").WithLocation(9, 9), // (9,20): error CS8701: Target runtime doesn't support default interface implementation. // i1.E400 += i1.M300; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.M300").WithLocation(9, 20), // (10,9): error CS8701: Target runtime doesn't support default interface implementation. // i1.E400 -= new D1(i1.M300); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.E400 -= new D1(i1.M300)").WithLocation(10, 9), // (10,27): error CS8701: Target runtime doesn't support default interface implementation. // i1.E400 -= new D1(i1.M300); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.M300").WithLocation(10, 27), // (11,9): error CS8701: Target runtime doesn't support default interface implementation. // i1["500"] = default; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, @"i1[""500""]").WithLocation(11, 9), // (12,13): error CS8701: Target runtime doesn't support default interface implementation. // _ = i1.P500; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.P500").WithLocation(12, 13), // (13,13): error CS8701: Target runtime doesn't support default interface implementation. // _ = i1.P600; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.P600").WithLocation(13, 13), // (14,9): error CS8701: Target runtime doesn't support default interface implementation. // i1.P500 = 12; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.P500").WithLocation(14, 9), // (15,9): error CS8701: Target runtime doesn't support default interface implementation. // i1.P600 = 13; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "i1.P600").WithLocation(15, 9) ); } } [Fact] public void UnsupportedMemberAccess_04() { var source1 = @" public interface I1 { protected interface I2 {} protected internal interface I3 {} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); compilation1.VerifyDiagnostics(); var source3 = @" interface Test3 : I1 { class C { static void M1(I1.I2 x) { System.Console.WriteLine(""M1""); } static void M2(I1.I3 x) { System.Console.WriteLine(""M2""); } static void Main() { M1(null); M2(null); } } } "; var source4 = @" class Test4 : I1 { interface Test5 : I1.I2 { } interface Test6 : I1.I3 { } } "; foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation3 = CreateCompilation(source3, options: TestOptions.DebugExe, targetFramework: TargetFramework.DesktopLatestExtended, references: new[] { reference }, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics( // (6,27): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // static void M1(I1.I2 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I2").WithLocation(6, 27), // (11,27): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // static void M2(I1.I3 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I3").WithLocation(11, 27) ); var compilation4 = CreateCompilation(source4, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, references: new[] { reference }, parseOptions: TestOptions.Regular); compilation4.VerifyDiagnostics( // (4,26): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // interface Test5 : I1.I2 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I2").WithLocation(4, 26), // (8,26): error CS8707: Target runtime doesn't support 'protected', 'protected internal', or 'private protected' accessibility for a member of an interface. // interface Test6 : I1.I3 Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportProtectedAccessForInterfaceMember, "I3").WithLocation(8, 26) ); } } [Fact] public void EntryPoint_01() { var source1 = @" public interface I1 { static void Main() { System.Console.WriteLine(""I1.Main""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "I1.Main"); } [Fact] public void EntryPoint_02() { var source1 = @" public interface I1 { static void Main() { System.Console.WriteLine(""I1.Main""); } } public interface I2 { static void Main() { System.Console.WriteLine(""I2.Main""); } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugExe.WithMainTypeName("I2"), parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : "I2.Main"); } [Fact] public void Operators_01() { var source1 = @" public interface I1 { public static I1 operator +(I1 x) { System.Console.WriteLine(""+""); return x; } public static I1 operator -(I1 x) { System.Console.WriteLine(""-""); return x; } public static I1 operator !(I1 x) { System.Console.WriteLine(""!""); return x; } public static I1 operator ~(I1 x) { System.Console.WriteLine(""~""); return x; } public static I1 operator ++(I1 x) { System.Console.WriteLine(""++""); return x; } public static I1 operator --(I1 x) { System.Console.WriteLine(""--""); return x; } public static bool operator true(I1 x) { System.Console.WriteLine(""true""); return true; } public static bool operator false(I1 x) { System.Console.WriteLine(""false""); return false; } public static I1 operator +(I1 x, I1 y) { System.Console.WriteLine(""+2""); return x; } public static I1 operator -(I1 x, I1 y) { System.Console.WriteLine(""-2""); return x; } public static I1 operator *(I1 x, I1 y) { System.Console.WriteLine(""*""); return x; } public static I1 operator /(I1 x, I1 y) { System.Console.WriteLine(""/""); return x; } public static I1 operator %(I1 x, I1 y) { System.Console.WriteLine(""%""); return x; } public static I1 operator &(I1 x, I1 y) { System.Console.WriteLine(""&""); return x; } public static I1 operator |(I1 x, I1 y) { System.Console.WriteLine(""|""); return x; } public static I1 operator ^(I1 x, I1 y) { System.Console.WriteLine(""^""); return x; } public static I1 operator <<(I1 x, int y) { System.Console.WriteLine(""<<""); return x; } public static I1 operator >>(I1 x, int y) { System.Console.WriteLine("">>""); return x; } public static I1 operator >(I1 x, I1 y) { System.Console.WriteLine("">""); return x; } public static I1 operator <(I1 x, I1 y) { System.Console.WriteLine(""<""); return x; } public static I1 operator >=(I1 x, I1 y) { System.Console.WriteLine("">=""); return x; } public static I1 operator <=(I1 x, I1 y) { System.Console.WriteLine(""<=""); return x; } } "; var source2 = @" class Test2 : I1 { static void Main() { I1 x = new Test2(); I1 y = new Test2(); x = +x; x = -x; x = !x; x = ~x; x = ++x; x = x--; x = x + y; x = x - y; x = x * y; x = x / y; x = x % y; if (x && y) { } x = x | y; x = x ^ y; x = x << 1; x = x >> 2; x = x > y; x = x < y; x = x >= y; x = x <= y; } } "; var expectedOutput = @" + - ! ~ ++ -- +2 -2 * / % false & true | ^ << >> > < >= <= "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr); var compilation6 = CreateCompilation(source1 + source2, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular7_3); compilation6.VerifyDiagnostics( // (4,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator +(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "+").WithArguments("default interface implementation", "8.0").WithLocation(4, 31), // (10,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator -(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "-").WithArguments("default interface implementation", "8.0").WithLocation(10, 31), // (16,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator !(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "!").WithArguments("default interface implementation", "8.0").WithLocation(16, 31), // (22,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator ~(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "~").WithArguments("default interface implementation", "8.0").WithLocation(22, 31), // (28,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator ++(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "++").WithArguments("default interface implementation", "8.0").WithLocation(28, 31), // (34,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator --(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "--").WithArguments("default interface implementation", "8.0").WithLocation(34, 31), // (40,33): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static bool operator true(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "true").WithArguments("default interface implementation", "8.0").WithLocation(40, 33), // (46,33): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static bool operator false(I1 x) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "false").WithArguments("default interface implementation", "8.0").WithLocation(46, 33), // (52,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator +(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "+").WithArguments("default interface implementation", "8.0").WithLocation(52, 31), // (58,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator -(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "-").WithArguments("default interface implementation", "8.0").WithLocation(58, 31), // (64,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator *(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "*").WithArguments("default interface implementation", "8.0").WithLocation(64, 31), // (70,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator /(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "/").WithArguments("default interface implementation", "8.0").WithLocation(70, 31), // (76,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator %(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "%").WithArguments("default interface implementation", "8.0").WithLocation(76, 31), // (82,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator &(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "&").WithArguments("default interface implementation", "8.0").WithLocation(82, 31), // (88,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator |(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "|").WithArguments("default interface implementation", "8.0").WithLocation(88, 31), // (94,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator ^(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "^").WithArguments("default interface implementation", "8.0").WithLocation(94, 31), // (100,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator <<(I1 x, int y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "<<").WithArguments("default interface implementation", "8.0").WithLocation(100, 31), // (106,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator >>(I1 x, int y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, ">>").WithArguments("default interface implementation", "8.0").WithLocation(106, 31), // (112,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator >(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, ">").WithArguments("default interface implementation", "8.0").WithLocation(112, 31), // (118,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator <(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "<").WithArguments("default interface implementation", "8.0").WithLocation(118, 31), // (124,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator >=(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, ">=").WithArguments("default interface implementation", "8.0").WithLocation(124, 31), // (130,31): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // public static I1 operator <=(I1 x, I1 y) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "<=").WithArguments("default interface implementation", "8.0").WithLocation(130, 31) ); var compilation61 = CreateCompilation(source1 + source2, options: TestOptions.DebugDll, targetFramework: TargetFramework.DesktopLatestExtended, parseOptions: TestOptions.Regular); compilation61.VerifyDiagnostics( // (4,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator +(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "+").WithLocation(4, 31), // (10,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator -(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "-").WithLocation(10, 31), // (16,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator !(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "!").WithLocation(16, 31), // (22,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator ~(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "~").WithLocation(22, 31), // (28,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator ++(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "++").WithLocation(28, 31), // (34,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator --(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "--").WithLocation(34, 31), // (40,33): error CS8701: Target runtime doesn't support default interface implementation. // public static bool operator true(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "true").WithLocation(40, 33), // (46,33): error CS8701: Target runtime doesn't support default interface implementation. // public static bool operator false(I1 x) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "false").WithLocation(46, 33), // (52,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator +(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "+").WithLocation(52, 31), // (58,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator -(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "-").WithLocation(58, 31), // (64,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator *(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "*").WithLocation(64, 31), // (70,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator /(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "/").WithLocation(70, 31), // (76,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator %(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "%").WithLocation(76, 31), // (82,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator &(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "&").WithLocation(82, 31), // (88,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator |(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "|").WithLocation(88, 31), // (94,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator ^(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "^").WithLocation(94, 31), // (100,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator <<(I1 x, int y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "<<").WithLocation(100, 31), // (106,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator >>(I1 x, int y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, ">>").WithLocation(106, 31), // (112,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator >(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, ">").WithLocation(112, 31), // (118,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator <(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "<").WithLocation(118, 31), // (124,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator >=(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, ">=").WithLocation(124, 31), // (130,31): error CS8701: Target runtime doesn't support default interface implementation. // public static I1 operator <=(I1 x, I1 y) Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "<=").WithLocation(130, 31) ); var compilation7 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular7_3); var expected7 = new DiagnosticDescription[] { // (9,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = +x; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "+x").WithArguments("default interface implementation", "8.0").WithLocation(9, 13), // (10,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = -x; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "-x").WithArguments("default interface implementation", "8.0").WithLocation(10, 13), // (11,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = !x; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "!x").WithArguments("default interface implementation", "8.0").WithLocation(11, 13), // (12,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = ~x; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "~x").WithArguments("default interface implementation", "8.0").WithLocation(12, 13), // (13,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = ++x; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "++x").WithArguments("default interface implementation", "8.0").WithLocation(13, 13), // (14,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x--; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x--").WithArguments("default interface implementation", "8.0").WithLocation(14, 13), // (16,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x + y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x + y").WithArguments("default interface implementation", "8.0").WithLocation(16, 13), // (17,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x - y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x - y").WithArguments("default interface implementation", "8.0").WithLocation(17, 13), // (18,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x * y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x * y").WithArguments("default interface implementation", "8.0").WithLocation(18, 13), // (19,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x / y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x / y").WithArguments("default interface implementation", "8.0").WithLocation(19, 13), // (20,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x % y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x % y").WithArguments("default interface implementation", "8.0").WithLocation(20, 13), // (21,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // if (x && y) { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x && y").WithArguments("default interface implementation", "8.0").WithLocation(21, 13), // (21,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // if (x && y) { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x && y").WithArguments("default interface implementation", "8.0").WithLocation(21, 13), // (22,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x | y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x | y").WithArguments("default interface implementation", "8.0").WithLocation(22, 13), // (23,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x ^ y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x ^ y").WithArguments("default interface implementation", "8.0").WithLocation(23, 13), // (24,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x << 1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x << 1").WithArguments("default interface implementation", "8.0").WithLocation(24, 13), // (25,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x >> 2; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x >> 2").WithArguments("default interface implementation", "8.0").WithLocation(25, 13), // (26,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x > y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x > y").WithArguments("default interface implementation", "8.0").WithLocation(26, 13), // (27,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x < y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x < y").WithArguments("default interface implementation", "8.0").WithLocation(27, 13), // (28,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x >= y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x >= y").WithArguments("default interface implementation", "8.0").WithLocation(28, 13), // (29,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x <= y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x <= y").WithArguments("default interface implementation", "8.0").WithLocation(29, 13) }; compilation7.VerifyDiagnostics(expected7); var compilation8 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular7_3); compilation8.VerifyDiagnostics(expected7); var source3 = @" class Test3 : I1 { static void Main() { I1 x = new Test3(); I1 y = new Test3(); if (x) { } x = x & y; } } "; var compilation9 = CreateCompilation(source3, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3); var expected9 = new DiagnosticDescription[] { // (8,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // if (x) { } Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x").WithArguments("default interface implementation", "8.0").WithLocation(8, 13), // (9,13): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // x = x & y; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "x & y").WithArguments("default interface implementation", "8.0").WithLocation(9, 13) }; compilation9.VerifyDiagnostics(expected9); var compilation10 = CreateCompilation(source3, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3); compilation10.VerifyDiagnostics(expected9); } [Fact] public void Operators_02() { var source1 = @" public class C1 { public static int operator +(C1 x, I1 y) { System.Console.WriteLine(""C1.+""); return 0; } public static int operator -(I1 x, C1 y) { System.Console.WriteLine(""C1.-""); return 0; } } public class C2 : C1 {} class Test : I1 { static void Main() { I1 x = new Test(); C2 y = new C2(); var r = y + x; r = x - y; } } "; var source2 = @" public interface I1 { } "; var source3 = @" public interface I1 { public static int operator +(C2 x, I1 y) { System.Console.WriteLine(""I1.+""); return 0; } public static int operator -(I1 x, C2 y) { System.Console.WriteLine(""I1.-""); return 0; } } "; var expectedOutput = @" C1.+ C1.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr); var compilation2 = CreateCompilation(source1 + source3, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput, verify: VerifyOnMonoOrCoreClr); } [Fact] public void Operators_03() { var source1 = @" public interface I1 { public static I1 operator ==(I1 x, I1 y) { System.Console.WriteLine(""==""); return x; } public static I1 operator !=(I1 x, I1 y) { System.Console.WriteLine(""!=""); return x; } } "; var source2 = @" class Test2 : I1 { static void Main() { I1 x = new Test2(); I1 y = new Test2(); x = x == y; x = x != y; } } "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (4,31): error CS0567: Interfaces cannot contain conversion, equality, or inequality operators // public static I1 operator ==(I1 x, I1 y) Diagnostic(ErrorCode.ERR_InterfacesCantContainConversionOrEqualityOperators, "==").WithLocation(4, 31), // (10,31): error CS0567: Interfaces cannot contain conversion, equality, or inequality operators // public static I1 operator !=(I1 x, I1 y) Diagnostic(ErrorCode.ERR_InterfacesCantContainConversionOrEqualityOperators, "!=").WithLocation(10, 31), // (24,13): error CS0029: Cannot implicitly convert type 'bool' to 'I1' // x = x == y; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x == y").WithArguments("bool", "I1").WithLocation(24, 13), // (25,13): error CS0029: Cannot implicitly convert type 'bool' to 'I1' // x = x != y; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x != y").WithArguments("bool", "I1").WithLocation(25, 13) ); CompilationReference compilationReference = compilation1.ToMetadataReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (9,13): error CS0029: Cannot implicitly convert type 'bool' to 'I1' // x = x == y; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x == y").WithArguments("bool", "I1").WithLocation(9, 13), // (10,13): error CS0029: Cannot implicitly convert type 'bool' to 'I1' // x = x != y; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x != y").WithArguments("bool", "I1").WithLocation(10, 13) ); var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig specialname static class I1 op_Equality(class I1 x, class I1 y) cil managed { // Code size 18 (0x12) .maxstack 1 .locals init (class I1 V_0) IL_0000: nop IL_0001: ldstr ""=="" IL_0006: call void [mscorlib]System.Console::WriteLine(string) IL_000b: nop IL_000c: ldarg.0 IL_000d: stloc.0 IL_000e: br.s IL_0010 IL_0010: ldloc.0 IL_0011: ret } // end of method I1::op_Equality .method public hidebysig specialname static class I1 op_Inequality(class I1 x, class I1 y) cil managed { // Code size 18 (0x12) .maxstack 1 .locals init (class I1 V_0) IL_0000: nop IL_0001: ldstr ""!="" IL_0006: call void [mscorlib]System.Console::WriteLine(string) IL_000b: nop IL_000c: ldarg.0 IL_000d: stloc.0 IL_000e: br.s IL_0010 IL_0010: ldloc.0 IL_0011: ret } // end of method I1::op_Inequality } // end of class I1 "; var compilation3 = CreateCompilationWithIL(source2, ilSource, options: TestOptions.DebugExe); compilation3.VerifyDiagnostics( // (9,13): error CS0029: Cannot implicitly convert type 'bool' to 'I1' // x = x == y; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x == y").WithArguments("bool", "I1").WithLocation(9, 13), // (10,13): error CS0029: Cannot implicitly convert type 'bool' to 'I1' // x = x != y; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x != y").WithArguments("bool", "I1").WithLocation(10, 13) ); var source3 = @" class Test2 : I1 { static void Main() { I1 x = new Test2(); I1 y = new Test2(); System.Console.WriteLine(x == y); System.Console.WriteLine(x != y); } } "; var compilation4 = CreateCompilationWithIL(source3, ilSource, options: TestOptions.DebugExe); compilation4.VerifyDiagnostics(); CompileAndVerify(compilation4, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @" False True "); } [Fact] public void Operators_04() { var source1 = @" public interface I1 { public static implicit operator int(I1 x) { return 0; } public static explicit operator byte(I1 x) { return 0; } public static void Test(I1 x) { int y = x; y = (int)x; var z = (byte)x; z = x; } } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics( // (4,37): error CS0567: Interfaces cannot contain conversion, equality, or inequality operators // public static implicit operator int(I1 x) Diagnostic(ErrorCode.ERR_InterfacesCantContainConversionOrEqualityOperators, "int").WithLocation(4, 37), // (8,37): error CS0567: Interfaces cannot contain conversion, equality, or inequality operators // public static explicit operator byte(I1 x) Diagnostic(ErrorCode.ERR_InterfacesCantContainConversionOrEqualityOperators, "byte").WithLocation(8, 37), // (15,17): error CS0029: Cannot implicitly convert type 'I1' to 'int' // int y = x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("I1", "int").WithLocation(15, 17), // (16,13): error CS0030: Cannot convert type 'I1' to 'int' // y = (int)x; Diagnostic(ErrorCode.ERR_NoExplicitConv, "(int)x").WithArguments("I1", "int").WithLocation(16, 13), // (17,17): error CS0030: Cannot convert type 'I1' to 'byte' // var z = (byte)x; Diagnostic(ErrorCode.ERR_NoExplicitConv, "(byte)x").WithArguments("I1", "byte").WithLocation(17, 17), // (18,13): error CS0029: Cannot implicitly convert type 'I1' to 'byte' // z = x; Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("I1", "byte").WithLocation(18, 13) ); } [Fact] public void Operators_05() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""-""); return x; } } public interface I2 : I1 {} "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); I1 y = -x; } } "; var expectedOutput = @" - "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest, parseOptions: TestOptions.Regular); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var source3 = @" class Test2 : I2 { static void Main() { Test2 x = new Test2(); I1 y = -x; } } "; var compilation9 = CreateCompilation(source3, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); var expected9 = new DiagnosticDescription[] { // (8,16): error CS0023: Operator '-' cannot be applied to operand of type 'Test2' // I1 y = -x; Diagnostic(ErrorCode.ERR_BadUnaryOp, "-x").WithArguments("-", "Test2").WithLocation(8, 16) }; compilation9.VerifyDiagnostics(expected9); var compilation10 = CreateCompilation(source3, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation10.VerifyDiagnostics(expected9); } [Fact] public void Operators_06() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""I1.-""); return x; } } public interface I2 : I1 { public static I2 operator -(I2 x) { System.Console.WriteLine(""I2.-""); return x; } } "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); var y = -x; } } "; var expectedOutput = @" I2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_07() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""I1.-""); return x; } } public interface I3 { public static I3 operator -(I3 x) { System.Console.WriteLine(""I3.-""); return x; } } public interface I4 : I1, I3 { public static I4 operator -(I4 x) { System.Console.WriteLine(""I4.-""); return x; } } public interface I2 : I4 { } "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); var y = -x; } } "; var expectedOutput = @" I4.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_08() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""I1.-""); return x; } } public interface I3 { public static I3 operator -(I3 x) { System.Console.WriteLine(""I3.-""); return x; } } public interface I4 : I1, I3 { } public interface I2 : I4 { } "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); var y = -x; } } "; var expected = new DiagnosticDescription[] { // (7,17): error CS0035: Operator '-' is ambiguous on an operand of type 'I2' // var y = -x; Diagnostic(ErrorCode.ERR_AmbigUnaryOp, "-x").WithArguments("-", "I2").WithLocation(7, 17) }; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(expected); CompilationReference compilationReference = compilation1.ToMetadataReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); } [Fact] public void Operators_09() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""I1.-""); return x; } } "; var source2 = @" class Test1 : Test2, I1 {} class Test2 { static void Main() { Test(new Test1()); } static void Test(T x) where T : Test2, I1 { var y = -x; } public static Test2 operator -(Test2 x) { System.Console.WriteLine(""Test2.-""); return x; } } "; var expectedOutput = @" Test2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_10() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""I1.-""); return x; } } public interface I3 { public static I3 operator -(I3 x) { System.Console.WriteLine(""I3.-""); return x; } } public interface I4 : I1, I3 { public static I4 operator -(I4 x) { System.Console.WriteLine(""I4.-""); return x; } } public interface I2 : I4 { }"; var source2 = @" class Test1 : Test2, I2 {} class Test2 { static void Main() { Test(new Test1()); } static void Test(T x) where T : Test2, I2 { var y = -x; } } "; var expectedOutput = @" I4.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_11() { var source0 = @" public interface I1 { } public interface I2 { } "; var source1 = @" public class C1 { public static C1 operator +(C1 x, I2 y) { System.Console.WriteLine(""C1.+1""); return x; } public static C1 operator +(C1 x, I1 y) { System.Console.WriteLine(""C1.+2""); return x; } } "; var source2 = @" public interface I3 : I1, I2 { } "; var source3 = @" class Test2 : I3 { static void Main() { I3 x = new Test2(); var y = new C1() + x; } } "; var expected = new DiagnosticDescription[] { // (7,17): error CS0034: Operator '+' is ambiguous on operands of type 'C1' and 'I3' // var y = new C1() + x; Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "new C1() + x").WithArguments("+", "C1", "I3").WithLocation(7, 17) }; var compilation0 = CreateCompilation(source0 + source1 + source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompilationReference compilationReference0 = compilation0.ToMetadataReference(); MetadataReference metadataReference0 = compilation0.EmitToImageReference(); var compilation1 = CreateCompilation(source3, new[] { compilationReference0 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source3, new[] { metadataReference0 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); var source4 = @" public interface I1 { public static C1 operator +(C1 x, I1 y) { System.Console.WriteLine(""I1.+""); return x; } } public interface I2 { } "; var compilation3 = CreateCompilation(source4 + source1 + source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompilationReference compilationReference3 = compilation3.ToMetadataReference(); MetadataReference metadataReference3 = compilation3.EmitToImageReference(); var compilation4 = CreateCompilation(source3, new[] { compilationReference3 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics(expected); var compilation5 = CreateCompilation(source3, new[] { metadataReference3 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics(expected); var source5 = @" public interface I3 : I1, I2 { public static C1 operator +(C1 x, I3 y) { System.Console.WriteLine(""I3.+""); return x; } } "; var compilation6 = CreateCompilation(source4 + source1 + source5, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation6.VerifyDiagnostics(); CompilationReference compilationReference6 = compilation6.ToMetadataReference(); MetadataReference metadataReference6 = compilation6.EmitToImageReference(); var compilation7 = CreateCompilation(source3, new[] { compilationReference6 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation7.VerifyDiagnostics(expected); var compilation8 = CreateCompilation(source3, new[] { metadataReference6 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation8.VerifyDiagnostics(expected); } [Fact] public void Operators_12() { var source0 = @" public interface I1 { } public interface I2 { } "; var source1 = @" public class C1 { public static C1 operator +(I2 x, C1 y) { System.Console.WriteLine(""C1.+1""); return y; } public static C1 operator +(I1 x, C1 y) { System.Console.WriteLine(""C1.+2""); return y; } } "; var source2 = @" public interface I3 : I1, I2 { } "; var source3 = @" class Test2 : I3 { static void Main() { I3 x = new Test2(); var y = x + new C1(); } } "; var expected = new DiagnosticDescription[] { // (7,17): error CS0034: Operator '+' is ambiguous on operands of type 'I3' and 'C1' // var y = x + new C1(); Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "x + new C1()").WithArguments("+", "I3", "C1").WithLocation(7, 17) }; var compilation0 = CreateCompilation(source0 + source1 + source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompilationReference compilationReference0 = compilation0.ToMetadataReference(); MetadataReference metadataReference0 = compilation0.EmitToImageReference(); var compilation1 = CreateCompilation(source3, new[] { compilationReference0 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source3, new[] { metadataReference0 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); var source4 = @" public interface I1 { public static C1 operator +(I1 x, C1 y) { System.Console.WriteLine(""I1.+""); return y; } } public interface I2 { } "; var compilation3 = CreateCompilation(source4 + source1 + source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompilationReference compilationReference3 = compilation3.ToMetadataReference(); MetadataReference metadataReference3 = compilation3.EmitToImageReference(); var compilation4 = CreateCompilation(source3, new[] { compilationReference3 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation4.VerifyDiagnostics(expected); var compilation5 = CreateCompilation(source3, new[] { metadataReference3 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation5.VerifyDiagnostics(expected); var source5 = @" public interface I3 : I1, I2 { public static C1 operator +(I3 x, C1 y) { System.Console.WriteLine(""I3.+""); return y; } } "; var compilation6 = CreateCompilation(source4 + source1 + source5, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation6.VerifyDiagnostics(); CompilationReference compilationReference6 = compilation6.ToMetadataReference(); MetadataReference metadataReference6 = compilation6.EmitToImageReference(); var compilation7 = CreateCompilation(source3, new[] { compilationReference6 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation7.VerifyDiagnostics(expected); var compilation8 = CreateCompilation(source3, new[] { metadataReference6 }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation8.VerifyDiagnostics(expected); } [Fact] public void Operators_13() { var source1 = @" public interface I1 { public static int operator +(I1 x, I2 y) { System.Console.WriteLine(""I1.+""); return 1; } } public interface I2 { public static int operator +(I1 x, I2 y) { System.Console.WriteLine(""I2.+""); return 2; } } "; var source2 = @" class Test2: I1, I2 { static void Main() { I1 x = new Test2(); I2 y = new Test2(); var z = x + y; z = y + x; } } "; var expected = new DiagnosticDescription[] { // (8,17): error CS0034: Operator '+' is ambiguous on operands of type 'I1' and 'I2' // var z = x + y; Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "x + y").WithArguments("+", "I1", "I2").WithLocation(8, 17), // (9,13): error CS0019: Operator '+' cannot be applied to operands of type 'I2' and 'I1' // z = y + x; Diagnostic(ErrorCode.ERR_BadBinaryOps, "y + x").WithArguments("+", "I2", "I1").WithLocation(9, 13) }; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(expected); } [Fact] public void Operators_14() { var source1 = @" public interface I1 { public static int operator +(I2 x, I1 y) { System.Console.WriteLine(""I1.+""); return 1; } } public interface I2 : I1 { public static int operator +(I2 x, I1 y) { System.Console.WriteLine(""I2.+""); return 2; } } "; var source2 = @" class Test2 : I2 { static void Main() { I1 x = new Test2(); I2 y = new Test2(); var z = y + x; z = x + y; } } "; var expected = new DiagnosticDescription[] { // (8,17): error CS0034: Operator '+' is ambiguous on operands of type 'I2' and 'I1' // var z = y + x; Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "y + x").WithArguments("+", "I2", "I1").WithLocation(8, 17), // (9,13): error CS0019: Operator '+' cannot be applied to operands of type 'I1' and 'I2' // z = x + y; Diagnostic(ErrorCode.ERR_BadBinaryOps, "x + y").WithArguments("+", "I1", "I2").WithLocation(9, 13) }; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(expected); } [Fact] public void Operators_15() { var source1 = @" public class I1 { public static int operator +(I1 x, C2 y) { System.Console.WriteLine(""I1.+1""); return 1; } public static int operator +(C2 x, I1 y) { System.Console.WriteLine(""I1.+2""); return 1; } } public class I2 : I1 { public static int operator +(I2 x, C1 y) { System.Console.WriteLine(""I2.+1""); return 1; } public static int operator +(C1 x, I2 y) { System.Console.WriteLine(""I2.+2""); return 1; } } public class C1 { } public class C2 : C1 { } "; var source2 = @" class Test2: I2 { static void Main() { I2 x = new Test2(); C2 y = new C2(); var z = x + y; z = y + x; } } "; var expectedOutput = @" I2.+1 I2.+2 "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_16() { var source1 = @" public interface I1 { public static int operator +(I1 x, I1 y) { System.Console.WriteLine(""I1.+""); return 1; } } "; var source2 = @" class Test2: I1 { static void Main() { I1 x = new Test2(); I1 y = new Test2(); var z = x + y; z = y + x; } } "; var expectedOutput = @" I1.+ I1.+ "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_17() { var source1 = @" public interface I1 { public static I1 operator +(I1 x, C1 y) { System.Console.WriteLine(""I1.+1""); return x; } public static I1 operator +(C1 x, I1 y) { System.Console.WriteLine(""I1.+2""); return y; } } public interface I2 : I1 {} public class C1{} "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); C1 y = new C1(); var z = x + y; z = y + x; } } "; var expectedOutput = @" I1.+1 I1.+2 "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var source3 = @" class Test2 : I2 { static void Main() { Test2 x = new Test2(); C1 y = new C1(); var z = x + y; z = y + x; } } "; var compilation9 = CreateCompilation(source3, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); var expected9 = new DiagnosticDescription[] { // (8,17): error CS0019: Operator '+' cannot be applied to operands of type 'Test2' and 'C1' // var z = x + y; Diagnostic(ErrorCode.ERR_BadBinaryOps, "x + y").WithArguments("+", "Test2", "C1").WithLocation(8, 17), // (9,13): error CS0019: Operator '+' cannot be applied to operands of type 'C1' and 'Test2' // z = y + x; Diagnostic(ErrorCode.ERR_BadBinaryOps, "y + x").WithArguments("+", "C1", "Test2").WithLocation(9, 13) }; compilation9.VerifyDiagnostics(expected9); var compilation10 = CreateCompilation(source3, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation10.VerifyDiagnostics(expected9); } [Fact] public void Operators_18() { var source1 = @" public interface I1 { public static int operator +(I1 x, I1 y) { System.Console.WriteLine(""I1.+""); return 1; } } public interface I2 : I1 {} "; var source2 = @" class Test2: I2 { static void Main() { I2 x = new Test2(); I1 y = new Test2(); var z = x + y; z = y + x; z = x + x; z = y + y; } } "; var expectedOutput = @" I1.+ I1.+ I1.+ I1.+ "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_19() { var source1 = @" public interface I1 { public static int operator +(I1 x, I1 y) { System.Console.WriteLine(""I1.+""); return 1; } } public interface I2 : I1 {} "; var source2 = @" class Test2: I2 { static void Main() { I2 x = new Test2(); I2 y = new Test2(); var z = x + y; z = y + x; I1 u = x; I1 v = y; z = y + u; z = u + y; z = x + v; z = v + x; } } "; var expectedOutput = @" I1.+ I1.+ I1.+ I1.+ I1.+ I1.+ "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_20() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, I2 y) { System.Console.WriteLine(""I1.-""); return x; } } public interface I2 : I1 { public static I2 operator -(I1 x, I2 y) { System.Console.WriteLine(""I2.-""); return y; } } "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); I2 y = new Test2(); var z = x - y; } } "; var expectedOutput = @" I2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_21() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, I2 y) { System.Console.WriteLine(""I1.-""); return x; } } public interface I2 : I1 { public static I2 operator -(I1 x, I2 y) { System.Console.WriteLine(""I2.-""); return y; } } public interface I3 : I2 {} public interface I4 : I2, I1 {} public interface I5 : I1, I2 {} "; var source2 = @" class Test2 : I3, I4, I5 { static void Main() { I3 x3 = new Test2(); I3 y3 = new Test2(); var z = x3 - y3; I4 x4 = new Test2(); I4 y4 = new Test2(); z = x4 - y4; I5 x5 = new Test2(); I5 y5 = new Test2(); z = x5 - y5; } } "; var expectedOutput = @" I2.- I2.- I2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_22() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, I2 y) { System.Console.WriteLine(""I1.-""); return x; } } public interface I2 : I1 { public static I2 operator -(I1 x, I2 y) { System.Console.WriteLine(""I2.-""); return y; } } public interface I3 : I2 {} public interface I4 : I3 {} "; var source2 = @" class Test2 : I3, I4 { static void Main() { I3 x = new Test2(); I4 y = new Test2(); var z = x - y; z = y - x; } } "; var expectedOutput = @" I2.- I2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_23() { var source1 = @" public interface I1 { public static int operator +(I1 x, I2 y) { System.Console.WriteLine(""I1.+""); return 1; } } public interface I2 : I1 { public static int operator +(I1 x, I2 y) { System.Console.WriteLine(""I2.+""); return 2; } } public interface I3 : I2 {} "; var source2 = @" class Test2 : I3 { static void Main() { I1 x = new Test2(); I3 y = new Test2(); var z = x + y; z = y + x; } } "; var expected = new DiagnosticDescription[] { // (8,17): error CS0034: Operator '+' is ambiguous on operands of type 'I1' and 'I3' // var z = x + y; Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "x + y").WithArguments("+", "I1", "I3").WithLocation(8, 17), // (9,13): error CS0019: Operator '+' cannot be applied to operands of type 'I3' and 'I1' // z = y + x; Diagnostic(ErrorCode.ERR_BadBinaryOps, "y + x").WithArguments("+", "I3", "I1").WithLocation(9, 13) }; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(expected); } [Fact] public void Operators_24() { var source1 = @" public interface I1 { public static int operator +(I2 x, I1 y) { System.Console.WriteLine(""I1.+""); return 1; } } public interface I2 : I1 { public static int operator +(I2 x, I1 y) { System.Console.WriteLine(""I2.+""); return 2; } } public interface I3 : I2 {} "; var source2 = @" class Test2 : I3 { static void Main() { I1 x = new Test2(); I3 y = new Test2(); var z = y + x; z = x + y; } } "; var expected = new DiagnosticDescription[] { // (8,17): error CS0034: Operator '+' is ambiguous on operands of type 'I3' and 'I1' // var z = y + x; Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "y + x").WithArguments("+", "I3", "I1").WithLocation(8, 17), // (9,13): error CS0019: Operator '+' cannot be applied to operands of type 'I1' and 'I3' // z = x + y; Diagnostic(ErrorCode.ERR_BadBinaryOps, "x + y").WithArguments("+", "I1", "I3").WithLocation(9, 13) }; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(expected); } [Fact] public void Operators_25() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, I1 y) { System.Console.WriteLine(""I1.-""); return x; } } public interface I3 { public static I3 operator -(I3 x, I3 y) { System.Console.WriteLine(""I3.-""); return x; } } public interface I4 : I1, I3 { } public interface I2 : I4 { } "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); var y = x - x; } } "; var expected = new DiagnosticDescription[] { // (7,17): error CS0034: Operator '-' is ambiguous on operands of type 'I2' and 'I2' // var y = x - x; Diagnostic(ErrorCode.ERR_AmbigBinaryOps, "x - x").WithArguments("-", "I2", "I2").WithLocation(7, 17) }; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(expected); CompilationReference compilationReference = compilation1.ToMetadataReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(expected); } [Fact] public void Operators_26() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, C1 y) { System.Console.WriteLine(""I1.-1""); return x; } public static I1 operator -(C1 x, I1 y) { System.Console.WriteLine(""I1.-2""); return y; } } public interface I3 { public static I3 operator -(I3 x, C2 y) { System.Console.WriteLine(""I3.-1""); return x; } public static I3 operator -(C2 x, I3 y) { System.Console.WriteLine(""I3.-2""); return y; } } public interface I4 { public static I4 operator -(I4 x, C1 y) { System.Console.WriteLine(""I4.-1""); return x; } public static I4 operator -(C1 x, I4 y) { System.Console.WriteLine(""I4.-2""); return y; } } public interface I5 : I1, I3, I4 { } public interface I2 : I5 { } public class C1{} public class C2 : C1{} "; var source2 = @" class Test2 : I2 { static void Main() { I2 x = new Test2(); var c = new C2(); var y = x - c; y = c - x; } } "; var expectedOutput = @" I3.-1 I3.-2 "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_27() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, I1 y) { System.Console.WriteLine(""I1.-""); return x; } } "; var source2 = @" class Test1 : Test2, I1 {} class Test2 { static void Main() { Test(new Test1()); } static void Test(T x) where T : Test2, I1 { var y = x - x; } public static Test2 operator -(Test2 x, Test2 y) { System.Console.WriteLine(""Test2.-""); return x; } } "; var expectedOutput = @" Test2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_28() { var source1 = @" public interface I1 { public static I1 operator -(I1 x, C1 y) { System.Console.WriteLine(""I1.-1""); return x; } public static I1 operator -(C1 x, I1 y) { System.Console.WriteLine(""I1.-2""); return y; } } public interface I3 { public static I3 operator -(I3 x, C2 y) { System.Console.WriteLine(""I3.-1""); return x; } public static I3 operator -(C2 x, I3 y) { System.Console.WriteLine(""I3.-2""); return y; } } public interface I4 { public static I4 operator -(I4 x, C1 y) { System.Console.WriteLine(""I4.-1""); return x; } public static I4 operator -(C1 x, I4 y) { System.Console.WriteLine(""I4.-2""); return y; } } public interface I5 : I1, I3, I4 { } public interface I2 : I5 { } public class C1{} public class C2 : C1{} "; var source2 = @" class Test1 : Test2, I2 {} class Test2 { static void Main() { Test(new Test1()); } static void Test(T x) where T : Test2, I2 { var c = new C2(); var y = c - x; y = x - c; } } "; var expectedOutput = @" I3.-2 I3.-1 "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void Operators_29() { var source1 = @" public interface I1 { public static I1 operator +(int x) => throw null; public static I1 operator -(int x) => throw null; public static I1 operator !(int x) => throw null; public static I1 operator ~(int x) => throw null; public static I1 operator ++(int x) => throw null; public static I1 operator --(int x) => throw null; public static bool operator true(int x) => throw null; public static bool operator false(int x) => throw null; public static I1 operator +(int x, int y) => throw null; public static I1 operator -(int x, int y) => throw null; public static I1 operator *(int x, int y) => throw null; public static I1 operator /(int x, int y) => throw null; public static I1 operator %(int x, int y) => throw null; public static I1 operator &(int x, int y) => throw null; public static I1 operator |(int x, int y) => throw null; public static I1 operator ^(int x, int y) => throw null; public static I1 operator <<(int x, int y) => throw null; public static I1 operator >>(int x, int y) => throw null; public static I1 operator >(int x, int y) => throw null; public static I1 operator <(int x, int y) => throw null; public static I1 operator >=(int x, int y) => throw null; public static I1 operator <=(int x, int y) => throw null; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,31): error CS0562: The parameter of a unary operator must be the containing type // public static I1 operator +(int x) => throw null; Diagnostic(ErrorCode.ERR_BadUnaryOperatorSignature, "+").WithLocation(4, 31), // (5,31): error CS0562: The parameter of a unary operator must be the containing type // public static I1 operator -(int x) => throw null; Diagnostic(ErrorCode.ERR_BadUnaryOperatorSignature, "-").WithLocation(5, 31), // (6,31): error CS0562: The parameter of a unary operator must be the containing type // public static I1 operator !(int x) => throw null; Diagnostic(ErrorCode.ERR_BadUnaryOperatorSignature, "!").WithLocation(6, 31), // (7,31): error CS0562: The parameter of a unary operator must be the containing type // public static I1 operator ~(int x) => throw null; Diagnostic(ErrorCode.ERR_BadUnaryOperatorSignature, "~").WithLocation(7, 31), // (8,31): error CS0559: The parameter type for ++ or -- operator must be the containing type // public static I1 operator ++(int x) => throw null; Diagnostic(ErrorCode.ERR_BadIncDecSignature, "++").WithLocation(8, 31), // (9,31): error CS0559: The parameter type for ++ or -- operator must be the containing type // public static I1 operator --(int x) => throw null; Diagnostic(ErrorCode.ERR_BadIncDecSignature, "--").WithLocation(9, 31), // (10,33): error CS0562: The parameter of a unary operator must be the containing type // public static bool operator true(int x) => throw null; Diagnostic(ErrorCode.ERR_BadUnaryOperatorSignature, "true").WithLocation(10, 33), // (11,33): error CS0562: The parameter of a unary operator must be the containing type // public static bool operator false(int x) => throw null; Diagnostic(ErrorCode.ERR_BadUnaryOperatorSignature, "false").WithLocation(11, 33), // (12,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator +(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "+").WithLocation(12, 31), // (13,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator -(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "-").WithLocation(13, 31), // (14,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator *(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "*").WithLocation(14, 31), // (15,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator /(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "/").WithLocation(15, 31), // (16,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator %(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "%").WithLocation(16, 31), // (17,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator &(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "&").WithLocation(17, 31), // (18,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator |(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "|").WithLocation(18, 31), // (19,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator ^(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "^").WithLocation(19, 31), // (20,31): error CS0564: The first operand of an overloaded shift operator must have the same type as the containing type, and the type of the second operand must be int // public static I1 operator <<(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadShiftOperatorSignature, "<<").WithLocation(20, 31), // (21,31): error CS0564: The first operand of an overloaded shift operator must have the same type as the containing type, and the type of the second operand must be int // public static I1 operator >>(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadShiftOperatorSignature, ">>").WithLocation(21, 31), // (22,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator >(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, ">").WithLocation(22, 31), // (23,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator <(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "<").WithLocation(23, 31), // (24,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator >=(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, ">=").WithLocation(24, 31), // (25,31): error CS0563: One of the parameters of a binary operator must be the containing type // public static I1 operator <=(int x, int y) => throw null; Diagnostic(ErrorCode.ERR_BadBinaryOperatorSignature, "<=").WithLocation(25, 31) ); } [Fact] public void Operators_30() { var source1 = @" public interface I1 { public static I1 operator <<(I1 x, I1 y) => throw null; public static I1 operator >>(I1 x, I1 y) => throw null; } public interface I2 { public static bool operator true(I2 x) => throw null; } public interface I3 { public static bool operator false(I3 x) => throw null; } public interface I4 { public static int operator true(I4 x) => throw null; public static int operator false(I4 x) => throw null; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (4,31): error CS0564: The first operand of an overloaded shift operator must have the same type as the containing type, and the type of the second operand must be int // public static I1 operator <<(I1 x, I1 y) => throw null; Diagnostic(ErrorCode.ERR_BadShiftOperatorSignature, "<<").WithLocation(4, 31), // (5,31): error CS0564: The first operand of an overloaded shift operator must have the same type as the containing type, and the type of the second operand must be int // public static I1 operator >>(I1 x, I1 y) => throw null; Diagnostic(ErrorCode.ERR_BadShiftOperatorSignature, ">>").WithLocation(5, 31), // (10,33): error CS0216: The operator 'I2.operator true(I2)' requires a matching operator 'false' to also be defined // public static bool operator true(I2 x) => throw null; Diagnostic(ErrorCode.ERR_OperatorNeedsMatch, "true").WithArguments("I2.operator true(I2)", "false").WithLocation(10, 33), // (15,33): error CS0216: The operator 'I3.operator false(I3)' requires a matching operator 'true' to also be defined // public static bool operator false(I3 x) => throw null; Diagnostic(ErrorCode.ERR_OperatorNeedsMatch, "false").WithArguments("I3.operator false(I3)", "true").WithLocation(15, 33), // (20,32): error CS0215: The return type of operator True or False must be bool // public static int operator true(I4 x) => throw null; Diagnostic(ErrorCode.ERR_OpTFRetType, "true").WithLocation(20, 32), // (21,32): error CS0215: The return type of operator True or False must be bool // public static int operator false(I4 x) => throw null; Diagnostic(ErrorCode.ERR_OpTFRetType, "false").WithLocation(21, 32) ); } [Fact] public void Operators_31() { var source1 = @" public interface I1 { public static I1 operator -(I1 x) { System.Console.WriteLine(""I1.-""); return x; } } public interface I2 : I1 { public static I2 operator -(I2 x) { System.Console.WriteLine(""I2.-""); return x; } } public interface I3 : I2 {} public interface I4 : I2, I1 {} public interface I5 : I1, I2 {} "; var source2 = @" class Test2 : I3, I4, I5 { static void Main() { I3 x3 = new Test2(); var y = -x3; I4 x4 = new Test2(); y = -x4; I5 x5 = new Test2(); y = -x5; } } "; var expectedOutput = @" I2.- I2.- I2.- "; var compilation1 = CreateCompilation(source1 + source2, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); CompilationReference compilationReference = compilation1.ToMetadataReference(); MetadataReference metadataReference = compilation1.EmitToImageReference(); var compilation2 = CreateCompilation(source2, new[] { compilationReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); CompileAndVerify(compilation2, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); var compilation3 = CreateCompilation(source2, new[] { metadataReference }, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation3, verify: VerifyOnMonoOrCoreClr, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : expectedOutput); } [Fact] public void RuntimeFeature_01() { var compilation1 = CreateCompilation("", options: TestOptions.DebugDll, references: new[] { TestReferences.Net461.mscorlibRef }, targetFramework: TargetFramework.Empty); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.False(compilation1.Assembly.CorLibrary.RuntimeSupportsDefaultInterfaceImplementation); } [Fact] public void RuntimeFeature_02() { var compilation1 = CreateCompilation("", options: TestOptions.DebugDll, references: new[] { TestReferences.NetCoreApp30.SystemRuntimeRef }, targetFramework: TargetFramework.Empty); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.True(compilation1.Assembly.CorLibrary.RuntimeSupportsDefaultInterfaceImplementation); } [Fact] public void RuntimeFeature_03() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public static class RuntimeFeature { public const string DefaultImplementationsOfInterfaces = ""DefaultImplementationsOfInterfaces""; } } } "; AssertRuntimeFeatureTrue(source); } private static void AssertRuntimeFeatureTrue(string source) { var compilation1 = CreateCompilation(source, options: TestOptions.DebugDll, targetFramework: TargetFramework.Empty); Assert.True(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.Same(compilation1.Assembly, compilation1.Assembly.CorLibrary); foreach (var reference in new[] { compilation1.EmitToImageReference(), compilation1.ToMetadataReference() }) { var compilation2 = CreateCompilation("", options: TestOptions.DebugDll, references: new[] { reference }, targetFramework: TargetFramework.Empty); Assert.True(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.True(compilation2.Assembly.CorLibrary.RuntimeSupportsDefaultInterfaceImplementation); } } [Fact] public void RuntimeFeature_04() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public static class RuntimeFeature { public const string DefaultImplementationsOfInterfaces = """"; } } } "; AssertRuntimeFeatureTrue(source); } [Fact] public void RuntimeFeature_05() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public static class RuntimeFeature { public static string DefaultImplementationsOfInterfaces; } } } "; AssertRuntimeFeatureTrue(source); } [Fact] public void RuntimeFeature_06() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public class RuntimeFeature { public const string DefaultImplementationsOfInterfaces = ""DefaultImplementationsOfInterfaces""; } } } "; AssertRuntimeFeatureTrue(source); } [Fact] public void RuntimeFeature_07() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public static class RuntimeFeature { static string DefaultImplementationsOfInterfaces; } } } "; AssertRuntimeFeatureFalse(source); } private static void AssertRuntimeFeatureFalse(string source) { var compilation1 = CreateCompilation(source, options: TestOptions.DebugDll, targetFramework: TargetFramework.Empty); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.Same(compilation1.Assembly, compilation1.Assembly.CorLibrary); foreach (var reference in new[] { compilation1.EmitToImageReference(), compilation1.ToMetadataReference() }) { var compilation2 = CreateCompilation("", options: TestOptions.DebugDll, references: new[] { reference }, targetFramework: TargetFramework.Empty); Assert.False(compilation2.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.False(compilation2.Assembly.CorLibrary.RuntimeSupportsDefaultInterfaceImplementation); } } [Fact] public void RuntimeFeature_08() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public class RuntimeFeature { public string DefaultImplementationsOfInterfaces; } } } "; AssertRuntimeFeatureFalse(source); } [Fact] public void RuntimeFeature_09() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} public struct Int32 {} namespace Runtime.CompilerServices { public static class RuntimeFeature { public const int DefaultImplementationsOfInterfaces = 0; } } } "; AssertRuntimeFeatureFalse(source); } [Fact] public void RuntimeFeature_10() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { public static class RuntimeFeature { } } } "; AssertRuntimeFeatureFalse(source); } [Fact] public void RuntimeFeature_11() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { } } "; AssertRuntimeFeatureFalse(source); } [Fact] public void RuntimeFeature_12() { var source = @" namespace System { public class Object {} public class String {} public struct Void {} public class ValueType {} namespace Runtime.CompilerServices { static class RuntimeFeature { public const string DefaultImplementationsOfInterfaces = ""DefaultImplementationsOfInterfaces""; } } } "; AssertRuntimeFeatureFalse(source); } [Fact] public void RuntimeFeature_13() { var source = @" namespace System { namespace Runtime.CompilerServices { public static class RuntimeFeature { public const string DefaultImplementationsOfInterfaces = ""DefaultImplementationsOfInterfaces""; } } } "; var compilation1 = CreateCompilation(source, options: TestOptions.DebugDll, references: new[] { TestReferences.Net461.mscorlibRef }, targetFramework: TargetFramework.Empty); Assert.False(compilation1.Assembly.RuntimeSupportsDefaultInterfaceImplementation); Assert.False(compilation1.Assembly.CorLibrary.RuntimeSupportsDefaultInterfaceImplementation); } [Fact] public void ProtectedAccessibility_01() { var source0 = @" interface I1 { sealed protected void M1() { System.Console.WriteLine(""M1""); } } "; var source1 = @" interface I2 : I1 { static void Test(T x) where T : I2 { x.M1(); } } class A : I2 { static void Main() { I2.Test(new A()); } } "; var compilation0 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); var source2 = @" interface I2 : I1 { static void Test(T x) where T : I1, I3 { x.M1(); } } interface I3 : I2 {} class A : I3 { static void Main() { I2.Test(new A()); } } "; var compilation1 = CreateCompilation(source0 + source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); var verifier = CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); verifier.VerifyIL("I2.Test", @" { // Code size 16 (0x10) .maxstack 1 IL_0000: nop IL_0001: ldarga.s V_0 IL_0003: constrained. ""T"" IL_0009: callvirt ""void I1.M1()"" IL_000e: nop IL_000f: ret } "); var source3 = @" interface I2 : I1 { static void Test(T x) where T : I1 { x.M1(); } } "; var compilation2 = CreateCompilation(source0 + source3, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (14,11): error CS1540: Cannot access protected member 'I1.M1()' via a qualifier of type 'T'; the qualifier must be of type 'I2' (or derived from it) // x.M1(); Diagnostic(ErrorCode.ERR_BadProtectedAccess, "M1").WithArguments("I1.M1()", "T", "I2").WithLocation(14, 11) ); } [Fact] public void ProtectedAccessibility_02() { var source0 = @" interface I1 { sealed protected void M1() { System.Console.WriteLine(""M1""); } static void Test(I1 x) { x.M1(); } } class A : I1 { static void Main() { I1.Test(new A()); } } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); } [Fact] public void ProtectedAccessibility_03() { var source0 = @" interface I1 { sealed protected void M1() { System.Console.WriteLine(""M1""); } } interface I3 : I1 {} "; var source1 = @" interface I2 : I3 { static void Test(I2 x) { x.M1(); } } class A : I2 { static void Main() { I2.Test(new A()); } } "; var compilation0 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); var source2 = @" interface I2 : I3 { static void Test(I4 x) { x.M1(); } } interface I4 : I2 {} class A : I4 { static void Main() { I2.Test(new A()); } } "; var compilation1 = CreateCompilation(source0 + source2, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); var source3 = @" interface I2 : I3 { static void Test(I3 x) { x.M1(); } static void Test(I1 y) { y.M1(); } } "; var compilation2 = CreateCompilation(source0 + source3, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (17,11): error CS1540: Cannot access protected member 'I1.M1()' via a qualifier of type 'I3'; the qualifier must be of type 'I2' (or derived from it) // x.M1(); Diagnostic(ErrorCode.ERR_BadProtectedAccess, "M1").WithArguments("I1.M1()", "I3", "I2").WithLocation(17, 11), // (22,11): error CS1540: Cannot access protected member 'I1.M1()' via a qualifier of type 'I1'; the qualifier must be of type 'I2' (or derived from it) // y.M1(); Diagnostic(ErrorCode.ERR_BadProtectedAccess, "M1").WithArguments("I1.M1()", "I1", "I2").WithLocation(22, 11) ); } [Fact] public void ProtectedAccessibility_04() { var source0 = @" interface I1 : I2 { sealed protected void M1() { } static void Test(I1 x) { x.M1(); } } interface I2 : I1 { static void Test(I2 y) { y.M1(); } } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics( // (2,11): error CS0529: Inherited interface 'I2' causes a cycle in the interface hierarchy of 'I1' // interface I1 : I2 Diagnostic(ErrorCode.ERR_CycleInInterfaceInheritance, "I1").WithArguments("I1", "I2").WithLocation(2, 11), // (13,11): error CS0529: Inherited interface 'I1' causes a cycle in the interface hierarchy of 'I2' // interface I2 : I1 Diagnostic(ErrorCode.ERR_CycleInInterfaceInheritance, "I2").WithArguments("I2", "I1").WithLocation(13, 11), // (17,11): error CS1061: 'I2' does not contain a definition for 'M1' and no accessible extension method 'M1' accepting a first argument of type 'I2' could be found (are you missing a using directive or an assembly reference?) // y.M1(); Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "M1").WithArguments("I2", "M1").WithLocation(17, 11) ); } [Fact] public void ProtectedAccessibility_05() { var source0 = @" interface I1 : I2 { static protected void M2() { } static void Test() { I1.M2(); } } interface I2 : I1 { static void Test() { I1.M2(); } } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics( // (2,11): error CS0529: Inherited interface 'I2' causes a cycle in the interface hierarchy of 'I1' // interface I1 : I2 Diagnostic(ErrorCode.ERR_CycleInInterfaceInheritance, "I1").WithArguments("I1", "I2").WithLocation(2, 11), // (13,11): error CS0529: Inherited interface 'I1' causes a cycle in the interface hierarchy of 'I2' // interface I2 : I1 Diagnostic(ErrorCode.ERR_CycleInInterfaceInheritance, "I2").WithArguments("I2", "I1").WithLocation(13, 11) ); } [Fact] public void ProtectedAccessibility_06() { var source0 = @" interface I1 { static protected void M1() { System.Console.WriteLine(""M1""); } } interface I3 : I1 {} "; var source1 = @" class I2 : I3 { public static void Test() { I1.M1(); } } class A { static void Main() { I2.Test(); } } "; var compilation0 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); var source3 = @" class I2 { static void Test() { I3.M1(); I1.M1(); } } "; var compilation2 = CreateCompilation(source0 + source3, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics( // (17,15): error CS0122: 'I1.M1()' is inaccessible due to its protection level // I3.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(17, 15), // (18,15): error CS0122: 'I1.M1()' is inaccessible due to its protection level // I1.M1(); Diagnostic(ErrorCode.ERR_BadAccess, "M1").WithArguments("I1.M1()").WithLocation(18, 15) ); } [Fact] public void ProtectedAccessibility_07() { var source0 = @" interface I1 { static protected void M1() { System.Console.WriteLine(""M1""); } } class I3 : I1 {} "; var source1 = @" class I2 : I3 { public static void Test() { I1.M1(); } } class A { static void Main() { I2.Test(); } } "; var compilation0 = CreateCompilation(source0 + source1, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); } private const string NoPiaAttributes = @" namespace System.Runtime.InteropServices { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] public sealed class GuidAttribute : Attribute { public GuidAttribute(string guid){} } [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = true)] public sealed class PrimaryInteropAssemblyAttribute : Attribute { public PrimaryInteropAssemblyAttribute(int major, int minor){} } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, Inherited = false)] public sealed class ComImportAttribute : Attribute { public ComImportAttribute(){} } [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] public sealed class TypeIdentifierAttribute : Attribute { public TypeIdentifierAttribute(){} public TypeIdentifierAttribute(string scope, string identifier){} } } "; [Fact] public void NoPia_01() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(){} } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia7 : ITest33 { } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (2,17): error CS8711: Type 'ITest33' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // class UsePia7 : ITest33 Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest33").WithArguments("ITest33").WithLocation(2, 17) ); } } [Fact] public void NoPia_02() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(){} } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main(ITest33 x) { x.M1(); } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (4,29): error CS8711: Type 'ITest33' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // public static void Main(ITest33 x) Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest33").WithArguments("ITest33").WithLocation(4, 29) ); } } [Fact] public void NoPia_03() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(){} void M2(); } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main(ITest33 x) { x.M2(); } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (4,29): error CS8711: Type 'ITest33' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // public static void Main(ITest33 x) Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest33").WithArguments("ITest33").WithLocation(4, 29) ); } } [Fact] public void NoPia_04() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { sealed void M1(){} } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main(ITest33 x) { x.M1(); } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (4,29): error CS8711: Type 'ITest33' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // public static void Main(ITest33 x) Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest33").WithArguments("ITest33").WithLocation(4, 29) ); } } [Fact] public void NoPia_05() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { static void M1(){} } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main() { ITest33.M1(); } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (6,9): error CS8711: Type 'ITest33' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // ITest33.M1(); Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest33").WithArguments("ITest33").WithLocation(6, 9) ); } } [Fact] public void NoPia_06() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58280"")] public interface I1 { } } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main(ITest33.I1 x) { } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (4,37): error CS1754: Type 'ITest33.I1' cannot be embedded because it is a nested type. Consider setting the 'Embed Interop Types' property to false. // public static void Main(ITest33.I1 x) Diagnostic(ErrorCode.ERR_NoPIANestedType, "I1").WithArguments("ITest33.I1").WithLocation(4, 37) ); } } [Fact] public void NoPia_07() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { public static int F1; } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main() { _ = ITest33.F1; } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (6,13): error CS8711: Type 'ITest33' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // _ = ITest33.F1; Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest33").WithArguments("ITest33").WithLocation(6, 13) ); } } [Fact] public void NoPia_08() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58280"")] public interface ITest44 : ITest33 { void ITest33.M1(){} } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main(ITest44 x) { x.M1(); } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (4,29): error CS8711: Type 'ITest44' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // public static void Main(ITest44 x) Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest44").WithArguments("ITest44").WithLocation(4, 29) ); } } [ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NoPiaNeedsDesktop)] public void NoPia_09() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(); public interface ITest55 { void M2(); } } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58280"")] public interface ITest44 : ITest33 { void ITest33.M1(){} } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer1 = @" public class UsePia { public static void Test(ITest33 x) { x.M1(); } } "; string consumer2 = @" class Test : ITest33 { public static void Main() { UsePia.Test(new Test()); } void ITest33.M1() { System.Console.WriteLine(""Test.M1""); } } "; string pia2 = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(); } " + NoPiaAttributes; var pia2Compilation = CreateCompilation(pia2, options: TestOptions.ReleaseDll); var pia2Refernce = pia2Compilation.EmitToImageReference(); foreach (var reference1 in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer1, options: TestOptions.ReleaseDll, references: new[] { reference1, attributesRef }, targetFramework: TargetFramework.StandardLatest); foreach (var reference2 in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(consumer2, options: TestOptions.ReleaseExe, references: new[] { reference2, pia2Refernce }, targetFramework: TargetFramework.StandardLatest); CompileAndVerify(compilation2, expectedOutput: "Test.M1"); } } } [Fact(Skip = "https://github.com/dotnet/roslyn/issues/35911")] [WorkItem(35911, "https://github.com/dotnet/roslyn/issues/35911")] public void NoPia_10() { var attributes = CreateCompilation(NoPiaAttributes, options: TestOptions.ReleaseDll, targetFramework: TargetFramework.NetStandardLatest); var attributesRef = attributes.EmitToImageReference(); string pia = @" using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; [assembly: PrimaryInteropAssemblyAttribute(1,1)] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58279"")] public interface ITest33 { void M1(); } [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58280"")] public interface ITest44 : ITest33 { abstract void ITest33.M1(); } "; var piaCompilation = CreateCompilation(pia, options: TestOptions.ReleaseDll, references: new[] { attributesRef }, targetFramework: TargetFramework.NetStandardLatest); CompileAndVerify(piaCompilation, verify: VerifyOnMonoOrCoreClr); string consumer = @" class UsePia { public static void Main(ITest44 x) { x.M1(); } } "; foreach (var reference in new[] { piaCompilation.ToMetadataReference(embedInteropTypes: true), piaCompilation.EmitToImageReference(embedInteropTypes: true) }) { var compilation1 = CreateCompilation(consumer, options: TestOptions.ReleaseDll, references: new[] { reference, attributesRef }, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyEmitDiagnostics( // (4,29): error CS8711: Type 'ITest44' cannot be embedded because it has a non-abstract member. Consider setting the 'Embed Interop Types' property to false. // public static void Main(ITest44 x) Diagnostic(ErrorCode.ERR_DefaultInterfaceImplementationInNoPIAType, "ITest44").WithArguments("ITest44").WithLocation(4, 29) ); } } [Fact] public void LambdaCaching_01() { var source0 = @" interface I1 { static void M1() { M2(() => System.Console.WriteLine(""M1"")); } static void M2(System.Action d) { d(); } } class A { static void Main() { I1.M1(); } } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); var verifier = CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); verifier.VerifyIL("I1.M1", @" { // Code size 39 (0x27) .maxstack 2 IL_0000: nop IL_0001: ldsfld ""System.Action I1.<>c.<>9__0_0"" IL_0006: dup IL_0007: brtrue.s IL_0020 IL_0009: pop IL_000a: ldsfld ""I1.<>c I1.<>c.<>9"" IL_000f: ldftn ""void I1.<>c.b__0_0()"" IL_0015: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_001a: dup IL_001b: stsfld ""System.Action I1.<>c.<>9__0_0"" IL_0020: call ""void I1.M2(System.Action)"" IL_0025: nop IL_0026: ret } "); } [Fact] public void LambdaCaching_02() { var source0 = @" interface I1 { void M1() { M2(() => System.Console.WriteLine(""M1"")); } static void M2(System.Action d) { d(); } } class A : I1 { static void Main() { ((I1)new A()).M1(); } } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); var verifier = CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"M1", verify: VerifyOnMonoOrCoreClr); verifier.VerifyIL("I1.M1", @" { // Code size 39 (0x27) .maxstack 2 IL_0000: nop IL_0001: ldsfld ""System.Action I1.<>c.<>9__0_0"" IL_0006: dup IL_0007: brtrue.s IL_0020 IL_0009: pop IL_000a: ldsfld ""I1.<>c I1.<>c.<>9"" IL_000f: ldftn ""void I1.<>c.b__0_0()"" IL_0015: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_001a: dup IL_001b: stsfld ""System.Action I1.<>c.<>9__0_0"" IL_0020: call ""void I1.M2(System.Action)"" IL_0025: nop IL_0026: ret } "); } [Fact] public void LambdaCaching_03() { var source0 = @" interface I1 { void M1() { M2(() => System.Console.WriteLine(this.ToString())); } static void M2(System.Action d) { d(); } } class A : I1 { static void Main() { ((I1)new A()).M1(); } } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugExe, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics(); var verifier = CompileAndVerify(compilation0, expectedOutput: !ExecutionConditionUtil.IsMonoOrCoreClr ? null : @"A", verify: VerifyOnMonoOrCoreClr); verifier.VerifyIL("I1.M1", @" { // Code size 20 (0x14) .maxstack 2 IL_0000: nop IL_0001: ldarg.0 IL_0002: ldftn ""void I1.b__0_0()"" IL_0008: newobj ""System.Action..ctor(object, System.IntPtr)"" IL_000d: call ""void I1.M2(System.Action)"" IL_0012: nop IL_0013: ret } "); } [Fact] public void MemberwiseClone_01() { var source0 = @" interface I1 { object M1(I2 x, I3 y) { x.MemberwiseClone(); y.MemberwiseClone(); this.MemberwiseClone(); return ((I1)this).MemberwiseClone(); } } interface I2 { } interface I3 : I1 { } "; var compilation0 = CreateCompilation(source0, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation0.VerifyDiagnostics( // (6,11): error CS0122: 'object.MemberwiseClone()' is inaccessible due to its protection level // x.MemberwiseClone(); Diagnostic(ErrorCode.ERR_BadAccess, "MemberwiseClone").WithArguments("object.MemberwiseClone()").WithLocation(6, 11), // (7,11): error CS0122: 'object.MemberwiseClone()' is inaccessible due to its protection level // y.MemberwiseClone(); Diagnostic(ErrorCode.ERR_BadAccess, "MemberwiseClone").WithArguments("object.MemberwiseClone()").WithLocation(7, 11), // (8,14): error CS0122: 'object.MemberwiseClone()' is inaccessible due to its protection level // this.MemberwiseClone(); Diagnostic(ErrorCode.ERR_BadAccess, "MemberwiseClone").WithArguments("object.MemberwiseClone()").WithLocation(8, 14), // (9,27): error CS0122: 'object.MemberwiseClone()' is inaccessible due to its protection level // return ((I1)this).MemberwiseClone(); Diagnostic(ErrorCode.ERR_BadAccess, "MemberwiseClone").WithArguments("object.MemberwiseClone()").WithLocation(9, 27) ); } [Fact] public void MethodReAbstraction_01() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract void I1.M1(); } "; var source2 = @" class Test1 : I2 { } "; ValidateMethodReAbstraction_01(source1, source2); } private static void ValidateMethodReAbstraction_01(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); var expected = new DiagnosticDescription[] { // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(2, 15) }; compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); ValidateReabstraction(i2m1); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } private static void ValidateReabstraction(MethodSymbol m) { Assert.True(m.IsMetadataVirtual()); Assert.True(m.IsMetadataFinal); Assert.False(m.IsMetadataNewSlot()); Assert.True(m.IsAbstract); Assert.False(m.IsVirtual); Assert.True(m.IsSealed); Assert.False(m.IsStatic); Assert.False(m.IsExtern); Assert.False(m.IsAsync); Assert.False(m.IsOverride); Assert.Equal(Accessibility.Private, m.DeclaredAccessibility); } [Fact] public void MethodReAbstraction_02() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } "; var source2 = @" class Test1 : I2 { } "; ValidateMethodReAbstraction_01(source1, source2); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void MethodReAbstraction_03() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract void I1.M1(); } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1.M1(); } void I1.M1() { System.Console.WriteLine(""Test1.M1""); } } "; ValidateMethodReAbstraction_03(source1, source2); } private void ValidateMethodReAbstraction_03(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test1.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "Test1.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Equal("void Test1.I1.M1()", test1.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void MethodReAbstraction_04() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1.M1(); } void I1.M1() { System.Console.WriteLine(""Test1.M1""); } } "; ValidateMethodReAbstraction_03(source1, source2); } [Fact] public void MethodReAbstraction_05() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidateMethodReAbstraction_05(source1, source2); } private static void ValidateMethodReAbstraction_05(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); var expected = new DiagnosticDescription[] { // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.M1()").WithLocation(2, 15) }; compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I3", i3.Name); var i1m1 = i3.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i3.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_06() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidateMethodReAbstraction_05(source1, source2); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void MethodReAbstraction_07() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I2 { void I1.M1() { System.Console.WriteLine(""I3.M1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1.M1(); } } "; ValidateMethodReAbstraction_07(source1, source2); } private void ValidateMethodReAbstraction_07(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I3.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I3.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I3", i3.Name); var i1m1 = i3.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Equal("void I3.I1.M1()", i3.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); Assert.Equal("void I3.I1.M1()", test1.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void MethodReAbstraction_08() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I2 { void I1.M1() { System.Console.WriteLine(""I3.M1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1.M1(); } } "; ValidateMethodReAbstraction_07(source1, source2); } [Fact] public void MethodReAbstraction_09() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I1 { abstract void I1.M1(); } "; var source2 = @" class Test1 : I2, I3 { } "; ValidateMethodReAbstraction_09(source1, source2); } private void ValidateMethodReAbstraction_09(string source1, string source2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); var expected = new DiagnosticDescription[] { // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15) }; compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1m1 = test1.InterfacesNoUseSiteDiagnostics().First().ContainingNamespace.GetTypeMember("I1").GetMember("M1"); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_10() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { void I1.M1() {} } public interface I3 : I1 { abstract void I1.M1(); } "; var source2 = @" class Test1 : I2, I3 { } "; ValidateMethodReAbstraction_09(source1, source2); } [Fact] public void MethodReAbstraction_11() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I1 { void I1.M1() {} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidateMethodReAbstraction_09(source1, source2); } [Fact] public void MethodReAbstraction_12() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I1 { abstract void I1.M1(); } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); var expected = new DiagnosticDescription[] { // (2,15): error CS8705: Interface member 'I1.M1()' does not have a most specific implementation. Neither 'I2.I1.M1()', nor 'I3.I1.M1()' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.M1()", "I2.I1.M1()", "I3.I1.M1()").WithLocation(2, 15) }; compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I4", i4.Name); var i1m1 = i4.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i4.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void MethodReAbstraction_13() { var source1 = @" public interface I1 { void M1() {} } public interface I2 : I1 { abstract void I1.M1(); } public interface I3 : I1 { abstract void I1.M1(); } public interface I4 : I2, I3 { void I1.M1() { System.Console.WriteLine(""I4.M1""); } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); i1.M1(); } } "; var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I4.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? "I4.M1" : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I4", i4.Name); var i1m1 = i4.ContainingNamespace.GetTypeMember("I1").GetMember("M1"); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Equal("void I4.I1.M1()", i4.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); Assert.Equal("void I4.I1.M1()", test1.FindImplementationForInterfaceMember(i1m1).ToTestDisplayString()); } } [Fact] public void MethodReAbstraction_14() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract void I1.M1() {} } class Test1 : I2 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics( // (9,22): error CS0500: 'I2.I1.M1()' cannot declare a body because it is marked abstract // abstract void I1.M1() {} Diagnostic(ErrorCode.ERR_AbstractHasBody, "M1").WithArguments("I2.I1.M1()").WithLocation(9, 22), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) ); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); ValidateReabstraction(i2m1); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_15() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract extern void I1.M1(); } class Test1 : I2 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics( // (9,29): error CS0180: 'I2.I1.M1()' cannot be both extern and abstract // abstract extern void I1.M1(); Diagnostic(ErrorCode.ERR_AbstractAndExtern, "M1").WithArguments("I2.I1.M1()").WithLocation(9, 29), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) ); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); Assert.True(i2m1.IsMetadataVirtual()); Assert.True(i2m1.IsMetadataFinal); Assert.False(i2m1.IsMetadataNewSlot()); Assert.True(i2m1.IsAbstract); Assert.False(i2m1.IsVirtual); Assert.True(i2m1.IsSealed); Assert.False(i2m1.IsStatic); Assert.True(i2m1.IsExtern); Assert.False(i2m1.IsAsync); Assert.False(i2m1.IsOverride); Assert.Equal(Accessibility.Private, i2m1.DeclaredAccessibility); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_16() { var source1 = @" public interface I1 { void M1(); } public partial interface I2 : I1 { abstract partial void I1.M1(); } class Test1 : I2 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics( // (9,30): error CS0754: A partial method may not explicitly implement an interface method // abstract partial void I1.M1(); Diagnostic(ErrorCode.ERR_PartialMethodNotExplicit, "M1").WithLocation(9, 30), // (9,30): error CS0750: A partial method cannot have access modifiers or the virtual, abstract, override, new, sealed, or extern modifiers // abstract partial void I1.M1(); Diagnostic(ErrorCode.ERR_PartialMethodInvalidModifier, "M1").WithLocation(9, 30), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) ); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); ValidateReabstraction(i2m1); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_17() { var source1 = @" public interface I1 { void M1(); } public partial interface I2 : I1 { abstract async void I1.M1(); } class Test1 : I2 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics( // (9,28): error CS1994: The 'async' modifier can only be used in methods that have a body. // abstract async void I1.M1(); Diagnostic(ErrorCode.ERR_BadAsyncLacksBody, "M1").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) ); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); Assert.True(i2m1.IsMetadataVirtual()); Assert.True(i2m1.IsMetadataFinal); Assert.False(i2m1.IsMetadataNewSlot()); Assert.True(i2m1.IsAbstract); Assert.False(i2m1.IsVirtual); Assert.True(i2m1.IsSealed); Assert.False(i2m1.IsStatic); Assert.False(i2m1.IsExtern); Assert.True(i2m1.IsAsync); Assert.False(i2m1.IsOverride); Assert.Equal(Accessibility.Private, i2m1.DeclaredAccessibility); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_18() { var source1 = @" public interface I1 { void M1(); } public partial interface I2 : I1 { abstract public void I1.M1(); } class Test1 : I2 { } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics( // (9,29): error CS0106: The modifier 'public' is not valid for this item // abstract public void I1.M1(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("public").WithLocation(9, 29), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.M1()' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.M1()").WithLocation(12, 15) ); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); ValidateReabstraction(i2m1); var i1m1 = i2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Null(i2.FindImplementationForInterfaceMember(i1m1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_19() { var source1 = @" public interface I1 { void M1(); } public class C2 : I1 { abstract void I1.M1(); } "; ValidateMethodReAbstraction_19(source1); } private static void ValidateMethodReAbstraction_19(string source1) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics( // (9,22): error CS0106: The modifier 'abstract' is not valid for this item // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_BadMemberFlag, "M1").WithArguments("abstract").WithLocation(9, 22), // (9,22): error CS0501: 'C2.I1.M1()' must declare a body because it is not marked abstract, extern, or partial // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "M1").WithArguments("C2.I1.M1()").WithLocation(9, 22) ); static void validate(ModuleSymbol m) { var c2 = m.GlobalNamespace.GetTypeMember("C2"); var c2m1 = c2.GetMember("I1.M1"); Assert.False(c2m1.IsAbstract); Assert.False(c2m1.IsSealed); var i1m1 = c2m1.ExplicitInterfaceImplementations.Single(); Assert.Equal("void I1.M1()", i1m1.ToTestDisplayString()); Assert.Same(c2m1, c2.FindImplementationForInterfaceMember(i1m1)); } } [Fact] public void MethodReAbstraction_20() { var source1 = @" public interface I1 { void M1(); } public struct C2 : I1 { abstract void I1.M1(); } "; ValidateMethodReAbstraction_19(source1); } [Fact] public void MethodReAbstraction_21() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract void I1.M1(); } class Test1 : I2 { } "; ValidateMethodReAbstraction_21(source1, // (8,22): error CS0539: 'I2.M1()' in explicit interface declaration is not found among members of the interface that can be implemented // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "M1").WithArguments("I2.M1()").WithLocation(8, 22) ); } private static void ValidateMethodReAbstraction_21(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2m1 = i2.GetMember("I1.M1"); ValidateReabstraction(i2m1); Assert.Empty(i2m1.ExplicitInterfaceImplementations); } } [Fact] public void MethodReAbstraction_22() { var source1 = @" public interface I2 : I1 { abstract void I1.M1(); } class Test1 : I2 { } "; ValidateMethodReAbstraction_21(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,19): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 19), // (4,19): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 19) ); } [Fact] public void MethodReAbstraction_23() { var source1 = @" public interface I1 { void M1(); } public interface I2 : I1 { abstract void I1.M1(); } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,22): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "M1").WithArguments("default interface implementation", "8.0").WithLocation(9, 22) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,22): error CS8701: Target runtime doesn't support default interface implementation. // abstract void I1.M1(); Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "M1").WithLocation(9, 22) ); } [Fact] public void PropertyReAbstraction_001() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 {get; set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } private static void ValidatePropertyReAbstraction_001(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); ValidateReabstraction(i2p1); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } else if (i2p1.GetMethod is object) { Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); } if (i1p1.SetMethod is object) { Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } else if (i2p1.SetMethod is object) { Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); } } } private static void ValidateReabstraction(PropertySymbol reabstracting) { Assert.True(reabstracting.IsAbstract); Assert.False(reabstracting.IsVirtual); Assert.True(reabstracting.IsSealed); Assert.False(reabstracting.IsStatic); Assert.False(reabstracting.IsExtern); Assert.False(reabstracting.IsOverride); Assert.Equal(Accessibility.Private, reabstracting.DeclaredAccessibility); if (reabstracting.GetMethod is object) { ValidateReabstraction(reabstracting.GetMethod); } if (reabstracting.SetMethod is object) { ValidateReabstraction(reabstracting.SetMethod); } } [Fact] public void PropertyReAbstraction_002() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_003() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 {get; set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; i1.P1 = 1; } int I1.P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set => System.Console.WriteLine(""Test1.set_P1""); } } "; ValidatePropertyReAbstraction_003(source1, source2, @" Test1.get_P1 Test1.set_P1 "); } private void ValidatePropertyReAbstraction_003(string source1, string source2, string expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test12p1 = test1.GetMembers().OfType().Single(); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Same(test12p1, test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Same(test12p1.GetMethod, test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } if (i1p1.SetMethod is object) { Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Same(test12p1.SetMethod, test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_004() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; i1.P1 = 1; } int I1.P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set => System.Console.WriteLine(""Test1.set_P1""); } } "; ValidatePropertyReAbstraction_003(source1, source2, @" Test1.get_P1 Test1.set_P1 "); } [Fact] public void PropertyReAbstraction_005() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } private static void ValidatePropertyReAbstraction_005(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I3", i3.Name); var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Null(i3.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } if (i1p1.SetMethod is object) { Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } } } [Fact] public void PropertyReAbstraction_006() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_007() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I2 { int I1.P1 { get { System.Console.WriteLine(""I3.get_P1""); return 0; } set => System.Console.WriteLine(""I3.set_P1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; i1.P1 = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, @" I3.get_P1 I3.set_P1 "); } private void ValidatePropertyReAbstraction_007(string source1, string source2, string expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I3", i3.Name); var i3p1 = i3.GetMembers().OfType().Single(); var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Same(i3p1, i3.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i3p1, test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Same(i3p1.GetMethod, i3.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Same(i3p1.GetMethod, test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } if (i1p1.SetMethod is object) { Assert.Same(i3p1.SetMethod, i3.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Same(i3p1.SetMethod, test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_008() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I2 { int I1.P1 { get { System.Console.WriteLine(""I3.get_P1""); return 0; } set => System.Console.WriteLine(""I3.set_P1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; i1.P1 = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, @" I3.get_P1 I3.set_P1 "); } [Fact] public void PropertyReAbstraction_009() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I1 { abstract int I1.P1 {get; set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } private static void ValidatePropertyReAbstraction_009(string source1, string source2, params DiagnosticDescription[] expected) { ValidatePropertyReAbstraction_009(source1, source2, expected, expected); } private static void ValidatePropertyReAbstraction_009(string source1, string source2, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); var expected = expected1; foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); expected = expected2; } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1p1 = test1.InterfacesNoUseSiteDiagnostics().First().ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } if (i1p1.SetMethod is object) { Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } } } [Fact] public void PropertyReAbstraction_010() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { int I1.P1 { get => throw null; set => throw null; } } public interface I3 : I1 { abstract int I1.P1 {get; set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_011() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I1 { int I1.P1 { get => throw null; set => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_012() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I1 { abstract int I1.P1 {get; set;} } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidatePropertyReAbstraction_012(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } private static void ValidatePropertyReAbstraction_012(string source1, string source2, params DiagnosticDescription[] expected) { ValidatePropertyReAbstraction_012(source1, source2, expected, expected); } private static void ValidatePropertyReAbstraction_012(string source1, string source2, DiagnosticDescription[] expected1, params DiagnosticDescription[] expected2) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected1); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); var expected = expected1; foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); expected = expected2; } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I4", i4.Name); var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Null(i4.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } if (i1p1.SetMethod is object) { Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_013() { var source1 = @" public interface I1 { int P1 { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get; set;} } public interface I3 : I1 { abstract int I1.P1 {get; set;} } public interface I4 : I2, I3 { int I1.P1 { get { System.Console.WriteLine(""I4.get_P1""); return 0; } set => System.Console.WriteLine(""I4.set_P1""); } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; i1.P1 = 1; } } "; ValidatePropertyReAbstraction_013(source1, source2, @" I4.get_P1 I4.set_P1 "); } private void ValidatePropertyReAbstraction_013(string source1, string source2, string expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I4", i4.Name); var i4p1 = i4.GetMembers().OfType().Single(); var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Same(i4p1, i4.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i4p1, test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Same(i4p1.GetMethod, i4.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Same(i4p1.GetMethod, test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } if (i1p1.SetMethod is object) { Assert.Same(i4p1.SetMethod, i4.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Same(i4p1.SetMethod, test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } } } [Fact] public void PropertyReAbstraction_014() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 { get { throw null; } set { throw null; } } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract // get Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), // (15,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract // set Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(15, 9), // (22,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(22, 15) ); } private static void ValidatePropertyReAbstraction_014(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); ValidateReabstraction(i2p1); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { if (i2p1.GetMethod is object) { Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); } Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } else if (i2p1.GetMethod is object) { Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); } if (i1p1.SetMethod is object) { if (i2p1.SetMethod is object) { Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); } Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } else if (i2p1.SetMethod is object) { Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); } } } [Fact] public void PropertyReAbstraction_015() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 { get => throw null; set => throw null; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), // (12,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract // set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(12, 9), // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) ); } [Fact] public void PropertyReAbstraction_016() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { extern abstract int I1.P1 {get; set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_016(source1, // (9,28): error CS0180: 'I2.I1.P1' cannot be both extern and abstract // extern abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I2.I1.P1").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } private static void ValidatePropertyReAbstraction_016(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); Assert.True(i2p1.IsAbstract); Assert.False(i2p1.IsVirtual); Assert.True(i2p1.IsSealed); Assert.False(i2p1.IsStatic); Assert.True(i2p1.IsExtern); Assert.False(i2p1.IsOverride); Assert.Equal(Accessibility.Private, i2p1.DeclaredAccessibility); var i2p1Get = i2p1.GetMethod; if (i2p1Get is object) { Assert.True(i2p1Get.IsMetadataVirtual()); Assert.True(i2p1Get.IsMetadataFinal); Assert.False(i2p1Get.IsMetadataNewSlot()); Assert.True(i2p1Get.IsAbstract); Assert.False(i2p1Get.IsVirtual); Assert.True(i2p1Get.IsSealed); Assert.False(i2p1Get.IsStatic); Assert.True(i2p1Get.IsExtern); Assert.False(i2p1Get.IsAsync); Assert.False(i2p1Get.IsOverride); Assert.Equal(Accessibility.Private, i2p1Get.DeclaredAccessibility); } var i2p1Set = i2p1.SetMethod; if (i2p1Set is object) { Assert.True(i2p1Set.IsMetadataVirtual()); Assert.True(i2p1Set.IsMetadataFinal); Assert.False(i2p1Set.IsMetadataNewSlot()); Assert.True(i2p1Set.IsAbstract); Assert.False(i2p1Set.IsVirtual); Assert.True(i2p1Set.IsSealed); Assert.False(i2p1Set.IsStatic); Assert.True(i2p1Set.IsExtern); Assert.False(i2p1Set.IsAsync); Assert.False(i2p1Set.IsOverride); Assert.Equal(Accessibility.Private, i2p1Set.DeclaredAccessibility); } var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } else if (i2p1.GetMethod is object) { Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); } if (i1p1.SetMethod is object) { Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } else if (i2p1.SetMethod is object) { Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); } } } [Fact] public void PropertyReAbstraction_017() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract public int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,28): error CS0106: The modifier 'public' is not valid for this item // abstract public int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_018() { var source1 = @" public interface I1 { int P1 {get; set;} } public class C2 : I1 { abstract int I1.P1 { get; set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) ); } private static void ValidatePropertyReAbstraction_018(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var c2 = m.GlobalNamespace.GetTypeMember("C2"); var c2p1 = c2.GetMembers().OfType().Single(); Assert.False(c2p1.IsAbstract); Assert.False(c2p1.IsSealed); var c2p1Get = c2p1.GetMethod; if (c2p1Get is object) { Assert.False(c2p1Get.IsAbstract); Assert.False(c2p1Get.IsSealed); } var c2p1Set = c2p1.SetMethod; if (c2p1Set is object) { Assert.False(c2p1Set.IsAbstract); Assert.False(c2p1Set.IsSealed); } var i1p1 = c2p1.ExplicitInterfaceImplementations.Single(); Assert.Same(c2p1, c2.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Same(i1p1.GetMethod, c2p1.GetMethod.ExplicitInterfaceImplementations.Single()); Assert.Same(c2p1Get, c2.FindImplementationForInterfaceMember(i1p1.GetMethod)); } else if (c2p1.GetMethod is object) { Assert.Empty(c2p1.GetMethod.ExplicitInterfaceImplementations); } if (i1p1.SetMethod is object) { Assert.Same(i1p1.SetMethod, c2p1.SetMethod.ExplicitInterfaceImplementations.Single()); Assert.Same(c2p1Set, c2.FindImplementationForInterfaceMember(i1p1.SetMethod)); } else if (c2p1.SetMethod is object) { Assert.Empty(c2p1.SetMethod.ExplicitInterfaceImplementations); } } } [Fact] public void PropertyReAbstraction_019() { var source1 = @" public interface I1 { int P1 {get; set;} } public struct C2 : I1 { abstract int I1.P1 { get; set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) ); } [Fact] public void PropertyReAbstraction_020() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 { get; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.set' // abstract int I1.P1 { get; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.set").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_021() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 { set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.get' // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.get").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_022() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,31): error CS0550: 'I2.I1.P1.set' adds an accessor not found in interface member 'I1.P1' // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.P1.set", "I1.P1").WithLocation(9, 31), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_023() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,26): error CS0550: 'I2.I1.P1.get' adds an accessor not found in interface member 'I1.P1' // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.P1.get", "I1.P1").WithLocation(9, 26), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_024() { var source1 = @" public interface I1 { int P1 {get => throw null; private set => throw null;} } public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,31): error CS0550: 'I2.I1.P1.set' adds an accessor not found in interface member 'I1.P1' // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.P1.set", "I1.P1").WithLocation(9, 31), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_025() { var source1 = @" public interface I1 { int P1 {private get => throw null; set => throw null;} } public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,26): error CS0550: 'I2.I1.P1.get' adds an accessor not found in interface member 'I1.P1' // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.P1.get", "I1.P1").WithLocation(9, 26), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_026() { var source1 = @" public interface I1 { internal int P1 {get => throw null; set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.P1' is inaccessible due to its protection level // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); } private static void ValidatePropertyReAbstraction_026(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, references: new[] { reference }, targetFramework: TargetFramework.NetStandardLatest); validate(compilation2.SourceModule); compilation2.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); ValidateReabstraction(i2p1); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.GetMethod is object) { Assert.Same(i1p1.GetMethod, i2p1.GetMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.GetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.GetMethod)); } else if (i2p1.GetMethod is object) { Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); } if (i1p1.SetMethod is object) { Assert.Same(i1p1.SetMethod, i2p1.SetMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.SetMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.SetMethod)); } else if (i2p1.SetMethod is object) { Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); } } } [Fact] public void PropertyReAbstraction_027() { var source1 = @" public interface I1 { int P1 {internal get => throw null; set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.P1.get' is inaccessible due to its protection level // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.get").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); } [Fact] public void PropertyReAbstraction_028() { var source1 = @" public interface I1 { int P1 {get => throw null; internal set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.P1 { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.P1.set' is inaccessible due to its protection level // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1.set").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_029() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 // Code size 3 (0x3) .maxstack 8 IL_0000: ldc.i4.s 65 IL_0002: ret } // end of method I2::I1.get_F1 .method private hidebysig specialname abstract virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 } // end of method I2::I1.set_F1 .property instance char I1.F1() { .get instance char I2::I1.get_F1() .set instance void I2::I1.set_F1(char) } // end of property I2::I1.F1 } // end of class I2 "; var source1 = @" class Test2 : I2 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); Assert.Equal("System.Char I2.I1.get_F1()", test2.FindImplementationForInterfaceMember(i1F1.GetMethod).ToTestDisplayString()); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_030() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname abstract virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 } // end of method I2::I1.get_F1 .method private hidebysig specialname virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 IL_0002: ret } // end of method I2::I1.set_F1 .property instance char I1.F1() { .get instance char I2::I1.get_F1() .set instance void I2::I1.set_F1(char) } // end of property I2::I1.F1 } // end of class I2 "; var source1 = @" class Test2 : I2 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Equal("void I2.I1.set_F1(System.Char value)", test2.FindImplementationForInterfaceMember(i1F1.SetMethod).ToTestDisplayString()); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_031() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 // Code size 3 (0x3) .maxstack 8 IL_0000: ldc.i4.s 65 IL_0002: ret } // end of method I2::I1.get_F1 .method private hidebysig specialname abstract virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 } // end of method I2::I1.set_F1 .property instance char I1.F1() { .get instance char I2::I1.get_F1() .set instance void I2::I1.set_F1(char) } // end of property I2::I1.F1 } // end of class I2 .class interface public abstract auto ansi I3 implements I1 { .method private hidebysig specialname abstract virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 } // end of method I3::I1.get_F1 .method private hidebysig specialname virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 IL_0002: ret } // end of method I3::I1.set_F1 .property instance char I1.F1() { .get instance char I3::I1.get_F1() .set instance void I3::I1.set_F1(char) } // end of property I3::I1.F1 } // end of class I3 "; var source1 = @" class Test2 : I2, I3 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS8705: Interface member 'I1.F1' does not have a most specific implementation. Neither 'I2.I1.F1', nor 'I3.I1.F1' are most specific. // class Test2 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.F1", "I2.I1.F1", "I3.I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_032() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 // Code size 3 (0x3) .maxstack 8 IL_0000: ldc.i4.s 65 IL_0002: ret } // end of method I2::I1.get_F1 .method private hidebysig specialname abstract virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 } // end of method I2::I1.set_F1 } // end of class I2 "; var source1 = @" class Test2 : I2 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); Assert.Equal("System.Char I2.I1.get_F1()", test2.FindImplementationForInterfaceMember(i1F1.GetMethod).ToTestDisplayString()); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_033() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname abstract virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 } // end of method I2::I1.get_F1 .method private hidebysig specialname virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 IL_0002: ret } // end of method I2::I1.set_F1 } // end of class I2 "; var source1 = @" class Test2 : I2 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Equal("void I2.I1.set_F1(System.Char value)", test2.FindImplementationForInterfaceMember(i1F1.SetMethod).ToTestDisplayString()); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_034() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 // Code size 3 (0x3) .maxstack 8 IL_0000: ldc.i4.s 65 IL_0002: ret } // end of method I2::I1.get_F1 .method private hidebysig specialname abstract virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 } // end of method I2::I1.set_F1 } // end of class I2 .class interface public abstract auto ansi I3 implements I1 { .method private hidebysig specialname abstract virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 } // end of method I3::I1.get_F1 .method private hidebysig specialname virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 IL_0002: ret } // end of method I3::I1.set_F1 .property instance char I1.F1() { .get instance char I3::I1.get_F1() .set instance void I3::I1.set_F1(char) } // end of property I3::I1.F1 } // end of class I3 "; var source1 = @" class Test2 : I2, I3 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2, I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_035() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 // Code size 3 (0x3) .maxstack 8 IL_0000: ldc.i4.s 65 IL_0002: ret } // end of method I2::I1.get_F1 .method private hidebysig specialname abstract virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 } // end of method I2::I1.set_F1 .property instance char I1.F1() { .get instance char I2::I1.get_F1() .set instance void I2::I1.set_F1(char) } // end of property I2::I1.F1 } // end of class I2 .class interface public abstract auto ansi I3 implements I1 { .method private hidebysig specialname abstract virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 } // end of method I3::I1.get_F1 .method private hidebysig specialname virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 IL_0002: ret } // end of method I3::I1.set_F1 } // end of class I3 "; var source1 = @" class Test2 : I2, I3 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2, I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); } [ConditionalFact(typeof(MonoOrCoreClrOnly))] public void PropertyReAbstraction_036() { var ilSource = @" .class interface public abstract auto ansi I1 { .method public hidebysig newslot specialname abstract virtual instance char get_F1() cil managed { } // end of method I1::get_F1 .method public hidebysig newslot specialname abstract virtual instance void set_F1(char 'value') cil managed { } // end of method I1::set_F1 .property instance char F1() { .get instance char I1::get_F1() .set instance void I1::set_F1(char) } // end of property I1::F1 } // end of class I1 .class interface public abstract auto ansi I2 implements I1 { .method private hidebysig specialname virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 // Code size 3 (0x3) .maxstack 8 IL_0000: ldc.i4.s 65 IL_0002: ret } // end of method I2::I1.get_F1 .method private hidebysig specialname abstract virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 } // end of method I2::I1.set_F1 } // end of class I2 .class interface public abstract auto ansi I3 implements I1 { .method private hidebysig specialname abstract virtual final instance char I1.get_F1() cil managed { .override I1::get_F1 } // end of method I3::I1.get_F1 .method private hidebysig specialname virtual final instance void I1.set_F1(char 'value') cil managed { .override I1::set_F1 IL_0002: ret } // end of method I3::I1.set_F1 } // end of class I3 "; var source1 = @" class Test2 : I2, I3 { } "; var compilation1 = CreateCompilationWithIL(source1, ilSource, options: TestOptions.DebugDll, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (2,15): error CS0535: 'Test2' does not implement interface member 'I1.F1' // class Test2 : I2, I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test2", "I1.F1").WithLocation(2, 15) ); var i1 = compilation1.GetTypeByMetadataName("I1"); var i1F1 = i1.GetMember("F1"); var test2 = compilation1.GetTypeByMetadataName("Test2"); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.SetMethod)); Assert.Null(test2.FindImplementationForInterfaceMember(i1F1.GetMethod)); } [Fact] public void PropertyReAbstraction_037() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 {get;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_038() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_039() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 {get;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } int I1.P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_040() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } int I1.P1 { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); } [Fact] public void PropertyReAbstraction_041() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_042() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_043() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I2 { int I1.P1 { get { System.Console.WriteLine(""I3.get_P1""); return 0; } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_044() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I2 { int I1.P1 { get { System.Console.WriteLine(""I3.get_P1""); return 0; } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); } [Fact] public void PropertyReAbstraction_045() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I1 { abstract int I1.P1 {get;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_046() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { int I1.P1 { get => throw null; } } public interface I3 : I1 { abstract int I1.P1 {get;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_047() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I1 { int I1.P1 { get => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_048() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I1 { abstract int I1.P1 {get;} } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidatePropertyReAbstraction_012(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_049() { var source1 = @" public interface I1 { int P1 { get => throw null; } } public interface I2 : I1 { abstract int I1.P1 {get;} } public interface I3 : I1 { abstract int I1.P1 {get;} } public interface I4 : I2, I3 { int I1.P1 { get { System.Console.WriteLine(""I4.get_P1""); return 0; } } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); _ = i1.P1; } } "; ValidatePropertyReAbstraction_013(source1, source2, "I4.get_P1"); } [Fact] public void PropertyReAbstraction_050() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 { get { throw null; } } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract // get Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(18, 15) ); } [Fact] public void PropertyReAbstraction_051() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 { get => throw null; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.P1.get").WithLocation(11, 9), // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(15, 15) ); } [Fact] public void PropertyReAbstraction_052() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 => throw null; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,27): error CS0500: 'I2.I1.P1.get' cannot declare a body because it is marked abstract // abstract int I1.P1 => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "throw null").WithArguments("I2.I1.P1.get").WithLocation(9, 27), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_053() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { extern abstract int I1.P1 {get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_016(source1, // (9,28): error CS0180: 'I2.I1.P1' cannot be both extern and abstract // extern abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I2.I1.P1").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_054() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract public int I1.P1 { get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,28): error CS0106: The modifier 'public' is not valid for this item // abstract public int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_055() { var source1 = @" public interface I1 { int P1 {get;} } public class C2 : I1 { abstract int I1.P1 { get; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) ); } [Fact] public void PropertyReAbstraction_056() { var source1 = @" public interface I1 { int P1 {get;} } public struct C2 : I1 { abstract int I1.P1 { get; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21) ); } [Fact] public void PropertyReAbstraction_057() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 { get; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.set' // abstract int I1.P1 { get; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.set").WithLocation(9, 21), // (9,26): error CS0550: 'I2.I1.P1.get' adds an accessor not found in interface member 'I1.P1' // abstract int I1.P1 { get; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.P1.get", "I1.P1").WithLocation(9, 26), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_058() { var source1 = @" public interface I1 { internal int P1 {get => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.P1 { get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.P1' is inaccessible due to its protection level // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); } [Fact] public void PropertyReAbstraction_059() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 {set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_060() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_061() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 {set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } int I1.P1 { set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_062() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } int I1.P1 { set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); } [Fact] public void PropertyReAbstraction_063() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_064() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_065() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I2 { int I1.P1 { set { System.Console.WriteLine(""I3.set_P1""); } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_066() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I2 { int I1.P1 { set { System.Console.WriteLine(""I3.set_P1""); } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); } [Fact] public void PropertyReAbstraction_067() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I1 { abstract int I1.P1 {set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_068() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { int I1.P1 { set => throw null; } } public interface I3 : I1 { abstract int I1.P1 {set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_069() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I1 { int I1.P1 { set => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void PropertyReAbstraction_070() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I1 { abstract int I1.P1 {set;} } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidatePropertyReAbstraction_012(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void PropertyReAbstraction_071() { var source1 = @" public interface I1 { int P1 { set => throw null; } } public interface I2 : I1 { abstract int I1.P1 {set;} } public interface I3 : I1 { abstract int I1.P1 {set;} } public interface I4 : I2, I3 { int I1.P1 { set { System.Console.WriteLine(""I4.set_P1""); } } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); i1.P1 = 1; } } "; ValidatePropertyReAbstraction_013(source1, source2, "I4.set_P1"); } [Fact] public void PropertyReAbstraction_072() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 { set { throw null; } } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract // set Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(11, 9), // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(18, 15) ); } [Fact] public void PropertyReAbstraction_073() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 { set => throw null; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.P1.set' cannot declare a body because it is marked abstract // set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.P1.set").WithLocation(11, 9), // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(15, 15) ); } [Fact] public void PropertyReAbstraction_074() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { extern abstract int I1.P1 {set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_016(source1, // (9,28): error CS0180: 'I2.I1.P1' cannot be both extern and abstract // extern abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "P1").WithArguments("I2.I1.P1").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_075() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract public int I1.P1 { set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,28): error CS0106: The modifier 'public' is not valid for this item // abstract public int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_076() { var source1 = @" public interface I1 { int P1 {set;} } public class C2 : I1 { abstract int I1.P1 { set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21), // (9,26): error CS8051: Auto-implemented properties must have get accessors. // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_AutoPropertyMustHaveGetAccessor, "set").WithArguments("C2.I1.P1.set").WithLocation(9, 26) ); } [Fact] public void PropertyReAbstraction_077() { var source1 = @" public interface I1 { int P1 {set;} } public struct C2 : I1 { abstract int I1.P1 { set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 21), // (9,26): error CS8051: Auto-implemented properties must have get accessors. // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_AutoPropertyMustHaveGetAccessor, "set").WithArguments("C2.I1.P1.set").WithLocation(9, 26) ); } [Fact] public void PropertyReAbstraction_078() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 { set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.P1' is missing accessor 'I1.P1.get' // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "P1").WithArguments("I2.I1.P1", "I1.P1.get").WithLocation(9, 21), // (9,26): error CS0550: 'I2.I1.P1.set' adds an accessor not found in interface member 'I1.P1' // abstract int I1.P1 { set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.P1.set", "I1.P1").WithLocation(9, 26), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_079() { var source1 = @" public interface I1 { internal int P1 {set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.P1 { set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.P1' is inaccessible due to its protection level // abstract int I1.P1 { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); } [Fact] public void PropertyReAbstraction_080() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 { get; set; } = 0; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS8050: Only auto-implemented properties can have initializers. // abstract int I1.P1 { get; set; } = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I2.I1.P1").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_081() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 { get; } = 0; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS8050: Only auto-implemented properties can have initializers. // abstract int I1.P1 { get; } = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I2.I1.P1").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_082() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 { set; } = 0; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS8050: Only auto-implemented properties can have initializers. // abstract int I1.P1 { set; } = 0; Diagnostic(ErrorCode.ERR_InitializerOnNonAutoProperty, "P1").WithArguments("I2.I1.P1").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void PropertyReAbstraction_083() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract int I1.P1 {get; set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (8,21): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 21) ); } private static void ValidatePropertyReAbstraction_083(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); ValidateReabstraction(i2p1); Assert.Empty(i2p1.ExplicitInterfaceImplementations); if (i2p1.GetMethod is object) { Assert.Empty(i2p1.GetMethod.ExplicitInterfaceImplementations); } if (i2p1.SetMethod is object) { Assert.Empty(i2p1.SetMethod.ExplicitInterfaceImplementations); } } } [Fact] public void PropertyReAbstraction_084() { var source1 = @" public interface I2 : I1 { abstract int I1.P1 {get; set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) ); } [Fact] public void PropertyReAbstraction_085() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract int I1.P1 {get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (8,21): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 21) ); } [Fact] public void PropertyReAbstraction_086() { var source1 = @" public interface I2 : I1 { abstract int I1.P1 {get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract int I1.P1 {get;} Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract int I1.P1 {get;} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) ); } [Fact] public void PropertyReAbstraction_087() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract int I1.P1 {set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (8,21): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 21) ); } [Fact] public void PropertyReAbstraction_088() { var source1 = @" public interface I2 : I1 { abstract int I1.P1 {set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract int I1.P1 {set;} Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract int I1.P1 {set;} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) ); } [Fact] public void PropertyReAbstraction_089() { var source1 = @" public interface I1 { int P1 {get; set;} } public interface I2 : I1 { abstract int I1.P1 {get; set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,25): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 25), // (9,30): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(9, 30) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,25): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 25), // (9,30): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.P1 {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 30) ); } [Fact] public void PropertyReAbstraction_090() { var source1 = @" public interface I1 { int P1 {get;} } public interface I2 : I1 { abstract int I1.P1 {get;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,25): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.P1 {get;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 25) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,25): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.P1 {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 25) ); } [Fact] public void PropertyReAbstraction_091() { var source1 = @" public interface I1 { int P1 {set;} } public interface I2 : I1 { abstract int I1.P1 {set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,25): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.P1 {set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(9, 25) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,25): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.P1 {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 25) ); } [Fact] public void EventReAbstraction_001() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1; } "; var source2 = @" class Test1 : I2 { } "; ValidateEventReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } private static void ValidateEventReAbstraction_001(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); ValidateReabstraction(i2p1); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i1p1.AddMethod, i2p1.AddMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(i1p1.RemoveMethod, i2p1.RemoveMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } private static void ValidateReabstraction(EventSymbol reabstracting) { Assert.True(reabstracting.IsAbstract); Assert.False(reabstracting.IsVirtual); Assert.True(reabstracting.IsSealed); Assert.False(reabstracting.IsStatic); Assert.False(reabstracting.IsExtern); Assert.False(reabstracting.IsOverride); Assert.Equal(Accessibility.Private, reabstracting.DeclaredAccessibility); if (reabstracting.AddMethod is object) { ValidateReabstraction(reabstracting.AddMethod); } if (reabstracting.RemoveMethod is object) { ValidateReabstraction(reabstracting.RemoveMethod); } } [Fact] public void EventReAbstraction_002() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } "; var source2 = @" class Test1 : I2 { } "; ValidateEventReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void EventReAbstraction_003() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1; } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1.P1 += null; i1.P1 -= null; } event System.Action I1.P1 { add { System.Console.WriteLine(""Test1.add_P1""); } remove => System.Console.WriteLine(""Test1.remove_P1""); } } "; ValidateEventReAbstraction_003(source1, source2, @" Test1.add_P1 Test1.remove_P1 "); } private void ValidateEventReAbstraction_003(string source1, string source2, string expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var test12p1 = test1.GetMembers().OfType().Single(); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Same(test12p1, test1.FindImplementationForInterfaceMember(i1p1)); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(test12p1.AddMethod, test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Same(test12p1.RemoveMethod, test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void EventReAbstraction_004() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1.P1 += null; i1.P1 -= null; } event System.Action I1.P1 { add { System.Console.WriteLine(""Test1.add_P1""); } remove => System.Console.WriteLine(""Test1.remove_P1""); } } "; ValidateEventReAbstraction_003(source1, source2, @" Test1.add_P1 Test1.remove_P1 "); } [Fact] public void EventReAbstraction_005() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidateEventReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } private static void ValidateEventReAbstraction_005(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I3", i3.Name); var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Null(i3.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(i3.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] public void EventReAbstraction_006() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidateEventReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.P1").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void EventReAbstraction_007() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I2 { event System.Action I1.P1 { add { System.Console.WriteLine(""I3.add_P1""); } remove => System.Console.WriteLine(""I3.remove_P1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1.P1 += null; i1.P1 -= null; } } "; ValidateEventReAbstraction_007(source1, source2, @" I3.add_P1 I3.remove_P1 "); } private void ValidateEventReAbstraction_007(string source1, string source2, string expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i3 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I3", i3.Name); var i3p1 = i3.GetMembers().OfType().Single(); var i1p1 = i3.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Same(i3p1, i3.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i3p1, test1.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i3p1.AddMethod, i3.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(i3p1.AddMethod, test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(i3p1.RemoveMethod, i3.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Same(i3p1.RemoveMethod, test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void EventReAbstraction_008() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I2 { event System.Action I1.P1 { add { System.Console.WriteLine(""I3.add_P1""); } remove => System.Console.WriteLine(""I3.remove_P1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1.P1 += null; i1.P1 -= null; } } "; ValidateEventReAbstraction_007(source1, source2, @" I3.add_P1 I3.remove_P1 "); } [Fact] public void EventReAbstraction_009() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I1 { abstract event System.Action I1.P1; } "; var source2 = @" class Test1 : I2, I3 { } "; ValidateEventReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } private static void ValidateEventReAbstraction_009(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i1p1 = test1.InterfacesNoUseSiteDiagnostics().First().ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] public void EventReAbstraction_010() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { event System.Action I1.P1 { add => throw null; remove => throw null; } } public interface I3 : I1 { abstract event System.Action I1.P1; } "; var source2 = @" class Test1 : I2, I3 { } "; ValidateEventReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void EventReAbstraction_011() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I1 { event System.Action I1.P1 { add => throw null; remove => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidateEventReAbstraction_009(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } [Fact] public void EventReAbstraction_012() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I1 { abstract event System.Action I1.P1; } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidateEventReAbstraction_012(source1, source2, // (2,15): error CS8705: Interface member 'I1.P1' does not have a most specific implementation. Neither 'I2.I1.P1', nor 'I3.I1.P1' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.P1", "I2.I1.P1", "I3.I1.P1").WithLocation(2, 15) ); } private static void ValidateEventReAbstraction_012(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugDll, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I4", i4.Name); var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Null(i4.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(i4.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void EventReAbstraction_013() { var source1 = @" public interface I1 { event System.Action P1 { add => throw null; remove => throw null; } } public interface I2 : I1 { abstract event System.Action I1.P1; } public interface I3 : I1 { abstract event System.Action I1.P1; } public interface I4 : I2, I3 { event System.Action I1.P1 { add { System.Console.WriteLine(""I4.add_P1""); } remove => System.Console.WriteLine(""I4.remove_P1""); } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); i1.P1 += null; i1.P1 -= null; } } "; ValidateEventReAbstraction_013(source1, source2, @" I4.add_P1 I4.remove_P1 "); } private void ValidateEventReAbstraction_013(string source1, string source2, string expected) { var compilation1 = CreateCompilation(source2 + source1, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation2.VerifyDiagnostics(); foreach (var reference in new[] { compilation2.ToMetadataReference(), compilation2.EmitToImageReference() }) { var compilation3 = CreateCompilation(source2, options: TestOptions.DebugExe, references: new[] { reference }, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation3.SourceModule); compilation3.VerifyDiagnostics(); CompileAndVerify(compilation1, expectedOutput: ExecutionConditionUtil.IsMonoOrCoreClr ? expected : null, verify: VerifyOnMonoOrCoreClr, symbolValidator: validate); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i4 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I4", i4.Name); var i4p1 = i4.GetMembers().OfType().Single(); var i1p1 = i4.ContainingNamespace.GetTypeMember("I1").GetMembers().OfType().Single(); Assert.Same(i4p1, i4.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i4p1, test1.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i4p1.AddMethod, i4.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(i4p1.AddMethod, test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(i4p1.RemoveMethod, i4.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Same(i4p1.RemoveMethod, test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] public void EventReAbstraction_014() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { add { throw null; } remove { throw null; } } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), // (22,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(22, 15) ); } private static void ValidateEventReAbstraction_014(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); ValidateReabstraction(i2p1); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); if (i1p1.AddMethod is object) { if (i2p1.AddMethod is object) { Assert.Same(i1p1.AddMethod, i2p1.AddMethod.ExplicitInterfaceImplementations.Single()); } Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); } else if (i2p1.AddMethod is object) { Assert.Empty(i2p1.AddMethod.ExplicitInterfaceImplementations); } if (i1p1.RemoveMethod is object) { if (i2p1.RemoveMethod is object) { Assert.Same(i1p1.RemoveMethod, i2p1.RemoveMethod.ExplicitInterfaceImplementations.Single()); } Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } else if (i2p1.RemoveMethod is object) { Assert.Empty(i2p1.RemoveMethod.ExplicitInterfaceImplementations); } } } [Fact] public void EventReAbstraction_015() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { add => throw null; remove => throw null; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) ); } [Fact] public void EventReAbstraction_016() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { extern abstract event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,44): error CS0106: The modifier 'extern' is not valid for this item // extern abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("extern").WithLocation(9, 44), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_017() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract public event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,44): error CS0106: The modifier 'public' is not valid for this item // abstract public event System.Action I1.P1; Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("public").WithLocation(9, 44), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_018() { var source1 = @" public interface I1 { event System.Action P1; } public class C2 : I1 { abstract event System.Action I1.P1; } "; ValidateEventReAbstraction_018(source1, // (7,19): error CS0535: 'C2' does not implement interface member 'I1.P1.remove' // public class C2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.remove").WithLocation(7, 19), // (7,19): error CS0535: 'C2' does not implement interface member 'I1.P1.add' // public class C2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.add").WithLocation(7, 19), // (9,37): error CS0071: An explicit interface implementation of an event must use event accessor syntax // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "P1").WithLocation(9, 37), // (9,37): error CS0106: The modifier 'abstract' is not valid for this item // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) ); } private static void ValidateEventReAbstraction_018(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var c2 = m.GlobalNamespace.GetTypeMember("C2"); var c2p1 = c2.GetMembers().OfType().Single(); Assert.False(c2p1.IsAbstract); Assert.False(c2p1.IsSealed); var i1p1 = c2p1.ExplicitInterfaceImplementations.Single(); Assert.Same(c2p1, c2.FindImplementationForInterfaceMember(i1p1)); var c2p1Add = c2p1.AddMethod; if (c2p1Add is object) { Assert.False(c2p1Add.IsAbstract); Assert.False(c2p1Add.IsSealed); Assert.Same(i1p1.AddMethod, c2p1Add.ExplicitInterfaceImplementations.Single()); Assert.Same(c2p1Add, c2.FindImplementationForInterfaceMember(i1p1.AddMethod)); } else { Assert.Null(c2.FindImplementationForInterfaceMember(i1p1.AddMethod)); } var c2p1Remove = c2p1.RemoveMethod; if (c2p1Remove is object) { Assert.False(c2p1Remove.IsAbstract); Assert.False(c2p1Remove.IsSealed); Assert.Same(i1p1.RemoveMethod, c2p1Remove.ExplicitInterfaceImplementations.Single()); Assert.Same(c2p1Remove, c2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } else { Assert.Null(c2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } } [Fact] public void EventReAbstraction_019() { var source1 = @" public interface I1 { event System.Action P1; } public class C2 : I1 { abstract event System.Action I1.P1 { add => throw null; remove => throw null; } } "; ValidateEventReAbstraction_018(source1, // (9,37): error CS0106: The modifier 'abstract' is not valid for this item // abstract event System.Action I1.P1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) ); } [Fact] public void EventReAbstraction_020() { var source1 = @" public interface I1 { event System.Action P1; } public struct C2 : I1 { abstract event System.Action I1.P1; } "; ValidateEventReAbstraction_018(source1, // (7,20): error CS0535: 'C2' does not implement interface member 'I1.P1.remove' // public struct C2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.remove").WithLocation(7, 20), // (7,20): error CS0535: 'C2' does not implement interface member 'I1.P1.add' // public struct C2 : I1 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I1").WithArguments("C2", "I1.P1.add").WithLocation(7, 20), // (9,37): error CS0071: An explicit interface implementation of an event must use event accessor syntax // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, "P1").WithLocation(9, 37), // (9,37): error CS0106: The modifier 'abstract' is not valid for this item // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) ); } [Fact] public void EventReAbstraction_021() { var source1 = @" public interface I1 { event System.Action P1; } public struct C2 : I1 { abstract event System.Action I1.P1 { add => throw null; remove => throw null; } } "; ValidateEventReAbstraction_018(source1, // (9,37): error CS0106: The modifier 'abstract' is not valid for this item // abstract event System.Action I1.P1 Diagnostic(ErrorCode.ERR_BadMemberFlag, "P1").WithArguments("abstract").WithLocation(9, 37) ); } [Fact] public void EventReAbstraction_022() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { add => throw null; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 { add => throw null; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_023() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { add; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 { add; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_024() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { remove => throw null; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 { remove => throw null; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_025() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { remove; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 { remove; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_026() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { add; remove; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 { add; remove; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_027() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 {} } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 {} Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_028() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 { add => throw null; remove => throw null; } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,40): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // abstract event System.Action I1.P1 { add => throw null; remove => throw null; } Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_029() { var source1 = @" public interface I1 { event System.Action P1 {add => throw null;} } public interface I2 : I1 { abstract event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors // event System.Action P1 {add => throw null;} Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_030() { var source1 = @" public interface I1 { event System.Action P1 {add => throw null;} } public interface I2 : I1 { abstract event System.Action I1.P1 { add {} remove {} } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors // event System.Action P1 {add => throw null;} Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) ); } [Fact] public void EventReAbstraction_031() { var source1 = @" public interface I1 { event System.Action P1 {remove => throw null;} } public interface I2 : I1 { abstract event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors // event System.Action P1 {remove => throw null;} Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_032() { var source1 = @" public interface I1 { event System.Action P1 {remove => throw null;} } public interface I2 : I1 { abstract event System.Action I1.P1 { add {} remove {} } } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (4,25): error CS0065: 'I1.P1': event property must have both add and remove accessors // event System.Action P1 {remove => throw null;} Diagnostic(ErrorCode.ERR_EventNeedsBothAccessors, "P1").WithArguments("I1.P1").WithLocation(4, 25), // (10,5): error CS8712: 'I2.I1.P1': abstract event cannot use event accessor syntax // { Diagnostic(ErrorCode.ERR_AbstractEventHasAccessors, "{").WithArguments("I2.I1.P1").WithLocation(10, 5), // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(16, 15) ); } [Fact] public void EventReAbstraction_033() { var source1 = @" public interface I1 { internal event System.Action P1 {add => throw null; remove => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_033(source1, source2, // (4,37): error CS0122: 'I1.P1' is inaccessible due to its protection level // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_BadAccess, "P1").WithArguments("I1.P1").WithLocation(4, 37), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(7, 15) ); } private static void ValidateEventReAbstraction_033(string source1, string source2, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics(); foreach (var reference in new[] { compilation1.ToMetadataReference(), compilation1.EmitToImageReference() }) { var compilation2 = CreateCompilation(source2, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, references: new[] { reference }, targetFramework: TargetFramework.NetStandardLatest); validate(compilation2.SourceModule); compilation2.VerifyDiagnostics(expected); } static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); var i1p1 = i2p1.ExplicitInterfaceImplementations.Single(); ValidateReabstraction(i2p1); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1)); Assert.Same(i1p1.AddMethod, i2p1.AddMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.AddMethod)); Assert.Same(i1p1.RemoveMethod, i2p1.RemoveMethod.ExplicitInterfaceImplementations.Single()); Assert.Null(i2.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); Assert.Null(test1.FindImplementationForInterfaceMember(i1p1.RemoveMethod)); } } [Fact] public void EventReAbstraction_034() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_034(source1, // (8,37): error CS0539: 'I2.P1' in explicit interface declaration is not found among members of the interface that can be implemented // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "P1").WithArguments("I2.P1").WithLocation(8, 37) ); } private static void ValidateEventReAbstraction_034(string source1, params DiagnosticDescription[] expected) { var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.NetStandardLatest); validate(compilation1.SourceModule); compilation1.VerifyDiagnostics(expected); static void validate(ModuleSymbol m) { var test1 = m.GlobalNamespace.GetTypeMember("Test1"); var i2 = test1.InterfacesNoUseSiteDiagnostics().First(); Assert.Equal("I2", i2.Name); var i2p1 = i2.GetMembers().OfType().Single(); ValidateReabstraction(i2p1); Assert.Empty(i2p1.ExplicitInterfaceImplementations); Assert.Empty(i2p1.AddMethod.ExplicitInterfaceImplementations); Assert.Empty(i2p1.RemoveMethod.ExplicitInterfaceImplementations); } } [Fact] public void EventReAbstraction_035() { var source1 = @" public interface I2 : I1 { abstract event System.Action I1.P1; } class Test1 : I2 { } "; ValidateEventReAbstraction_034(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,34): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 34), // (4,34): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 34) ); } [Fact] public void EventReAbstraction_036() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1 } class Test1 : I2 { } "; ValidateEventReAbstraction_014(source1, // (9,36): error CS0071: An explicit interface implementation of an event must use event accessor syntax // abstract event System.Action I1.P1 Diagnostic(ErrorCode.ERR_ExplicitEventFieldImpl, ".").WithLocation(9, 36), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.P1' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.P1").WithLocation(12, 15) ); } [Fact] public void EventReAbstraction_037() { var source1 = @" public interface I1 { event System.Action P1; } public interface I2 : I1 { abstract event System.Action I1.P1; } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,37): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "P1").WithArguments("default interface implementation", "8.0").WithLocation(9, 37) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,37): error CS8701: Target runtime doesn't support default interface implementation. // abstract event System.Action I1.P1; Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "P1").WithLocation(9, 37) ); } [Fact] public void IndexerReAbstraction_001() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_002() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_003() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; i1[0] = 1; } int I1.this[int i] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set => System.Console.WriteLine(""Test1.set_P1""); } } "; ValidatePropertyReAbstraction_003(source1, source2, @" Test1.get_P1 Test1.set_P1 "); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_004() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; i1[0] = 1; } int I1.this[int i] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } set => System.Console.WriteLine(""Test1.set_P1""); } } "; ValidatePropertyReAbstraction_003(source1, source2, @" Test1.get_P1 Test1.set_P1 "); } [Fact] public void IndexerReAbstraction_005() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_006() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_007() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I2 { int I1.this[int i] { get { System.Console.WriteLine(""I3.get_P1""); return 0; } set => System.Console.WriteLine(""I3.set_P1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; i1[0] = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, @" I3.get_P1 I3.set_P1 "); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_008() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I2 { int I1.this[int i] { get { System.Console.WriteLine(""I3.get_P1""); return 0; } set => System.Console.WriteLine(""I3.set_P1""); } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; i1[0] = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, @" I3.get_P1 I3.set_P1 "); } [Fact] public void IndexerReAbstraction_009() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I1 { abstract int I1.this[int i] {get; set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_010() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { int I1.this[int i] { get => throw null; set => throw null; } } public interface I3 : I1 { abstract int I1.this[int i] {get; set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_011() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I1 { int I1.this[int i] { get => throw null; set => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_012() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I1 { abstract int I1.this[int i] {get; set;} } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidatePropertyReAbstraction_012(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_013() { var source1 = @" public interface I1 { int this[int i] { get => throw null; set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } public interface I3 : I1 { abstract int I1.this[int i] {get; set;} } public interface I4 : I2, I3 { int I1.this[int i] { get { System.Console.WriteLine(""I4.get_P1""); return 0; } set => System.Console.WriteLine(""I4.set_P1""); } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; i1[0] = 1; } } "; ValidatePropertyReAbstraction_013(source1, source2, @" I4.get_P1 I4.set_P1 "); } [Fact] public void IndexerReAbstraction_014() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] { get { throw null; } set { throw null; } } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract // get Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), // (15,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract // set Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(15, 9), // (22,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(22, 15) ); } [Fact] public void IndexerReAbstraction_015() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] { get => throw null; set => throw null; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), // (12,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract // set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(12, 9), // (16,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(16, 15) ); } [Fact] public void IndexerReAbstraction_016() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { extern abstract int I1.this[int i] {get; set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_016(source1, // (9,28): error CS0180: 'I2.I1.this[int]' cannot be both extern and abstract // extern abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I2.I1.this[int]").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_017() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract public int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,28): error CS0106: The modifier 'public' is not valid for this item // abstract public int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_018() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public class C2 : I1 { abstract int I1.this[int i] { get; set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35), // (9,40): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 40) ); } [Fact] public void IndexerReAbstraction_019() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public struct C2 : I1 { abstract int I1.this[int i] { get; set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35), // (9,40): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 40) ); } [Fact] public void IndexerReAbstraction_020() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] { get; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].set' // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].set").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_021() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] { set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].get' // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].get").WithLocation(9, 21), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_022() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,40): error CS0550: 'I2.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.this[int].set", "I1.this[int]").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_023() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,35): error CS0550: 'I2.I1.this[int].get' adds an accessor not found in interface member 'I1.this[int]' // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.this[int].get", "I1.this[int]").WithLocation(9, 35), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_024() { var source1 = @" public interface I1 { int this[int i] {get => throw null; private set => throw null;} } public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,40): error CS0550: 'I2.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.this[int].set", "I1.this[int]").WithLocation(9, 40), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_025() { var source1 = @" public interface I1 { int this[int i] {private get => throw null; set => throw null;} } public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,35): error CS0550: 'I2.I1.this[int].get' adds an accessor not found in interface member 'I1.this[int]' // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.this[int].get", "I1.this[int]").WithLocation(9, 35), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_026() { var source1 = @" public interface I1 { internal int this[int i] {get => throw null; set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) ); } [Fact] public void IndexerReAbstraction_027() { var source1 = @" public interface I1 { int this[int i] {internal get => throw null; set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.this[int].get' is inaccessible due to its protection level // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int].get").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) ); } [Fact] public void IndexerReAbstraction_028() { var source1 = @" public interface I1 { int this[int i] {get => throw null; internal set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.this[int i] { get; set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.this[int].set' is inaccessible due to its protection level // abstract int I1.this[int i] { get; set; } Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int].set").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) ); } [Fact] public void IndexerReAbstraction_037() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] {get;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_038() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_039() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] {get;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } int I1.this[int i] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_040() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } int I1.this[int i] { get { System.Console.WriteLine(""Test1.get_P1""); return 0; } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.get_P1"); } [Fact] public void IndexerReAbstraction_041() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_042() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_043() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I2 { int I1.this[int i] { get { System.Console.WriteLine(""I3.get_P1""); return 0; } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_044() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I2 { int I1.this[int i] { get { System.Console.WriteLine(""I3.get_P1""); return 0; } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.get_P1"); } [Fact] public void IndexerReAbstraction_045() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I1 { abstract int I1.this[int i] {get;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_046() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { int I1.this[int i] { get => throw null; } } public interface I3 : I1 { abstract int I1.this[int i] {get;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_047() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I1 { int I1.this[int i] { get => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_048() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I1 { abstract int I1.this[int i] {get;} } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidatePropertyReAbstraction_012(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_049() { var source1 = @" public interface I1 { int this[int i] { get => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {get;} } public interface I3 : I1 { abstract int I1.this[int i] {get;} } public interface I4 : I2, I3 { int I1.this[int i] { get { System.Console.WriteLine(""I4.get_P1""); return 0; } } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); _ = i1[0]; } } "; ValidatePropertyReAbstraction_013(source1, source2, "I4.get_P1"); } [Fact] public void IndexerReAbstraction_050() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] { get { throw null; } } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract // get Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(18, 15) ); } [Fact] public void IndexerReAbstraction_051() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] { get => throw null; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract // get => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "get").WithArguments("I2.I1.this[int].get").WithLocation(11, 9), // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(15, 15) ); } [Fact] public void IndexerReAbstraction_052() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] => throw null; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,36): error CS0500: 'I2.I1.this[int].get' cannot declare a body because it is marked abstract // abstract int I1.this[int i] => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "throw null").WithArguments("I2.I1.this[int].get").WithLocation(9, 36), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_053() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { extern abstract int I1.this[int i] {get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_016(source1, // (9,28): error CS0180: 'I2.I1.this[int]' cannot be both extern and abstract // extern abstract int I1.this[int i] {get;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I2.I1.this[int]").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_054() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract public int I1.this[int i] { get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,28): error CS0106: The modifier 'public' is not valid for this item // abstract public int I1.this[int i] { get;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_055() { var source1 = @" public interface I1 { int this[int i] {get;} } public class C2 : I1 { abstract int I1.this[int i] { get; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35) ); } [Fact] public void IndexerReAbstraction_056() { var source1 = @" public interface I1 { int this[int i] {get;} } public struct C2 : I1 { abstract int I1.this[int i] { get; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), // (9,35): error CS0501: 'C2.I1.this[int].get' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "get").WithArguments("C2.I1.this[int].get").WithLocation(9, 35) ); } [Fact] public void IndexerReAbstraction_057() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] { get; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].set' // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].set").WithLocation(9, 21), // (9,35): error CS0550: 'I2.I1.this[int].get' adds an accessor not found in interface member 'I1.this[int]' // abstract int I1.this[int i] { get; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "get").WithArguments("I2.I1.this[int].get", "I1.this[int]").WithLocation(9, 35), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_058() { var source1 = @" public interface I1 { internal int this[int i] {get => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.this[int i] { get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // abstract int I1.this[int i] { get;} Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) ); } [Fact] public void IndexerReAbstraction_059() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] {set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_060() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } "; var source2 = @" class Test1 : I2 { } "; ValidatePropertyReAbstraction_001(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_061() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] {set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } int I1.this[int i] { set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_062() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } "; var source2 = @" class Test1 : I2 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } int I1.this[int i] { set { System.Console.WriteLine(""Test1.set_P1""); } } } "; ValidatePropertyReAbstraction_003(source1, source2, "Test1.set_P1"); } [Fact] public void IndexerReAbstraction_063() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_064() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I2 {} "; var source2 = @" class Test1 : I3 { } "; ValidatePropertyReAbstraction_005(source1, source2, // (2,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I3 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I3").WithArguments("Test1", "I1.this[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_065() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I2 { int I1.this[int i] { set { System.Console.WriteLine(""I3.set_P1""); } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_066() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I2 { int I1.this[int i] { set { System.Console.WriteLine(""I3.set_P1""); } } } "; var source2 = @" class Test1 : I3 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } } "; ValidatePropertyReAbstraction_007(source1, source2, "I3.set_P1"); } [Fact] public void IndexerReAbstraction_067() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I1 { abstract int I1.this[int i] {set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_068() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { int I1.this[int i] { set => throw null; } } public interface I3 : I1 { abstract int I1.this[int i] {set;} } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_069() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I1 { int I1.this[int i] { set => throw null; } } "; var source2 = @" class Test1 : I2, I3 { } "; ValidatePropertyReAbstraction_009(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I2, I3 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I2").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] public void IndexerReAbstraction_070() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I1 { abstract int I1.this[int i] {set;} } public interface I4 : I2, I3 {} "; var source2 = @" class Test1 : I4 { } "; ValidatePropertyReAbstraction_012(source1, source2, new[] { // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.this[int]', nor 'I3.I1.this[int]' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.this[int]", "I3.I1.this[int]").WithLocation(2, 15) }, // (2,15): error CS8705: Interface member 'I1.this[int]' does not have a most specific implementation. Neither 'I2.I1.Item[int]', nor 'I3.I1.Item[int]' are most specific. // class Test1 : I4 Diagnostic(ErrorCode.ERR_MostSpecificImplementationIsNotFound, "I4").WithArguments("I1.this[int]", "I2.I1.Item[int]", "I3.I1.Item[int]").WithLocation(2, 15) ); } [Fact] [WorkItem(35769, "https://github.com/dotnet/roslyn/issues/35769")] public void IndexerReAbstraction_071() { var source1 = @" public interface I1 { int this[int i] { set => throw null; } } public interface I2 : I1 { abstract int I1.this[int i] {set;} } public interface I3 : I1 { abstract int I1.this[int i] {set;} } public interface I4 : I2, I3 { int I1.this[int i] { set { System.Console.WriteLine(""I4.set_P1""); } } } "; var source2 = @" class Test1 : I4 { static void Main() { I1 i1 = new Test1(); i1[0] = 1; } } "; ValidatePropertyReAbstraction_013(source1, source2, "I4.set_P1"); } [Fact] public void IndexerReAbstraction_072() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] { set { throw null; } } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract // set Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(11, 9), // (18,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(18, 15) ); } [Fact] public void IndexerReAbstraction_073() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] { set => throw null; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (11,9): error CS0500: 'I2.I1.this[int].set' cannot declare a body because it is marked abstract // set => throw null; Diagnostic(ErrorCode.ERR_AbstractHasBody, "set").WithArguments("I2.I1.this[int].set").WithLocation(11, 9), // (15,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(15, 15) ); } [Fact] public void IndexerReAbstraction_074() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { extern abstract int I1.this[int i] {set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_016(source1, // (9,28): error CS0180: 'I2.I1.this[int]' cannot be both extern and abstract // extern abstract int I1.this[int i] {set;} Diagnostic(ErrorCode.ERR_AbstractAndExtern, "this").WithArguments("I2.I1.this[int]").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_075() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract public int I1.this[int i] { set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,28): error CS0106: The modifier 'public' is not valid for this item // abstract public int I1.this[int i] { set;} Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("public").WithLocation(9, 28), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_076() { var source1 = @" public interface I1 { int this[int i] {set;} } public class C2 : I1 { abstract int I1.this[int i] { set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), // (9,35): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 35) ); } [Fact] public void IndexerReAbstraction_077() { var source1 = @" public interface I1 { int this[int i] {set;} } public struct C2 : I1 { abstract int I1.this[int i] { set; } } "; ValidatePropertyReAbstraction_018(source1, // (9,21): error CS0106: The modifier 'abstract' is not valid for this item // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_BadMemberFlag, "this").WithArguments("abstract").WithLocation(9, 21), // (9,35): error CS0501: 'C2.I1.this[int].set' must declare a body because it is not marked abstract, extern, or partial // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_ConcreteMissingBody, "set").WithArguments("C2.I1.this[int].set").WithLocation(9, 35) ); } [Fact] public void IndexerReAbstraction_078() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] { set; } } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,21): error CS0551: Explicit interface implementation 'I2.I1.this[int]' is missing accessor 'I1.this[int].get' // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyMissingAccessor, "this").WithArguments("I2.I1.this[int]", "I1.this[int].get").WithLocation(9, 21), // (9,35): error CS0550: 'I2.I1.this[int].set' adds an accessor not found in interface member 'I1.this[int]' // abstract int I1.this[int i] { set; } Diagnostic(ErrorCode.ERR_ExplicitPropertyAddingAccessor, "set").WithArguments("I2.I1.this[int].set", "I1.this[int]").WithLocation(9, 35), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_079() { var source1 = @" public interface I1 { internal int this[int i] {set => throw null;} } "; var source2 = @" public interface I2 : I1 { abstract int I1.this[int i] { set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_026(source1, source2, // (4,21): error CS0122: 'I1.this[int]' is inaccessible due to its protection level // abstract int I1.this[int i] { set;} Diagnostic(ErrorCode.ERR_BadAccess, "this").WithArguments("I1.this[int]").WithLocation(4, 21), // (7,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(7, 15) ); } [Fact] public void IndexerReAbstraction_080() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] { get; set; } = 0; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,47): error CS1519: Invalid token '=' in class, struct, or interface member declaration // abstract int I1.this[int i] { get; set; } = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(9, 47), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_081() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] { get; } = 0; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,42): error CS1519: Invalid token '=' in class, struct, or interface member declaration // abstract int I1.this[int i] { get; } = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(9, 42), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_082() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] { set; } = 0; } class Test1 : I2 { } "; ValidatePropertyReAbstraction_014(source1, // (9,42): error CS1519: Invalid token '=' in class, struct, or interface member declaration // abstract int I1.this[int i] { set; } = 0; Diagnostic(ErrorCode.ERR_InvalidMemberDecl, "=").WithArguments("=").WithLocation(9, 42), // (12,15): error CS0535: 'Test1' does not implement interface member 'I1.this[int]' // class Test1 : I2 Diagnostic(ErrorCode.ERR_UnimplementedInterfaceMember, "I2").WithArguments("Test1", "I1.this[int]").WithLocation(12, 15) ); } [Fact] public void IndexerReAbstraction_083() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (8,21): error CS0539: 'I2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("I2.this[int]").WithLocation(8, 21) ); } [Fact] public void IndexerReAbstraction_084() { var source1 = @" public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) ); } [Fact] public void IndexerReAbstraction_085() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract int I1.this[int i] {get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (8,21): error CS0539: 'I2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // abstract int I1.this[int i] {get;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("I2.this[int]").WithLocation(8, 21) ); } [Fact] public void IndexerReAbstraction_086() { var source1 = @" public interface I2 : I1 { abstract int I1.this[int i] {get;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract int I1.this[int i] {get;} Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract int I1.this[int i] {get;} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) ); } [Fact] public void IndexerReAbstraction_087() { var source1 = @" public interface I1 { } public interface I2 : I1 { abstract int I1.this[int i] {set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (8,21): error CS0539: 'I2.this[int]' in explicit interface declaration is not found among members of the interface that can be implemented // abstract int I1.this[int i] {set;} Diagnostic(ErrorCode.ERR_InterfaceMemberNotFound, "this").WithArguments("I2.this[int]").WithLocation(8, 21) ); } [Fact] public void IndexerReAbstraction_088() { var source1 = @" public interface I2 : I1 { abstract int I1.this[int i] {set;} } class Test1 : I2 { } "; ValidatePropertyReAbstraction_083(source1, // (2,23): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // public interface I2 : I1 Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(2, 23), // (4,18): error CS0246: The type or namespace name 'I1' could not be found (are you missing a using directive or an assembly reference?) // abstract int I1.this[int i] {set;} Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "I1").WithArguments("I1").WithLocation(4, 18), // (4,18): error CS0538: 'I1' in explicit interface declaration is not an interface // abstract int I1.this[int i] {set;} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationNotInterface, "I1").WithArguments("I1").WithLocation(4, 18) ); } [Fact] public void IndexerReAbstraction_089() { var source1 = @" public interface I1 { int this[int i] {get; set;} } public interface I2 : I1 { abstract int I1.this[int i] {get; set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,34): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 34), // (9,39): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(9, 39) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,34): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 34), // (9,39): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.this[int i] {get; set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 39) ); } [Fact] public void IndexerReAbstraction_090() { var source1 = @" public interface I1 { int this[int i] {get;} } public interface I2 : I1 { abstract int I1.this[int i] {get;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,34): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.this[int i] {get;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "get").WithArguments("default interface implementation", "8.0").WithLocation(9, 34) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,34): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.this[int i] {get;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "get").WithLocation(9, 34) ); } [Fact] public void IndexerReAbstraction_091() { var source1 = @" public interface I1 { int this[int i] {set;} } public interface I2 : I1 { abstract int I1.this[int i] {set;} } "; var compilation1 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular7_3, targetFramework: TargetFramework.NetStandardLatest); compilation1.VerifyDiagnostics( // (9,34): error CS8652: The feature 'default interface implementation' is not available in C# 7.3. Please use language version 8.0 or greater. // abstract int I1.this[int i] {set;} Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7_3, "set").WithArguments("default interface implementation", "8.0").WithLocation(9, 34) ); var compilation2 = CreateCompilation(source1, options: TestOptions.DebugDll, parseOptions: TestOptions.Regular, targetFramework: TargetFramework.DesktopLatestExtended); compilation2.VerifyDiagnostics( // (9,34): error CS8701: Target runtime doesn't support default interface implementation. // abstract int I1.this[int i] {set;} Diagnostic(ErrorCode.ERR_RuntimeDoesNotSupportDefaultInterfaceImplementation, "set").WithLocation(9, 34) ); } } }