提交 c0738262 编写于 作者: A Aaron Bockover 提交者: Tomáš Matoušek

Compilation: use System.Object from target corlib (#8507)

* Tests: fix minasync Task<T> 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.
上级 dd42f4c6
...@@ -236,14 +236,20 @@ internal TypeSymbol ResultType ...@@ -236,14 +236,20 @@ internal TypeSymbol ResultType
out TypeSymbol resultType, out TypeSymbol resultType,
out TypeSymbol returnType) 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 taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T);
var useSiteDiagnostic = taskT.GetUseSiteDiagnostic(); var useSiteDiagnostic = taskT.GetUseSiteDiagnostic();
if (useSiteDiagnostic != null) if (useSiteDiagnostic != null)
{ {
diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton); 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); returnType = taskT.Construct(resultType);
} }
} }
......
...@@ -1484,6 +1484,33 @@ class A ...@@ -1484,6 +1484,33 @@ class A
Assert.Equal("ModuleAssemblyName", compilation.Assembly.Identity.Name); 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")] [WorkItem(3719, "https://github.com/dotnet/roslyn/issues/3719")]
[Fact] [Fact]
public void GetEntryPoint_Script() public void GetEntryPoint_Script()
......
...@@ -330,7 +330,7 @@ internal int GetSubmissionSlotIndex() ...@@ -330,7 +330,7 @@ internal int GetSubmissionSlotIndex()
/// <summary> /// <summary>
/// The type object that represents the type of submission result the host requested. /// The type object that represents the type of submission result the host requested.
/// </summary> /// </summary>
internal Type SubmissionReturnType => ScriptCompilationInfo?.ReturnType; internal Type SubmissionReturnType => ScriptCompilationInfo?.ReturnTypeOpt;
internal static bool IsValidSubmissionReturnType(Type type) internal static bool IsValidSubmissionReturnType(Type type)
{ {
......
...@@ -6,12 +6,13 @@ namespace Microsoft.CodeAnalysis ...@@ -6,12 +6,13 @@ namespace Microsoft.CodeAnalysis
{ {
public abstract class ScriptCompilationInfo public abstract class ScriptCompilationInfo
{ {
public Type ReturnType { get; } internal Type ReturnTypeOpt { get; }
public Type ReturnType => ReturnTypeOpt ?? typeof(object);
public Type GlobalsType { get; } public Type GlobalsType { get; }
internal ScriptCompilationInfo(Type returnType, Type globalsType) internal ScriptCompilationInfo(Type returnType, Type globalsType)
{ {
ReturnType = returnType ?? typeof(object); ReturnTypeOpt = returnType;
GlobalsType = globalsType; GlobalsType = globalsType;
} }
......
...@@ -136,6 +136,7 @@ ...@@ -136,6 +136,7 @@
<Content Include="NetFX\Minimal\build.cmd" /> <Content Include="NetFX\Minimal\build.cmd" />
<Content Include="NetFX\Minimal\Key.snk" /> <Content Include="NetFX\Minimal\Key.snk" />
<Content Include="NetFX\Minimal\minasync.cs" /> <Content Include="NetFX\Minimal\minasync.cs" />
<EmbeddedResource Include="NetFX\Minimal\minasynccorlib.dll" />
<Content Include="NetFX\Minimal\mincorlib.cs" /> <Content Include="NetFX\Minimal\mincorlib.cs" />
<EmbeddedResource Include="NetFX\ValueTuple\System.ValueTuple.dll" /> <EmbeddedResource Include="NetFX\ValueTuple\System.ValueTuple.dll" />
<EmbeddedResource Include="SymbolsTests\Metadata\public-and-private.dll" /> <EmbeddedResource Include="SymbolsTests\Metadata\public-and-private.dll" />
......
...@@ -2,3 +2,4 @@ ...@@ -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 /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 /r:mincorlib.dll /out:minasync.dll minasync.cs
csc /target:library /nostdlib /noconfig /keyfile:Key.snk /out:minasynccorlib.dll mincorlib.cs minasync.cs
...@@ -14,9 +14,9 @@ public class Task : IAsyncResult, IDisposable ...@@ -14,9 +14,9 @@ public class Task : IAsyncResult, IDisposable
public Awaiter GetAwaiter() => null; public Awaiter GetAwaiter() => null;
} }
public class Task<T> : IAsyncResult, IDisposable public class Task<T> : Task, IAsyncResult, IDisposable
{ {
public Awaiter<T> GetAwaiter() => null; public new Awaiter<T> GetAwaiter() => null;
} }
public class Awaiter : INotifyCompletion public class Awaiter : INotifyCompletion
......
...@@ -165,6 +165,9 @@ public static class Minimal ...@@ -165,6 +165,9 @@ public static class Minimal
private static byte[] s_minasync; private static byte[] s_minasync;
public static byte[] minasync => ResourceLoader.GetOrCreateResource(ref s_minasync, "NetFX.Minimal.minasync.dll"); public static byte[] minasync => 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 public static class ValueTuple
......
...@@ -149,16 +149,28 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols ...@@ -149,16 +149,28 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols
ByRef resultType As TypeSymbol, ByRef resultType As TypeSymbol,
ByRef returnType 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 taskT = compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T)
Dim useSiteDiagnostic = taskT.GetUseSiteErrorInfo() Dim useSiteDiagnostic = taskT.GetUseSiteErrorInfo()
If useSiteDiagnostic IsNot Nothing Then If useSiteDiagnostic IsNot Nothing Then
diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton) diagnostics.Add(useSiteDiagnostic, NoLocation.Singleton)
End If 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) returnType = taskT.Construct(resultType)
End Sub End Sub
End Class End Class
End Namespace End Namespace
\ No newline at end of file
...@@ -1311,6 +1311,32 @@ End Class ...@@ -1311,6 +1311,32 @@ End Class
Assert.Equal("ModuleAssemblyName", c.Assembly.Identity.Name) Assert.Equal("ModuleAssemblyName", c.Assembly.Identity.Name)
End Sub End Sub
<WorkItem(8506, "https://github.com/dotnet/roslyn/issues/8506")>
<Fact()>
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
<WorkItem(3719, "https://github.com/dotnet/roslyn/issues/3719")> <WorkItem(3719, "https://github.com/dotnet/roslyn/issues/3719")>
<Fact()> <Fact()>
Public Sub GetEntryPoint_Script() Public Sub GetEntryPoint_Script()
......
...@@ -170,6 +170,20 @@ public static PortableExecutableReference minasync ...@@ -170,6 +170,20 @@ public static PortableExecutableReference minasync
return s_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 public static class ValueTuple
......
...@@ -325,6 +325,8 @@ public static MetadataReference MscorlibRefSilverlight ...@@ -325,6 +325,8 @@ public static MetadataReference MscorlibRefSilverlight
public static MetadataReference MinCorlibRef => TestReferences.NetFx.Minimal.mincorlib; public static MetadataReference MinCorlibRef => TestReferences.NetFx.Minimal.mincorlib;
public static MetadataReference MinAsyncCorlibRef => TestReferences.NetFx.Minimal.minasynccorlib;
public static MetadataReference ValueTupleRef => TestReferences.NetFx.ValueTuple.tuplelib; public static MetadataReference ValueTupleRef => TestReferences.NetFx.ValueTuple.tuplelib;
private static MetadataReference s_msvbRef; private static MetadataReference s_msvbRef;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册