/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/HideByNameTests.cs
837 строк
19 KB
Jared Parsons
generated move
28 сен 2020, 19:36
28 сен 2020, 19:36
1cca63b
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class HideByNameTests : CSharpTestBase { #region Methods [WorkItem(545796, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545796")] [Fact] public void MethodOverloadResolutionHidesByNameStatic() { var il = @" .class public auto ansi A extends [mscorlib]System.Object { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } .method public static string Goo(string x) cil managed { ldarg.0 ret } } // end of class A .class public auto ansi B extends A { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } .method public static void Goo(int32 x) cil managed { ret } } // end of class B"; var csharp = @" class Program { static void Main() { B.Goo(""""); } }"; CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics( // (6,15): error CS1503: Argument 1: cannot convert from 'string' to 'int' // B.Goo(""); Diagnostic(ErrorCode.ERR_BadArgType, @"""""").WithArguments("1", "string", "int")); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void MethodOverloadResolutionHidesByNameInstance() { var il = @" .class public auto ansi A extends [mscorlib]System.Object { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } .method public instance string Goo(string x) cil managed { ldarg.0 ret } } // end of class A .class public auto ansi B extends A { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } .method public instance void Goo(int32 x) cil managed { ret } } // end of class B"; var csharp = @" class Program { static void Main() { new B().Goo(""""); } }"; CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics( // (6,21): error CS1503: Argument 1: cannot convert from 'string' to 'int' // new B().Goo(""); Diagnostic(ErrorCode.ERR_BadArgType, @"""""").WithArguments("1", "string", "int")); } [Fact] public void MethodOverloadResolutionHidesByNameOverride() { var il = @" .class public auto ansi A extends [mscorlib]System.Object { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } .method public hidebysig newslot virtual instance void M(int32 x) cil managed { ret } } // end of class A .class public auto ansi B extends A { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } .method public virtual instance void M(int32 x) cil managed { ret } } // end of class B"; var csharp = @" public class C : B { public override void M(int i) { } } class Program { static void Main() { new B().M(1); new C().M(2); } }"; var comp = CreateCompilationWithILAndMscorlib40(csharp, il); CompileAndVerify(comp).VerifyIL("Program.Main", @" { // Code size 23 (0x17) .maxstack 2 IL_0000: newobj ""B..ctor()"" IL_0005: ldc.i4.1 IL_0006: callvirt ""void B.M(int)"" IL_000b: newobj ""C..ctor()"" IL_0010: ldc.i4.2 IL_0011: callvirt ""void B.M(int)"" IL_0016: ret }"); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void MethodOverloadResolutionHidesByNameParams() { var il = @" .class public auto ansi A extends [mscorlib]System.Object { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } // params .method public hidebysig newslot virtual instance void M(int32[] a) cil managed { .param [1] .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = {} ret } } // end of class A .class public auto ansi B extends A { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } // Not params .method public virtual instance void M(int32[] a) cil managed { ret } } // end of class B"; var csharp = @" class Program { static void Main() { new B().M(1, 2); // This would work if B.M was not hide-by-name (since A.M is params) } }"; CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics( // (6,9): error CS1501: No overload for method 'M' takes 2 arguments // new B().M(1, 2); // This would work if B.M was not hide-by-name (since A.M is params) Diagnostic(ErrorCode.ERR_BadArgCount, "M").WithArguments("M", "2")); } [Fact] public void MethodOverridingHidesByName() { var il = @" .class public auto ansi A extends [mscorlib]System.Object { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } .method public hidebysig newslot virtual instance void M(int32 a) cil managed { ret } } // end of class A .class public auto ansi B extends A { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } .method public newslot virtual instance void M(int64 a) cil managed { ret } } // end of class B"; var csharp = @" public class C : B { public override void M(int a) { } }"; // NOTE: unlike overload resolution, override resolution does not respect hide-by-name. CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics(); } [Fact] public void MethodInterfaceImplementationHidesByName() { var il = @" .class public auto ansi A extends [mscorlib]System.Object { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } .method public hidebysig newslot virtual instance void M(int32 a) cil managed { ret } } // end of class A .class public auto ansi B extends A { .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } .method public newslot virtual instance void M(int64 a) cil managed { ret } } // end of class B"; var csharp = @" interface I { void M(int a); } public class C : B, I { }"; // NOTE: unlike overload resolution, implicit interface implementation resolution does not respect hide-by-name. CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics(); } #endregion Methods #region Indexers [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void IndexerOverloadResolutionHidesByNameInstance() { var il = @" .class public auto ansi beforefieldinit A extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public hidebysig newslot specialname virtual instance int32 get_Item(int32 x) cil managed { ldc.i4.0 ret } .property instance int32 Item(int32) { .get instance int32 A::get_Item(int32) } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } // end of class A .class public auto ansi B extends A { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public newslot specialname virtual instance int32 get_Item(string x) cil managed { ldc.i4.0 ret } .property instance int32 Item(string) { .get instance int32 B::get_Item(string) } .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } } // end of class B"; var csharp = @" class Program { static void Main() { int x = new B()[0]; } }"; CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics( // (6,25): error CS1503: Argument 1: cannot convert from 'int' to 'string' // int x = new B()[0]; Diagnostic(ErrorCode.ERR_BadArgType, "0").WithArguments("1", "int", "string")); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void IndexerOverloadResolutionHidesByNameOverride() { var il = @" .class public auto ansi beforefieldinit A extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public hidebysig newslot specialname virtual instance void set_Item(int32 x, int32 'value') cil managed { ret } .property instance int32 Item(int32) { .set instance void A::set_Item(int32, int32) } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } // end of class A .class public auto ansi B extends A { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public specialname virtual instance void set_Item(int32 x, int32 'value') cil managed { ret } .property instance int32 Item(int32) { .set instance void B::set_Item(int32, int32) } .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } } // end of class B"; var csharp = @" public class C : B { public override int this[int x] { set { } } } class Program { static void Main() { new B()[1] = 2; new C()[2] = 1; } }"; var comp = CreateCompilationWithILAndMscorlib40(csharp, il); CompileAndVerify(comp).VerifyIL("Program.Main", @" { // Code size 25 (0x19) .maxstack 3 IL_0000: newobj ""B..ctor()"" IL_0005: ldc.i4.1 IL_0006: ldc.i4.2 IL_0007: callvirt ""void B.this[int].set"" IL_000c: newobj ""C..ctor()"" IL_0011: ldc.i4.2 IL_0012: ldc.i4.1 IL_0013: callvirt ""void B.this[int].set"" IL_0018: ret }"); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void IndexerOverloadResolutionHidesByNameParams() { var il = @" .class public auto ansi beforefieldinit A extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public hidebysig newslot specialname virtual instance int32 get_Item(int32[] x) cil managed { .param [1] .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = {} ldc.i4.0 ret } .property instance int32 Item(int32[]) { .get instance int32 A::get_Item(int32[]) } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } // end of class A .class public auto ansi B extends A { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public specialname virtual instance int32 get_Item(int32[] x) cil managed { ldc.i4.0 ret } .property instance int32 Item(int32[]) { .get instance int32 B::get_Item(int32[]) } .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } } // end of class B"; var csharp = @" class Program { static void Main() { int x = new B()[1, 2]; // This would work if B.Item was not hide-by-name (since A.Item is params) } }"; CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics( // (6,17): error CS1501: No overload for method 'this' takes 2 arguments // int x = new B()[1, 2]; // This would work if B.Item was not hide-by-name (since A.Item is params) Diagnostic(ErrorCode.ERR_BadArgCount, "new B()[1, 2]").WithArguments("this", "2")); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void IndexerOverridingHidesByName() { var il = @" .class public auto ansi beforefieldinit A extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public hidebysig newslot specialname virtual instance void set_Item(int32 x, int32 'value') cil managed { ret } .property instance int32 Item(int32) { .set instance void A::set_Item(int32, int32) } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } // end of class A .class public auto ansi B extends A { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public newslot specialname virtual instance void set_Item(int64 x, int32 'value') cil managed { ret } .property instance int32 Item(int64) { .set instance void B::set_Item(int64, int32) } .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } } // end of class B"; var csharp = @" public class C : B { public override int this[int x] { set { } } }"; // NOTE: unlike overload resolution, override resolution does not respect hide-by-name. CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics(); } [ClrOnlyFact(ClrOnlyReason.Ilasm)] public void IndexerInterfaceImplementationHidesByName() { var il = @" .class public auto ansi beforefieldinit A extends [mscorlib]System.Object { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public hidebysig newslot specialname virtual instance void set_Item(int32 x, int32 'value') cil managed { ret } .property instance int32 Item(int32) { .set instance void A::set_Item(int32, int32) } .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void [mscorlib]System.Object::.ctor() ret } } // end of class A .class public auto ansi B extends A { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = {string('Item')} .method public newslot specialname virtual instance void set_Item(int64 x, int32 'value') cil managed { ret } .property instance int32 Item(int64) { .set instance void B::set_Item(int64, int32) } .method public specialname rtspecialname instance void .ctor() cil managed { ldarg.0 call instance void A::.ctor() ret } } // end of class B"; var csharp = @" interface I { int this[int x] { set; } } public class C : B, I { }"; // NOTE: unlike overload resolution, implicit interface implementation resolution does not respect hide-by-name. CreateCompilationWithILAndMscorlib40(csharp, il).VerifyDiagnostics(); } #endregion Indexers [Fact, WorkItem(897971, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/897971")] public void LocalHideFieldByName() { CreateCompilation(@" using System; public class M { int x; void P1(int[] xs) { for (int i = 0; i < xs.Length; i++) { int x = xs[i]; Console.WriteLine(x); } for (int i = 0; i < xs.Length; i++) { x = xs[i]; Console.WriteLine(x); } x = xs.Length; } } ").VerifyDiagnostics(); CreateCompilation(@" using System; public class M { int x; public virtual void P2(int[] xs) { for (int i = 0; i < xs.Length; i++) { for (int j = 0; j < xs.Length; j++) { int x = xs[j]; Console.WriteLine(x); } x = xs.Length; } } } ").VerifyDiagnostics(); CreateCompilation(@" using System; public class M { int x; void P1(int[] xs) { for (int i = 0; i < xs.Length; i++) { int x = xs[i]; Console.WriteLine(x); } for (int i = 0; i < xs.Length; i++) { x = xs[i]; Console.WriteLine(x); } this.x = xs.Length; } public virtual void P2(int[] xs) { for (int i = 0; i < xs.Length; i++) { for (int j = 0; j < xs.Length; j++) { int x = xs[j]; Console.WriteLine(x); } this.x = xs.Length; } } } ").VerifyDiagnostics(); } } }