/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenScriptTests.cs
657 строк
22 KB
Jared Parsons
Move net451 test assets to net461 (#74766)
17 авг 2024, 19:21
Не верифицирован
17 авг 2024, 19:21
75b26a2
Код
Авторство
О чём код?
// 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.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Emit { public class CodeGenScriptTests : CSharpTestBase { [Fact] public void AnonymousTypes_TopLevelVar() { string test = @" using System; var o = new { a = 1 }; Console.WriteLine(o.ToString()); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); CompileAndVerify( CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), references: new[] { SystemCoreRef }), expectedOutput: "{ a = 1 }" ); } [Fact] public void AnonymousTypes_TopLevel_Object() { string test = @" using System; object o = new { a = 1 }; Console.WriteLine(o.ToString()); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); CompileAndVerify( CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), references: new[] { SystemCoreRef }), expectedOutput: "{ a = 1 }" ); } [Fact] public void AnonymousTypes_TopLevel_NoLocal() { string test = @" using System; Console.WriteLine(new { a = 1 }.ToString()); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); CompileAndVerify( CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), references: new[] { SystemCoreRef }), expectedOutput: "{ a = 1 }" ); } [Fact] public void AnonymousTypes_NestedClass_Method() { string test = @" using System; class CLS { public void M() { Console.WriteLine(new { a = 1 }.ToString()); } } new CLS().M(); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); CompileAndVerify( CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script"), references: new[] { SystemCoreRef }), expectedOutput: "{ a = 1 }" ); } [Fact] public void AnonymousTypes_NestedClass_MethodParamDefValue() { string test = @" using System; class CLS { public void M(object p = new { a = 1 }) { Console.WriteLine(""OK""); } } new CLS().M(); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); var compilation = CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script")); compilation.VerifyDiagnostics( // (5,30): error CS1736: Default parameter value for 'p' must be a compile-time constant // public void M(object p = new { a = 1 }) Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "new { a = 1 }").WithArguments("p")); } [Fact] public void AnonymousTypes_TopLevel_MethodParamDefValue() { string test = @" using System; public void M(object p = new { a = 1 }) { Console.WriteLine(""OK""); } M(); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); var compilation = CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script")); compilation.VerifyDiagnostics( // (4,26): error CS1736: Default parameter value for 'p' must be a compile-time constant // public void M(object p = new { a = 1 }) Diagnostic(ErrorCode.ERR_DefaultValueMustBeConstant, "new { a = 1 }").WithArguments("p")); } [Fact] public void AnonymousTypes_TopLevel_MethodAttribute() { string test = @" using System; class A: Attribute { public object P; } [A(P = new { a = 1 })] public void M() { Console.WriteLine(""OK""); } M(); "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); var compilation = CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script")); compilation.VerifyDiagnostics( // (9,8): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type // [A(P = new { a = 1 })] Diagnostic(ErrorCode.ERR_BadAttributeArgument, "new { a = 1 }")); } [Fact] public void AnonymousTypes_NestedTypeAttribute() { string test = @" using System; class A: Attribute { public object P; } [A(P = new { a = 1 })] class CLS { } "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); var compilation = CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script")); compilation.VerifyDiagnostics( // (9,8): error CS0836: Cannot use anonymous type in a constant expression // [A(P = new { a = 1 })] Diagnostic(ErrorCode.ERR_AnonymousTypeNotAvailable, "new")); } [Fact] public void CompilationChain_AnonymousTypeTemplates() { var s0 = CreateSubmission("var x = new { a = 1 }; "); var sx = CreateSubmission("var y = new { b = 2 }; ", previous: s0); var s1 = CreateSubmission("var y = new { b = new { a = 3 } };", previous: s0); var s2 = CreateSubmission("x = y.b; ", previous: s1); s2.VerifyDiagnostics(); s2.EmitToArray(); Assert.True(s2.AnonymousTypeManager.AreTemplatesSealed); Assert.Equal(0, s2.AnonymousTypeManager.GetAllCreatedTemplates().Length); Assert.True(s1.AnonymousTypeManager.AreTemplatesSealed); Assert.Equal(1, s1.AnonymousTypeManager.GetAllCreatedTemplates().Length); Assert.True(s0.AnonymousTypeManager.AreTemplatesSealed); Assert.Equal(1, s0.AnonymousTypeManager.GetAllCreatedTemplates().Length); Assert.False(sx.AnonymousTypeManager.AreTemplatesSealed); } [Fact] public void CompilationChain_DynamicSiteDelegates() { // TODO: references should be inherited MetadataReference[] references = { SystemCoreRef, CSharpRef }; var s0 = CreateSubmission("var i = 1; dynamic d = null; d.m(ref i);", references); var sx = CreateSubmission("var i = 1; dynamic d = null; d.m(ref i, ref i);", references, previous: s0); var s1 = CreateSubmission("var i = 1; dynamic d = null; d.m(out i);", references, previous: s0); s1.VerifyDiagnostics(); s1.EmitToArray(); // no new delegates should have been created: Assert.True(s1.AnonymousTypeManager.AreTemplatesSealed); Assert.Equal(0, s1.AnonymousTypeManager.GetAllCreatedTemplates().Length); // delegate for (ref) Assert.True(s0.AnonymousTypeManager.AreTemplatesSealed); Assert.Equal(1, s0.AnonymousTypeManager.GetAllCreatedTemplates().Length); Assert.False(sx.AnonymousTypeManager.AreTemplatesSealed); } [Fact] public void Submissions_EmitToPeStream() { var s0 = CreateSubmission("int a = 1;"); var s11 = CreateSubmission("a + 1", previous: s0); var s12 = CreateSubmission("a + 2", previous: s0); s11.VerifyEmitDiagnostics(); s12.VerifyEmitDiagnostics(); } [Fact] public void CrossSubmissionGenericInterfaceImplementation_Generic() { var c0 = CreateSubmission(@" public interface I<T> { void m<TT>(T x, TT y); } "); var c1 = CreateSubmission(@" abstract public class C : I<int> { public void m<TT>(int x, TT y) { } }", previous: c0); c0.VerifyEmitDiagnostics(); c1.VerifyEmitDiagnostics(); } [Fact] public void CrossSubmissionGenericInterfaceImplementation_Explicit_GenericMethod() { var c0 = CreateSubmission(@" public interface I<T> { void m<S>(T x, S y); } "); var c1 = CreateSubmission(@" abstract public class C : I<int> { void I<int>.m<S>(int x, S y) { } }", previous: c0); c0.VerifyEmitDiagnostics(); c1.VerifyEmitDiagnostics(); } [Fact] public void CrossSubmissionGenericInterfaceImplementation_Explicit() { var c0 = CreateSubmission(@" public interface I<T> { void m(T x); } "); var c1 = CreateSubmission(@" abstract public class C : I<int> { void I<int>.m(int x) { } }", previous: c0); c0.VerifyEmitDiagnostics(); c1.VerifyEmitDiagnostics(); } [Fact] public void CrossSubmissionGenericInterfaceImplementation_Explicit_NoGenericParametersInSignature() { var c0 = CreateSubmission(@" public interface I<T> { void m(byte x); } "); var c1 = CreateSubmission(@" abstract public class C : I<int> { void I<int>.m(byte x) { } }", previous: c0); c0.VerifyEmitDiagnostics(); c1.VerifyEmitDiagnostics(); } [Fact] public void GenericInterfaceImplementation_Explicit_NoGenericParametersInSignature() { var c0 = CreateSubmission(@" public interface I<T> { void m(byte x); } abstract public class C : I<int> { void I<int>.m(byte x) { } }"); c0.VerifyEmitDiagnostics(); } [Fact] public void CrossSubmissionInterfaceImplementation_Explicit_NoGenericParametersInSignature() { var c0 = CreateSubmission(@" public interface I { void m(byte x); } "); var c1 = CreateSubmission(@" abstract public class C : I { void I.m(byte x) { } }", previous: c0); c0.VerifyEmitDiagnostics(); c1.VerifyEmitDiagnostics(); } [Fact] public void CrossSubmissionNestedGenericInterfaceImplementation_Explicit() { var c0 = CreateSubmission(@" class C<T> { public interface I { void m(T x); } } "); var c1 = CreateSubmission(@" abstract public class D : C<int>.I { void C<int>.I.m(int x) { } }", previous: c0); c0.VerifyEmitDiagnostics(); c1.VerifyEmitDiagnostics(); } [Fact] public void NestedGenericInterfaceImplementation_Explicit() { var c0 = CreateSubmission(@" class C<T> { public interface I { void m(T x); } } abstract public class D : C<int>.I { void C<int>.I.m(int x) { } }"); c0.VerifyEmitDiagnostics(); } [Fact] public void ExternalInterfaceImplementation_Explicit() { var c0 = CreateSubmission(@" using System.Collections; using System.Collections.Generic; abstract public class C : IEnumerable<int> { IEnumerator<int> IEnumerable<int>.GetEnumerator() { return null; } IEnumerator IEnumerable.GetEnumerator() { return null; } }"); c0.VerifyEmitDiagnostics(); } [Fact] public void AbstractAccessors() { var c0 = CreateSubmission(@" public abstract class C { public abstract event System.Action vEv; public abstract int prop { get; set; } } "); c0.VerifyEmitDiagnostics(); } [Fact] public void ExprStmtWithMethodCall() { var s0 = CreateSubmission("int Goo() { return 2;}"); var s1 = CreateSubmission("(4 + 5) * Goo()", previous: s0); s0.VerifyEmitDiagnostics(); s1.VerifyEmitDiagnostics(); } /// <summary> /// The script entry point should complete synchronously. /// </summary> [WorkItem(4495, "https://github.com/dotnet/roslyn/issues/4495")] [ConditionalFact(typeof(DesktopOnly))] public void ScriptEntryPoint() { var source = @"{ await System.Threading.Tasks.Task.Delay(100); System.Console.Write(""complete""); }"; var compilation = CreateCompilationWithMscorlib461(source, parseOptions: TestOptions.Script, options: TestOptions.DebugExe); var verifier = CompileAndVerify(compilation, expectedOutput: @"complete"); var methodData = verifier.TestData.GetMethodData("<Initialize>"); Assert.Equal("System.Threading.Tasks.Task<object>", ((MethodSymbol)methodData.Method).ReturnType.ToDisplayString()); methodData.VerifyIL( @"{ // Code size 57 (0x39) .maxstack 2 .locals init (<<Initialize>>d__0 V_0) IL_0000: newobj ""<<Initialize>>d__0..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: call ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Create()"" IL_000c: stfld ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0011: ldloc.0 IL_0012: ldarg.0 IL_0013: stfld ""Script <<Initialize>>d__0.<>4__this"" IL_0018: ldloc.0 IL_0019: ldc.i4.m1 IL_001a: stfld ""int <<Initialize>>d__0.<>1__state"" IL_001f: ldloc.0 IL_0020: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0025: ldloca.s V_0 IL_0027: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Start<<<Initialize>>d__0>(ref <<Initialize>>d__0)"" IL_002c: nop IL_002d: ldloc.0 IL_002e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0033: call ""System.Threading.Tasks.Task<object> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Task.get"" IL_0038: ret }"); methodData = verifier.TestData.GetMethodData("<Main>"); Assert.True(((MethodSymbol)methodData.Method).ReturnsVoid); methodData.VerifyIL( @"{ // Code size 25 (0x19) .maxstack 1 .locals init (System.Runtime.CompilerServices.TaskAwaiter<object> V_0) IL_0000: newobj "".ctor()"" IL_0005: callvirt ""System.Threading.Tasks.Task<object> <Initialize>()"" IL_000a: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<object> System.Threading.Tasks.Task<object>.GetAwaiter()"" IL_000f: stloc.0 IL_0010: ldloca.s V_0 IL_0012: call ""object System.Runtime.CompilerServices.TaskAwaiter<object>.GetResult()"" IL_0017: pop IL_0018: ret }"); } [ConditionalFact(typeof(DesktopOnly))] public void SubmissionEntryPoint() { var references = new[] { MscorlibRef_v4_0_30316_17626, SystemCoreRef }; var source0 = @"{ await System.Threading.Tasks.Task.Delay(100); System.Console.Write(""complete""); }"; var s0 = CSharpCompilation.CreateScriptCompilation( "s0.dll", SyntaxFactory.ParseSyntaxTree(source0, options: TestOptions.Script), references); var verifier = CompileAndVerify(s0, verify: Verification.FailsPEVerify); var methodData = verifier.TestData.GetMethodData("<Initialize>"); Assert.Equal("System.Threading.Tasks.Task<object>", ((MethodSymbol)methodData.Method).ReturnType.ToDisplayString()); methodData.VerifyIL( @"{ // Code size 57 (0x39) .maxstack 2 .locals init (<<Initialize>>d__0 V_0) IL_0000: newobj ""<<Initialize>>d__0..ctor()"" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: call ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Create()"" IL_000c: stfld ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0011: ldloc.0 IL_0012: ldarg.0 IL_0013: stfld ""Script <<Initialize>>d__0.<>4__this"" IL_0018: ldloc.0 IL_0019: ldc.i4.m1 IL_001a: stfld ""int <<Initialize>>d__0.<>1__state"" IL_001f: ldloc.0 IL_0020: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0025: ldloca.s V_0 IL_0027: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Start<<<Initialize>>d__0>(ref <<Initialize>>d__0)"" IL_002c: nop IL_002d: ldloc.0 IL_002e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object> <<Initialize>>d__0.<>t__builder"" IL_0033: call ""System.Threading.Tasks.Task<object> System.Runtime.CompilerServices.AsyncTaskMethodBuilder<object>.Task.get"" IL_0038: ret }"); methodData = verifier.TestData.GetMethodData("<Factory>"); Assert.Equal("System.Threading.Tasks.Task<object>", ((MethodSymbol)methodData.Method).ReturnType.ToDisplayString()); methodData.VerifyIL( @"{ // Code size 12 (0xc) .maxstack 1 IL_0000: ldarg.0 IL_0001: newobj "".ctor(object[])"" IL_0006: callvirt ""System.Threading.Tasks.Task<object> <Initialize>()"" IL_000b: ret }"); } [Fact] public void ScriptEntryPoint_MissingMethods() { var source = "System.Console.WriteLine(1);"; var compilation = CreateCompilationWithMscorlib40(source, parseOptions: TestOptions.Script, options: TestOptions.DebugExe); compilation.VerifyEmitDiagnostics( // error CS1061: 'Task<object>' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'Task<object>' could be found (are you missing a using directive or an assembly reference?) // Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "").WithArguments("System.Threading.Tasks.Task<object>", "GetAwaiter").WithLocation(1, 1), // (1,1): error CS0518: Predefined type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1' is not defined or imported // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "System.Console.WriteLine(1);").WithArguments("System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1").WithLocation(1, 1), // (1,1): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Create' // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "System.Console.WriteLine(1);").WithArguments("System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1", "Create").WithLocation(1, 1), // (1,1): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.Task' // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "System.Console.WriteLine(1);").WithArguments("System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1", "Task").WithLocation(1, 1), // (1,1): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext' // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "System.Console.WriteLine(1);").WithArguments("System.Runtime.CompilerServices.IAsyncStateMachine", "MoveNext").WithLocation(1, 1), // (1,1): error CS0656: Missing compiler required member 'System.Runtime.CompilerServices.IAsyncStateMachine.SetStateMachine' // System.Console.WriteLine(1); Diagnostic(ErrorCode.ERR_MissingPredefinedMember, "System.Console.WriteLine(1);").WithArguments("System.Runtime.CompilerServices.IAsyncStateMachine", "SetStateMachine").WithLocation(1, 1)); } [Fact] public void ExplicitImplementation() { string test = @" interface I1 { void M(); } void I1.M() {} "; var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script); var compilation = CreateCompilationWithMscorlib461( new[] { tree }, options: TestOptions.ReleaseExe.WithScriptClassName("Script")); compilation.VerifyDiagnostics( // (7,6): error CS0540: 'I1.M()': containing type does not implement interface 'I1' // void I1.M() {} Diagnostic(ErrorCode.ERR_ClassDoesntImplementInterface, "I1").WithArguments("I1.M()", "I1").WithLocation(7, 6) ); var s = CreateSubmission(test); s.VerifyDiagnostics( // (7,9): error CS0541: 'M()': explicit interface declaration can only be declared in a class, record, struct or interface // void I1.M() {} Diagnostic(ErrorCode.ERR_ExplicitInterfaceImplementationInNonClassOrStruct, "M").WithArguments("M()").WithLocation(7, 9) ); } } }