private string GetScriptCode(ScriptContext context) { string code; // when processing raw code, make sure we inject new lines after preprocessor directives if (context.FilePath == null) { var syntaxTree = CSharpSyntaxTree.ParseText(context.Code, ParseOptions); var syntaxRewriter = new PreprocessorLineRewriter(); var newSyntaxTree = syntaxRewriter.Visit(syntaxTree.GetRoot()); code = newSyntaxTree.ToFullString(); } else { code = context.Code.ToString(); } return(code); }
public virtual ScriptCompilationContext <TReturn> CreateCompilationContext <TReturn, THost>(ScriptContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var platformIdentifier = RuntimeHelper.GetPlatformIdentifier(); Logger.Verbose($"Current runtime is '{platformIdentifier}'."); var runtimeDependencies = RuntimeDependencyResolver.GetDependencies(context.WorkingDirectory, context.ScriptMode, context.Code.ToString()).ToArray(); var opts = CreateScriptOptions(context, runtimeDependencies.ToList()); var runtimeId = RuntimeHelper.GetRuntimeIdentifier(); var inheritedAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(runtimeId).Where(x => x.FullName.StartsWith("microsoft.codeanalysis", StringComparison.OrdinalIgnoreCase)).ToArray(); // Build up a dependency map that picks runtime assembly with the highest version. // This aligns with the CoreCLR that uses the highest version strategy. var dependencyMap = runtimeDependencies.SelectMany(rtd => rtd.Assemblies).Distinct().GroupBy(rdt => rdt.Name.Name, rdt => rdt) .Select(gr => new { Name = gr.Key, ResolvedRuntimeAssembly = gr.OrderBy(rdt => rdt.Name.Version).Last() }) .ToDictionary(f => f.Name, f => f.ResolvedRuntimeAssembly, StringComparer.OrdinalIgnoreCase); foreach (var runtimeAssembly in dependencyMap.Values) { Logger.Verbose("Adding reference to a runtime dependency => " + runtimeAssembly); opts = opts.AddReferences(MetadataReference.CreateFromFile(runtimeAssembly.Path)); } foreach (var nativeAsset in runtimeDependencies.SelectMany(rtd => rtd.NativeAssets).Distinct()) { if (RuntimeHelper.IsWindows()) { LoadLibrary(nativeAsset); } } foreach (var inheritedAssemblyName in inheritedAssemblyNames) { // Always prefer the resolved runtime dependency rather than the inherited assembly. if (!dependencyMap.ContainsKey(inheritedAssemblyName.Name)) { Logger.Verbose($"Adding reference to an inherited dependency => {inheritedAssemblyName.FullName}"); var assembly = Assembly.Load(inheritedAssemblyName); opts = opts.AddReferences(assembly); } } AssemblyLoadContext.Default.Resolving += (assemblyLoadContext, assemblyName) => MapUnresolvedAssemblyToRuntimeLibrary(dependencyMap, assemblyLoadContext, assemblyName); // when processing raw code, make sure we inject new lines after preprocessor directives string code; if (context.FilePath == null) { var syntaxTree = CSharpSyntaxTree.ParseText(context.Code, ParseOptions); var syntaxRewriter = new PreprocessorLineRewriter(); var newSyntaxTree = syntaxRewriter.Visit(syntaxTree.GetRoot()); code = newSyntaxTree.ToFullString(); } else { code = context.Code.ToString(); } var loader = new InteractiveAssemblyLoader(); var script = CSharpScript.Create <TReturn>(code, opts, typeof(THost), loader); var orderedDiagnostics = script.GetDiagnostics(SuppressedDiagnosticIds); if (orderedDiagnostics.Any(d => d.Severity == DiagnosticSeverity.Error)) { throw new CompilationErrorException("Script compilation failed due to one or more errors.", orderedDiagnostics.ToImmutableArray()); } return(new ScriptCompilationContext <TReturn>(script, context.Code, loader, opts)); }