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

Merge pull request #15658 from tmat/ScriptingOnCore11

Scripting on .NET Core 1.1
......@@ -16,6 +16,7 @@
<MicrosoftCodeAnalysisAnalyzersVersion>1.1.0</MicrosoftCodeAnalysisAnalyzersVersion>
<MicrosoftCodeAnalysisElfieVersion>0.10.6-rc2</MicrosoftCodeAnalysisElfieVersion>
<MicrosoftCompositionVersion>1.0.27</MicrosoftCompositionVersion>
<MicrosoftCSharpVersion>4.3.0</MicrosoftCSharpVersion>
<MicrosoftDiagnosticsRuntimeVersion>0.8.31-beta</MicrosoftDiagnosticsRuntimeVersion>
<MicrosoftDiagnosticsTracingTraceEventVersion>1.0.35</MicrosoftDiagnosticsTracingTraceEventVersion>
<MicrosoftDiaSymReaderVersion>1.1.0-beta1-60818-02</MicrosoftDiaSymReaderVersion>
......
......@@ -37,6 +37,7 @@
"Microsoft.CodeAnalysis.Analyzers",
"Microsoft.VisualBasic",
"Microsoft.Composition",
"Microsoft.CSharp",
"MicroBuild.*",
"ManagedEsent",
"Microsoft.CodeAnalysis.Elfie",
......
......@@ -229,7 +229,7 @@ public class TestAnalyzer : DiagnosticAnalyzer
new SyntaxTree[] { CSharp.SyntaxFactory.ParseSyntaxTree(analyzerSource) },
new MetadataReference[]
{
SystemRuntimeNetstandard13FacadeRef.Value,
TestReferences.NetStandard13.SystemRuntime,
MetadataReference.CreateFromFile(immutable.Path),
MetadataReference.CreateFromFile(analyzer.Path)
},
......
......@@ -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
{
internal static readonly Type Type = typeof(Assembly);
......
......@@ -295,7 +295,7 @@ internal static MetadataReference CreateFromAssemblyInternal(Assembly assembly)
return CreateFromAssemblyInternal(assembly, properties, documentation);
}
internal static MetadataReference CreateFromAssemblyInternal(
internal static PortableExecutableReference CreateFromAssemblyInternal(
Assembly assembly,
MetadataReferenceProperties properties,
DocumentationProvider documentation = null)
......
......@@ -2,6 +2,7 @@
using Roslyn.Utilities;
using System;
using System.Reflection;
namespace Microsoft.CodeAnalysis.Scripting
{
......@@ -15,5 +16,15 @@ internal static class AssemblyLoadContext
internal static readonly Type Type = ReflectionUtilities.TryGetType(
"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.
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Reflection;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Scripting.Hosting
{
......@@ -17,14 +15,18 @@ internal static int Main(string[] args)
{
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(
clientDir: AppContext.BaseDirectory,
clientDir: csiDirectory,
workingDir: Directory.GetCurrentDirectory(),
sdkDir: CorLightup.Desktop.TryGetRuntimeDirectory(),
sdkDir: RuntimeMetadataReferenceResolver.GetDesktopFrameworkDirectory(),
tempDir: Path.GetTempPath());
var compiler = new CSharpInteractiveCompiler(
responseFile: responseFile,
responseFile: Path.Combine(csiDirectory, InteractiveResponseFileName),
buildPaths: buildPaths,
args: args,
analyzerLoader: new NotImplementedAnalyzerLoader());
......
# references
/r:System.Collections.dll
/r:System.Console.dll
/r:System.Diagnostics.Process.dll
/r:System.Dynamic.Runtime.dll
/r:System.Globalization.dll
/r:System.IO.dll
/r:System.IO.FileSystem.dll
/r:System.IO.FileSystem.Primitives.dll
/r:System.Linq.dll
/r:System.Linq.Expressions.dll
/r:System.Reflection.dll
/r:System.Reflection.Primitives.dll
/r:System.Runtime.dll
/r:System.Runtime.Numerics.dll
/r:System.Runtime.Serialization.Json.dll
/r:System.Runtime.Serialization.Primitives.dll
/r:System.Text.Encoding.CodePages.dll
/r:System.Text.Encoding.dll
/r:System.Text.Encoding.Extensions.dll
/r:System.Text.RegularExpressions.dll
/r:System.Threading.dll
/r:System.Threading.Tasks.dll
/r:System.Threading.Tasks.Parallel.dll
/r:System.Threading.Thread.dll
# basic references
/r:System.Collections
/r:System.Collections.Concurrent
/r:System.Console
/r:System.Diagnostics.Debug
/r:System.Diagnostics.Process
/r:System.Diagnostics.StackTrace
/r:System.Globalization
/r:System.IO
/r:System.IO.FileSystem
/r:System.IO.FileSystem.Primitives
/r:System.Reflection
/r:System.Reflection.Primitives
/r:System.Runtime
/r:System.Runtime.InteropServices
/r:System.Text.Encoding
/r:System.Text.Encoding.CodePages
/r:System.Text.Encoding.Extensions
/r:System.Text.RegularExpressions
/r:System.Threading
/r:System.Threading.Tasks
/r:System.Threading.Tasks.Parallel
/r:System.Threading.Thread
# extra references
/r:System.Linq
/r:System.Linq.Expressions
/r:System.Runtime.Numerics
/r:System.Dynamic.Runtime
/r:System.ValueTuple.dll
/r:Microsoft.CSharp
# imports
/u:System
/u:System.IO
......
{
"dependencies": {
"System.ValueTuple": "4.3.0"
"System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.CSharp": "4.3.0"
},
"frameworks": {
// 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)
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(
new RelativePathResolver(searchPaths, baseDirectory),
null,
GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) => metadataService.GetReference(path, properties));
packageResolver: null,
gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
useCoreResolver: false,
fileReferenceProvider: (path, properties) => metadataService.GetReference(path, properties));
}
private static SourceReferenceResolver CreateSourceReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory)
......
......@@ -172,9 +172,10 @@ private MetadataReferenceResolver CreateMetadataReferenceResolver(ImmutableArray
{
return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(searchPaths, baseDirectory),
null,
GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) => new ShadowCopyReference(_metadataFileProvider, path, properties));
packageResolver: null,
gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
useCoreResolver: !GacFileResolver.IsAvailable,
fileReferenceProvider: (path, properties) => new ShadowCopyReference(_metadataFileProvider, path, properties));
}
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.
Imports System.IO
Imports System.Reflection
Imports Microsoft.CodeAnalysis.Scripting.Hosting
Imports Roslyn.Utilities
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
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(
clientDir:=AppContext.BaseDirectory,
workingDir:=CorLightup.Desktop.TryGetRuntimeDirectory(),
sdkDir:=AppContext.BaseDirectory,
clientDir:=vbiDirectory,
workingDir:=Directory.GetCurrentDirectory(),
sdkDir:=RuntimeMetadataReferenceResolver.GetDesktopFrameworkDirectory(),
tempDir:=Path.GetTempPath())
Dim compiler = New VisualBasicInteractiveCompiler(
responseFile,
buildPaths,
args,
New NotImplementedAnalyzerLoader())
responseFile:=Path.Combine(vbiDirectory, InteractiveResponseFileName),
buildPaths:=buildPaths,
args:=args,
analyzerLoader:=New NotImplementedAnalyzerLoader())
Dim runner = New CommandLineRunner(
ConsoleIO.Default,
......
{
"dependencies": {
"System.ValueTuple": "4.3.0"
"System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.VisualBasic": "10.1.0"
},
"frameworks": {
// We don't actually target netstandard1.6; this is to work around https://github.com/dotnet/roslyn/issues/12458
......
{
"dependencies": {
"System.ValueTuple": "4.3.0"
"System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.CSharp": "4.3.0"
},
"frameworks": {
"net46": {}
......
{
"dependencies": {
"System.ValueTuple": "4.3.0"
"System.ValueTuple": "4.3.0",
"System.Dynamic.Runtime": "4.3.0",
"Microsoft.VisualBasic": "10.1.0"
},
"frameworks": {
"net46": {}
......
......@@ -20,6 +20,9 @@
<dependency id="Microsoft.CodeAnalysis.Compilers" version="$version$" />
<dependency id="Microsoft.CodeAnalysis.Scripting" version="$version$" />
<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>
</dependencies>
</metadata>
......
......@@ -3,30 +3,37 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Microsoft.CodeAnalysis.Scripting.Test;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using TestBase = PortableTestUtils::Roslyn.Test.Utilities.TestBase;
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
{
using static TestCompilationFactory;
using DiagnosticExtensions = PortableTestUtils::Microsoft.CodeAnalysis.DiagnosticExtensions;
using TestReferences = PortableTestUtils::TestReferences;
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]
public async Task CompilationChain_GlobalImportsRebinding()
{
......@@ -362,8 +369,11 @@ public void References_Versioning_StrongNames2()
[Fact]
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 c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray());
var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
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($@"
#r ""{c1.Path}""
......@@ -378,8 +388,11 @@ public void References_Versioning_WeakNames1()
[Fact]
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 c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray());
var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
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($@"
#r ""{c1.Path}""
......@@ -395,8 +408,11 @@ public void References_Versioning_WeakNames2()
[Fact]
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 c2 = Temp.CreateFile(extension: ".dll").WriteAllBytes(CreateCSharpCompilationWithMscorlib(@"[assembly: System.Reflection.AssemblyVersion(""2.0.0.0"")] public class C {}", assemblyName: "C").EmitToArray());
var c1 = Temp.CreateFile(extension: ".dll").WriteAllBytes(
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($@"
#r ""{c1.Path}""
......@@ -545,7 +561,7 @@ public async Task MissingRefrencesAutoResolution()
[Fact]
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 libRef = MetadataImageReference.CreateFromImage(libImage);
......@@ -567,5 +583,541 @@ public void HostObjectInInMemoryAssembly()
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.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
......@@ -11,8 +12,8 @@
using Microsoft.CodeAnalysis.Scripting.Test;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.Scripting.UnitTests
{
......@@ -26,10 +27,55 @@ public class CommandLineRunnerTests : TestBase
// default csi.rsp
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",
};
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(
string[] args = null,
string input = "",
......@@ -46,7 +92,7 @@ public class CommandLineRunnerTests : TestBase
var compiler = new CSharpInteractiveCompiler(
responseFile,
buildPaths,
args ?? s_defaultArgs,
args?.Where(a => a != null).ToArray() ?? s_defaultArgs,
new NotImplementedAnalyzerLoader());
return new CommandLineRunner(io, compiler, CSharpScriptCompiler.Instance, CSharpObjectFormatter.Instance);
......@@ -94,10 +140,10 @@ public void Await()
public void TestDisplayResultsWithCurrentUICulture()
{
var runner = CreateRunner(input:
@"using static System.Globalization.CultureInfo;
DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"")
@"using System.Globalization;
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
Math.PI
DefaultThreadCurrentUICulture = GetCultureInfo(""de-DE"")
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""de-DE"")
Math.PI
");
runner.RunInteractive();
......@@ -107,12 +153,12 @@ public void TestDisplayResultsWithCurrentUICulture()
Copyright (C) Microsoft Corporation. All rights reserved.
Type ""#help"" for more information.
> using static System.Globalization.CultureInfo;
> DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"")
> using System.Globalization;
> CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
[en-GB]
> Math.PI
3.1415926535897931
> DefaultThreadCurrentUICulture = GetCultureInfo(""de-DE"")
> CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""de-DE"")
[de-DE]
> Math.PI
3,1415926535897931
......@@ -120,11 +166,11 @@ > Math.PI
// Tests that DefaultThreadCurrentUICulture is respected and not DefaultThreadCurrentCulture.
runner = CreateRunner(input:
@"using static System.Globalization.CultureInfo;
DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"")
DefaultThreadCurrentCulture = GetCultureInfo(""en-GB"")
@"using System.Globalization;
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""en-GB"")
Math.PI
DefaultThreadCurrentCulture = GetCultureInfo(""de-DE"")
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""de-DE"")
Math.PI
");
runner.RunInteractive();
......@@ -134,14 +180,14 @@ > Math.PI
Copyright (C) Microsoft Corporation. All rights reserved.
Type ""#help"" for more information.
> using static System.Globalization.CultureInfo;
> DefaultThreadCurrentUICulture = GetCultureInfo(""en-GB"")
> using System.Globalization;
> CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(""en-GB"")
[en-GB]
> DefaultThreadCurrentCulture = GetCultureInfo(""en-GB"")
> CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""en-GB"")
[en-GB]
> Math.PI
3.1415926535897931
> DefaultThreadCurrentCulture = GetCultureInfo(""de-DE"")
> CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(""de-DE"")
[de-DE]
> Math.PI
3.1415926535897931
......@@ -280,7 +326,7 @@ public void Args_Interactive2()
AssertEx.AssertEqualToleratingWhitespaceDifferences(error, runner.Console.Error.ToString());
}
[Fact]
[ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_InteractiveWithScript1()
{
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
......@@ -313,7 +359,7 @@ > 1
> ", runner.Console.Out.ToString());
}
[Fact]
[ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_Script1()
{
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
......@@ -321,7 +367,7 @@ public void Args_Script1()
var runner = CreateRunner(
args: new[] { script.Path, "arg1", "arg2", "arg3" });
Assert.Equal(0, runner.RunInteractive());
Assert.True(runner.RunInteractive() == 0, userMessage: runner.Console.Error.ToString());
AssertEx.AssertEqualToleratingWhitespaceDifferences($@"
""arg1""
......@@ -330,7 +376,7 @@ public void Args_Script1()
", runner.Console.Out.ToString());
}
[Fact]
[ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_Script2()
{
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
......@@ -338,7 +384,7 @@ public void Args_Script2()
var runner = CreateRunner(
args: new[] { script.Path, "@arg1", "@arg2", "@arg3" });
Assert.Equal(0, runner.RunInteractive());
Assert.True(runner.RunInteractive() == 0, userMessage: runner.Console.Error.ToString());
AssertEx.AssertEqualToleratingWhitespaceDifferences($@"
""@arg1""
......@@ -347,7 +393,7 @@ public void Args_Script2()
", runner.Console.Out.ToString());
}
[Fact]
[ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void Args_Script3()
{
var script = Temp.CreateFile(extension: ".csx").WriteAllText("foreach (var arg in Args) Print(arg);");
......@@ -366,7 +412,7 @@ public void Args_Script3()
args: new[] { $"@{rsp.Path}", "/arg5", "--", "/arg7" },
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($@"
""--""
......@@ -482,11 +528,16 @@ public void Script_BadUsings()
{
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());
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.Error.ToString());
}
......@@ -577,16 +628,16 @@ public void ReferenceSearchPaths1()
");
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();
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();
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();
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 });
......
......@@ -30,12 +30,6 @@ public class HostModel
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;
#region Namespaces, Types
......@@ -1134,579 +1128,69 @@ public void AwaitChain2()
[Fact]
public void ReferenceDirective_FileWithDependencies()
{
string file1 = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSClasses01).Path;
string file2 = Temp.CreateFile().WriteAllBytes(TestResources.MetadataTests.InterfaceAndClass.CSInterfaces01).Path;
// 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 file1 = Temp.CreateFile();
var file2 = Temp.CreateFile();
var libBase2 = TestCompilationFactory.CreateCSharpCompilation(@"
[assembly: System.Reflection.AssemblyVersion(""1.0.0.0"")]
public class LibBase
var lib1 = CreateCSharpCompilationWithCorlib(@"
public interface I
{
public readonly int X = 2;
}
", new[] { TestReferences.NetFx.v4_0_30319.mscorlib }, libBaseName, s_signedDll2);
int F();
}");
var lib1 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib1
{
public LibBase libBase = new LibBase();
}
", new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libBase1.ToMetadataReference() }, lib1Name);
lib1.Emit(file1.Path);
var lib2 = TestCompilationFactory.CreateCSharpCompilation(@"
public class Lib2
var lib2 = CreateCSharpCompilation(@"
public class C : I
{
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}""");
public int F() => 1;
}", new MetadataReference[] { TestReferences.NetStandard13.SystemRuntime, lib1.ToMetadataReference() });
bool exceptionSeen = false;
try
{
await s2.ContinueWithAsync($@"new Lib2().libBase.X");
}
catch (FileLoadException fileLoadEx) when (fileLoadEx.InnerException is InteractiveAssemblyLoaderException)
{
exceptionSeen = true;
}
lib2.Emit(file2.Path);
Assert.True(exceptionSeen);
object result = CSharpScript.EvaluateAsync($@"
#r ""{file1.Path}""
#r ""{file2.Path}""
new C()
").Result;
Assert.NotNull(result);
}
[Fact]
public async Task SharedLibCopy_DifferentVersion_Weak()
public void ReferenceDirective_RelativeToBaseParent()
{
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);
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 file = Temp.CreateFile();
var lib = CreateCSharpCompilationWithCorlib("public class C {}");
lib.Emit(file.Path);
var libBase1Image = libBase1.EmitToArray();
var libBase2Image = libBase2.EmitToArray();
var lib1Image = lib1.EmitToArray();
var lib2Image = lib2.EmitToArray();
string dir = Path.Combine(Path.GetDirectoryName(file.Path), "subdir");
string libFileName = Path.GetFileName(file.Path);
string scriptPath = Path.Combine(dir, "a.csx");
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;
}
var script = CSharpScript.Create(
$@"#r ""{Path.Combine("..", libFileName)}""",
ScriptOptions.Default.WithFilePath(scriptPath));
Assert.True(exceptionSeen);
script.GetCompilation().VerifyDiagnostics();
}
[Fact]
public async Task SharedLibCopy_DifferentVersion_Strong()
[ConditionalFact(typeof(WindowsOnly)), WorkItem(15860, "https://github.com/dotnet/roslyn/issues/15860")]
public void ReferenceDirective_RelativeToBaseRoot()
{
string libBaseName = "LibBase_" + Guid.NewGuid();
string lib1Name = "Lib1_" + Guid.NewGuid();
string lib2Name = "Lib2_" + Guid.NewGuid();
var file = Temp.CreateFile();
var lib = CreateCSharpCompilationWithCorlib("public class C {}");
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, s_signedDll);
string root = Path.GetPathRoot(file.Path);
string unrooted = file.Path.Substring(root.Length);
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, 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);
string dir = Path.Combine(root, "foo", "bar", "baz");
string scriptPath = Path.Combine(dir, "a.csx");
var dir2 = root.CreateDirectory("2");
var file2 = dir2.CreateFile(lib2Name + ".dll").WriteAllBytes(lib2Image);
var fileBase2 = dir2.CreateFile(libBaseName + ".dll").WriteAllBytes(libBase2Image);
var script = CSharpScript.Create(
$@"#r ""\{unrooted}""",
ScriptOptions.Default.WithFilePath(scriptPath));
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);
script.GetCompilation().VerifyDiagnostics();
}
[Fact]
......@@ -1715,13 +1199,13 @@ public void ExtensionPriority1()
string mainName = "Main_" + Guid.NewGuid();
string libName = "Lib_" + Guid.NewGuid();
var libExe = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""exe""; }", libName);
var libDll = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""dll""; }", libName);
var libWinmd = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""winmd""; }", libName);
var libExe = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""exe""; }", libName);
var libDll = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""dll""; }", 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(); }",
new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libExe.ToMetadataReference() },
new MetadataReference[] { TestReferences.NetStandard13.SystemRuntime, libExe.ToMetadataReference() },
mainName);
var exeImage = libExe.EmitToArray();
......@@ -1745,13 +1229,13 @@ public void ExtensionPriority2()
string mainName = "Main_" + Guid.NewGuid();
string libName = "Lib_" + Guid.NewGuid();
var libExe = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""exe""; }", libName);
var libDll = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""dll""; }", libName);
var libWinmd = TestCompilationFactory.CreateCSharpCompilationWithMscorlib(@"public class C { public string F = ""winmd""; }", libName);
var libExe = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""exe""; }", libName);
var libDll = CreateCSharpCompilationWithCorlib(@"public class C { public string F = ""dll""; }", 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(); }",
new MetadataReference[] { TestReferences.NetFx.v4_0_30319.mscorlib, libExe.ToMetadataReference() },
new MetadataReference[] { TestReferences.NetStandard13.SystemRuntime, libExe.ToMetadataReference() },
mainName);
var exeImage = libExe.EmitToArray();
......@@ -1779,7 +1263,7 @@ public class D { }
public class E { }
";
var libRef = CreateCSharpCompilationWithMscorlib(source, "lib").EmitToImageReference();
var libRef = CreateCSharpCompilationWithCorlib(source, "lib").EmitToImageReference();
var script = CSharpScript.Create(@"new C()",
ScriptOptions.Default.WithReferences(libRef.WithAliases(new[] { "Hidden" })).WithImports("Hidden::N"));
......
......@@ -342,7 +342,7 @@ public void LongMembers()
Assert.Equal("LongMembers { LongNa...", str);
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]
......@@ -418,7 +418,16 @@ public void DebuggerProxy_FrameworkTypes_IEnumerable()
obj = Enumerable.Range(0, 10);
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]
......@@ -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()
{
try
......@@ -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()
{
try
......@@ -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()
{
try
......@@ -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()
{
try
......@@ -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()
{
try
......@@ -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()
{
try
......
{
"dependencies": {
"System.AppContext": "4.3.0",
"System.ValueTuple": "4.3.0"
},
"frameworks": {
......
......@@ -15,7 +15,7 @@ internal sealed class CoreAssemblyLoaderImpl : AssemblyLoaderImpl
internal CoreAssemblyLoaderImpl(InteractiveAssemblyLoader loader)
: base(loader)
{
_inMemoryAssemblyContext = new LoadContext(this, null);
_inMemoryAssemblyContext = new LoadContext(Loader, null);
}
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)
{
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);
}
......@@ -37,30 +41,33 @@ public override void Dispose()
private sealed class LoadContext : AssemblyLoadContext
{
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);
_loader = loader;
_loadDirectoryOpt = loadDirectoryOpt;
}
protected override Assembly Load(AssemblyName assemblyName)
{
return _loader.Loader.ResolveAssembly(AssemblyIdentity.FromAssemblyReference(assemblyName), _loadDirectoryOpt) ??
Default.LoadFromAssemblyName(assemblyName);
}
// CoreCLR resolves assemblies in steps:
//
// 1) Call AssemblyLoadContext.Load -- our context returns null
// 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)
{
return base.LoadFromStream(assembly, assemblySymbols);
Resolving += (_, assemblyName) =>
_loader.ResolveAssembly(AssemblyIdentity.FromAssemblyReference(assemblyName), _loadDirectoryOpt);
}
public new Assembly LoadFromAssemblyPath(string assemblyPath)
{
return base.LoadFromAssemblyPath(assemblyPath);
}
protected override Assembly Load(AssemblyName assemblyName) => null;
}
}
}
......@@ -155,10 +155,11 @@ private static ScriptOptions GetScriptOptions(CommandLineArguments arguments, st
internal static MetadataReferenceResolver GetMetadataReferenceResolver(CommandLineArguments arguments, TouchedFileLogger loggerOpt)
{
return new RuntimeMetadataReferenceResolver(
new RelativePathResolver(arguments.ReferencePaths, arguments.BaseDirectory),
null,
GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
(path, properties) =>
pathResolver: new RelativePathResolver(arguments.ReferencePaths, arguments.BaseDirectory),
packageResolver: null,
gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver(preferredCulture: CultureInfo.CurrentCulture) : null,
useCoreResolver: !GacFileResolver.IsAvailable,
fileReferenceProvider: (path, properties) =>
{
loggerOpt?.AddRead(path);
return MetadataReference.CreateFromFile(path, properties);
......
......@@ -5,6 +5,7 @@
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
namespace Microsoft.CodeAnalysis.Scripting.Hosting
{
......@@ -33,6 +34,11 @@ public override bool Include(StackFrame frame)
return false;
}
if (type == typeof(ExceptionDispatchInfo) && method.Name == nameof(ExceptionDispatchInfo.Throw))
{
return false;
}
return true;
}
......
......@@ -3,9 +3,13 @@
#pragma warning disable 436 // The type 'RelativePathResolver' conflicts with imported type
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Loader;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Scripting.Hosting
......@@ -19,23 +23,34 @@ namespace Microsoft.CodeAnalysis.Scripting.Hosting
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}.
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 NuGetPackageResolver PackageResolver;
internal readonly GacFileResolver GacFileResolver;
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)
// The extensions are in order in which the CLR loader looks for assembly files.
internal static ImmutableArray<string> AssemblyExtensions = ImmutableArray.Create(".dll", ".exe");
internal RuntimeMetadataReferenceResolver(
ImmutableArray<string> searchPaths,
string baseDirectory)
: this(new RelativePathResolver(searchPaths, baseDirectory), null, GacFileResolver.IsAvailable ? new GacFileResolver() : null)
internal RuntimeMetadataReferenceResolver(ImmutableArray<string> searchPaths, string baseDirectory)
: this(pathResolver: new RelativePathResolver(searchPaths, baseDirectory),
packageResolver: null,
gacFileResolver: GacFileResolver.IsAvailable ? new GacFileResolver() : null,
useCoreResolver: !GacFileResolver.IsAvailable,
fileReferenceProvider: null)
{
}
......@@ -43,11 +58,13 @@ internal sealed class RuntimeMetadataReferenceResolver : MetadataReferenceResolv
RelativePathResolver pathResolver,
NuGetPackageResolver packageResolver,
GacFileResolver gacFileResolver,
bool useCoreResolver,
Func<string, MetadataReferenceProperties, PortableExecutableReference> fileReferenceProvider = null)
{
PathResolver = pathResolver;
PackageResolver = packageResolver;
GacFileResolver = gacFileResolver;
_useCoreResolver = useCoreResolver;
_fileReferenceProvider = fileReferenceProvider ??
new Func<string, MetadataReferenceProperties, PortableExecutableReference>((path, properties) => MetadataReference.CreateFromFile(path, properties));
}
......@@ -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:
var definitionPath = (definition as PortableExecutableReference)?.FilePath;
string definitionPath = (definition as PortableExecutableReference)?.FilePath;
if (definitionPath != null)
{
var pathWithoutExtension = PathUtilities.CombinePathsUnchecked(PathUtilities.GetDirectoryName(definitionPath), referenceIdentity.Name);
foreach (var extension in AssemblyExtensions)
string pathWithoutExtension = PathUtilities.CombinePathsUnchecked(PathUtilities.GetDirectoryName(definitionPath), referenceIdentity.Name);
foreach (string extension in AssemblyExtensions)
{
var fullPath = pathWithoutExtension + extension;
string fullPath = pathWithoutExtension + extension;
if (File.Exists(fullPath))
{
return CreateResolvedMissingReference(fullPath);
......@@ -91,9 +118,7 @@ private PortableExecutableReference CreateResolvedMissingReference(string fullPa
public override ImmutableArray<PortableExecutableReference> ResolveReference(string reference, string baseFilePath, MetadataReferenceProperties properties)
{
string packageName;
string packageVersion;
if (NuGetPackageResolver.TryParsePackageReference(reference, out packageName, out packageVersion))
if (NuGetPackageResolver.TryParsePackageReference(reference, out string packageName, out string packageVersion))
{
if (PackageResolver != null)
{
......@@ -106,28 +131,83 @@ public override ImmutableArray<PortableExecutableReference> ResolveReference(str
{
if (PathResolver != null)
{
var resolvedPath = PathResolver.ResolvePath(reference, baseFilePath);
string resolvedPath = PathResolver.ResolvePath(reference, baseFilePath);
if (resolvedPath != null)
{
return ImmutableArray.Create(_fileReferenceProvider(resolvedPath, properties));
}
}
}
else if (GacFileResolver != null)
else
{
var path = GacFileResolver.Resolve(reference);
if (path != null)
if (GacFileResolver != 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;
}
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()
{
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)
......@@ -136,7 +216,8 @@ public bool Equals(RuntimeMetadataReferenceResolver other)
other != null &&
Equals(PathResolver, other.PathResolver) &&
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);
......@@ -144,7 +225,7 @@ public bool Equals(RuntimeMetadataReferenceResolver other)
internal RuntimeMetadataReferenceResolver WithRelativePathResolver(RelativePathResolver resolver)
{
return Equals(resolver, PathResolver) ? this :
new RuntimeMetadataReferenceResolver(resolver, PackageResolver, GacFileResolver, _fileReferenceProvider);
new RuntimeMetadataReferenceResolver(resolver, PackageResolver, GacFileResolver, _useCoreResolver, _fileReferenceProvider);
}
}
}
......@@ -4,9 +4,11 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Scripting
{
......@@ -19,11 +21,50 @@ public sealed class ScriptOptions
{
public static ScriptOptions Default { get; } = new ScriptOptions(
filePath: "",
references: ImmutableArray<MetadataReference>.Empty,
references: GetDefaultMetadataReferences(),
namespaces: ImmutableArray<string>.Empty,
metadataResolver: RuntimeMetadataReferenceResolver.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>
/// An array of <see cref="MetadataReference"/>s to be added to the script.
/// </summary>
......
......@@ -18,8 +18,10 @@
<Name>CodeAnalysis</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Any CPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Any CPU' "></PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Any CPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Any CPU' ">
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|ARM' ">
<PlatformTarget>ARM</PlatformTarget>
</PropertyGroup>
......@@ -40,28 +42,28 @@
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\Compilers\Core\Portable\FileSystem\RelativePathResolver.cs">
<Link>Resolvers\RelativePathResolver.cs</Link>
<Link>Hosting\Resolvers\RelativePathResolver.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\CoreClrShim.cs">
<Link>CoreClrShim.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\ClrGlobalAssemblyCache.cs">
<Link>Resolvers\ClrGlobalAssemblyCache.cs</Link>
<Link>Hosting\Resolvers\ClrGlobalAssemblyCache.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\FusionAssemblyIdentity.cs">
<Link>Resolvers\FusionAssemblyIdentity.cs</Link>
<Link>Hosting\Resolvers\FusionAssemblyIdentity.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GacFileResolver.cs">
<Link>Resolvers\GacFileResolver.cs</Link>
<Link>Hosting\Resolvers\GacFileResolver.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GlobalAssemblyCache.cs">
<Link>Resolvers\GlobalAssemblyCache.cs</Link>
<Link>Hosting\Resolvers\GlobalAssemblyCache.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\GlobalAssemblyCacheLocation.cs">
<Link>Resolvers\GlobalAssemblyCache.Location.cs</Link>
<Link>Hosting\Resolvers\GlobalAssemblyCacheLocation.cs</Link>
</Compile>
<Compile Include="..\..\Compilers\Shared\GlobalAssemblyCacheHelpers\MonoGlobalAssemblyCache.cs">
<Link>Resolvers\MonoGlobalAssemblyCache.cs</Link>
<Link>Hosting\Resolvers\MonoGlobalAssemblyCache.cs</Link>
</Compile>
<Compile Include="Hosting\AssemblyLoader\AssemblyAndLocation.cs" />
<Compile Include="Hosting\AssemblyLoader\AssemblyLoadResult.cs" />
......@@ -157,4 +159,4 @@
<PublicAPI Include="PublicAPI.Unshipped.txt" />
</ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" />
</Project>
</Project>
\ No newline at end of file
{
"dependencies": {
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
"System.AppContext": "4.3.0",
"System.Collections": "4.3.0",
"System.Diagnostics.Debug": "4.3.0",
"System.Diagnostics.StackTrace": "4.3.0",
......
......@@ -26,7 +26,9 @@ public void Resolve()
var resolver = new RuntimeMetadataReferenceResolver(
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))),
gacFileResolver: null);
gacFileResolver: null,
useCoreResolver: false);
// Recognized NuGet reference.
var actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly);
AssertEx.SetEqual(actualReferences.SelectAsArray(r => r.FilePath), assembly1.Path, assembly2.Path);
......@@ -44,7 +46,9 @@ public void Resolve()
resolver = new RuntimeMetadataReferenceResolver(
new RelativePathResolver(ImmutableArray.Create(directory.Path), baseDirectory: directory.Path),
packageResolver: null,
gacFileResolver: null);
gacFileResolver: null,
useCoreResolver: false);
// Unrecognized NuGet reference.
actualReferences = resolver.ResolveReference("nuget:N/1.0", baseFilePath: null, properties: MetadataReferenceProperties.Assembly);
Assert.True(actualReferences.IsEmpty);
......
......@@ -3,9 +3,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
using Microsoft.CodeAnalysis.Scripting.Hosting;
using Roslyn.Test.Utilities;
using Xunit;
......@@ -23,7 +22,7 @@ public void AddReferences()
AddReferences("System.Linq").
AddReferences("System.Linq");
Assert.Equal(5, options.MetadataReferences.Length);
Assert.Equal(GacFileResolver.IsAvailable ? 5 : 28, options.MetadataReferences.Length);
}
[Fact]
......@@ -31,7 +30,7 @@ public void AddReferences_Errors()
{
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[0]", () => options.AddReferences(new MetadataReference[] { null }));
......@@ -54,15 +53,17 @@ public void AddReferences_Errors()
[Fact]
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);
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);
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);
}
......@@ -71,7 +72,7 @@ public void WithReferences_Errors()
{
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((IEnumerable<MetadataReference>)null));
Assert.Throws<ArgumentNullException>("references", () => options.WithReferences(default(ImmutableArray<MetadataReference>)));
......
......@@ -15,7 +15,7 @@ public abstract class ObjectFormatterTestBase
public void AssertMembers(string str, params string[] expected)
{
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)
{
......@@ -23,7 +23,7 @@ public void AssertMembers(string str, params string[] expected)
}
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
{
......
......@@ -2,16 +2,21 @@
using System;
using System.IO;
using System.Threading;
namespace Microsoft.CodeAnalysis.Scripting
{
public sealed class OutputRedirect : IDisposable
{
private static readonly object s_guard = new object();
private readonly TextWriter _oldOut;
private readonly StringWriter _newOut;
public OutputRedirect(IFormatProvider formatProvider)
{
Monitor.Enter(s_guard);
_oldOut = Console.Out;
_newOut = new StringWriter(formatProvider);
Console.SetOut(_newOut);
......@@ -23,6 +28,8 @@ void IDisposable.Dispose()
{
Console.SetOut(_oldOut);
_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.
using System;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.VisualBasic;
......@@ -9,28 +10,28 @@ internal static class TestCompilationFactory
{
// TODO: we need to clean up and refactor CreateCompilationWithMscorlib in compiler 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(
assemblyName,
assemblyName ?? Guid.NewGuid().ToString(),
new[] { CSharp.SyntaxFactory.ParseSyntaxTree(source) },
new[] { TestReferences.NetFx.v4_0_30319.mscorlib },
new[] { TestReferences.NetStandard13.SystemRuntime },
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
}
internal static Compilation CreateVisualBasicCompilationWithMscorlib(string source, string assemblyName)
internal static Compilation CreateVisualBasicCompilationWithCorlib(string source, string assemblyName = null)
{
return VisualBasicCompilation.Create(
assemblyName,
assemblyName ?? Guid.NewGuid().ToString(),
new[] { VisualBasic.SyntaxFactory.ParseSyntaxTree(source) },
new[] { TestReferences.NetFx.v4_0_30319.mscorlib },
new[] { TestReferences.NetStandard13.SystemRuntime },
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(
assemblyName,
assemblyName ?? Guid.NewGuid().ToString(),
new[] { CSharp.SyntaxFactory.ParseSyntaxTree(source) },
references,
options ?? new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
......
......@@ -32,7 +32,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Scripting.UnitTests
Dim buildPaths = New BuildPaths(
clientDir:=AppContext.BaseDirectory,
workingDir:=If(workingDirectory, AppContext.BaseDirectory),
sdkDir:=CorLightup.Desktop.TryGetRuntimeDirectory(),
sdkDir:=RuntimeMetadataReferenceResolver.GetDesktopFrameworkDirectory(),
tempDir:=Path.GetTempPath())
Dim compiler = New VisualBasicInteractiveCompiler(
......@@ -80,7 +80,7 @@ Type ""#help"" for more information.
<Fact()>
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 Function Foo() As String
Return ""Bar""
......
{
"dependencies": {
"System.AppContext": "4.3.0"
},
"frameworks": {
"netstandard1.3": {
......
......@@ -65,6 +65,10 @@
<Project>{12a68549-4e8c-42d6-8703-a09335f97997}</Project>
<Name>Scripting</Name>
</ProjectReference>
<ProjectReference Include="..\..\Scripting\CSharpTest\CSharpScriptingTest.csproj">
<Project>{2dae4406-7a89-4b5f-95c3-bc5422ce47ce}</Project>
<Name>CSharpScriptingTest</Name>
</ProjectReference>
<ProjectReference Include="..\..\Scripting\CSharp\CSharpScripting.csproj">
<Project>{066f0dbd-c46c-4c20-afec-99829a172625}</Project>
<Name>CSharpScripting</Name>
......@@ -87,4 +91,4 @@
</ProjectReference>
</ItemGroup>
<Import Project="..\..\..\build\Targets\Imports.targets" />
</Project>
</Project>
\ No newline at end of file
......@@ -120,7 +120,7 @@ public class TestAnalyzer : DiagnosticAnalyzer
new SyntaxTree[] { SyntaxFactory.ParseSyntaxTree(analyzerSource) },
new MetadataReference[]
{
TestBase.SystemRuntimeNetstandard13FacadeRef.Value,
TestReferences.NetStandard13.SystemRuntime,
MetadataReference.CreateFromFile(immutable.Path),
MetadataReference.CreateFromFile(analyzer.Path)
},
......
......@@ -11,7 +11,9 @@
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Extensions;
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using Xunit.Sdk;
......@@ -33,7 +35,7 @@ public static class CompilationExtensions
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);
}
......
......@@ -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 ErrTestLib01
......
......@@ -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;
public static MetadataReference FSharpTestLibraryRef
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册