diff --git a/NuGet.Config b/NuGet.Config
index 872c1fe3d5..57859c5533 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -1,9 +1,9 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/OmniSharp.Script/CachingScriptMetadataResolver.cs b/src/OmniSharp.Script/CachingScriptMetadataResolver.cs
index deee618000..5ff02eed44 100644
--- a/src/OmniSharp.Script/CachingScriptMetadataResolver.cs
+++ b/src/OmniSharp.Script/CachingScriptMetadataResolver.cs
@@ -1,27 +1,31 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Scripting;
namespace OmniSharp.Script
{
public class CachingScriptMetadataResolver : MetadataReferenceResolver
{
+ private readonly MetadataReferenceResolver _defaultReferenceResolver;
private static Dictionary> DirectReferenceCache = new Dictionary>();
private static Dictionary MissingReferenceCache = new Dictionary();
- private static MetadataReferenceResolver _defaultRuntimeResolver = ScriptMetadataResolver.Default;
+
+ public CachingScriptMetadataResolver(MetadataReferenceResolver defaultReferenceResolver)
+ {
+ _defaultReferenceResolver = defaultReferenceResolver;
+ }
public override bool Equals(object other)
{
- return _defaultRuntimeResolver.Equals(other);
+ return _defaultReferenceResolver.Equals(other);
}
public override int GetHashCode()
{
- return _defaultRuntimeResolver.GetHashCode();
+ return _defaultReferenceResolver.GetHashCode();
}
- public override bool ResolveMissingAssemblies => _defaultRuntimeResolver.ResolveMissingAssemblies;
+ public override bool ResolveMissingAssemblies => _defaultReferenceResolver.ResolveMissingAssemblies;
public override PortableExecutableReference ResolveMissingAssembly(MetadataReference definition, AssemblyIdentity referenceIdentity)
{
@@ -30,7 +34,7 @@ public override PortableExecutableReference ResolveMissingAssembly(MetadataRefer
return MissingReferenceCache[referenceIdentity.Name];
}
- var result = _defaultRuntimeResolver.ResolveMissingAssembly(definition, referenceIdentity);
+ var result = _defaultReferenceResolver.ResolveMissingAssembly(definition, referenceIdentity);
if (result != null)
{
MissingReferenceCache[referenceIdentity.Name] = result;
@@ -47,7 +51,7 @@ public override ImmutableArray ResolveReference(str
return DirectReferenceCache[key];
}
- var result = _defaultRuntimeResolver.ResolveReference(reference, baseFilePath, properties);
+ var result = _defaultReferenceResolver.ResolveReference(reference, baseFilePath, properties);
if (result.Length > 0)
{
DirectReferenceCache[key] = result;
diff --git a/src/OmniSharp.Script/OmniSharp.Script.csproj b/src/OmniSharp.Script/OmniSharp.Script.csproj
index e715469547..44bfc5b5a1 100644
--- a/src/OmniSharp.Script/OmniSharp.Script.csproj
+++ b/src/OmniSharp.Script/OmniSharp.Script.csproj
@@ -15,6 +15,7 @@
+
diff --git a/src/OmniSharp.Script/ScriptHelper.cs b/src/OmniSharp.Script/ScriptHelper.cs
index d6002b8e51..c7ddc926b1 100644
--- a/src/OmniSharp.Script/ScriptHelper.cs
+++ b/src/OmniSharp.Script/ScriptHelper.cs
@@ -1,15 +1,19 @@
using System;
using System.Collections.Generic;
using System.Reflection;
+using Dotnet.Script.NuGetMetadataResolver;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.Scripting.Hosting;
+using Microsoft.Extensions.Configuration;
namespace OmniSharp.Script
{
- public static class ScriptHelper
+ public class ScriptHelper
{
+ private readonly IConfiguration _configuration;
+
// aligned with CSI.exe
// https://github.com/dotnet/roslyn/blob/version-2.0.0-rc3/src/Interactive/csi/csi.rsp
internal static readonly IEnumerable DefaultNamespaces = new[]
@@ -28,28 +32,41 @@ public static class ScriptHelper
private static readonly CSharpParseOptions ParseOptions = new CSharpParseOptions(LanguageVersion.Default, DocumentationMode.Parse, SourceCodeKind.Script);
- private static readonly Lazy CompilationOptions = new Lazy(() =>
+ private readonly Lazy _compilationOptions;
+
+ public ScriptHelper(IConfiguration configuration = null)
+ {
+ this._configuration = configuration;
+ _compilationOptions = new Lazy(CreateCompilationOptions);
+ }
+
+ private CSharpCompilationOptions CreateCompilationOptions()
{
var compilationOptions = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
usings: DefaultNamespaces,
allowUnsafe: true,
- metadataReferenceResolver: new CachingScriptMetadataResolver(),
+ metadataReferenceResolver:
+ CreateMetadataReferenceResolver(),
sourceReferenceResolver: ScriptSourceResolver.Default,
- assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default).
- WithSpecificDiagnosticOptions(new Dictionary
+ assemblyIdentityComparer: DesktopAssemblyIdentityComparer.Default).WithSpecificDiagnosticOptions(
+ new Dictionary
{
// ensure that specific warnings about assembly references are always suppressed
// https://github.com/dotnet/roslyn/issues/5501
- { "CS1701", ReportDiagnostic.Suppress },
- { "CS1702", ReportDiagnostic.Suppress },
- { "CS1705", ReportDiagnostic.Suppress }
- });
+ {"CS1701", ReportDiagnostic.Suppress},
+ {"CS1702", ReportDiagnostic.Suppress},
+ {"CS1705", ReportDiagnostic.Suppress}
+ });
- var topLevelBinderFlagsProperty = typeof(CSharpCompilationOptions).GetProperty("TopLevelBinderFlags", BindingFlags.Instance | BindingFlags.NonPublic);
- var binderFlagsType = typeof(CSharpCompilationOptions).GetTypeInfo().Assembly.GetType("Microsoft.CodeAnalysis.CSharp.BinderFlags");
+ var topLevelBinderFlagsProperty =
+ typeof(CSharpCompilationOptions).GetProperty("TopLevelBinderFlags",
+ BindingFlags.Instance | BindingFlags.NonPublic);
+ var binderFlagsType = typeof(CSharpCompilationOptions).GetTypeInfo().Assembly
+ .GetType("Microsoft.CodeAnalysis.CSharp.BinderFlags");
- var ignoreCorLibraryDuplicatedTypesMember = binderFlagsType?.GetField("IgnoreCorLibraryDuplicatedTypes", BindingFlags.Static | BindingFlags.Public);
+ var ignoreCorLibraryDuplicatedTypesMember =
+ binderFlagsType?.GetField("IgnoreCorLibraryDuplicatedTypes", BindingFlags.Static | BindingFlags.Public);
var ignoreCorLibraryDuplicatedTypesValue = ignoreCorLibraryDuplicatedTypesMember?.GetValue(null);
if (ignoreCorLibraryDuplicatedTypesValue != null)
{
@@ -57,9 +74,25 @@ public static class ScriptHelper
}
return compilationOptions;
- });
+ }
- public static ProjectInfo CreateProject(string csxFileName, IEnumerable references, IEnumerable namespaces = null)
+ private CachingScriptMetadataResolver CreateMetadataReferenceResolver()
+ {
+ bool enableScriptNuGetReferences = false;
+
+ if (_configuration != null)
+ {
+ if (!bool.TryParse(_configuration["enableScriptNuGetReferences"], out enableScriptNuGetReferences))
+ {
+ enableScriptNuGetReferences = false;
+ }
+ }
+
+ return enableScriptNuGetReferences ? new CachingScriptMetadataResolver(new NuGetMetadataReferenceResolver(ScriptMetadataResolver.Default))
+ : new CachingScriptMetadataResolver(ScriptMetadataResolver.Default);
+ }
+
+ public ProjectInfo CreateProject(string csxFileName, IEnumerable references, IEnumerable namespaces = null)
{
var project = ProjectInfo.Create(
id: ProjectId.CreateNewId(),
@@ -67,7 +100,7 @@ public static ProjectInfo CreateProject(string csxFileName, IEnumerable _targetFrameWork = new Lazy(ResolveTargetFramework);
[ImportingConstructor]
public ScriptProjectSystem(OmniSharpWorkspace workspace, IOmniSharpEnvironment env, ILoggerFactory loggerFactory, MetadataFileReferenceCache metadataFileReferenceCache)
@@ -38,6 +41,7 @@ public ScriptProjectSystem(OmniSharpWorkspace workspace, IOmniSharpEnvironment e
_env = env;
_logger = loggerFactory.CreateLogger();
_projects = new Dictionary();
+ _scriptProjectProvider = ScriptProjectProvider.Create(loggerFactory);
}
public string Key => "Script";
@@ -46,6 +50,8 @@ public ScriptProjectSystem(OmniSharpWorkspace workspace, IOmniSharpEnvironment e
public void Initalize(IConfiguration configuration)
{
+ var scriptHelper = new ScriptHelper(configuration);
+
_logger.LogInformation($"Detecting CSX files in '{_env.TargetDirectory}'.");
// Nothing to do if there are no CSX files
@@ -60,15 +66,25 @@ public void Initalize(IConfiguration configuration)
// explicitly inherit scripting library references to all global script object (InteractiveScriptGlobals) to be recognized
var inheritedCompileLibraries = DependencyContext.Default.CompileLibraries.Where(x =>
- x.Name.ToLowerInvariant().StartsWith("microsoft.codeanalysis")).ToList();
+ x.Name.ToLowerInvariant().StartsWith("microsoft.codeanalysis")).ToList();
// explicitly include System.ValueTuple
inheritedCompileLibraries.AddRange(DependencyContext.Default.CompileLibraries.Where(x =>
- x.Name.ToLowerInvariant().StartsWith("system.valuetuple")));
+ x.Name.ToLowerInvariant().StartsWith("system.valuetuple")));
var runtimeContexts = File.Exists(Path.Combine(_env.TargetDirectory, "project.json")) ? ProjectContext.CreateContextForEachTarget(_env.TargetDirectory) : null;
var commonReferences = new HashSet();
+
+ if (!bool.TryParse(configuration["enableScriptNuGetReferences"], out var enableScriptNuGetReferences))
+ {
+ enableScriptNuGetReferences = false;
+ }
+
+ if (enableScriptNuGetReferences && (runtimeContexts == null || runtimeContexts.Any() == false))
+ {
+ runtimeContexts = TryCreateRuntimeContextsFromScriptFiles();
+ }
// if we have no context, then we also have no dependencies
// we can assume desktop framework
@@ -81,7 +97,7 @@ public void Initalize(IConfiguration configuration)
AddMetadataReference(commonReferences, typeof(Enumerable).GetTypeInfo().Assembly.Location);
inheritedCompileLibraries.AddRange(DependencyContext.Default.CompileLibraries.Where(x =>
- x.Name.ToLowerInvariant().StartsWith("system.runtime")));
+ x.Name.ToLowerInvariant().StartsWith("system.runtime")));
}
// otherwise we will grab dependencies for the script from the runtime context
else
@@ -106,7 +122,7 @@ public void Initalize(IConfiguration configuration)
{
inheritedCompileLibraries.AddRange(DependencyContext.Default.CompileLibraries.Where(x =>
- x.Name.ToLowerInvariant().StartsWith("system.runtime")));
+ x.Name.ToLowerInvariant().StartsWith("system.runtime")));
}
}
@@ -124,7 +140,7 @@ public void Initalize(IConfiguration configuration)
try
{
var csxFileName = Path.GetFileName(csxPath);
- var project = ScriptHelper.CreateProject(csxFileName, commonReferences);
+ var project = scriptHelper.CreateProject(csxFileName, commonReferences);
// add CSX project to workspace
_workspace.AddProject(project);
@@ -139,6 +155,21 @@ public void Initalize(IConfiguration configuration)
}
}
+ private IEnumerable TryCreateRuntimeContextsFromScriptFiles()
+ {
+ _logger.LogInformation($"Attempting to create runtime context from script files. Default target framework {_targetFrameWork.Value}");
+ try
+ {
+ var scriptProjectInfo = _scriptProjectProvider.CreateProject(_env.TargetDirectory, _targetFrameWork.Value);
+ return ProjectContext.CreateContextForEachTarget(Path.GetDirectoryName(scriptProjectInfo.PathToProjectJson));
+ }
+ catch (Exception exception)
+ {
+ _logger.LogError(exception, "Unable to create runtime context from script files.");
+ }
+ return null;
+ }
+
private void AddMetadataReference(ISet referenceCollection, string fileReference)
{
if (!File.Exists(fileReference))
@@ -201,5 +232,13 @@ Task