From c0738262f286a3c16932b36ab0ac0ee4199cb4a5 Mon Sep 17 00:00:00 2001 From: Aaron Bockover Date: Wed, 1 Jun 2016 21:43:04 -0400 Subject: [PATCH] Compilation: use System.Object from target corlib (#8507) * Tests: fix minasync Task to derive from Task * Tests: provide MinAsyncCorlibRef This combines the async features of minasync with mincorlib to produce a minimum unversioned corlib with async stubs. * Compilation: use System.Object from target corlib When creating a script compilation without an explicit return type, System.Object was being resolved via reflection from the host. This resulted in an implicit dependency of a script compilation on the host corlib, even if a different corlib was specified as a reference for the compilation (e.g. Xamarin.iOS). Fix this by using System.Object as defined in the corlib resovled for the compilation. --- ...SynthesizedInteractiveInitializerMethod.cs | 10 +++++-- .../Symbol/Compilation/CompilationAPITests.cs | 27 ++++++++++++++++++ .../Core/Portable/Compilation/Compilation.cs | 2 +- .../Compilation/ScriptCompilationInfo.cs | 5 ++-- .../Core/CompilerTestResources.csproj | 1 + .../Resources/Core/NetFX/Minimal/build.cmd | 1 + .../Resources/Core/NetFX/Minimal/minasync.cs | 4 +-- .../Resources/Core/NetFX/Minimal/minasync.dll | Bin 5120 -> 5120 bytes .../Core/NetFX/Minimal/minasynccorlib.dll | Bin 0 -> 7680 bytes .../Test/Resources/Core/TestResources.cs | 3 ++ ...SynthesizedInteractiveInitializerMethod.vb | 18 ++++++++++-- .../Compilation/CompilationAPITests.vb | 26 +++++++++++++++++ .../Utilities/Shared/Mocks/TestReferences.cs | 14 +++++++++ src/Test/Utilities/Shared/TestBase.cs | 2 ++ 14 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 src/Compilers/Test/Resources/Core/NetFX/Minimal/minasynccorlib.dll diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInteractiveInitializerMethod.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInteractiveInitializerMethod.cs index 5ae3468323a..ba473a5e763 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInteractiveInitializerMethod.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedInteractiveInitializerMethod.cs @@ -236,14 +236,20 @@ internal TypeSymbol ResultType out TypeSymbol resultType, out TypeSymbol returnType) { - var submissionReturnType = compilation.SubmissionReturnType ?? typeof(object); + var submissionReturnTypeOpt = compilation.ScriptCompilationInfo?.ReturnTypeOpt; var taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T); var useSiteDiagnostic = taskT.GetUseSiteDiagnostic(); if (useSiteDiagnostic != null) { diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton); } - resultType = compilation.GetTypeByReflectionType(submissionReturnType, diagnostics); + // If no explicit return type is set on ScriptCompilationInfo, default to + // System.Object from the target corlib. This allows cross compiling scripts + // to run on a target corlib that may differ from the host compiler's corlib. + // cf. https://github.com/dotnet/roslyn/issues/8506 + resultType = (object)submissionReturnTypeOpt == null + ? compilation.GetSpecialType(SpecialType.System_Object) + : compilation.GetTypeByReflectionType(submissionReturnTypeOpt, diagnostics); returnType = taskT.Construct(resultType); } } diff --git a/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs index 90fa3f80d16..001dabf6c02 100644 --- a/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Compilation/CompilationAPITests.cs @@ -1484,6 +1484,33 @@ class A Assert.Equal("ModuleAssemblyName", compilation.Assembly.Identity.Name); } + [WorkItem(8506, "https://github.com/dotnet/roslyn/issues/8506")] + [Fact] + public void CrossCorlibSystemObjectReturnType_Script() + { + // MinAsyncCorlibRef corlib is used since it provides just enough corlib type definitions + // and Task APIs necessary for script hosting are provided by MinAsyncRef. This ensures that + // `System.Object, mscorlib, Version=4.0.0.0` will not be provided (since it's unversioned). + // + // In the original bug, Xamarin iOS, Android, and Mac Mobile profile corlibs were + // realistic cross-compilation targets. + var compilation = CSharpCompilation.CreateScriptCompilation( + "submission-assembly", + references: new [] { MinAsyncCorlibRef }, + syntaxTree: Parse("true", options: TestOptions.Script) + ).VerifyDiagnostics(); + + Assert.True(compilation.IsSubmission); + + var taskOfT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T); + var taskOfObject = taskOfT.Construct(compilation.ObjectType); + var entryPoint = compilation.GetEntryPoint(default(CancellationToken)); + + Assert.Same(compilation.ObjectType.ContainingAssembly, taskOfT.ContainingAssembly); + Assert.Same(compilation.ObjectType.ContainingAssembly, taskOfObject.ContainingAssembly); + Assert.Equal(taskOfObject, entryPoint.ReturnType); + } + [WorkItem(3719, "https://github.com/dotnet/roslyn/issues/3719")] [Fact] public void GetEntryPoint_Script() diff --git a/src/Compilers/Core/Portable/Compilation/Compilation.cs b/src/Compilers/Core/Portable/Compilation/Compilation.cs index e6e1e8bac0a..154c14b85be 100644 --- a/src/Compilers/Core/Portable/Compilation/Compilation.cs +++ b/src/Compilers/Core/Portable/Compilation/Compilation.cs @@ -330,7 +330,7 @@ internal int GetSubmissionSlotIndex() /// /// The type object that represents the type of submission result the host requested. /// - internal Type SubmissionReturnType => ScriptCompilationInfo?.ReturnType; + internal Type SubmissionReturnType => ScriptCompilationInfo?.ReturnTypeOpt; internal static bool IsValidSubmissionReturnType(Type type) { diff --git a/src/Compilers/Core/Portable/Compilation/ScriptCompilationInfo.cs b/src/Compilers/Core/Portable/Compilation/ScriptCompilationInfo.cs index 927a52c7670..8f45663b1ec 100644 --- a/src/Compilers/Core/Portable/Compilation/ScriptCompilationInfo.cs +++ b/src/Compilers/Core/Portable/Compilation/ScriptCompilationInfo.cs @@ -6,12 +6,13 @@ namespace Microsoft.CodeAnalysis { public abstract class ScriptCompilationInfo { - public Type ReturnType { get; } + internal Type ReturnTypeOpt { get; } + public Type ReturnType => ReturnTypeOpt ?? typeof(object); public Type GlobalsType { get; } internal ScriptCompilationInfo(Type returnType, Type globalsType) { - ReturnType = returnType ?? typeof(object); + ReturnTypeOpt = returnType; GlobalsType = globalsType; } diff --git a/src/Compilers/Test/Resources/Core/CompilerTestResources.csproj b/src/Compilers/Test/Resources/Core/CompilerTestResources.csproj index 4bb2c2ab0bb..de418166daa 100644 --- a/src/Compilers/Test/Resources/Core/CompilerTestResources.csproj +++ b/src/Compilers/Test/Resources/Core/CompilerTestResources.csproj @@ -136,6 +136,7 @@ + diff --git a/src/Compilers/Test/Resources/Core/NetFX/Minimal/build.cmd b/src/Compilers/Test/Resources/Core/NetFX/Minimal/build.cmd index ba14a626bc9..c465afaf1dd 100644 --- a/src/Compilers/Test/Resources/Core/NetFX/Minimal/build.cmd +++ b/src/Compilers/Test/Resources/Core/NetFX/Minimal/build.cmd @@ -2,3 +2,4 @@ csc /target:library /nostdlib /noconfig /keyfile:Key.snk /out:mincorlib.dll mincorlib.cs csc /target:library /nostdlib /noconfig /keyfile:Key.snk /r:mincorlib.dll /out:minasync.dll minasync.cs +csc /target:library /nostdlib /noconfig /keyfile:Key.snk /out:minasynccorlib.dll mincorlib.cs minasync.cs diff --git a/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasync.cs b/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasync.cs index d31e1f78056..fc97264291b 100644 --- a/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasync.cs +++ b/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasync.cs @@ -14,9 +14,9 @@ public class Task : IAsyncResult, IDisposable public Awaiter GetAwaiter() => null; } - public class Task : IAsyncResult, IDisposable + public class Task : Task, IAsyncResult, IDisposable { - public Awaiter GetAwaiter() => null; + public new Awaiter GetAwaiter() => null; } public class Awaiter : INotifyCompletion diff --git a/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasync.dll b/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasync.dll index f9e08aaab65303d142554546ea9d000b165702eb..979309bb0ef25bf7bffdeadb9113ca5915e6600d 100644 GIT binary patch delta 322 zcmZqBXwaC@!E##5FMMK;3}fBImHJE_MH6qSG3rcaWUOawncT=&FPNas00tgFl8J$p zVZmfUCUMp^S_}*glMNY_CkHTT^C&TCC^9gxF=%m#X>G1&n$5_lvRRttFC%01WJxw@ zph2c==KL)RAamL{3K`586&X4rFZLQ!7 zXM(5y>tQr9*p#|~rC)2eYfhH%5xspybt1<$Lu8wp=x-kY~|V z{?=o`rnd8OdA8GT@7I#{KMv>evR>(*|Bz2K1nOy!i}NNM@=7x%O!np7xtWje7c*0X N^=3h#_ly$_*Z~FJYySWM delta 321 zcmZqBXwaC@!4i>nE^K0t3}e~EmHJHGmnYs*V^o>U$XL%zT&GSDS`XjzsF)FuN^SoYVrbJHqYSY)fY2Ux(Y<+*t_nxd= z*$N)v-mvRF-`~u+BpusoR(Mu8)(7fYkc-nmY=w!6VvG@!LwR>jG~n3G$M=hwsls}* LpwN59i3aQdzu<7` diff --git a/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasynccorlib.dll b/src/Compilers/Test/Resources/Core/NetFX/Minimal/minasynccorlib.dll new file mode 100644 index 0000000000000000000000000000000000000000..79bee6784a7d3c91b38a33dbb549c17a65aaa5e9 GIT binary patch literal 7680 zcmeHL4R96J6+U<0OY#y3=7&g>02=}!28iL$p-M5oLNp~xZ`F9k6)GqDERm9BE(g96RYxns`enWP<}s$ zsGS>iM2FFDL|H>LdIa;IV5mfaG_?Tm;xt_2=o=j1rm-N9$ym?v5B8cGJ7$L3LEh)7^D z5C7*^Q*o^zSSFY%ETS_dsK;klkD;+&p`;8}r3^J>2)yIU2Ejd0M$Tsz8Q>p>(TeLa zC!>gtAZjvX<3W87yf))1$@VtEIZdP}Ne(ejoi@T!1U!%;=qKCE=NK7tKTHXohll6^#f^g7bxa`VzXDqA zKfrGBmn#Y=tQ=5Qqpe7EDW#(s8E8%hN{DpLUngrp=N*@8fo!^o zWwJd+(uX7+l>BFT{hxSqxX{IfuPx(sWec68%tx9??!&r0|1#T7*u$hGVh`oRnGbAN?iCeD8T(5i_E$m2 zk`e6|Q<9qOFNN6O)TE64RVESp!_FeDY=OT=M0HX&=-;1)*x&Swd6*i^c<*4M?t61E1*@_Ujx{!-vq6t zcR=UTd!X~_x1bB?1ZW+71lmNWKo`>)&{p!{?O#d(vCFrTj*F*3&x&_JOB7$$N?M@2 z3)(ER#+l|kyZ0cjvpmdKbjG}^aLxM(*L;WM+PkaaJajSdDa_CJYTi{C^ZkZvz7KJI zfmdJX)#JU|T`NR0JzN9rT$%`4iIa62#x)Zse~lc^4si&khKT8F%2S|s$hJ#&D9?kl zLwOl{?r6j(FeV@7eT=+EoCm64G<X z>SF_Dh}&(tv(^eX#3M#nw^?wV7I9>2d5h`HnN3_>GFMi!E};c&Ryc0x3n@tbni1E# zx+oekHMSPAY$MX`8dz?|v>v_PY_y_%hVJNLmz~b&)t#=ESV}=+bFFT}eVAe_O`=XK z5~c-7yl{P2SA!N>kBj{k5#4~O-Y~4|+Tw;2fxD67PR)pf+szRIH+YK591sH4?H(

?ItVEtYvZ2i9~fdqQ#mSPO*Xm zeY(f#z?dQ6U^B)n1J2~QnWkWeqd9t;7FruI;a5&v2CGANGH@(iACbp(_D_wr4m%{1 z6w+c&lWyp}%&B+q6RA7y=*weTubxEIr1xmZXqz7G*6kF#J?^ByQVm}T>TO#aNbx!v z24HoW?!;|Vx_4I!xxd8RmDi{lMmJ`VLcX z%DfG?``u}#2Fo&Z&7_cp88PFU6R}LH56Q~4Q?pF(F?5&Hvcz&CJp(K4~NJx*JE9Q73hHjrL53a>R31gYo z@N^`*HCl$3uoyKOS}c}YH$lzD?8T_PdmU0rmRn)EF+2(`(_>gg-oo_&LiAclsMoSx zz2<)1bg))5+o3kAUthxCSmX*rCSzEO#sDp~tv=m$26#V1>DM2cn|Q2m$t`qd|3xot znoj;4+ya$i%FPiag^B$DIbNN(4?92k6GU6lF&l>><7FN7vvBI*h!8Y=o3;L$?_IlT z-g7hOcTTEbSlM^ci3cD1Q_g`o6K;50k9~Fas!Mx+xT5IKmu|h}<)izyZhh;{tK07g z?P#k!{K?0Af3tJvUHeB_=CO|M+Y63OduR6BHLtuLnD^dCn`XaoBDyo**R$(_tLJn- zU;fy~r&k_a_2}gKx2&FZHyxk3e$Ugn`69IbXHWRgZpHxlF!A%z;#ZmQaq8zI)sN!} z1Y$pqEfDDV(I7vE;^$-ApO7sTEk4ARY{j2lm`Etu0iQ}DTNMHbO~sFQg!FtInMR^S)(M9QmG z6s`*c$T@esJn!&_0y?>WZDgzpmS`eZ$=k zl^<<5^rC;;xLc22bMffyzx%ko^W+O3b>3?ofAh!rd9{-dJ^1nu7QOMwmu{b*rJlZh z=$Qld13e8tu|Lcm_wDindnSyX%Y$=E4YySfoKvZ3dbpP~T6U9Rv}qBOqA?uQx-K_W z?sRr4Z1CFpy!>BefWL^z&&!F-aCmbg{H~x8eAZixXGI<1iz6eqgcV*yowx;efi}}J zv|8|`eF<<2=oRi)cY4x);tanj=a$Po2ER{fW+k@?RKTi6Hta<3?G|?%GO33wDW4+W z;UJ_MxG~5za-e4cxn-~a8MqV}lLM^?_`QF}(tT2=7IC|ObE%tifL~b(`VM<;g7+AO zq@BJDKPq%-!_oHAT8xuO#j`~EYxnrBZ6g^Qd-~V>&Xw^l zg*^+SiDP^YW-2r4RJ ResourceLoader.GetOrCreateResource(ref s_minasync, "NetFX.Minimal.minasync.dll"); + + private static byte [] s_minasynccorlib; + public static byte [] minasynccorlib => ResourceLoader.GetOrCreateResource(ref s_minasynccorlib, "NetFX.Minimal.minasynccorlib.dll"); } public static class ValueTuple diff --git a/src/Compilers/VisualBasic/Portable/Symbols/Source/SynthesizedInteractiveInitializerMethod.vb b/src/Compilers/VisualBasic/Portable/Symbols/Source/SynthesizedInteractiveInitializerMethod.vb index 3f6aad78210..d9e88c538a8 100644 --- a/src/Compilers/VisualBasic/Portable/Symbols/Source/SynthesizedInteractiveInitializerMethod.vb +++ b/src/Compilers/VisualBasic/Portable/Symbols/Source/SynthesizedInteractiveInitializerMethod.vb @@ -149,16 +149,28 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ByRef resultType As TypeSymbol, ByRef returnType As TypeSymbol) - Dim submissionReturnType = If(compilation.SubmissionReturnType, GetType(Object)) + Dim submissionReturnType As Type = Nothing + If compilation.ScriptCompilationInfo IsNot Nothing Then + submissionReturnType = compilation.ScriptCompilationInfo.ReturnTypeOpt + End If + Dim taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T) Dim useSiteDiagnostic = taskT.GetUseSiteErrorInfo() If useSiteDiagnostic IsNot Nothing Then diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton) End If - resultType = compilation.GetTypeByReflectionType(submissionReturnType, diagnostics) + ' If no explicit return type is set on ScriptCompilationInfo, default to + ' System.Object from the target corlib. This allows cross compiling scripts + ' to run on a target corlib that may differ from the host compiler's corlib. + ' cf. https://github.com/dotnet/roslyn/issues/8506 + If submissionReturnType Is Nothing Then + resultType = compilation.GetSpecialType(SpecialType.System_Object) + Else + resultType = compilation.GetTypeByReflectionType(submissionReturnType, diagnostics) + End If returnType = taskT.Construct(resultType) End Sub End Class -End Namespace \ No newline at end of file +End Namespace diff --git a/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb b/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb index 93a83ce9896..0355b7bb8a3 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb +++ b/src/Compilers/VisualBasic/Test/Semantic/Compilation/CompilationAPITests.vb @@ -1311,6 +1311,32 @@ End Class Assert.Equal("ModuleAssemblyName", c.Assembly.Identity.Name) End Sub + + + Public Sub CrossCorlibSystemObjectReturnType_Script() + ' MinAsyncCorlibRef corlib Is used since it provides just enough corlib type definitions + ' And Task APIs necessary for script hosting are provided by MinAsyncRef. This ensures that + ' `System.Object, mscorlib, Version=4.0.0.0` will Not be provided (since it's unversioned). + ' + ' In the original bug, Xamarin iOS, Android, And Mac Mobile profile corlibs were + ' realistic cross-compilation targets. + Dim compilation = VisualBasicCompilation.CreateScriptCompilation( + "submission-assembly", + references:={MinAsyncCorlibRef}, + syntaxTree:=Parse("? True", options:=TestOptions.Script) + ).VerifyDiagnostics() + + Assert.True(compilation.IsSubmission) + + Dim taskOfT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T) + Dim taskOfObject = taskOfT.Construct(compilation.ObjectType) + Dim entryPoint = compilation.GetEntryPoint(Nothing) + + Assert.Same(compilation.ObjectType.ContainingAssembly, taskOfT.ContainingAssembly) + Assert.Same(compilation.ObjectType.ContainingAssembly, taskOfObject.ContainingAssembly) + Assert.Equal(taskOfObject, entryPoint.ReturnType) + End Sub + Public Sub GetEntryPoint_Script() diff --git a/src/Test/Utilities/Shared/Mocks/TestReferences.cs b/src/Test/Utilities/Shared/Mocks/TestReferences.cs index 51436e8191f..09be1347e67 100644 --- a/src/Test/Utilities/Shared/Mocks/TestReferences.cs +++ b/src/Test/Utilities/Shared/Mocks/TestReferences.cs @@ -170,6 +170,20 @@ public static PortableExecutableReference minasync return s_minasync; } } + + private static PortableExecutableReference s_minasynccorlib; + public static PortableExecutableReference minasynccorlib + { + get + { + if (s_minasynccorlib == null) + { + s_minasynccorlib = AssemblyMetadata.CreateFromImage(TestResources.NetFX.Minimal.minasynccorlib).GetReference(display: "minasynccorlib.dll"); + } + + return s_minasynccorlib; + } + } } public static class ValueTuple diff --git a/src/Test/Utilities/Shared/TestBase.cs b/src/Test/Utilities/Shared/TestBase.cs index 6f9375eef9a..445a43529b2 100644 --- a/src/Test/Utilities/Shared/TestBase.cs +++ b/src/Test/Utilities/Shared/TestBase.cs @@ -325,6 +325,8 @@ public static MetadataReference MscorlibRefSilverlight public static MetadataReference MinCorlibRef => TestReferences.NetFx.Minimal.mincorlib; + public static MetadataReference MinAsyncCorlibRef => TestReferences.NetFx.Minimal.minasynccorlib; + public static MetadataReference ValueTupleRef => TestReferences.NetFx.ValueTuple.tuplelib; private static MetadataReference s_msvbRef; -- GitLab