提交 60562c55 编写于 作者: T Tomáš Matoušek 提交者: GitHub

Merge pull request #15658 from tmat/ScriptingOnCore11

Scripting on .NET Core 1.1
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<MicrosoftCodeAnalysisAnalyzersVersion>1.1.0</MicrosoftCodeAnalysisAnalyzersVersion> <MicrosoftCodeAnalysisAnalyzersVersion>1.1.0</MicrosoftCodeAnalysisAnalyzersVersion>
<MicrosoftCodeAnalysisElfieVersion>0.10.6-rc2</MicrosoftCodeAnalysisElfieVersion> <MicrosoftCodeAnalysisElfieVersion>0.10.6-rc2</MicrosoftCodeAnalysisElfieVersion>
<MicrosoftCompositionVersion>1.0.27</MicrosoftCompositionVersion> <MicrosoftCompositionVersion>1.0.27</MicrosoftCompositionVersion>
<MicrosoftCSharpVersion>4.3.0</MicrosoftCSharpVersion>
<MicrosoftDiagnosticsRuntimeVersion>0.8.31-beta</MicrosoftDiagnosticsRuntimeVersion> <MicrosoftDiagnosticsRuntimeVersion>0.8.31-beta</MicrosoftDiagnosticsRuntimeVersion>
<MicrosoftDiagnosticsTracingTraceEventVersion>1.0.35</MicrosoftDiagnosticsTracingTraceEventVersion> <MicrosoftDiagnosticsTracingTraceEventVersion>1.0.35</MicrosoftDiagnosticsTracingTraceEventVersion>
<MicrosoftDiaSymReaderVersion>1.1.0-beta1-60818-02</MicrosoftDiaSymReaderVersion> <MicrosoftDiaSymReaderVersion>1.1.0-beta1-60818-02</MicrosoftDiaSymReaderVersion>
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
"Microsoft.CodeAnalysis.Analyzers", "Microsoft.CodeAnalysis.Analyzers",
"Microsoft.VisualBasic", "Microsoft.VisualBasic",
"Microsoft.Composition", "Microsoft.Composition",
"Microsoft.CSharp",
"MicroBuild.*", "MicroBuild.*",
"ManagedEsent", "ManagedEsent",
"Microsoft.CodeAnalysis.Elfie", "Microsoft.CodeAnalysis.Elfie",
......
...@@ -229,7 +229,7 @@ public class TestAnalyzer : DiagnosticAnalyzer ...@@ -229,7 +229,7 @@ public class TestAnalyzer : DiagnosticAnalyzer
new SyntaxTree[] { CSharp.SyntaxFactory.ParseSyntaxTree(analyzerSource) }, new SyntaxTree[] { CSharp.SyntaxFactory.ParseSyntaxTree(analyzerSource) },
new MetadataReference[] new MetadataReference[]
{ {
SystemRuntimeNetstandard13FacadeRef.Value, TestReferences.NetStandard13.SystemRuntime,
MetadataReference.CreateFromFile(immutable.Path), MetadataReference.CreateFromFile(immutable.Path),
MetadataReference.CreateFromFile(analyzer.Path) MetadataReference.CreateFromFile(analyzer.Path)
}, },
......
...@@ -49,18 +49,6 @@ private static class CultureTypes ...@@ -49,18 +49,6 @@ private static class CultureTypes
} }
} }
private static class _RuntimeEnvironment
{
internal static readonly Type TypeOpt = ReflectionUtilities.TryGetType("System.Runtime.InteropServices.RuntimeEnvironment, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
internal static readonly Func<string> GetRuntimeDirectoryOpt = TypeOpt?
.GetTypeInfo()
.GetDeclaredMethod("GetRuntimeDirectory", Array.Empty<Type>())?
.CreateDelegate<Func<string>>();
}
internal static string TryGetRuntimeDirectory() => _RuntimeEnvironment.GetRuntimeDirectoryOpt?.Invoke();
private static class _Assembly private static class _Assembly
{ {
internal static readonly Type Type = typeof(Assembly); internal static readonly Type Type = typeof(Assembly);
......
...@@ -295,7 +295,7 @@ internal static MetadataReference CreateFromAssemblyInternal(Assembly assembly) ...@@ -295,7 +295,7 @@ internal static MetadataReference CreateFromAssemblyInternal(Assembly assembly)
return CreateFromAssemblyInternal(assembly, properties, documentation); return CreateFromAssemblyInternal(assembly, properties, documentation);
} }
internal static MetadataReference CreateFromAssemblyInternal( internal static PortableExecutableReference CreateFromAssemblyInternal(
Assembly assembly, Assembly assembly,
MetadataReferenceProperties properties, MetadataReferenceProperties properties,
DocumentationProvider documentation = null) DocumentationProvider documentation = null)
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
using Roslyn.Utilities; using Roslyn.Utilities;
using System; using System;
using System.Reflection;
namespace Microsoft.CodeAnalysis.Scripting namespace Microsoft.CodeAnalysis.Scripting
{ {
...@@ -15,5 +16,15 @@ internal static class AssemblyLoadContext ...@@ -15,5 +16,15 @@ internal static class AssemblyLoadContext
internal static readonly Type Type = ReflectionUtilities.TryGetType( internal static readonly Type Type = ReflectionUtilities.TryGetType(
"System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); "System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
} }
internal static class AppContext
{
internal static readonly Type Type = ReflectionUtilities.TryGetType(
"System.AppContext, System.AppContext, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
// only available in netstandard 1.6+
internal static readonly Func<string, object> GetData =
Type.GetTypeInfo().GetDeclaredMethod("GetData")?.CreateDelegate<Func<string, object>>();
}
} }
} }
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Reflection;
using Microsoft.CodeAnalysis.Scripting.Hosting; using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Scripting.Hosting namespace Microsoft.CodeAnalysis.CSharp.Scripting.Hosting
{ {
...@@ -17,14 +15,18 @@ internal static int Main(string[] args) ...@@ -17,14 +15,18 @@ internal static int Main(string[] args)
{ {
try try
{ {
var responseFile = Path.Combine(AppContext.BaseDirectory, InteractiveResponseFileName); // Note that AppContext.BaseDirectory isn't necessarily the directory containing csi.exe.
// For example, when executed via corerun it's the directory containing corerun.
string csiDirectory = Path.GetDirectoryName(typeof(Csi).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName);
var buildPaths = new BuildPaths( var buildPaths = new BuildPaths(
clientDir: AppContext.BaseDirectory, clientDir: csiDirectory,
workingDir: Directory.GetCurrentDirectory(), workingDir: Directory.GetCurrentDirectory(),
sdkDir: CorLightup.Desktop.TryGetRuntimeDirectory(), sdkDir: RuntimeMetadataReferenceResolver.GetDesktopFrameworkDirectory(),
tempDir: Path.GetTempPath()); tempDir: Path.GetTempPath());
var compiler = new CSharpInteractiveCompiler( var compiler = new CSharpInteractiveCompiler(
responseFile: responseFile, responseFile: Path.Combine(csiDirectory, InteractiveResponseFileName),
buildPaths: buildPaths, buildPaths: buildPaths,
args: args, args: args,
analyzerLoader: new NotImplementedAnalyzerLoader()); analyzerLoader: new NotImplementedAnalyzerLoader());
......
# references # basic references
/r:System.Collections.dll /r:System.Collections
/r:System.Console.dll /r:System.Collections.Concurrent
/r:System.Diagnostics.Process.dll /r:System.Console
/r:System.Dynamic.Runtime.dll /r:System.Diagnostics.Debug
/r:System.Globalization.dll /r:System.Diagnostics.Process
/r:System.IO.dll /r:System.Diagnostics.StackTrace
/r:System.IO.FileSystem.dll /r:System.Globalization
/r:System.IO.FileSystem.Primitives.dll /r:System.IO
/r:System.Linq.dll /r:System.IO.FileSystem
/r:System.Linq.Expressions.dll /r:System.IO.FileSystem.Primitives
/r:System.Reflection.dll /r:System.Reflection
/r:System.Reflection.Primitives.dll /r:System.Reflection.Primitives
/r:System.Runtime.dll /r:System.Runtime
/r:System.Runtime.Numerics.dll /r:System.Runtime.InteropServices
/r:System.Runtime.Serialization.Json.dll /r:System.Text.Encoding
/r:System.Runtime.Serialization.Primitives.dll /r:System.Text.Encoding.CodePages
/r:System.Text.Encoding.CodePages.dll /r:System.Text.Encoding.Extensions
/r:System.Text.Encoding.dll /r:System.Text.RegularExpressions
/r:System.Text.Encoding.Extensions.dll /r:System.Threading
/r:System.Text.RegularExpressions.dll /r:System.Threading.Tasks
/r:System.Threading.dll /r:System.Threading.Tasks.Parallel
/r:System.Threading.Tasks.dll /r:System.Threading.Thread
/r:System.Threading.Tasks.Parallel.dll # extra references
/r:System.Threading.Thread.dll /r:System.Linq
/r:System.Linq.Expressions
/r:System.Runtime.Numerics
/r:System.Dynamic.Runtime
/r:System.ValueTuple.dll /r:System.ValueTuple.dll
/r:Microsoft.CSharp
# imports # imports
/u:System /u:System
/u:System.IO /u:System.IO
......
{ {
"dependencies": { "dependencies": {
"System.ValueTuple": "4.3.0" "System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.CSharp": "4.3.0"
}, },
"frameworks": { "frameworks": {
// We don't actually target netstandard1.6; this is to work around https://github.com/dotnet/roslyn/issues/12458 // We don't actually target netstandard1.6; this is to work around https://github.com/dotnet/roslyn/issues/12458
......
...@@ -262,11 +262,14 @@ private void ProcessStarting(bool initialize) ...@@ -262,11 +262,14 @@ private void ProcessStarting(bool initialize)
private static MetadataReferenceResolver CreateMetadataReferenceResolver(IMetadataService metadataService, ImmutableArray<string> searchPaths, string baseDirectory) private static MetadataReferenceResolver CreateMetadataReferenceResolver(IMetadataService metadataService, ImmutableArray<string> searchPaths, string baseDirectory)
{ {
// TODO: To support CoreCLR we need to query the remote process for TPA list and pass it to the resolver.
// https://github.com/dotnet/roslyn/issues/4788
return new RuntimeMetadataReferenceResolver( return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(searchPaths, baseDirectory), new RelativePathResolver(searchPaths, baseDirectory),
null, packageResolver: null,
GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null, gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) => metadataService.GetReference(path, properties)); useCoreResolver: false,
fileReferenceProvider: (path, properties) => metadataService.GetReference(path, properties));
} }
private static SourceReferenceResolver CreateSourceReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory) private static SourceReferenceResolver CreateSourceReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory)
......
...@@ -172,9 +172,10 @@ private MetadataReferenceResolver CreateMetadataReferenceResolver(ImmutableArray ...@@ -172,9 +172,10 @@ private MetadataReferenceResolver CreateMetadataReferenceResolver(ImmutableArray
{ {
return new RuntimeMetadataReferenceResolver( return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(searchPaths, baseDirectory), new RelativePathResolver(searchPaths, baseDirectory),
null, packageResolver: null,
GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null, gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) => new ShadowCopyReference(_metadataFileProvider, path, properties)); useCoreResolver: !GacFileResolver.IsAvailable,
fileReferenceProvider: (path, properties) => new ShadowCopyReference(_metadataFileProvider, path, properties));
} }
private SourceReferenceResolver CreateSourceReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory) private SourceReferenceResolver CreateSourceReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory)
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.IO Imports System.IO
Imports System.Reflection
Imports Microsoft.CodeAnalysis.Scripting.Hosting Imports Microsoft.CodeAnalysis.Scripting.Hosting
Imports Roslyn.Utilities
Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.Hosting Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.Hosting
...@@ -11,18 +11,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.Hosting ...@@ -11,18 +11,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.Hosting
Public Shared Function Main(args As String()) As Integer Public Shared Function Main(args As String()) As Integer
Try Try
Dim responseFile = Path.Combine(AppContext.BaseDirectory, InteractiveResponseFileName) ' Note that AppContext.BaseDirectory isn't necessarily the directory containing vbi.exe.
' For example, when executed via corerun it's the directory containing corerun.
Dim vbiDirectory = Path.GetDirectoryName(GetType(Vbi).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName)
Dim buildPaths = New BuildPaths( Dim buildPaths = New BuildPaths(
clientDir:=AppContext.BaseDirectory, clientDir:=vbiDirectory,
workingDir:=CorLightup.Desktop.TryGetRuntimeDirectory(), workingDir:=Directory.GetCurrentDirectory(),
sdkDir:=AppContext.BaseDirectory, sdkDir:=RuntimeMetadataReferenceResolver.GetDesktopFrameworkDirectory(),
tempDir:=Path.GetTempPath()) tempDir:=Path.GetTempPath())
Dim compiler = New VisualBasicInteractiveCompiler( Dim compiler = New VisualBasicInteractiveCompiler(
responseFile, responseFile:=Path.Combine(vbiDirectory, InteractiveResponseFileName),
buildPaths, buildPaths:=buildPaths,
args, args:=args,
New NotImplementedAnalyzerLoader()) analyzerLoader:=New NotImplementedAnalyzerLoader())
Dim runner = New CommandLineRunner( Dim runner = New CommandLineRunner(
ConsoleIO.Default, ConsoleIO.Default,
......
{ {
"dependencies": { "dependencies": {
"System.ValueTuple": "4.3.0" "System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.VisualBasic": "10.1.0"
}, },
"frameworks": { "frameworks": {
// We don't actually target netstandard1.6; this is to work around https://github.com/dotnet/roslyn/issues/12458 // We don't actually target netstandard1.6; this is to work around https://github.com/dotnet/roslyn/issues/12458
......
{ {
"dependencies": { "dependencies": {
"System.ValueTuple": "4.3.0" "System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.CSharp": "4.3.0"
}, },
"frameworks": { "frameworks": {
"net46": {} "net46": {}
......
{ {
"dependencies": { "dependencies": {
"System.ValueTuple": "4.3.0" "System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.VisualBasic": "10.1.0"
}, },
"frameworks": { "frameworks": {
"net46": {} "net46": {}
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
<dependency id="Microsoft.CodeAnalysis.Compilers" version="$version$" /> <dependency id="Microsoft.CodeAnalysis.Compilers" version="$version$" />
<dependency id="Microsoft.CodeAnalysis.Scripting" version="$version$" /> <dependency id="Microsoft.CodeAnalysis.Scripting" version="$version$" />
<dependency id="NETStandard.Library" version="1.6.0" /> <dependency id="NETStandard.Library" version="1.6.0" />
<dependency id="Microsoft.CSharp" version="$MicrosoftCSharpVersion$" />
<dependency id="System.Dynamic.Runtime" version="$SystemDynamicRuntimeVersion$" />
<dependency id="System.ValueTuple" version="$SystemValueTupleVersion$" />
</group> </group>
</dependencies> </dependencies>
</metadata> </metadata>
......
...@@ -3,30 +3,37 @@ ...@@ -3,30 +3,37 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting; using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.Scripting.Hosting; using Microsoft.CodeAnalysis.Scripting.Hosting;
using Microsoft.CodeAnalysis.Scripting.Test; using Microsoft.CodeAnalysis.Scripting.Test;
using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Xunit; using Xunit;
using TestBase = PortableTestUtils::Roslyn.Test.Utilities.TestBase;
using AssertEx = PortableTestUtils::Roslyn.Test.Utilities.AssertEx; using AssertEx = PortableTestUtils::Roslyn.Test.Utilities.AssertEx;
using TestBase = PortableTestUtils::Roslyn.Test.Utilities.TestBase;
using WorkItemAttribute = PortableTestUtils::Roslyn.Test.Utilities.WorkItemAttribute;
namespace Microsoft.CodeAnalysis.CSharp.Scripting.Test namespace Microsoft.CodeAnalysis.CSharp.Scripting.Test
{ {
using static TestCompilationFactory; using static TestCompilationFactory;
using DiagnosticExtensions = PortableTestUtils::Microsoft.CodeAnalysis.DiagnosticExtensions; using DiagnosticExtensions = PortableTestUtils::Microsoft.CodeAnalysis.DiagnosticExtensions;
using TestReferences = PortableTestUtils::TestReferences;
public class InteractiveSessionTests : TestBase public class InteractiveSessionTests : TestBase
{ {
private static readonly CSharpCompilationOptions s_signedDll =
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, cryptoPublicKey: TestResources.TestKeys.PublicKey_ce65828c82a341f2);
private static readonly CSharpCompilationOptions s_signedDll2 =
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, cryptoPublicKey: TestResources.TestKeys.PublicKey_ce65828c82a341f2);
[Fact] [Fact]
public async Task CompilationChain_GlobalImportsRebinding() public async Task CompilationChain_GlobalImportsRebinding()
{ {
...@@ -362,8 +369,11 @@ public void References_Versioning_StrongNames2() ...@@ -362,8 +369,11 @@ public void References_Versioning_StrongNames2()
[Fact] [Fact]
public void References_Versioning_WeakNames1() public void References_Versioning_WeakNames1()
{ {
var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray()); var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray()); CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());
var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());
var result = CSharpScript.EvaluateAsync($@" var result = CSharpScript.EvaluateAsync($@"
#r ""{c1.Path}"" #r ""{c1.Path}""
...@@ -378,8 +388,11 @@ public void References_Versioning_WeakNames1() ...@@ -378,8 +388,11 @@ public void References_Versioning_WeakNames1()
[Fact] [Fact]
public void References_Versioning_WeakNames2() public void References_Versioning_WeakNames2()
{ {
var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray()); var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray()); CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());
var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());
var result = CSharpScript.Create($@" var result = CSharpScript.Create($@"
#r ""{c1.Path}"" #r ""{c1.Path}""
...@@ -395,8 +408,11 @@ public void References_Versioning_WeakNames2() ...@@ -395,8 +408,11 @@ public void References_Versioning_WeakNames2()
[Fact] [Fact]
public void References_Versioning_WeakNames3() public void References_Versioning_WeakNames3()
{ {
var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray()); var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray()); CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());
var c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
CreateCSharpCompilation(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, assemblyName: "C").EmitToArray());
var script0 = CSharpScript.Create($@" var script0 = CSharpScript.Create($@"
#r ""{c1.Path}"" #r ""{c1.Path}""
...@@ -545,7 +561,7 @@ public async Task MissingRefrencesAutoResolution() ...@@ -545,7 +561,7 @@ public async Task MissingRefrencesAutoResolution()
[Fact] [Fact]
public void HostObjectInInMemoryAssembly() public void HostObjectInInMemoryAssembly()
{ {
var lib = CreateCSharpCompilationWithMscorlib("public class C { public int X = 1, Y = 2; }", "HostLib"); var lib = CreateCSharpCompilation("public class C { public int X = 1, Y = 2; }", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, "HostLib");
var libImage = lib.EmitToArray(); var libImage = lib.EmitToArray();
var libRef = MetadataImageReference.CreateFromImage(libImage); var libRef = MetadataImageReference.CreateFromImage(libImage);
...@@ -567,5 +583,541 @@ public void HostObjectInInMemoryAssembly() ...@@ -567,5 +583,541 @@ public void HostObjectInInMemoryAssembly()
Assert.Equal(3, result); Assert.Equal(3, result);
} }
} }
[Fact]
public async Task SharedLibCopy_Identical_Weak()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase = CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib2Name);
var libBaseImage = libBase.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1();");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
var s3 = await s2.ContinueWithAsync($@"var l2 = new Lib2();");
var s4 = await s3.ContinueWithAsync($@"l2.libBase.X");
var c4 = s4.Script.GetCompilation();
c4.VerifyAssemblyAliases(
lib2Name,
lib1Name,
"mscorlib",
libBaseName + ": <implicit>,global");
var libBaseRefAndSymbol = c4.GetBoundReferenceManager().GetReferencedAssemblies().ToArray()[3];
Assert.Equal(fileBase1.Path, ((PortableExecutableReference)libBaseRefAndSymbol.Key).FilePath);
}
[Fact]
public async Task SharedLibCopy_Identical_Strong()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase = CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib2Name);
var libBaseImage = libBase.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1();");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
var s3 = await s2.ContinueWithAsync($@"var l2 = new Lib2();");
var s4 = await s3.ContinueWithAsync($@"l2.libBase.X");
var c4 = s4.Script.GetCompilation();
c4.VerifyAssemblyAliases(
lib2Name,
lib1Name,
"mscorlib",
libBaseName + ": <implicit>,global");
var libBaseRefAndSymbol = c4.GetBoundReferenceManager().GetReferencedAssemblies().ToArray()[3];
Assert.Equal(fileBase1.Path, ((PortableExecutableReference)libBaseRefAndSymbol.Key).FilePath);
}
[Fact]
public async Task SharedLibCopy_SameVersion_Weak_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var libBase2 = CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1();");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"var l2 = new Lib2();");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_SameVersion_Strong_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_SameVersion_StrongWeak_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_SameVersion_StrongDifferentPKT_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll2);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_DifferentVersion_Weak()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var libBase2 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase2.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1().libBase.X;");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"var l2 = new Lib2().libBase.X;");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_DifferentVersion_Strong()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var lib1 = CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase2.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
Assert.Equal(1, s1.ReturnValue);
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
var s3 = await s2.ContinueWithAsync($@"new Lib2().libBase.X");
Assert.Equal(2, s3.ReturnValue);
}
[Fact, WorkItem(6457, "https://github.com/dotnet/roslyn/issues/6457")]
public async Task MissingReferencesReuse()
{
var source = @"
public class C
{
public System.Diagnostics.Process P;
}
";
var lib = CSharpCompilation.Create(
"Lib",
new[] { SyntaxFactory.ParseSyntaxTree(source) },
new[] { TestReferences.NetFx.v4_0_30319.mscorlib, TestReferences.NetFx.v4_0_30319.System },
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
var libFile = Temp.CreateFile("lib").WriteAllBytes(lib.EmitToArray());
var s0 = await CSharpScript.RunAsync("C c;", ScriptOptions.Default.WithReferences(libFile.Path));
var s1 = await s0.ContinueWithAsync("c = new C()");
}
} }
} }
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
...@@ -11,8 +12,8 @@ ...@@ -11,8 +12,8 @@
using Microsoft.CodeAnalysis.Scripting.Test; using Microsoft.CodeAnalysis.Scripting.Test;
using Microsoft.CodeAnalysis.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Xunit;
using Roslyn.Utilities; using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.Scripting.UnitTests namespace Microsoft.CodeAnalysis.CSharp.Scripting.UnitTests
{ {
...@@ -26,10 +27,55 @@ public class CommandLineRunnerTests : TestBase ...@@ -26,10 +27,55 @@ public class CommandLineRunnerTests : TestBase
// default csi.rsp // default csi.rsp
private static readonly string[] s_defaultArgs = new[] private static readonly string[] s_defaultArgs = new[]
{ {
"/r:System;System.Core;Microsoft.CSharp;System.ValueTuple.dll", "/r:" + string.Join(";", GetReferences()),
"/u:System;System.IO;System.Collections.Generic;System.Diagnostics;System.Dynamic;System.Linq;System.Linq.Expressions;System.Text;System.Threading.Tasks", "/u:System;System.IO;System.Collections.Generic;System.Diagnostics;System.Dynamic;System.Linq;System.Linq.Expressions;System.Text;System.Threading.Tasks",
}; };
private static IEnumerable<string> GetReferences()
{
if (GacFileResolver.IsAvailable)
{
// keep in sync with list in csi.rsp
yield return "System";
yield return "System.Core";
yield return "Microsoft.CSharp";
yield return "System.ValueTuple.dll";
}
else
{
// keep in sync with list in core csi.rsp
yield return "System.Collections";
yield return "System.Collections.Concurrent";
yield return "System.Console";
yield return "System.Diagnostics.Debug";
yield return "System.Diagnostics.Process";
yield return "System.Diagnostics.StackTrace";
yield return "System.Globalization";
yield return "System.IO";
yield return "System.IO.FileSystem";
yield return "System.IO.FileSystem.Primitives";
yield return "System.Reflection";
yield return "System.Reflection.Extensions";
yield return "System.Reflection.Primitives";
yield return "System.Runtime";
yield return "System.Runtime.InteropServices";
yield return "System.Text.Encoding";
yield return "System.Text.Encoding.CodePages";
yield return "System.Text.Encoding.Extensions";
yield return "System.Text.RegularExpressions";
yield return "System.Threading";
yield return "System.Threading.Tasks";
yield return "System.Threading.Tasks.Parallel";
yield return "System.Threading.Thread";
yield return "System.Linq";
yield return "System.Linq.Expressions";
yield return "System.Runtime.Numerics";
yield return "System.Dynamic.Runtime";
yield return "System.ValueTuple";
yield return "Microsoft.CSharp";
}
}
private static CommandLineRunner CreateRunner( private static CommandLineRunner CreateRunner(
string[] args = null, string[] args = null,
string input = "", string input = "",
...@@ -46,7 +92,7 @@ public class CommandLineRunnerTests : TestBase ...@@ -46,7 +92,7 @@ public class CommandLineRunnerTests : TestBase
var compiler = new CSharpInteractiveCompiler( var compiler = new CSharpInteractiveCompiler(
responseFile, responseFile,
buildPaths, buildPaths,
args ?? s_defaultArgs, args?.Where(a => a != null).ToArray() ?? s_defaultArgs,
new NotImplementedAnalyzerLoader()); new NotImplementedAnalyzerLoader());
return new CommandLineRunner(io, compiler, CSharpScriptCompiler.Instance, CSharpObjectFormatter.Instance); return new CommandLineRunner(io, compiler, CSharpScriptCompiler.Instance, CSharpObjectFormatter.Instance);
...@@ -94,10 +140,10 @@ public void Await() ...@@ -94,10 +140,10 @@ public void Await()
public void TestDisplayResultsWithCurrentUICulture() public void TestDisplayResultsWithCurrentUICulture()
{ {
var runner = CreateRunner(input: var runner = CreateRunner(input:
@"using static System.Globalization.CultureInfo; @"using System.Globalization;
DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"") CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
Math.PI Math.PI
DefaultThreadCurrentUICulture = GetCultureInfo(""de-DE"") CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""de-DE"")
Math.PI Math.PI
"); ");
runner.RunInteractive(); runner.RunInteractive();
...@@ -107,12 +153,12 @@ public void TestDisplayResultsWithCurrentUICulture() ...@@ -107,12 +153,12 @@ public void TestDisplayResultsWithCurrentUICulture()
Copyright (C) Microsoft Corporation. All rights reserved. Copyright (C) Microsoft Corporation. All rights reserved.
Type ""#help"" for more information. Type ""#help"" for more information.
> using static System.Globalization.CultureInfo; > using System.Globalization;
> DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"") > CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
[en-GB] [en-GB]
> Math.PI > Math.PI
3.1415926535897931 3.1415926535897931
> DefaultThreadCurrentUICulture = GetCultureInfo(""de-DE"") > CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""de-DE"")
[de-DE] [de-DE]
> Math.PI > Math.PI
3,1415926535897931 3,1415926535897931
...@@ -120,11 +166,11 @@ > Math.PI ...@@ -120,11 +166,11 @@ > Math.PI
// Tests that DefaultThreadCurrentUICulture is respected and not DefaultThreadCurrentCulture. // Tests that DefaultThreadCurrentUICulture is respected and not DefaultThreadCurrentCulture.
runner = CreateRunner(input: runner = CreateRunner(input:
@"using static System.Globalization.CultureInfo; @"using System.Globalization;
DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"") CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
DefaultThreadCurrentCulture = GetCultureInfo(""en-GB"") CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""en-GB"")
Math.PI Math.PI
DefaultThreadCurrentCulture = GetCultureInfo(""de-DE"") CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""de-DE"")
Math.PI Math.PI
"); ");
runner.RunInteractive(); runner.RunInteractive();
...@@ -134,14 +180,14 @@ > Math.PI ...@@ -134,14 +180,14 @@ > Math.PI
Copyright (C) Microsoft Corporation. All rights reserved. Copyright (C) Microsoft Corporation. All rights reserved.
Type ""#help"" for more information. Type ""#help"" for more information.
> using static System.Globalization.CultureInfo; > using System.Globalization;
> DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"") > CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
[en-GB] [en-GB]
> DefaultThreadCurrentCulture = GetCultureInfo(""en-GB"") > CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""en-GB"")
[en-GB] [en-GB]
> Math.PI > Math.PI
3.1415926535897931 3.1415926535897931
> DefaultThreadCurrentCulture = GetCultureInfo(""de-DE"") > CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""de-DE"")
[de-DE] [de-DE]
> Math.PI > Math.PI
3.1415926535897931 3.1415926535897931
...@@ -280,7 +326,7 @@ public void Args_Interactive2() ...@@ -280,7 +326,7 @@ public void Args_Interactive2()
AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Error.ToString()); AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Error.ToString());
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_InteractiveWithScript1() public void Args_InteractiveWithScript1()
{ {
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);"); var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
...@@ -313,7 +359,7 @@ > 1 ...@@ -313,7 +359,7 @@ > 1
> ", runner.Console.Out.ToString()); > ", runner.Console.Out.ToString());
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_Script1() public void Args_Script1()
{ {
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);"); var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
...@@ -321,7 +367,7 @@ public void Args_Script1() ...@@ -321,7 +367,7 @@ public void Args_Script1()
var runner = CreateRunner( var runner = CreateRunner(
args: new[] { script.Path, "arg1", "arg2", "arg3" }); args: new[] { script.Path, "arg1", "arg2", "arg3" });
Assert.Equal(0, runner.RunInteractive()); Assert.True(runner.RunInteractive() == 0, userMessage: runner.Console.Error.ToString());
AssertEx.AssertEqualToleratingWhitespaceDifferences($@" AssertEx.AssertEqualToleratingWhitespaceDifferences($@"
""arg1"" ""arg1""
...@@ -330,7 +376,7 @@ public void Args_Script1() ...@@ -330,7 +376,7 @@ public void Args_Script1()
", runner.Console.Out.ToString()); ", runner.Console.Out.ToString());
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_Script2() public void Args_Script2()
{ {
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);"); var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
...@@ -338,7 +384,7 @@ public void Args_Script2() ...@@ -338,7 +384,7 @@ public void Args_Script2()
var runner = CreateRunner( var runner = CreateRunner(
args: new[] { script.Path, "@arg1", "@arg2", "@arg3" }); args: new[] { script.Path, "@arg1", "@arg2", "@arg3" });
Assert.Equal(0, runner.RunInteractive()); Assert.True(runner.RunInteractive() == 0, userMessage: runner.Console.Error.ToString());
AssertEx.AssertEqualToleratingWhitespaceDifferences($@" AssertEx.AssertEqualToleratingWhitespaceDifferences($@"
""@arg1"" ""@arg1""
...@@ -347,7 +393,7 @@ public void Args_Script2() ...@@ -347,7 +393,7 @@ public void Args_Script2()
", runner.Console.Out.ToString()); ", runner.Console.Out.ToString());
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_Script3() public void Args_Script3()
{ {
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);"); var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
...@@ -366,7 +412,7 @@ public void Args_Script3() ...@@ -366,7 +412,7 @@ public void Args_Script3()
args: new[] { $"@{rsp.Path}", "/arg5", "--", "/arg7" }, args: new[] { $"@{rsp.Path}", "/arg5", "--", "/arg7" },
input: "foreach (var arg in Args) Print(arg);"); input: "foreach (var arg in Args) Print(arg);");
Assert.Equal(0, runner.RunInteractive()); Assert.True(runner.RunInteractive() == 0, userMessage: runner.Console.Error.ToString());
AssertEx.AssertEqualToleratingWhitespaceDifferences($@" AssertEx.AssertEqualToleratingWhitespaceDifferences($@"
""--"" ""--""
...@@ -482,11 +528,16 @@ public void Script_BadUsings() ...@@ -482,11 +528,16 @@ public void Script_BadUsings()
{ {
var script = Temp.CreateFile(extension: ".csx").WriteAllText("WriteLine(42);"); var script = Temp.CreateFile(extension: ".csx").WriteAllText("WriteLine(42);");
var runner = CreateRunner(new[] { "/u:System.Console;Foo.Bar", script.Path }); var runner = CreateRunner(new[]
{
GacFileResolver.IsAvailable ? null : "/r:System.Console",
"/u:System.Console;Alpha.Beta",
script.Path
});
Assert.Equal(1, runner.RunInteractive()); Assert.Equal(1, runner.RunInteractive());
const string error = @"error CS0246: The type or namespace name 'Foo' could not be found (are you missing a using directive or an assembly reference?)"; const string error = @"error CS0246: The type or namespace name 'Alpha' could not be found (are you missing a using directive or an assembly reference?)";
AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Out.ToString()); AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Out.ToString());
AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Error.ToString()); AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Error.ToString());
} }
...@@ -577,16 +628,16 @@ public void ReferenceSearchPaths1() ...@@ -577,16 +628,16 @@ public void ReferenceSearchPaths1()
"); ");
var dir1 = Temp.CreateDirectory(); var dir1 = Temp.CreateDirectory();
dir1.CreateFile("1.dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib("public class C1 {}", "1").EmitToArray()); dir1.CreateFile("1.dll").WriteAllBytes(CreateCSharpCompilationWithCorlib("public class C1 {}", "1").EmitToArray());
var dir2 = Temp.CreateDirectory(); var dir2 = Temp.CreateDirectory();
dir2.CreateFile("2.dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib("public class C2 {}", "2").EmitToArray()); dir2.CreateFile("2.dll").WriteAllBytes(CreateCSharpCompilationWithCorlib("public class C2 {}", "2").EmitToArray());
var dir3 = Temp.CreateDirectory(); var dir3 = Temp.CreateDirectory();
dir3.CreateFile("3.dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib("public class C3 {}", "3").EmitToArray()); dir3.CreateFile("3.dll").WriteAllBytes(CreateCSharpCompilationWithCorlib("public class C3 {}", "3").EmitToArray());
var dir4 = Temp.CreateDirectory(); var dir4 = Temp.CreateDirectory();
dir4.CreateFile("4.dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib("public class C4 {}", "4").EmitToArray()); dir4.CreateFile("4.dll").WriteAllBytes(CreateCSharpCompilationWithCorlib("public class C4 {}", "4").EmitToArray());
var runner = CreateRunner(new[] { "/r:4.dll", $"/lib:{dir1.Path}", $"/libpath:{dir2.Path}", $"/libpaths:{dir3.Path};{dir4.Path}", main.Path }); var runner = CreateRunner(new[] { "/r:4.dll", $"/lib:{dir1.Path}", $"/libpath:{dir2.Path}", $"/libpaths:{dir3.Path};{dir4.Path}", main.Path });
......
...@@ -30,12 +30,6 @@ public class HostModel ...@@ -30,12 +30,6 @@ public class HostModel
public class InteractiveSessionTests : TestBase public class InteractiveSessionTests : TestBase
{ {
private static readonly CSharpCompilationOptions s_signedDll =
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, cryptoPublicKey: TestResources.TestKeys.PublicKey_ce65828c82a341f2);
private static readonly CSharpCompilationOptions s_signedDll2 =
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, cryptoPublicKey: TestResources.TestKeys.PublicKey_ce65828c82a341f2);
internal static readonly Assembly HostAssembly = typeof(InteractiveSessionTests).GetTypeInfo().Assembly; internal static readonly Assembly HostAssembly = typeof(InteractiveSessionTests).GetTypeInfo().Assembly;
#region Namespaces, Types #region Namespaces, Types
...@@ -1134,579 +1128,69 @@ public void AwaitChain2() ...@@ -1134,579 +1128,69 @@ public void AwaitChain2()
[Fact] [Fact]
public void ReferenceDirective_FileWithDependencies() public void ReferenceDirective_FileWithDependencies()
{ {
string file1 = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01).Path; var file1 = Temp.CreateFile();
string file2 = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSInterfaces01).Path; var file2 = Temp.CreateFile();
// ICSPropImpl in CSClasses01.dll implements ICSProp in CSInterfces01.dll.
object result = CSharpScript.EvaluateAsync(@"
#r """ + file1 + @"""
#r """ + file2 + @"""
new Metadata.ICSPropImpl()
").Result;
Assert.NotNull(result);
}
[Fact]
public void ReferenceDirective_RelativeToBaseParent()
{
string path = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01).Path;
string fileName = Path.GetFileName(path);
string dir = Path.Combine(Path.GetDirectoryName(path), "subdir");
var script = CSharpScript.Create($@"#r ""..\{fileName}""",
ScriptOptions.Default.WithFilePath(Path.Combine(dir, "a.csx")));
script.GetCompilation().VerifyDiagnostics();
}
[Fact]
public void ReferenceDirective_RelativeToBaseRoot()
{
string path = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01).Path;
string root = Path.GetPathRoot(path);
string unrooted = path.Substring(root.Length);
string dir = Path.Combine(root, "foo", "bar", "baz");
var script = CSharpScript.Create($@"#r ""\{unrooted}""",
ScriptOptions.Default.WithFilePath(Path.Combine(dir, "a.csx")));
script.GetCompilation().VerifyDiagnostics();
}
[Fact, WorkItem(6457, "https://github.com/dotnet/roslyn/issues/6457")]
public async Task MissingReferencesReuse()
{
var source = @"
public class C
{
public System.Diagnostics.Process P;
}
";
var lib = CSharpCompilation.Create(
"Lib",
new[] { SyntaxFactory.ParseSyntaxTree(source) },
new[] { TestReferences.NetFx.v4_0_30319.mscorlib, TestReferences.NetFx.v4_0_30319.System },
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
var libFile = Temp.CreateFile("lib").WriteAllBytes(lib.EmitToArray());
var s0 = await CSharpScript.RunAsync("C c;", ScriptOptions.Default.WithReferences(libFile.Path));
var s1 = await s0.ContinueWithAsync("c = new C()");
}
[Fact]
public async Task SharedLibCopy_Identical_Weak()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase = TestCompilationFactory.CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib2Name);
var libBaseImage = libBase.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1();");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
var s3 = await s2.ContinueWithAsync($@"var l2 = new Lib2();");
var s4 = await s3.ContinueWithAsync($@"l2.libBase.X");
var c4 = s4.Script.GetCompilation();
c4.VerifyAssemblyAliases(
lib2Name,
lib1Name,
"mscorlib",
libBaseName + ": <implicit>,global");
var libBaseRefAndSymbol = c4.GetBoundReferenceManager().GetReferencedAssemblies().ToArray()[3];
Assert.Equal(fileBase1.Path, ((PortableExecutableReference)libBaseRefAndSymbol.Key).FilePath);
}
[Fact]
public async Task SharedLibCopy_Identical_Strong()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase = TestCompilationFactory.CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase.ToMetadataReference() }, lib2Name);
var libBaseImage = libBase.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBaseImage);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1();");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
var s3 = await s2.ContinueWithAsync($@"var l2 = new Lib2();");
var s4 = await s3.ContinueWithAsync($@"l2.libBase.X");
var c4 = s4.Script.GetCompilation();
c4.VerifyAssemblyAliases(
lib2Name,
lib1Name,
"mscorlib",
libBaseName + ": <implicit>,global");
var libBaseRefAndSymbol = c4.GetBoundReferenceManager().GetReferencedAssemblies().ToArray()[3];
Assert.Equal(fileBase1.Path, ((PortableExecutableReference)libBaseRefAndSymbol.Key).FilePath);
}
[Fact]
public async Task SharedLibCopy_SameVersion_Weak_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1();");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"var l2 = new Lib2();");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_SameVersion_Strong_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_SameVersion_StrongWeak_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen);
}
[Fact]
public async Task SharedLibCopy_SameVersion_StrongDifferentPKT_DifferentContent()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var libBase1 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@" var lib1 = CreateCSharpCompilationWithCorlib(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] public interface I
public class LibBase
{ {
public readonly int X = 2; int F();
} }");
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll2);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@" lib1.Emit(file1.Path);
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@" var lib2 = CreateCSharpCompilation(@"
public class Lib2 public class C : I
{ {
public LibBase libBase = new LibBase(); public int F() => 1;
} }", new MetadataReference[] { TestReferences.NetStandard13.SystemRuntime, lib1.ToMetadataReference() });
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false; lib2.Emit(file2.Path);
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen); object result = CSharpScript.EvaluateAsync($@"
#r ""{file1.Path}""
#r ""{file2.Path}""
new C()
").Result;
Assert.NotNull(result);
} }
[Fact] [Fact]
public async Task SharedLibCopy_DifferentVersion_Weak() public void ReferenceDirective_RelativeToBaseParent()
{ {
string libBaseName = "LibBase_" + Guid.NewGuid(); var file = Temp.CreateFile();
string lib1Name = "Lib1_" + Guid.NewGuid(); var lib = CreateCSharpCompilationWithCorlib("public class C {}");
string lib2Name = "Lib2_" + Guid.NewGuid(); lib.Emit(file.Path);
var libBase1 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")]
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase2.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray(); string dir = Path.Combine(Path.GetDirectoryName(file.Path), "subdir");
var libBase2Image = libBase2.EmitToArray(); string libFileName = Path.GetFileName(file.Path);
var lib1Image = lib1.EmitToArray(); string scriptPath = Path.Combine(dir, "a.csx");
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory(); var script = CSharpScript.Create(
var dir1 = root.CreateDirectory("1"); $@"#r ""{Path.Combine("..", libFileName)}""",
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image); ScriptOptions.Default.WithFilePath(scriptPath));
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}""");
var s1 = await s0.ContinueWithAsync($@"var l1 = new Lib1().libBase.X;");
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"var l2 = new Lib2().libBase.X;");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
Assert.True(exceptionSeen); script.GetCompilation().VerifyDiagnostics();
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public async Task SharedLibCopy_DifferentVersion_Strong() public void ReferenceDirective_RelativeToBaseRoot()
{ {
string libBaseName = "LibBase_" + Guid.NewGuid(); var file = Temp.CreateFile();
string lib1Name = "Lib1_" + Guid.NewGuid(); var lib = CreateCSharpCompilationWithCorlib("public class C {}");
string lib2Name = "Lib2_" + Guid.NewGuid(); lib.Emit(file.Path);
var libBase1 = TestCompilationFactory.CreateCSharpCompilation(@" string root = Path.GetPathRoot(file.Path);
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")] string unrooted = file.Path.Substring(root.Length);
public class LibBase
{
public readonly int X = 1;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@" string dir = Path.Combine(root, "foo", "bar", "baz");
[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] string scriptPath = Path.Combine(dir, "a.csx");
public class LibBase
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll);
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase2.ToMetadataReference() }, lib2Name);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
var root = Temp.CreateDirectory();
var dir1 = root.CreateDirectory("1");
var file1 = dir1.CreateFile(lib1Name + ".dll").WriteAllBytes(lib1Image);
var fileBase1 = dir1.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase1Image);
var dir2 = root.CreateDirectory("2"); var script = CSharpScript.Create(
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image); $@"#r ""\{unrooted}""",
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image); ScriptOptions.Default.WithFilePath(scriptPath));
var s0 = await CSharpScript.RunAsync($@"#r ""{file1.Path}"""); script.GetCompilation().VerifyDiagnostics();
var s1 = await s0.ContinueWithAsync($@"new Lib1().libBase.X");
Assert.Equal(1, s1.ReturnValue);
var s2 = await s1.ContinueWithAsync($@"#r ""{file2.Path}""");
var s3 = await s2.ContinueWithAsync($@"new Lib2().libBase.X");
Assert.Equal(2, s3.ReturnValue);
} }
[Fact] [Fact]
...@@ -1715,13 +1199,13 @@ public void ExtensionPriority1() ...@@ -1715,13 +1199,13 @@ public void ExtensionPriority1()
string mainName = "Main_" + Guid.NewGuid(); string mainName = "Main_" + Guid.NewGuid();
string libName = "Lib_" + Guid.NewGuid(); string libName = "Lib_" + Guid.NewGuid();
var libExe = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""exe""; }", libName); var libExe = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""exe""; }", libName);
var libDll = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""dll""; }", libName); var libDll = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""dll""; }", libName);
var libWinmd = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""winmd""; }", libName); var libWinmd = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""winmd""; }", libName);
var main = TestCompilationFactory.CreateCSharpCompilation( var main = CreateCSharpCompilation(
@"public static class M { public static readonly C X = new C(); }", @"public static class M { public static readonly C X = new C(); }",
new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libExe.ToMetadataReference() }, new MetadataReference[] { TestReferences.NetStandard13.SystemRuntime, libExe.ToMetadataReference() },
mainName); mainName);
var exeImage = libExe.EmitToArray(); var exeImage = libExe.EmitToArray();
...@@ -1745,13 +1229,13 @@ public void ExtensionPriority2() ...@@ -1745,13 +1229,13 @@ public void ExtensionPriority2()
string mainName = "Main_" + Guid.NewGuid(); string mainName = "Main_" + Guid.NewGuid();
string libName = "Lib_" + Guid.NewGuid(); string libName = "Lib_" + Guid.NewGuid();
var libExe = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""exe""; }", libName); var libExe = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""exe""; }", libName);
var libDll = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""dll""; }", libName); var libDll = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""dll""; }", libName);
var libWinmd = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""winmd""; }", libName); var libWinmd = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""winmd""; }", libName);
var main = TestCompilationFactory.CreateCSharpCompilation( var main = CreateCSharpCompilation(
@"public static class M { public static readonly C X = new C(); }", @"public static class M { public static readonly C X = new C(); }",
new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libExe.ToMetadataReference() }, new MetadataReference[] { TestReferences.NetStandard13.SystemRuntime, libExe.ToMetadataReference() },
mainName); mainName);
var exeImage = libExe.EmitToArray(); var exeImage = libExe.EmitToArray();
...@@ -1779,7 +1263,7 @@ public class D { } ...@@ -1779,7 +1263,7 @@ public class D { }
public class E { } public class E { }
"; ";
var libRef = CreateCSharpCompilationWithMscorlib(source, "lib").EmitToImageReference(); var libRef = CreateCSharpCompilationWithCorlib(source, "lib").EmitToImageReference();
var script = CSharpScript.Create(@"new C()", var script = CSharpScript.Create(@"new C()",
ScriptOptions.Default.WithReferences(libRef.WithAliases(new[] { "Hidden" })).WithImports("Hidden::N")); ScriptOptions.Default.WithReferences(libRef.WithAliases(new[] { "Hidden" })).WithImports("Hidden::N"));
......
...@@ -342,7 +342,7 @@ public void LongMembers() ...@@ -342,7 +342,7 @@ public void LongMembers()
Assert.Equal("LongMembers { LongNa...", str); Assert.Equal("LongMembers { LongNa...", str);
str = new TestCSharpObjectFormatter(maximumLineLength: 20).FormatObject(obj, SeparateLinesOptions); str = new TestCSharpObjectFormatter(maximumLineLength: 20).FormatObject(obj, SeparateLinesOptions);
Assert.Equal("LongMembers {\r\n LongName0123456789...\r\n LongValue: \"012345...\r\n}\r\n", str); Assert.Equal($"LongMembers {{{Environment.NewLine} LongName0123456789...{Environment.NewLine} LongValue: \"012345...{Environment.NewLine}}}{Environment.NewLine}", str);
} }
[Fact] [Fact]
...@@ -418,7 +418,16 @@ public void DebuggerProxy_FrameworkTypes_IEnumerable() ...@@ -418,7 +418,16 @@ public void DebuggerProxy_FrameworkTypes_IEnumerable()
obj = Enumerable.Range(0, 10); obj = Enumerable.Range(0, 10);
str = s_formatter.FormatObject(obj, SingleLineOptions); str = s_formatter.FormatObject(obj, SingleLineOptions);
Assert.Equal("RangeIterator { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }", str);
// the implementation differs between .NET Core and .NET FX
if (str.StartsWith("Enumerable"))
{
Assert.Equal("Enumerable.RangeIterator { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }", str);
}
else
{
Assert.Equal("RangeIterator { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }", str);
}
} }
[Fact] [Fact]
...@@ -825,7 +834,7 @@ public static void Method<U>() ...@@ -825,7 +834,7 @@ public static void Method<U>()
} }
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void StackTrace_NonGeneric() public void StackTrace_NonGeneric()
{ {
try try
...@@ -846,7 +855,7 @@ public void StackTrace_NonGeneric() ...@@ -846,7 +855,7 @@ public void StackTrace_NonGeneric()
} }
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void StackTrace_GenericMethod() public void StackTrace_GenericMethod()
{ {
try try
...@@ -868,7 +877,7 @@ public void StackTrace_GenericMethod() ...@@ -868,7 +877,7 @@ public void StackTrace_GenericMethod()
} }
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void StackTrace_GenericType() public void StackTrace_GenericType()
{ {
try try
...@@ -890,7 +899,7 @@ public void StackTrace_GenericType() ...@@ -890,7 +899,7 @@ public void StackTrace_GenericType()
} }
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void StackTrace_GenericMethodInGenericType() public void StackTrace_GenericMethodInGenericType()
{ {
try try
...@@ -959,7 +968,7 @@ public static void Method<U>(ref U u) ...@@ -959,7 +968,7 @@ public static void Method<U>(ref U u)
} }
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void StackTrace_RefOutParameters() public void StackTrace_RefOutParameters()
{ {
try try
...@@ -982,7 +991,7 @@ public void StackTrace_RefOutParameters() ...@@ -982,7 +991,7 @@ public void StackTrace_RefOutParameters()
} }
} }
[Fact] [ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void StackTrace_GenericRefParameter() public void StackTrace_GenericRefParameter()
{ {
try try
......
{ {
"dependencies": { "dependencies": {
"System.AppContext": "4.3.0",
"System.ValueTuple": "4.3.0" "System.ValueTuple": "4.3.0"
}, },
"frameworks": { "frameworks": {
......
...@@ -15,7 +15,7 @@ internal sealed class CoreAssemblyLoaderImpl : AssemblyLoaderImpl ...@@ -15,7 +15,7 @@ internal sealed class CoreAssemblyLoaderImpl : AssemblyLoaderImpl
internal CoreAssemblyLoaderImpl(InteractiveAssemblyLoader loader) internal CoreAssemblyLoaderImpl(InteractiveAssemblyLoader loader)
: base(loader) : base(loader)
{ {
_inMemoryAssemblyContext = new LoadContext(this, null); _inMemoryAssemblyContext = new LoadContext(Loader, null);
} }
public override Assembly LoadFromStream(Stream peStream, Stream pdbStream) public override Assembly LoadFromStream(Stream peStream, Stream pdbStream)
...@@ -25,7 +25,11 @@ public override Assembly LoadFromStream(Stream peStream, Stream pdbStream) ...@@ -25,7 +25,11 @@ public override Assembly LoadFromStream(Stream peStream, Stream pdbStream)
public override AssemblyAndLocation LoadFromPath(string path) public override AssemblyAndLocation LoadFromPath(string path)
{ {
var assembly = new LoadContext(this, Path.GetDirectoryName(path)).LoadFromAssemblyPath(path); // Create a new context that knows the directory where the assembly was loaded from
// and uses it to resolve dependencies of the assembly. We could create one context per directory,
// but there is no need to reuse contexts.
var assembly = new LoadContext(Loader, Path.GetDirectoryName(path)).LoadFromAssemblyPath(path);
return new AssemblyAndLocation(assembly, path, fromGac: false); return new AssemblyAndLocation(assembly, path, fromGac: false);
} }
...@@ -37,30 +41,33 @@ public override void Dispose() ...@@ -37,30 +41,33 @@ public override void Dispose()
private sealed class LoadContext : AssemblyLoadContext private sealed class LoadContext : AssemblyLoadContext
{ {
private readonly string _loadDirectoryOpt; private readonly string _loadDirectoryOpt;
private readonly CoreAssemblyLoaderImpl _loader; private readonly InteractiveAssemblyLoader _loader;
internal LoadContext(CoreAssemblyLoaderImpl loader, string loadDirectoryOpt) internal LoadContext(InteractiveAssemblyLoader loader, string loadDirectoryOpt)
{ {
Debug.Assert(loader != null); Debug.Assert(loader != null);
_loader = loader; _loader = loader;
_loadDirectoryOpt = loadDirectoryOpt; _loadDirectoryOpt = loadDirectoryOpt;
}
protected override Assembly Load(AssemblyName assemblyName) // CoreCLR resolves assemblies in steps:
{ //
return _loader.Loader.ResolveAssembly(AssemblyIdentity.FromAssemblyReference(assemblyName), _loadDirectoryOpt) ?? // 1) Call AssemblyLoadContext.Load -- our context returns null
Default.LoadFromAssemblyName(assemblyName); // 2) TPA list
} // 3) Default.Resolving event
// 4) AssemblyLoadContext.Resolving event -- hooked below
//
// What we want is to let the default context load assemblies it knows about (this includes already loaded assemblies,
// assemblies in AppPath, platform assemblies, assemblies explciitly resolved by the App by hooking Default.Resolving, etc.).
// Only if the assembly can't be resolved that way, the interactive resolver steps in.
//
// This order is necessary to avoid loading assemblies twice (by the host App and by interactive loader).
public new Assembly LoadFromStream(Stream assembly, Stream assemblySymbols) Resolving += (_, assemblyName) =>
{ _loader.ResolveAssembly(AssemblyIdentity.FromAssemblyReference(assemblyName), _loadDirectoryOpt);
return base.LoadFromStream(assembly, assemblySymbols);
} }
public new Assembly LoadFromAssemblyPath(string assemblyPath) protected override Assembly Load(AssemblyName assemblyName) => null;
{
return base.LoadFromAssemblyPath(assemblyPath);
}
} }
} }
} }
...@@ -155,10 +155,11 @@ private static ScriptOptions GetScriptOptions(CommandLineArguments arguments, st ...@@ -155,10 +155,11 @@ private static ScriptOptions GetScriptOptions(CommandLineArguments arguments, st
internal static MetadataReferenceResolver GetMetadataReferenceResolver(CommandLineArguments arguments, TouchedFileLogger loggerOpt) internal static MetadataReferenceResolver GetMetadataReferenceResolver(CommandLineArguments arguments, TouchedFileLogger loggerOpt)
{ {
return new RuntimeMetadataReferenceResolver( return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(arguments.ReferencePaths, arguments.BaseDirectory), pathResolver: new RelativePathResolver(arguments.ReferencePaths, arguments.BaseDirectory),
null, packageResolver: null,
GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null, gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) => useCoreResolver: !GacFileResolver.IsAvailable,
fileReferenceProvider: (path, properties) =>
{ {
loggerOpt?.AddRead(path); loggerOpt?.AddRead(path);
return MetadataReference.CreateFromFile(path, properties); return MetadataReference.CreateFromFile(path, properties);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
namespace Microsoft.CodeAnalysis.Scripting.Hosting namespace Microsoft.CodeAnalysis.Scripting.Hosting
{ {
...@@ -33,6 +34,11 @@ public override bool Include(StackFrame frame) ...@@ -33,6 +34,11 @@ public override bool Include(StackFrame frame)
return false; return false;
} }
if (type == typeof(ExceptionDispatchInfo) && method.Name == nameof(ExceptionDispatchInfo.Throw))
{
return false;
}
return true; return true;
} }
......
...@@ -3,9 +3,13 @@ ...@@ -3,9 +3,13 @@
#pragma warning disable 436 // The type 'RelativePathResolver' conflicts with imported type #pragma warning disable 436 // The type 'RelativePathResolver' conflicts with imported type
using System; using System;
using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Loader;
using Roslyn.Utilities; using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Scripting.Hosting namespace Microsoft.CodeAnalysis.Scripting.Hosting
...@@ -19,23 +23,34 @@ namespace Microsoft.CodeAnalysis.Scripting.Hosting ...@@ -19,23 +23,34 @@ namespace Microsoft.CodeAnalysis.Scripting.Hosting
internal sealed class RuntimeMetadataReferenceResolver : MetadataReferenceResolver, IEquatable<RuntimeMetadataReferenceResolver> internal sealed class RuntimeMetadataReferenceResolver : MetadataReferenceResolver, IEquatable<RuntimeMetadataReferenceResolver>
{ {
// Ideally we'd use properties with no aliases, but currently that's not possible since empty aliases mean {global}. // Ideally we'd use properties with no aliases, but currently that's not possible since empty aliases mean {global}.
private static readonly MetadataReferenceProperties s_resolvedMissingAssemblyReferenceProperties = MetadataReferenceProperties.Assembly.WithAliases(ImmutableArray.Create("<implicit>")); private static readonly MetadataReferenceProperties s_resolvedMissingAssemblyReferenceProperties =
MetadataReferenceProperties.Assembly.WithAliases(ImmutableArray.Create("<implicit>"));
public static readonly RuntimeMetadataReferenceResolver Default = new RuntimeMetadataReferenceResolver(ImmutableArray<string>.Empty, baseDirectory: null); internal static string GetDesktopFrameworkDirectory() => GacFileResolver.IsAvailable ?
PathUtilities.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.ManifestModule.FullyQualifiedName) : null;
// file name to path:
private static ImmutableDictionary<string, string> _lazyTrustedPlatformAssemblies;
public static readonly RuntimeMetadataReferenceResolver Default =
new RuntimeMetadataReferenceResolver(ImmutableArray<string>.Empty, baseDirectory: null);
internal readonly RelativePathResolver PathResolver; internal readonly RelativePathResolver PathResolver;
internal readonly NuGetPackageResolver PackageResolver; internal readonly NuGetPackageResolver PackageResolver;
internal readonly GacFileResolver GacFileResolver; internal readonly GacFileResolver GacFileResolver;
private readonly Func<string, MetadataReferenceProperties, PortableExecutableReference> _fileReferenceProvider; private readonly Func<string, MetadataReferenceProperties, PortableExecutableReference> _fileReferenceProvider;
private readonly bool _useCoreResolver;
// TODO: Look for .winmd, but only if the identity has content WindowsRuntime (https://github.com/dotnet/roslyn/issues/6483) // TODO: Look for .winmd, but only if the identity has content WindowsRuntime (https://github.com/dotnet/roslyn/issues/6483)
// The extensions are in order in which the CLR loader looks for assembly files. // The extensions are in order in which the CLR loader looks for assembly files.
internal static ImmutableArray<string> AssemblyExtensions = ImmutableArray.Create(".dll", ".exe"); internal static ImmutableArray<string> AssemblyExtensions = ImmutableArray.Create(".dll", ".exe");
internal RuntimeMetadataReferenceResolver( internal RuntimeMetadataReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory)
ImmutableArray<string> searchPaths, : this(pathResolver: new RelativePathResolver(searchPaths, baseDirectory),
string baseDirectory) packageResolver: null,
: this(new RelativePathResolver(searchPaths, baseDirectory), null, GacFileResolver.IsAvailable ? new GacFileResolver() : null) gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver() : null,
useCoreResolver: !GacFileResolver.IsAvailable,
fileReferenceProvider: null)
{ {
} }
...@@ -43,11 +58,13 @@ internal sealed class RuntimeMetadataReferenceResolver : MetadataReferenceResolv ...@@ -43,11 +58,13 @@ internal sealed class RuntimeMetadataReferenceResolver : MetadataReferenceResolv
RelativePathResolver pathResolver, RelativePathResolver pathResolver,
NuGetPackageResolver packageResolver, NuGetPackageResolver packageResolver,
GacFileResolver gacFileResolver, GacFileResolver gacFileResolver,
bool useCoreResolver,
Func<string, MetadataReferenceProperties, PortableExecutableReference> fileReferenceProvider = null) Func<string, MetadataReferenceProperties, PortableExecutableReference> fileReferenceProvider = null)
{ {
PathResolver = pathResolver; PathResolver = pathResolver;
PackageResolver = packageResolver; PackageResolver = packageResolver;
GacFileResolver = gacFileResolver; GacFileResolver = gacFileResolver;
_useCoreResolver = useCoreResolver;
_fileReferenceProvider = fileReferenceProvider ?? _fileReferenceProvider = fileReferenceProvider ??
new Func<string, MetadataReferenceProperties, PortableExecutableReference>((path, properties) => MetadataReference.CreateFromFile(path, properties)); new Func<string, MetadataReferenceProperties, PortableExecutableReference>((path, properties) => MetadataReference.CreateFromFile(path, properties));
} }
...@@ -66,14 +83,24 @@ public override PortableExecutableReference ResolveMissingAssembly(MetadataRefer ...@@ -66,14 +83,24 @@ public override PortableExecutableReference ResolveMissingAssembly(MetadataRefer
} }
} }
// look into a directory containing CorLib:
if (_useCoreResolver)
{
var result = ResolveTrustedPlatformAssemblyCore(referenceIdentity.Name, s_resolvedMissingAssemblyReferenceProperties);
if (result != null)
{
return result;
}
}
// look in the directory of the requesting definition: // look in the directory of the requesting definition:
var definitionPath = (definition as PortableExecutableReference)?.FilePath; string definitionPath = (definition as PortableExecutableReference)?.FilePath;
if (definitionPath != null) if (definitionPath != null)
{ {
var pathWithoutExtension = PathUtilities.CombinePathsUnchecked(PathUtilities.GetDirectoryName(definitionPath), referenceIdentity.Name); string pathWithoutExtension = PathUtilities.CombinePathsUnchecked(PathUtilities.GetDirectoryName(definitionPath), referenceIdentity.Name);
foreach (var extension in AssemblyExtensions) foreach (string extension in AssemblyExtensions)
{ {
var fullPath = pathWithoutExtension + extension; string fullPath = pathWithoutExtension + extension;
if (File.Exists(fullPath)) if (File.Exists(fullPath))
{ {
return CreateResolvedMissingReference(fullPath); return CreateResolvedMissingReference(fullPath);
...@@ -91,9 +118,7 @@ private PortableExecutableReference CreateResolvedMissingReference(string fullPa ...@@ -91,9 +118,7 @@ private PortableExecutableReference CreateResolvedMissingReference(string fullPa
public override ImmutableArray<PortableExecutableReference> ResolveReference(string reference, string baseFilePath, MetadataReferenceProperties properties) public override ImmutableArray<PortableExecutableReference> ResolveReference(string reference, string baseFilePath, MetadataReferenceProperties properties)
{ {
string packageName; if (NuGetPackageResolver.TryParsePackageReference(reference, out string packageName, out string packageVersion))
string packageVersion;
if (NuGetPackageResolver.TryParsePackageReference(reference, out packageName, out packageVersion))
{ {
if (PackageResolver != null) if (PackageResolver != null)
{ {
...@@ -106,28 +131,83 @@ public override ImmutableArray<PortableExecutableReference> ResolveReference(str ...@@ -106,28 +131,83 @@ public override ImmutableArray<PortableExecutableReference> ResolveReference(str
{ {
if (PathResolver != null) if (PathResolver != null)
{ {
var resolvedPath = PathResolver.ResolvePath(reference, baseFilePath); string resolvedPath = PathResolver.ResolvePath(reference, baseFilePath);
if (resolvedPath != null) if (resolvedPath != null)
{ {
return ImmutableArray.Create(_fileReferenceProvider(resolvedPath, properties)); return ImmutableArray.Create(_fileReferenceProvider(resolvedPath, properties));
} }
} }
} }
else if (GacFileResolver != null) else
{ {
var path = GacFileResolver.Resolve(reference); if (GacFileResolver != null)
if (path != null)
{ {
return ImmutableArray.Create(_fileReferenceProvider(path, properties)); string path = GacFileResolver.Resolve(reference);
if (path != null)
{
return ImmutableArray.Create(_fileReferenceProvider(path, properties));
}
}
if (_useCoreResolver && AssemblyIdentity.TryParseDisplayName(reference, out var identity, out var identityParts))
{
var result = ResolveTrustedPlatformAssemblyCore(identity.Name, properties);
if (result != null)
{
return ImmutableArray.Create(result);
}
} }
} }
return ImmutableArray<PortableExecutableReference>.Empty; return ImmutableArray<PortableExecutableReference>.Empty;
} }
private PortableExecutableReference ResolveTrustedPlatformAssemblyCore(string name, MetadataReferenceProperties properties)
{
if (_lazyTrustedPlatformAssemblies == null)
{
_lazyTrustedPlatformAssemblies = GetTrustedPlatformAssemblyMap();
}
if (_lazyTrustedPlatformAssemblies.TryGetValue(name, out string path) && File.Exists(path))
{
return MetadataReference.CreateFromFile(path, properties);
}
return null;
}
private static ImmutableDictionary<string, string> GetTrustedPlatformAssemblyMap()
{
var set = ImmutableDictionary.CreateBuilder<string, string>(StringComparer.OrdinalIgnoreCase);
if (CoreClrShim.AppContext.GetData?.Invoke("TRUSTED_PLATFORM_ASSEMBLIES") is string paths)
{
foreach (var path in paths.Split(Path.PathSeparator))
{
if (PathUtilities.GetExtension(path) == ".dll")
{
string fileName = PathUtilities.GetFileName(path, includeExtension: false);
if (fileName.EndsWith(".ni", StringComparison.OrdinalIgnoreCase))
{
fileName = fileName.Substring(0, fileName.Length - ".ni".Length);
}
// last one wins:
set[fileName] = path;
}
}
}
return set.ToImmutable();
}
public override int GetHashCode() public override int GetHashCode()
{ {
return Hash.Combine(PathResolver, Hash.Combine(PackageResolver, Hash.Combine(GacFileResolver, 0))); return Hash.Combine(PathResolver,
Hash.Combine(PackageResolver,
Hash.Combine(GacFileResolver,
Hash.Combine(_useCoreResolver, 0))));
} }
public bool Equals(RuntimeMetadataReferenceResolver other) public bool Equals(RuntimeMetadataReferenceResolver other)
...@@ -136,7 +216,8 @@ public bool Equals(RuntimeMetadataReferenceResolver other) ...@@ -136,7 +216,8 @@ public bool Equals(RuntimeMetadataReferenceResolver other)
other != null && other != null &&
Equals(PathResolver, other.PathResolver) && Equals(PathResolver, other.PathResolver) &&
Equals(PackageResolver, other.PackageResolver) && Equals(PackageResolver, other.PackageResolver) &&
Equals(GacFileResolver, other.GacFileResolver); Equals(GacFileResolver, other.GacFileResolver) &&
_useCoreResolver == other._useCoreResolver;
} }
public override bool Equals(object other) => Equals(other as RuntimeMetadataReferenceResolver); public override bool Equals(object other) => Equals(other as RuntimeMetadataReferenceResolver);
...@@ -144,7 +225,7 @@ public bool Equals(RuntimeMetadataReferenceResolver other) ...@@ -144,7 +225,7 @@ public bool Equals(RuntimeMetadataReferenceResolver other)
internal RuntimeMetadataReferenceResolver WithRelativePathResolver(RelativePathResolver resolver) internal RuntimeMetadataReferenceResolver WithRelativePathResolver(RelativePathResolver resolver)
{ {
return Equals(resolver, PathResolver) ? this : return Equals(resolver, PathResolver) ? this :
new RuntimeMetadataReferenceResolver(resolver, PackageResolver, GacFileResolver, _fileReferenceProvider); new RuntimeMetadataReferenceResolver(resolver, PackageResolver, GacFileResolver, _useCoreResolver, _fileReferenceProvider);
} }
} }
} }
...@@ -4,9 +4,11 @@ ...@@ -4,9 +4,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using Microsoft.CodeAnalysis.Scripting.Hosting; using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Scripting namespace Microsoft.CodeAnalysis.Scripting
{ {
...@@ -19,11 +21,50 @@ public sealed class ScriptOptions ...@@ -19,11 +21,50 @@ public sealed class ScriptOptions
{ {
public static ScriptOptions Default { get; } = new ScriptOptions( public static ScriptOptions Default { get; } = new ScriptOptions(
filePath: "", filePath: "",
references: ImmutableArray<MetadataReference>.Empty, references: GetDefaultMetadataReferences(),
namespaces: ImmutableArray<string>.Empty, namespaces: ImmutableArray<string>.Empty,
metadataResolver: RuntimeMetadataReferenceResolver.Default, metadataResolver: RuntimeMetadataReferenceResolver.Default,
sourceResolver: SourceFileResolver.Default); sourceResolver: SourceFileResolver.Default);
private static ImmutableArray<MetadataReference> GetDefaultMetadataReferences()
{
if (GacFileResolver.IsAvailable)
{
return ImmutableArray<MetadataReference>.Empty;
}
// Provide similar surface to mscorlib (netstandard 2.0).
// These references are resolved lazily. Keep in sync with list in core csi.rsp.
var files = new[]
{
"System.Collections",
"System.Collections.Concurrent",
"System.Console",
"System.Diagnostics.Debug",
"System.Diagnostics.Process",
"System.Diagnostics.StackTrace",
"System.Globalization",
"System.IO",
"System.IO.FileSystem",
"System.IO.FileSystem.Primitives",
"System.Reflection",
"System.Reflection.Extensions",
"System.Reflection.Primitives",
"System.Runtime",
"System.Runtime.InteropServices",
"System.Text.Encoding",
"System.Text.Encoding.CodePages",
"System.Text.Encoding.Extensions",
"System.Text.RegularExpressions",
"System.Threading",
"System.Threading.Tasks",
"System.Threading.Tasks.Parallel",
"System.Threading.Thread",
};
return ImmutableArray.CreateRange(files.Select(CreateUnresolvedReference));
}
/// <summary> /// <summary>
/// An array of <see cref="MetadataReference"/>s to be added to the script. /// An array of <see cref="MetadataReference"/>s to be added to the script.
/// </summary> /// </summary>
......
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
<Name>CodeAnalysis</Name> <Name>CodeAnalysis</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Any CPU' "></PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Any CPU' ">
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Any CPU' "></PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Any CPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' ">
<PlatformTarget>ARM</PlatformTarget> <PlatformTarget>ARM</PlatformTarget>
</PropertyGroup> </PropertyGroup>
...@@ -40,28 +42,28 @@ ...@@ -40,28 +42,28 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\..\Compilers\Core\Portable\FileSystem\RelativePathResolver.cs"> <Compile Include="..\..\Compilers\Core\Portable\FileSystem\RelativePathResolver.cs">
<Link>Resolvers\RelativePathResolver.cs</Link> <Link>Hosting\Resolvers\RelativePathResolver.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\CoreClrShim.cs"> <Compile Include="..\..\Compilers\Shared\CoreClrShim.cs">
<Link>CoreClrShim.cs</Link> <Link>CoreClrShim.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\ClrGlobalAssemblyCache.cs"> <Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\ClrGlobalAssemblyCache.cs">
<Link>Resolvers\ClrGlobalAssemblyCache.cs</Link> <Link>Hosting\Resolvers\ClrGlobalAssemblyCache.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\FusionAssemblyIdentity.cs"> <Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\FusionAssemblyIdentity.cs">
<Link>Resolvers\FusionAssemblyIdentity.cs</Link> <Link>Hosting\Resolvers\FusionAssemblyIdentity.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GacFileResolver.cs"> <Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GacFileResolver.cs">
<Link>Resolvers\GacFileResolver.cs</Link> <Link>Hosting\Resolvers\GacFileResolver.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GlobalAssemblyCache.cs"> <Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GlobalAssemblyCache.cs">
<Link>Resolvers\GlobalAssemblyCache.cs</Link> <Link>Hosting\Resolvers\GlobalAssemblyCache.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GlobalAssemblyCacheLocation.cs"> <Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GlobalAssemblyCacheLocation.cs">
<Link>Resolvers\GlobalAssemblyCache.Location.cs</Link> <Link>Hosting\Resolvers\GlobalAssemblyCacheLocation.cs</Link>
</Compile> </Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\MonoGlobalAssemblyCache.cs"> <Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\MonoGlobalAssemblyCache.cs">
<Link>Resolvers\MonoGlobalAssemblyCache.cs</Link> <Link>Hosting\Resolvers\MonoGlobalAssemblyCache.cs</Link>
</Compile> </Compile>
<Compile Include="Hosting\AssemblyLoader\AssemblyAndLocation.cs" /> <Compile Include="Hosting\AssemblyLoader\AssemblyAndLocation.cs" />
<Compile Include="Hosting\AssemblyLoader\AssemblyLoadResult.cs" /> <Compile Include="Hosting\AssemblyLoader\AssemblyLoadResult.cs" />
...@@ -157,4 +159,4 @@ ...@@ -157,4 +159,4 @@
<PublicAPI Include="PublicAPI.Unshipped.txt" /> <PublicAPI Include="PublicAPI.Unshipped.txt" />
</ItemGroup> </ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" /> <Import Project="..\..\..\build\Targets\Imports.targets" />
</Project> </Project>
\ No newline at end of file
{ {
"dependencies": { "dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1", "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"System.AppContext": "4.3.0",
"System.Collections": "4.3.0", "System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0", "System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.StackTrace": "4.3.0", "System.Diagnostics.StackTrace": "4.3.0",
......
...@@ -26,7 +26,9 @@ public void Resolve() ...@@ -26,7 +26,9 @@ public void Resolve()
var resolver = new RuntimeMetadataReferenceResolver( var resolver = new RuntimeMetadataReferenceResolver(
new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path), new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path),
new PackageResolver(ImmutableDictionary<string, ImmutableArray<string>>.Empty.Add("nuget:N/1.0", ImmutableArray.Create(assembly1.Path, assembly2.Path))), new PackageResolver(ImmutableDictionary<string, ImmutableArray<string>>.Empty.Add("nuget:N/1.0", ImmutableArray.Create(assembly1.Path, assembly2.Path))),
gacFileResolver: null); gacFileResolver: null,
useCoreResolver: false);
// Recognized NuGet reference. // Recognized NuGet reference.
var actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly); var actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly);
AssertEx.SetEqual(actualReferences.SelectAsArray(r => r.FilePath), assembly1.Path, assembly2.Path); AssertEx.SetEqual(actualReferences.SelectAsArray(r => r.FilePath), assembly1.Path, assembly2.Path);
...@@ -44,7 +46,9 @@ public void Resolve() ...@@ -44,7 +46,9 @@ public void Resolve()
resolver = new RuntimeMetadataReferenceResolver( resolver = new RuntimeMetadataReferenceResolver(
new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path), new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path),
packageResolver: null, packageResolver: null,
gacFileResolver: null); gacFileResolver: null,
useCoreResolver: false);
// Unrecognized NuGet reference. // Unrecognized NuGet reference.
actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly); actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly);
Assert.True(actualReferences.IsEmpty); Assert.True(actualReferences.IsEmpty);
......
...@@ -3,9 +3,8 @@ ...@@ -3,9 +3,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Xunit; using Xunit;
...@@ -23,7 +22,7 @@ public void AddReferences() ...@@ -23,7 +22,7 @@ public void AddReferences()
AddReferences("System.Linq"). AddReferences("System.Linq").
AddReferences("System.Linq"); AddReferences("System.Linq");
Assert.Equal(5, options.MetadataReferences.Length); Assert.Equal(GacFileResolver.IsAvailable ? 5 : 28, options.MetadataReferences.Length);
} }
[Fact] [Fact]
...@@ -31,7 +30,7 @@ public void AddReferences_Errors() ...@@ -31,7 +30,7 @@ public void AddReferences_Errors()
{ {
var moduleRef = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.NetModule01.ModuleCS00).GetReference(); var moduleRef = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.NetModule01.ModuleCS00).GetReference();
var options = ScriptOptions.Default; var options = ScriptOptions.Default.WithReferences(ImmutableArray<MetadataReference>.Empty);
Assert.Throws<ArgumentNullException>("references", () => options.AddReferences((MetadataReference[])null)); Assert.Throws<ArgumentNullException>("references", () => options.AddReferences((MetadataReference[])null));
Assert.Throws<ArgumentNullException>("references[0]", () => options.AddReferences(new MetadataReference[] { null })); Assert.Throws<ArgumentNullException>("references[0]", () => options.AddReferences(new MetadataReference[] { null }));
...@@ -54,15 +53,17 @@ public void AddReferences_Errors() ...@@ -54,15 +53,17 @@ public void AddReferences_Errors()
[Fact] [Fact]
public void WithReferences() public void WithReferences()
{ {
var options = ScriptOptions.Default.WithReferences("System.Linq", "system.linq"); var empty = ScriptOptions.Default.WithReferences(ImmutableArray<MetadataReference>.Empty);
var options = empty.WithReferences("System.Linq", "system.linq");
Assert.Equal(2, options.MetadataReferences.Length); Assert.Equal(2, options.MetadataReferences.Length);
options = ScriptOptions.Default.WithReferences(typeof(int).GetTypeInfo().Assembly, typeof(int).GetTypeInfo().Assembly); options = empty.WithReferences(typeof(int).GetTypeInfo().Assembly, typeof(int).GetTypeInfo().Assembly);
Assert.Equal(2, options.MetadataReferences.Length); Assert.Equal(2, options.MetadataReferences.Length);
var assemblyRef = ModuleMetadata.CreateFromImage(TestResources.SymbolsTests.Methods.CSMethods).GetReference(); var assemblyRef = ModuleMetadata.CreateFromImage(TestResources.SymbolsTests.Methods.CSMethods).GetReference();
options = ScriptOptions.Default.WithReferences(assemblyRef, assemblyRef); options = empty.WithReferences(assemblyRef, assemblyRef);
Assert.Equal(2, options.MetadataReferences.Length); Assert.Equal(2, options.MetadataReferences.Length);
} }
...@@ -71,7 +72,7 @@ public void WithReferences_Errors() ...@@ -71,7 +72,7 @@ public void WithReferences_Errors()
{ {
var moduleRef = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.NetModule01.ModuleCS00).GetReference(); var moduleRef = ModuleMetadata.CreateFromImage(TestResources.MetadataTests.NetModule01.ModuleCS00).GetReference();
var options = ScriptOptions.Default; var options = ScriptOptions.Default.WithReferences(ImmutableArray<MetadataReference>.Empty);
Assert.Throws<ArgumentNullException>("references", () => options.WithReferences((MetadataReference[])null)); Assert.Throws<ArgumentNullException>("references", () => options.WithReferences((MetadataReference[])null));
Assert.Throws<ArgumentNullException>("references", () => options.WithReferences((IEnumerable<MetadataReference>)null)); Assert.Throws<ArgumentNullException>("references", () => options.WithReferences((IEnumerable<MetadataReference>)null));
Assert.Throws<ArgumentNullException>("references", () => options.WithReferences(default(ImmutableArray<MetadataReference>))); Assert.Throws<ArgumentNullException>("references", () => options.WithReferences(default(ImmutableArray<MetadataReference>)));
......
...@@ -15,7 +15,7 @@ public abstract class ObjectFormatterTestBase ...@@ -15,7 +15,7 @@ public abstract class ObjectFormatterTestBase
public void AssertMembers(string str, params string[] expected) public void AssertMembers(string str, params string[] expected)
{ {
int i = 0; int i = 0;
foreach (var line in str.Split(new[] { "\r\n " }, StringSplitOptions.None)) foreach (var line in str.Split(new[] { Environment.NewLine + " " }, StringSplitOptions.None))
{ {
if (i == 0) if (i == 0)
{ {
...@@ -23,7 +23,7 @@ public void AssertMembers(string str, params string[] expected) ...@@ -23,7 +23,7 @@ public void AssertMembers(string str, params string[] expected)
} }
else if (i == expected.Length - 1) else if (i == expected.Length - 1)
{ {
Assert.Equal(expected[i] + "\r\n}\r\n", line); Assert.Equal(expected[i] + Environment.NewLine + "}" + Environment.NewLine, line);
} }
else else
{ {
......
...@@ -2,16 +2,21 @@ ...@@ -2,16 +2,21 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading;
namespace Microsoft.CodeAnalysis.Scripting namespace Microsoft.CodeAnalysis.Scripting
{ {
public sealed class OutputRedirect : IDisposable public sealed class OutputRedirect : IDisposable
{ {
private static readonly object s_guard = new object();
private readonly TextWriter _oldOut; private readonly TextWriter _oldOut;
private readonly StringWriter _newOut; private readonly StringWriter _newOut;
public OutputRedirect(IFormatProvider formatProvider) public OutputRedirect(IFormatProvider formatProvider)
{ {
Monitor.Enter(s_guard);
_oldOut = Console.Out; _oldOut = Console.Out;
_newOut = new StringWriter(formatProvider); _newOut = new StringWriter(formatProvider);
Console.SetOut(_newOut); Console.SetOut(_newOut);
...@@ -23,6 +28,8 @@ void IDisposable.Dispose() ...@@ -23,6 +28,8 @@ void IDisposable.Dispose()
{ {
Console.SetOut(_oldOut); Console.SetOut(_oldOut);
_newOut.Dispose(); _newOut.Dispose();
Monitor.Exit(s_guard);
} }
} }
} }
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. // 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 Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.VisualBasic; using Microsoft.CodeAnalysis.VisualBasic;
...@@ -9,28 +10,28 @@ internal static class TestCompilationFactory ...@@ -9,28 +10,28 @@ internal static class TestCompilationFactory
{ {
// TODO: we need to clean up and refactor CreateCompilationWithMscorlib in compiler tests // TODO: we need to clean up and refactor CreateCompilationWithMscorlib in compiler tests
// so that it can be used in portable tests. // so that it can be used in portable tests.
internal static Compilation CreateCSharpCompilationWithMscorlib(string source, string assemblyName) internal static Compilation CreateCSharpCompilationWithCorlib(string source, string assemblyName = null)
{ {
return CSharpCompilation.Create( return CSharpCompilation.Create(
assemblyName, assemblyName ?? Guid.NewGuid().ToString(),
new[] { CSharp.SyntaxFactory.ParseSyntaxTree(source) }, new[] { CSharp.SyntaxFactory.ParseSyntaxTree(source) },
new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, new[] { TestReferences.NetStandard13.SystemRuntime },
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
} }
internal static Compilation CreateVisualBasicCompilationWithMscorlib(string source, string assemblyName) internal static Compilation CreateVisualBasicCompilationWithCorlib(string source, string assemblyName = null)
{ {
return VisualBasicCompilation.Create( return VisualBasicCompilation.Create(
assemblyName, assemblyName ?? Guid.NewGuid().ToString(),
new[] { VisualBasic.SyntaxFactory.ParseSyntaxTree(source) }, new[] { VisualBasic.SyntaxFactory.ParseSyntaxTree(source) },
new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, new[] { TestReferences.NetStandard13.SystemRuntime },
new VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); new VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
} }
internal static Compilation CreateCSharpCompilation(string source, MetadataReference[] references, string assemblyName, CSharpCompilationOptions options = null) internal static Compilation CreateCSharpCompilation(string source, MetadataReference[] references, string assemblyName = null, CSharpCompilationOptions options = null)
{ {
return CSharpCompilation.Create( return CSharpCompilation.Create(
assemblyName, assemblyName ?? Guid.NewGuid().ToString(),
new[] { CSharp.SyntaxFactory.ParseSyntaxTree(source) }, new[] { CSharp.SyntaxFactory.ParseSyntaxTree(source) },
references, references,
options ?? new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); options ?? new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
......
...@@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.UnitTests ...@@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.UnitTests
Dim buildPaths = New BuildPaths( Dim buildPaths = New BuildPaths(
clientDir:=AppContext.BaseDirectory, clientDir:=AppContext.BaseDirectory,
workingDir:=If(workingDirectory, AppContext.BaseDirectory), workingDir:=If(workingDirectory, AppContext.BaseDirectory),
sdkDir:=CorLightup.Desktop.TryGetRuntimeDirectory(), sdkDir:=RuntimeMetadataReferenceResolver.GetDesktopFrameworkDirectory(),
tempDir:=Path.GetTempPath()) tempDir:=Path.GetTempPath())
Dim compiler = New VisualBasicInteractiveCompiler( Dim compiler = New VisualBasicInteractiveCompiler(
...@@ -80,7 +80,7 @@ Type ""#help"" for more information. ...@@ -80,7 +80,7 @@ Type ""#help"" for more information.
<Fact()> <Fact()>
Public Sub TestReferenceDirective() Public Sub TestReferenceDirective()
Dim file1 = Temp.CreateFile("1.dll").WriteAllBytes(TestCompilationFactory.CreateVisualBasicCompilationWithMscorlib(" Dim file1 = Temp.CreateFile("1.dll").WriteAllBytes(TestCompilationFactory.CreateVisualBasicCompilationWithCorlib("
public Class C1 public Class C1
Public Function Foo() As String Public Function Foo() As String
Return ""Bar"" Return ""Bar""
......
{ {
"dependencies": { "dependencies": {
"System.AppContext": "4.3.0"
}, },
"frameworks": { "frameworks": {
"netstandard1.3": { "netstandard1.3": {
......
...@@ -65,6 +65,10 @@ ...@@ -65,6 +65,10 @@
<Project>{12a68549-4e8c-42d6-8703-a09335f97997}</Project> <Project>{12a68549-4e8c-42d6-8703-a09335f97997}</Project>
<Name>Scripting</Name> <Name>Scripting</Name>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\..\Scripting\CSharpTest\CSharpScriptingTest.csproj">
<Project>{2dae4406-7a89-4b5f-95c3-bc5422ce47ce}</Project>
<Name>CSharpScriptingTest</Name>
</ProjectReference>
<ProjectReference Include="..\..\Scripting\CSharp\CSharpScripting.csproj"> <ProjectReference Include="..\..\Scripting\CSharp\CSharpScripting.csproj">
<Project>{066f0dbd-c46c-4c20-afec-99829a172625}</Project> <Project>{066f0dbd-c46c-4c20-afec-99829a172625}</Project>
<Name>CSharpScripting</Name> <Name>CSharpScripting</Name>
...@@ -87,4 +91,4 @@ ...@@ -87,4 +91,4 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" /> <Import Project="..\..\..\build\Targets\Imports.targets" />
</Project> </Project>
\ No newline at end of file
...@@ -120,7 +120,7 @@ public class TestAnalyzer : DiagnosticAnalyzer ...@@ -120,7 +120,7 @@ public class TestAnalyzer : DiagnosticAnalyzer
new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(analyzerSource) }, new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(analyzerSource) },
new MetadataReference[] new MetadataReference[]
{ {
TestBase.SystemRuntimeNetstandard13FacadeRef.Value, TestReferences.NetStandard13.SystemRuntime,
MetadataReference.CreateFromFile(immutable.Path), MetadataReference.CreateFromFile(immutable.Path),
MetadataReference.CreateFromFile(analyzer.Path) MetadataReference.CreateFromFile(analyzer.Path)
}, },
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
using Microsoft.CodeAnalysis.CodeGen; using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Extensions; using Microsoft.CodeAnalysis.Test.Extensions;
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities; using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit; using Xunit;
using Xunit.Sdk; using Xunit.Sdk;
...@@ -33,7 +35,7 @@ public static class CompilationExtensions ...@@ -33,7 +35,7 @@ public static class CompilationExtensions
if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug && options?.DebugInformationFormat != DebugInformationFormat.Embedded) if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug && options?.DebugInformationFormat != DebugInformationFormat.Embedded)
{ {
if (MonoHelpers.IsRunningOnMono()) if (MonoHelpers.IsRunningOnMono() || PathUtilities.IsUnixLikePlatform)
{ {
options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb); options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
} }
......
...@@ -534,6 +534,23 @@ public static PortableExecutableReference mscorlib ...@@ -534,6 +534,23 @@ public static PortableExecutableReference mscorlib
} }
} }
public static class NetStandard13
{
private static PortableExecutableReference s_systemRuntime;
public static PortableExecutableReference SystemRuntime
{
get
{
if (s_systemRuntime == null)
{
s_systemRuntime = AssemblyMetadata.CreateFromImage(TestResources.NetFX.ReferenceAssemblies_netstandard1_3.System_Runtime).GetReference(display: @"System.Runtime.dll (netstandard13 ref)");
}
return s_systemRuntime;
}
}
}
public static class DiagnosticTests public static class DiagnosticTests
{ {
public static class ErrTestLib01 public static class ErrTestLib01
......
...@@ -526,11 +526,6 @@ public static MetadataReference SystemRuntimePP7Ref ...@@ -526,11 +526,6 @@ public static MetadataReference SystemRuntimePP7Ref
} }
} }
public static Lazy<MetadataReference> SystemRuntimeNetstandard13FacadeRef { get; } =
new Lazy<MetadataReference>(() => AssemblyMetadata.CreateFromImage(
TestResources.NetFX.ReferenceAssemblies_netstandard1_3.System_Runtime)
.GetReference(display: "System.Runtime.dll"));
private static MetadataReference s_FSharpTestLibraryRef; private static MetadataReference s_FSharpTestLibraryRef;
public static MetadataReference FSharpTestLibraryRef public static MetadataReference FSharpTestLibraryRef
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册