Exemplo n.º 1
0
        public async Task MissingRefrencesAutoResolution()
        {
            var portableLib = CSharpCompilation.Create(
                "PortableLib",
                new[] { SyntaxFactory.ParseSyntaxTree("public class C {}") },
                new[] { SystemRuntimePP7Ref },
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            var portableLibRef = portableLib.ToMetadataReference();

            var loader = new InteractiveAssemblyLoader();

            loader.RegisterDependency(Assembly.Load(portableLib.EmitToArray().ToArray()));

            var s0 = await CSharpScript.Create("new C()", options : ScriptOptions.Default.AddReferences(portableLibRef), assemblyLoader : loader).RunAsync();

            var c0 = s0.Script.GetCompilation();

            // includes corlib, host type assembly by default:
            AssertEx.Equal(new[]
            {
                typeof(object).GetTypeInfo().Assembly.Location,
                "PortableLib"
            }, c0.ExternalReferences.SelectAsArray(m => m.Display));

            // System.Runtime, 4.0.0.0 depends on all the assemblies below:
            AssertEx.Equal(new[]
            {
                "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "PortableLib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
                "System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.ComponentModel.Composition, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.Data.SqlXml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
            }, c0.GetBoundReferenceManager().GetReferencedAssemblies().Select(a => a.Value.Identity.GetDisplayName()));
        }
            public void Initialize(Type replServiceProviderType, string cultureName)
            {
                Debug.Assert(replServiceProviderType != null);
                Debug.Assert(cultureName != null);

                Debug.Assert(_metadataFileProvider == null);
                Debug.Assert(_assemblyLoader == null);
                Debug.Assert(_replServiceProvider == null);

                // TODO (tomat): we should share the copied files with the host
                _metadataFileProvider = new MetadataShadowCopyProvider(
                    Path.Combine(Path.GetTempPath(), "InteractiveHostShadow"),
                    noShadowCopyDirectories: s_systemNoShadowCopyDirectories,
                    documentationCommentsCulture: new CultureInfo(cultureName));

                _assemblyLoader = new InteractiveAssemblyLoader(_metadataFileProvider);

                _replServiceProvider = (ReplServiceProvider)Activator.CreateInstance(replServiceProviderType);

                _globals = new InteractiveScriptGlobals(Console.Out, _replServiceProvider.ObjectFormatter);
            }
        private async void CommandBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && !Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
            {
                Debug.WriteLine(CommandBox.Text);
                e.Handled            = true;
                CommandBox.IsEnabled = false;
                object result;
                try
                {
                    using (var loader = new InteractiveAssemblyLoader())
                    {
                        loader.RegisterDependency(typeof(UndertaleObject).GetTypeInfo().Assembly);

                        var script = CSharpScript.Create <object>(CommandBox.Text, ScriptOptions.Default
                                                                  .AddImports("UndertaleModLib", "UndertaleModLib.Models", "UndertaleModLib.Decompiler", "UndertaleModLib.Scripting")
                                                                  .AddImports("System", "System.IO", "System.Collections.Generic", "System.Text.RegularExpressions")
                                                                  .AddReferences(Program.GetAssemblyMetadata(typeof(UndertaleObject).GetTypeInfo().Assembly))
                                                                  .AddReferences(typeof(System.Text.RegularExpressions.Regex).GetTypeInfo().Assembly),
                                                                  typeof(IScriptInterface), loader);

                        result = (await script.RunAsync(this)).ReturnValue;
                    }
                }
                catch (CompilationErrorException exc)
                {
                    result = exc.Message;
                    Debug.WriteLine(exc);
                }
                catch (Exception exc)
                {
                    result = exc;
                }
                CommandBox.Text = result != null?result.ToString() : "";

                CommandBox.IsEnabled = true;
            }
        }
Exemplo n.º 4
0
        public virtual ScriptCompilationContext <TReturn> CreateCompilationContext <TReturn, THost>(ScriptContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            Logger.Verbose($"Current runtime is '{_scriptEnvironment.PlatformIdentifier}'.");
            RuntimeDependency[] runtimeDependencies = GetRuntimeDependencies(context);

            var encoding      = context.Code.Encoding ?? Encoding.UTF8; // encoding is required when emitting debug information
            var scriptOptions = CreateScriptOptions(context, runtimeDependencies.ToList())
                                .WithFileEncoding(encoding);

            var loadedAssembliesMap = CreateLoadedAssembliesMap();

            var scriptDependenciesMap = CreateScriptDependenciesMap(runtimeDependencies);

            scriptOptions = AddScriptReferences(scriptOptions, loadedAssembliesMap, scriptDependenciesMap);

            LoadNativeAssets(runtimeDependencies);

            AppDomain.CurrentDomain.AssemblyResolve +=
                (sender, args) => MapUnresolvedAssemblyToRuntimeLibrary(scriptDependenciesMap, loadedAssembliesMap, args);

            string code = GetScriptCode(context);

            var loader = new InteractiveAssemblyLoader();

            var script = CSharpScript.Create <TReturn>(code, scriptOptions, typeof(THost), loader);

            SetOptimizationLevel(context, script);

            EvaluateDiagnostics(script);

            return(new ScriptCompilationContext <TReturn>(script, context.Code, loader, scriptOptions));
        }
Exemplo n.º 5
0
        public virtual ScriptCompilationContext <TReturn> CreateCompilationContext <TReturn, THost>(ScriptContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            Logger.Verbose($"Current runtime is '{RuntimeHelper.GetPlatformIdentifier()}'.");

            var runtimeDependencies = RuntimeDependencyResolver.GetDependencies(context.WorkingDirectory, context.ScriptMode, context.Code.ToString()).ToArray();

            var scriptOptions = CreateScriptOptions(context, runtimeDependencies.ToList());

            var loadedAssembliesMap = CreateLoadedAssembliesMap();

            var scriptDependenciesMap = CreateScriptDependenciesMap(runtimeDependencies);

            scriptOptions = AddScriptReferences(scriptOptions, loadedAssembliesMap, scriptDependenciesMap);

            LoadNativeAssets(runtimeDependencies);

            AppDomain.CurrentDomain.AssemblyResolve +=
                (sender, args) => MapUnresolvedAssemblyToRuntimeLibrary(scriptDependenciesMap, loadedAssembliesMap, args);

            string code = GetScriptCode(context);

            var loader = new InteractiveAssemblyLoader();

            var script = CSharpScript.Create <TReturn>(code, scriptOptions, typeof(THost), loader);

            SetOptimizationLevel(context, script);

            EvaluateDiagnostics(script);

            return(new ScriptCompilationContext <TReturn>(script, context.Code, loader, scriptOptions));
        }
Exemplo n.º 6
0
        // SCRIPT evaluate python script in node name or in node note in node
        private async System.Threading.Tasks.Task EvaluateAsync(Diagram.Diagram diagram, DiagramView diagramView, Node node, string clipboard = "")
        {
            string body = node.note;

            if (this.interactiveLoader == null)
            {
                this.interactiveLoader = new InteractiveAssemblyLoader();
            }

            if (this.scriptOptions == null)
            {
                this.scriptOptions = ScriptOptions.Default;

                var asms = AppDomain.CurrentDomain.GetAssemblies();
                foreach (Assembly asm in asms)
                {
                    Program.log.Write("CSScriptPlugin: " + asm.ManifestModule.Name);
                    if (asm.ManifestModule.Name == "InfiniteDiagram.exe")
                    {
                        this.scriptOptions = this.scriptOptions.AddReferences(asm);
                    }
                }

                this.scriptOptions = this.scriptOptions.AddImports("Diagram");
            }

            System.Threading.Tasks.Task <ScriptState <object> > task = CSharpScript.Create(
                options: this.scriptOptions,
                code: body,
                globalsType: typeof(Globals),
                assemblyLoader: this.interactiveLoader
                )
                                                                       .RunAsync(new Globals {
                Script = new Tools(diagram, diagramView, node, clipboard)
            });;
        }
        public void HostObjectInInMemoryAssembly()
        {
            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);

            var libAssembly = Assembly.Load(libImage.ToArray());
            var globalsType = libAssembly.GetType("C");
            var globals     = Activator.CreateInstance(globalsType);

            using (var loader = new InteractiveAssemblyLoader())
            {
                loader.RegisterDependency(libAssembly);

                var script = CSharpScript.Create <int>(
                    "X+Y",
                    ScriptOptions.Default.WithReferences(libRef),
                    globalsType: globalsType,
                    assemblyLoader: loader);

                int result = script.RunAsync(globals).Result.ReturnValue;
                Assert.Equal(3, result);
            }
        }
Exemplo n.º 8
0
            public Service()
            {
                // TODO (tomat): we should share the copied files with the host
                _metadataFileProvider = new MetadataShadowCopyProvider(
                    Path.Combine(Path.GetTempPath(), "InteractiveHostShadow"),
                    noShadowCopyDirectories: s_systemNoShadowCopyDirectories);

                _options = ScriptOptions.Default.WithSearchPaths(DefaultReferenceSearchPaths);

                _assemblyLoader    = new InteractiveAssemblyLoader(_metadataFileProvider);
                _sourceSearchPaths = DefaultSourceSearchPaths;
                _formattingOptions = new ObjectFormattingOptions(
                    memberFormat: MemberDisplayFormat.Inline,
                    quoteStrings: true,
                    useHexadecimalNumbers: false,
                    maxOutputLength: 200,
                    memberIndentation: "  ");

                // We want to be sure to delete the shadow-copied files when the process goes away. Frankly
                // there's nothing we can do if the process is forcefully quit or goes down in a completely
                // uncontrolled manner (like a stack overflow). When the process goes down in a controlled
                // manned, we should generally expect this event to be called.
                AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            }
Exemplo n.º 9
0
        public ScriptCompilationContext(Script <TReturn> script, SourceText sourceText, InteractiveAssemblyLoader loader, ScriptOptions scriptOptions, RuntimeDependency[] runtimeDependencies, Diagnostic[] diagnostics)
        {
            Script              = script;
            SourceText          = sourceText;
            ScriptOptions       = scriptOptions;
            Loader              = loader;
            RuntimeDependencies = runtimeDependencies;

            Warnings = diagnostics.Where(x => x.Severity == DiagnosticSeverity.Warning).ToArray();
            Errors   = diagnostics.Where(x => x.Severity == DiagnosticSeverity.Error).ToArray();
        }
 public ScriptCompilationContext(Script <TReturn> script, SourceText sourceText, InteractiveAssemblyLoader loader, ScriptOptions scriptOptions, RuntimeDependency[] runtimeDependencies)
 {
     Script              = script;
     SourceText          = sourceText;
     ScriptOptions       = scriptOptions;
     Loader              = loader;
     RuntimeDependencies = runtimeDependencies;
 }
Exemplo n.º 11
0
        public virtual ScriptCompilationContext <TReturn> CreateCompilationContext <TReturn, THost>(ScriptContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var runtimeContext    = ProjectContext.CreateContextForEachTarget(context.WorkingDirectory).First();
            var runtimeIdentitfer = GetRuntimeIdentitifer();

            _logger.Verbose($"Current runtime is '{runtimeIdentitfer}'.");
            _logger.Verbose($"Found runtime context for '{runtimeContext.ProjectFile.ProjectFilePath}'.");

            var projectExporter = runtimeContext.CreateExporter(context.Configuration);

            var runtimeDependencies = new HashSet <string>();
            var projectDependencies = projectExporter.GetDependencies();

            foreach (var projectDependency in projectDependencies)
            {
                var runtimeAssemblyGroups = projectDependency.RuntimeAssemblyGroups;

                foreach (var libraryAsset in runtimeAssemblyGroups.GetDefaultAssets())
                {
                    var runtimeAssemblyPath = libraryAsset.ResolvedPath;
                    _logger.Verbose($"Discovered runtime dependency for '{runtimeAssemblyPath}'");
                    runtimeDependencies.Add(runtimeAssemblyPath);
                }

                foreach (var runtimeAssemblyGroup in runtimeAssemblyGroups)
                {
                    if (!string.IsNullOrWhiteSpace(runtimeAssemblyGroup.Runtime) && runtimeAssemblyGroup.Runtime == runtimeIdentitfer)
                    {
                        foreach (var runtimeAsset in runtimeAssemblyGroups.GetRuntimeAssets(GetRuntimeIdentitifer()))
                        {
                            var runtimeAssetPath = runtimeAsset.ResolvedPath;
                            _logger.Verbose($"Discovered runtime asset dependency ('{runtimeIdentitfer}') for '{runtimeAssetPath}'");
                            runtimeDependencies.Add(runtimeAssetPath);
                        }
                    }
                }
            }

            var opts = CreateScriptOptions(context);

            var runtimeId = RuntimeEnvironment.GetRuntimeIdentifier();
            var inheritedAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(runtimeId).Where(x =>
                                                                                                            x.FullName.StartsWith("system.", StringComparison.OrdinalIgnoreCase) ||
                                                                                                            x.FullName.StartsWith("microsoft.codeanalysis", StringComparison.OrdinalIgnoreCase) ||
                                                                                                            x.FullName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase));

            foreach (var inheritedAssemblyName in inheritedAssemblyNames)
            {
                _logger.Verbose("Adding reference to an inherited dependency => " + inheritedAssemblyName.FullName);
                var assembly = Assembly.Load(inheritedAssemblyName);
                opts = opts.AddReferences(assembly);
            }

            foreach (var runtimeDep in runtimeDependencies)
            {
                _logger.Verbose("Adding reference to a runtime dependency => " + runtimeDep);
                opts = opts.AddReferences(MetadataReference.CreateFromFile(runtimeDep));
            }

            var loader      = new InteractiveAssemblyLoader();
            var script      = CSharpScript.Create <TReturn>(context.Code.ToString(), opts, typeof(THost), loader);
            var compilation = script.GetCompilation();

            var diagnostics        = compilation.GetDiagnostics();
            var orderedDiagnostics = diagnostics.OrderBy((d1, d2) =>
            {
                var severityDiff = (int)d2.Severity - (int)d1.Severity;
                return(severityDiff != 0 ? severityDiff : d1.Location.SourceSpan.Start - d2.Location.SourceSpan.Start);
            });

            if (orderedDiagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                foreach (var diagnostic in orderedDiagnostics)
                {
                    _logger.Log(diagnostic.ToString());
                }

                throw new CompilationErrorException("Script compilation failed due to one or more errors.",
                                                    orderedDiagnostics.ToImmutableArray());
            }

            return(new ScriptCompilationContext <TReturn>(script, context.Code, loader));
        }
Exemplo n.º 12
0
 protected override Script <T> Create <T>(string code, ScriptOptions options, Type globalsType, InteractiveAssemblyLoader assemblyLoader) =>
 CSharpScript.Create <T>(code, options, globalsType, assemblyLoader);
Exemplo n.º 13
0
 public ScriptCompilationContext(Script <TReturn> script, SourceText sourceText, InteractiveAssemblyLoader loader)
 {
     Script     = script;
     SourceText = sourceText;
     Loader     = loader;
 }
Exemplo n.º 14
0
 /// <summary>
 /// Create a new C# script.
 /// </summary>
 /// <param name="code">The source code of the script.</param>
 /// <param name="options">The script options.</param>
 /// <param name="globalsType">Type of global object.</param>
 /// <param name="assemblyLoader">Custom  assembly loader.</param>
 public static Script <object> Create(string code, ScriptOptions options = null, Type globalsType = null, InteractiveAssemblyLoader assemblyLoader = null)
 {
     return(Create <object>(code, options, globalsType, assemblyLoader));
 }
Exemplo n.º 15
0
 /// <summary>
 /// Create a new C# script.
 /// </summary>
 /// <param name="code">The <see cref="Stream"/> representing the source code of the script.</param>
 /// <param name="options">The script options.</param>
 /// <param name="globalsType">Type of global object.</param>
 /// <param name="assemblyLoader">Custom  assembly loader.</param>
 /// <exception cref="ArgumentNullException">Stream is null.</exception>
 /// <exception cref="ArgumentException">Stream is not readable or seekable.</exception>
 public static Script <object> Create(Stream code, ScriptOptions options = null, Type globalsType = null, InteractiveAssemblyLoader assemblyLoader = null)
 {
     if (code == null)
     {
         throw new ArgumentNullException(nameof(code));
     }
     return(Create <object>(code, options, globalsType, assemblyLoader));
 }
Exemplo n.º 16
0
        public async Task <EvaluationDetails?> EvaluateAsync(RiasCommandContext context, string code)
        {
            var globals = new RoslynGlobals
            {
                Rias    = RiasBot,
                Context = context
            };

            var imports = new[]
            {
                "System", "System.Collections.Generic", "System.Linq", "Disqord", "Disqord.WebSocket",
                "System.Threading.Tasks", "System.Text", "Microsoft.Extensions.DependencyInjection", "System.Net.Http",
                "Rias.Core.Extensions", "Rias.Core.Database", "Qmmands"
            };

            var scriptOptions = ScriptOptions.Default.WithReferences(typeof(Rias).Assembly).AddImports(imports);

            code = SanitizeCode(code);

            using var loader = new InteractiveAssemblyLoader();
            var sw          = Stopwatch.StartNew();
            var script      = CSharpScript.Create(code, scriptOptions, typeof(RoslynGlobals), loader);
            var diagnostics = script.Compile();

            sw.Stop();

            var compilationTime = sw.Elapsed;

            if (diagnostics.Any(x => x.Severity == DiagnosticSeverity.Error))
            {
                return(new EvaluationDetails
                {
                    CompilationTime = compilationTime,
                    Code = code,
                    IsCompiled = false,
                    Exception = string.Join("\n", diagnostics.Select(x => x.ToString()))
                });
            }

            sw.Restart();

            try
            {
                var result = await script.RunAsync(globals);

                sw.Stop();

                if (result.ReturnValue is null)
                {
                    return(null);
                }

                var evaluationDetails = new EvaluationDetails
                {
                    CompilationTime = compilationTime,
                    ExecutionTime   = sw.Elapsed,
                    Code            = code,
                    IsCompiled      = true,
                    Success         = true
                };

                var returnValue = result.ReturnValue;
                var type        = result.ReturnValue.GetType();

                switch (returnValue)
                {
                case string str:
                    evaluationDetails.Result     = str;
                    evaluationDetails.ReturnType = type.Name;
                    break;

                case IEnumerable enumerable:
                    var list     = enumerable.Cast <object>().ToList();
                    var enumType = enumerable.GetType();

                    evaluationDetails.Result     = list.Count != 0 ? $"[{string.Join(", ", list)}]" : "empty";
                    evaluationDetails.ReturnType = $"{enumType.Name}<{string.Join(", ", enumType.GenericTypeArguments.Select(t => t.Name))}>";
                    break;

                case Enum @enum:
                    evaluationDetails.Result     = @enum.ToString();
                    evaluationDetails.ReturnType = @enum.GetType().Name;
                    break;

                default:
                    evaluationDetails.Result     = returnValue.ToString();
                    evaluationDetails.ReturnType = type.Name;
                    break;
                }

                return(evaluationDetails);
            }
            catch (Exception ex)
            {
                sw.Stop();
                return(new EvaluationDetails
                {
                    CompilationTime = compilationTime,
                    ExecutionTime = sw.Elapsed,
                    Code = code,
                    ReturnType = ex.GetType().Name,
                    IsCompiled = true,
                    Success = false,
                    Exception = ex.Message
                });
            }
        }
Exemplo n.º 17
0
 public Loader(Uri scriptUri, ScriptOptions options, InteractiveAssemblyLoader assemblyLoader)
 {
     this.scriptUri      = scriptUri;
     this.options        = options;
     this.assemblyLoader = assemblyLoader;
 }
Exemplo n.º 18
0
 /// <summary>
 /// Create a new C# script.
 /// </summary>
 /// <param name="code">The <see cref="Stream"/> representing the source code of the script.</param>
 /// <param name="options">The script options.</param>
 /// <param name="globalsType">Type of global object.</param>
 /// <param name="assemblyLoader">Custom  assembly loader.</param>
 /// <typeparam name="T">The return type of the script</typeparam>
 /// <exception cref="ArgumentNullException">Stream is null.</exception>
 /// <exception cref="ArgumentException">Stream is not readable or seekable.</exception>
 public static Script <T> Create <T>(Stream code, ScriptOptions options = null, Type globalsType = null, InteractiveAssemblyLoader assemblyLoader = null)
 {
     if (code == null)
     {
         throw new ArgumentNullException(nameof(code));
     }
     return(Script.CreateInitialScript <T>(CSharpScriptCompiler.Instance, SourceText.From(code, options?.FileEncoding), options, globalsType, assemblyLoader));
 }
        public ScriptCompilationContext <TReturn> CreateCompilationContext <TReturn, THost>(ScriptContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var runtimeContext = ProjectContext.CreateContextForEachTarget(context.WorkingDirectory).First();

            _logger.Verbose($"Found runtime context for '{runtimeContext.ProjectFile.ProjectFilePath}'");

            var projectExporter     = runtimeContext.CreateExporter(context.Configuration);
            var runtimeDependencies = new HashSet <string>();
            var projectDependencies = projectExporter.GetDependencies();

            foreach (var projectDependency in projectDependencies)
            {
                var runtimeAssemblies = projectDependency.RuntimeAssemblyGroups;

                foreach (var runtimeAssembly in runtimeAssemblies.GetDefaultAssets())
                {
                    var runtimeAssemblyPath = runtimeAssembly.ResolvedPath;
                    _logger.Verbose($"Discovered runtime dependency for '{runtimeAssemblyPath}'");
                    runtimeDependencies.Add(runtimeAssemblyPath);
                }
            }

            var opts = ScriptOptions.Default.
                       AddImports(DefaultNamespaces).
                       AddReferences(DefaultAssemblies).
                       WithSourceResolver(new RemoteFileResolver(context.WorkingDirectory));

            if (!string.IsNullOrWhiteSpace(context.FilePath))
            {
                opts = opts.WithFilePath(context.FilePath);
            }

            var runtimeId = RuntimeEnvironment.GetRuntimeIdentifier();
            var inheritedAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(runtimeId).Where(x =>
                                                                                                            x.FullName.ToLowerInvariant().StartsWith("system.") ||
                                                                                                            x.FullName.ToLowerInvariant().StartsWith("microsoft.codeanalysis") ||
                                                                                                            x.FullName.ToLowerInvariant().StartsWith("mscorlib"));

            foreach (var inheritedAssemblyName in inheritedAssemblyNames)
            {
                _logger.Verbose("Adding reference to an inherited dependency => " + inheritedAssemblyName.FullName);
                var assembly = Assembly.Load(inheritedAssemblyName);
                opts = opts.AddReferences(assembly);
            }

            foreach (var runtimeDep in runtimeDependencies)
            {
                _logger.Verbose("Adding reference to a runtime dependency => " + runtimeDep);
                opts = opts.AddReferences(MetadataReference.CreateFromFile(runtimeDep));
            }

            var loader      = new InteractiveAssemblyLoader();
            var script      = CSharpScript.Create <TReturn>(context.Code.ToString(), opts, typeof(THost), loader);
            var compilation = script.GetCompilation();
            var diagnostics = compilation.GetDiagnostics();

            if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                foreach (var diagnostic in diagnostics)
                {
                    _logger.Log(diagnostic.ToString());
                }

                throw new CompilationErrorException("Script compilation failed due to one or more errors.",
                                                    diagnostics);
            }

            return(new ScriptCompilationContext <TReturn>(script, context.Code, loader));
        }
        private static async Task RunScript()
        {
            var code =
                @"
// Demo 1: Resolve reference with custom source reference resolver.
#load ""WelcomeScript.csx""

// Demo 2: Resolve reference with custom metadata reference resolver.
#r ""MathNet.Numerics.dll""

using System;
using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.LinearAlgebra.Double;

Matrix<double> A = DenseMatrix.OfArray(new double[,] {
        {1,1,1,1},
        {1,2,3,4},
        {4,3,2,1}});

Vector<double>[] nullspace = A.Kernel();

// verify: the following should be approximately (0,0,0)
var result = (A * (2*nullspace[0] - 3*nullspace[1]));

Console.WriteLine();
Console.WriteLine(""Demo 1"");
Console.WriteLine();
Console.WriteLine(""If you can see the Welcome box above, demo 1 was successful."");
Console.WriteLine();
Console.WriteLine(""#########################################################################################"");
Console.WriteLine();
Console.WriteLine(""Demo 2"");
Console.WriteLine();
Console.WriteLine(""The null space was calculated by the script. This is the result:"");
Console.WriteLine();
Console.WriteLine(result.ToString());
Console.WriteLine(""So we have the evidence that demo 2 works as well, because MathNet.Numerics.dll could be resolved."");
Console.WriteLine();
";

            var loader = new InteractiveAssemblyLoader();

            var options = ScriptOptions
                          .Default
                          .WithMetadataResolver(new CustomMetadataReferenceResolver())
                          .WithSourceResolver(new CustomSourceReferenceResolver())
                          .WithFilePath(Environment.CurrentDirectory);

            var script      = CSharpScript.Create(code, options, null, loader);
            var scriptState = await script.RunAsync();

            Console.WriteLine("#########################################################################################");

            Console.WriteLine($"{Environment.NewLine}Demo 3");
            Console.WriteLine($"{Environment.NewLine}Use InteractiveAssemblyLoader to made dynamic generates types available in the script.");
            Console.WriteLine($"{Environment.NewLine}First, let's try to create an instance of 'DynamicGeneratedClass1' by continuing the current script...{Environment.NewLine}");

            script = script.ContinueWith("var instance = new DynamicGeneratedClass1();");
            Console.WriteLine($"An error occured: {script.Compile().First().GetMessage()}");

            Console.WriteLine($"{Environment.NewLine}Now we generate the types DynamicGeneratedBaseClass, DynamicGeneratedClass1 and DynamicGeneratedClass2 in a in-memory assembly and expose the assembly to the InteractiveAssemblyLoader...");

            var dynamicGeneratedTypesReference = GenerateDynamicTypesAndExposeToScript(loader);

            options = options.AddReferences(dynamicGeneratedTypesReference);
            script  = script.WithOptions(options);

            Console.WriteLine($"{Environment.NewLine}Now, we try to create an instance of 'DynamicGeneratedClass1' again in the script...");

            script      = script.ContinueWith("var instance = new DynamicGeneratedClass1();");
            scriptState = await script.RunFromAsync(scriptState);

            Console.WriteLine($"...no error. Variable '{scriptState.Variables[3].Name}' with value '{scriptState.Variables[3].Value}' found in script result.{Environment.NewLine}");

            Console.WriteLine("#########################################################################################");

            Console.WriteLine();
            Console.WriteLine($"{Environment.NewLine}Press any key to close window...");
            Console.ReadKey();
        }
Exemplo n.º 21
0
        public async Task <bool> InitScript(CancellationToken token = default)
        {
            using (await _scriptStateLock.LockAsync(token))
            {
                if (_scriptState != null)
                {
                    return(true);
                }

                try
                {
                    var options = ScriptOptions.Default
                                  .WithReferences(_references.ToArrayLocked(_lockReferences))
                                  .WithImports(_usings.ToArrayLocked(_lockUsings));

                    var globals = _globals.ToDictionaryLocked(_lockGlobals);

                    if (globals.Any())
                    {
                        var createGlobalsScript = CSharpScript.Create(CreateGlobalsType(), options);
                        var image = createGlobalsScript.GetCompilation();

                        var stream = new MemoryStream();
                        var result = image.Emit(stream, cancellationToken: token);

                        if (!result.Success)
                        {
                            var scriptResult = new ScriptResult
                            {
                                Result  = string.Join("\n", result.Diagnostics.Select(d => d.GetMessage())),
                                IsError = true
                            };

                            Results.Add(scriptResult);
                            ScriptResultReceived?.Invoke(this, scriptResult);

                            return(false);
                        }

                        var imageArray = ImmutableArray.Create(stream.ToArray());

                        var portableReference = MetadataReference.CreateFromImage(imageArray);

                        var libAssembly     = Assembly.Load(imageArray.ToArray());
                        var globalsType     = libAssembly.GetTypes().FirstOrDefault(t => t.Name == "ScriptGlobals");
                        var globalsInstance = Activator.CreateInstance(globalsType);

                        foreach (var propInfo in globalsType.GetFields())
                        {
                            propInfo.SetValue(globalsInstance, globals[propInfo.Name]);
                        }

                        using (var loader = new InteractiveAssemblyLoader())
                        {
                            loader.RegisterDependency(libAssembly);

                            var script = CSharpScript.Create(string.Empty, options.AddReferences(portableReference), globalsType, loader);
                            _scriptState = await script.RunAsync(globalsInstance, cancellationToken : token);
                        }
                    }
                    else
                    {
                        _scriptState = await CSharpScript.RunAsync(string.Empty, options, cancellationToken : token);
                    }
                }
                catch (OperationCanceledException)
                {
                    _scriptState = null;
                }
            }

            return(_scriptState != null);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Create a new C# script.
        /// </summary>
        /// <param name="code">The source code of the script.</param>
        /// <param name="options">The script options.</param>
        /// <param name="allowSingleQuotes">Are single quoted literal strings in Macros allowed (true = VO compatible).</param>
        /// <param name="assemblyLoader">Custom  assembly loader.</param>
        /// <typeparam name="T">The return type of the script</typeparam>
        public static T Compile <T>(string code, ScriptOptions options = null, bool allowSingleQuotes = true, InteractiveAssemblyLoader assemblyLoader = null)
        {
            Type globalsType = null;
            CancellationToken cancellationToken = default(CancellationToken);

            return(Script.CreateInitialScript <T>(XSharpMacroCompiler.GetInstance(allowSingleQuotes), SourceText.From(code, options?.FileEncoding), options, globalsType, assemblyLoader).RunAsync(null, cancellationToken).GetEvaluationResultAsync().Result);
        }
Exemplo n.º 23
0
 public abstract Script <T> CreateScript <T>(string code, ScriptOptions options, Type globalsTypeOpt, InteractiveAssemblyLoader assemblyLoader);
 public override Script <T> CreateScript <T>(string code, ScriptOptions options, Type globalsTypeOpt, InteractiveAssemblyLoader assemblyLoader)
 {
     return(CSharpScript.Create <T>(code, options, globalsTypeOpt, assemblyLoader));
 }
            public Service()
            {
                // TODO (tomat): we should share the copied files with the host
                _metadataFileProvider = new MetadataShadowCopyProvider(
                    Path.Combine(Path.GetTempPath(), "InteractiveHostShadow"),
                    noShadowCopyDirectories: s_systemNoShadowCopyDirectories);

                _assemblyLoader = new InteractiveAssemblyLoader(_metadataFileProvider);

                _formattingOptions = new ObjectFormattingOptions(
                    memberFormat: MemberDisplayFormat.Inline,
                    quoteStrings: true,
                    useHexadecimalNumbers: false,
                    maxOutputLength: 200,
                    memberIndentation: "  ");

                _hostObject = new InteractiveHostObject();

                var initialState = new EvaluationState(
                    scriptState: null,
                    scriptOptions: ScriptOptions.Default,
                    sourceSearchPaths: ImmutableArray<string>.Empty,
                    referenceSearchPaths: ImmutableArray<string>.Empty,
                    workingDirectory: Directory.GetCurrentDirectory());

                _lastTask = Task.FromResult(initialState);

                Console.OutputEncoding = Encoding.UTF8;
              
                // We want to be sure to delete the shadow-copied files when the process goes away. Frankly
                // there's nothing we can do if the process is forcefully quit or goes down in a completely
                // uncontrolled manner (like a stack overflow). When the process goes down in a controlled
                // manned, we should generally expect this event to be called.
                AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            }
Exemplo n.º 26
0
 /// <summary>
 /// Create a new C# script.
 /// </summary>
 /// <param name="code">The source code of the script.</param>
 /// <param name="options">The script options.</param>
 /// <param name="globalsType">Type of global object.</param>
 /// <param name="assemblyLoader">Custom  assembly loader.</param>
 /// <typeparam name="T">The return type of the script</typeparam>
 public static Script <T> Create <T>(string code, ScriptOptions options = null, Type globalsType = null, InteractiveAssemblyLoader assemblyLoader = null)
 {
     return(Script.CreateInitialScript <T>(CSharpScriptCompiler.Instance, code, options, globalsType, assemblyLoader));
 }
Exemplo n.º 27
0
            public void Initialize(Type replServiceProviderType, string cultureName)
            {
                Debug.Assert(replServiceProviderType != null);
                Debug.Assert(cultureName != null);

                Debug.Assert(_metadataFileProvider == null);
                Debug.Assert(_assemblyLoader == null);
                Debug.Assert(_replServiceProvider == null);

                // TODO (tomat): we should share the copied files with the host
                _metadataFileProvider = new MetadataShadowCopyProvider(
                    Path.Combine(Path.GetTempPath(), "InteractiveHostShadow"),
                    noShadowCopyDirectories: s_systemNoShadowCopyDirectories,
                    documentationCommentsCulture: new CultureInfo(cultureName));

                _assemblyLoader = new InteractiveAssemblyLoader(_metadataFileProvider);

                _replServiceProvider = (ReplServiceProvider)Activator.CreateInstance(replServiceProviderType);

                _globals = new InteractiveScriptGlobals(Console.Out, _replServiceProvider.ObjectFormatter);
            }
Exemplo n.º 28
0
        public virtual ScriptCompilationContext <TReturn> CreateCompilationContext <TReturn, THost>(ScriptContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var runtimeIdentitfer = GetRuntimeIdentitifer();

            _logger.Verbose($"Current runtime is '{runtimeIdentitfer}'.");

            var opts = CreateScriptOptions(context);

            var runtimeId = RuntimeEnvironment.GetRuntimeIdentifier();
            var inheritedAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(runtimeId).Where(x =>
                                                                                                            x.FullName.StartsWith("system.", StringComparison.OrdinalIgnoreCase) ||
                                                                                                            x.FullName.StartsWith("microsoft.codeanalysis", StringComparison.OrdinalIgnoreCase) ||
                                                                                                            x.FullName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase));

            foreach (var inheritedAssemblyName in inheritedAssemblyNames)
            {
                _logger.Verbose("Adding reference to an inherited dependency => " + inheritedAssemblyName.FullName);
                var assembly = Assembly.Load(inheritedAssemblyName);
                opts = opts.AddReferences(assembly);
            }

            var runtimeContext = File.Exists(Path.Combine(context.WorkingDirectory, Project.FileName)) ? ProjectContext.CreateContextForEachTarget(context.WorkingDirectory).FirstOrDefault() : null;

            if (runtimeContext == null)
            {
                _logger.Verbose("Unable to find project context for CSX files. Will default to non-context usage.");
                var scriptProjectProvider = ScriptProjectProvider.Create(new LoggerFactory());
                var scriptProjectInfo     = scriptProjectProvider.CreateProject(context.WorkingDirectory, "netcoreapp1.1");
                runtimeContext = ProjectContext.CreateContextForEachTarget(scriptProjectInfo.PathToProjectJson).FirstOrDefault();
            }

            _logger.Verbose($"Found runtime context for '{runtimeContext.ProjectFile.ProjectFilePath}'.");
            var projectExporter = runtimeContext.CreateExporter(context.Configuration);

            var runtimeDependencies = new HashSet <string>();
            var projectDependencies = projectExporter.GetDependencies();

            foreach (var projectDependency in projectDependencies)
            {
                var runtimeAssemblyGroups = projectDependency.RuntimeAssemblyGroups;

                foreach (var libraryAsset in runtimeAssemblyGroups.GetDefaultAssets())
                {
                    var runtimeAssemblyPath = libraryAsset.ResolvedPath;
                    _logger.Verbose($"Discovered runtime dependency for '{runtimeAssemblyPath}'");
                    runtimeDependencies.Add(runtimeAssemblyPath);
                }

                foreach (var runtimeAssemblyGroup in runtimeAssemblyGroups)
                {
                    if (!string.IsNullOrWhiteSpace(runtimeAssemblyGroup.Runtime) && runtimeAssemblyGroup.Runtime == runtimeIdentitfer)
                    {
                        foreach (var runtimeAsset in runtimeAssemblyGroups.GetRuntimeAssets(GetRuntimeIdentitifer()))
                        {
                            var runtimeAssetPath = runtimeAsset.ResolvedPath;
                            _logger.Verbose($"Discovered runtime asset dependency ('{runtimeIdentitfer}') for '{runtimeAssetPath}'");
                            runtimeDependencies.Add(runtimeAssetPath);
                        }
                    }
                }
            }

            foreach (var runtimeDep in runtimeDependencies)
            {
                _logger.Verbose("Adding reference to a runtime dependency => " + runtimeDep);
                opts = opts.AddReferences(MetadataReference.CreateFromFile(runtimeDep));
            }

            var loader             = new InteractiveAssemblyLoader();
            var script             = CSharpScript.Create <TReturn>(context.Code.ToString(), opts, typeof(THost), loader);
            var orderedDiagnostics = script.GetDiagnostics(SuppressedDiagnosticIds);

            if (orderedDiagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                foreach (var diagnostic in orderedDiagnostics)
                {
                    _logger.Log(diagnostic.ToString());
                }

                throw new CompilationErrorException("Script compilation failed due to one or more errors.",
                                                    orderedDiagnostics.ToImmutableArray());
            }

            return(new ScriptCompilationContext <TReturn>(script, context.Code, loader));
        }
Exemplo n.º 29
0
        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 opts = CreateScriptOptions(context);

            var runtimeId = RuntimeEnvironment.GetRuntimeIdentifier();
            var inheritedAssemblyNames = DependencyContext.Default.GetRuntimeAssemblyNames(runtimeId).Where(x =>
                                                                                                            x.FullName.StartsWith("system.", StringComparison.OrdinalIgnoreCase) ||
                                                                                                            x.FullName.StartsWith("microsoft.codeanalysis", StringComparison.OrdinalIgnoreCase) ||
                                                                                                            x.FullName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase));

            foreach (var inheritedAssemblyName in inheritedAssemblyNames)
            {
                _logger.Verbose("Adding reference to an inherited dependency => " + inheritedAssemblyName.FullName);
                var assembly = Assembly.Load(inheritedAssemblyName);
                opts = opts.AddReferences(assembly);
            }

            var pathToProjectJson = Path.Combine(context.WorkingDirectory, Project.FileName);

            IList <RuntimeDependency> runtimeDependencies = new List <RuntimeDependency>();

            if (!File.Exists(pathToProjectJson))
            {
                _logger.Verbose("Unable to find project context for CSX files. Will default to non-context usage.");
                var pathToCsProj       = _scriptProjectProvider.CreateProject(context.WorkingDirectory);
                var dependencyResolver = new DependencyResolver(new CommandRunner(_logger), _logger);
                runtimeDependencies = dependencyResolver.GetRuntimeDependencies(pathToCsProj).ToList();
            }
            else
            {
                _logger.Verbose($"Found runtime context for '{pathToProjectJson}'.");
                var dependencyResolver = new LegacyDependencyResolver(_logger);
                runtimeDependencies = dependencyResolver.GetRuntimeDependencies(pathToProjectJson).ToList();
            }

            AssemblyLoadContext.Default.Resolving +=
                (assemblyLoadContext, assemblyName) => MapUnresolvedAssemblyToRuntimeLibrary(runtimeDependencies.ToList(), assemblyLoadContext, assemblyName);


            foreach (var runtimeDep in runtimeDependencies)
            {
                _logger.Verbose("Adding reference to a runtime dependency => " + runtimeDep);
                opts = opts.AddReferences(MetadataReference.CreateFromFile(runtimeDep.Path));
            }

            var loader             = new InteractiveAssemblyLoader();
            var script             = CSharpScript.Create <TReturn>(context.Code.ToString(), opts, typeof(THost), loader);
            var orderedDiagnostics = script.GetDiagnostics(SuppressedDiagnosticIds);

            if (orderedDiagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                foreach (var diagnostic in orderedDiagnostics)
                {
                    _logger.Log(diagnostic.ToString());
                }

                throw new CompilationErrorException("Script compilation failed due to one or more errors.",
                                                    orderedDiagnostics.ToImmutableArray());
            }

            return(new ScriptCompilationContext <TReturn>(script, context.Code, loader));
        }
Exemplo n.º 30
0
 protected abstract Script <T> Create <T>(string code, ScriptOptions options, Type globalsType, InteractiveAssemblyLoader assemblyLoader);
        public async Task MissingRefrencesAutoResolution()  
        {
            var portableLib = CSharpCompilation.Create(
                "PortableLib",                                                
                new[] { SyntaxFactory.ParseSyntaxTree("public class C {}") }, 
                new[] { SystemRuntimePP7Ref },
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));

            var portableLibRef = portableLib.ToMetadataReference();

            var loader = new InteractiveAssemblyLoader();
            loader.RegisterDependency(Assembly.Load(portableLib.EmitToArray().ToArray()));

            var s0 = await CSharpScript.Create("new C()", options: ScriptOptions.Default.AddReferences(portableLibRef), assemblyLoader: loader).RunAsync();
            var c0 = s0.Script.GetCompilation();

            // includes corlib, host type assembly by default:
            AssertEx.Equal(new[]
            {
                typeof(object).GetTypeInfo().Assembly.Location,
                "PortableLib"
            }, c0.ExternalReferences.SelectAsArray(m => m.Display));

            // System.Runtime, 4.0.0.0 depends on all the assemblies below:
            AssertEx.Equal(new[]
            {
                "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "PortableLib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null",
                "System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.ComponentModel.Composition, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.Data.SqlXml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
                "System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
                "System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
            }, c0.GetBoundReferenceManager().GetReferencedAssemblies().Select(a => a.Value.Identity.GetDisplayName()));
        }
        public void HostObjectInInMemoryAssembly()
        {
            var lib = CreateCompilationWithMscorlib("public class C { public int X = 1, Y = 2; }", "HostLib");
            var libImage = lib.EmitToArray();
            var libRef = MetadataImageReference.CreateFromImage(libImage);

            var libAssembly = Assembly.Load(libImage.ToArray());
            var globalsType = libAssembly.GetType("C");
            var globals = Activator.CreateInstance(globalsType);

            using (var loader = new InteractiveAssemblyLoader())
            {
                loader.RegisterDependency(libAssembly);

                var script = CSharpScript.Create<int>(
                    "X+Y", 
                    ScriptOptions.Default.WithReferences(libRef), 
                    globalsType: globalsType,
                    assemblyLoader: loader);

                int result = script.RunAsync(globals).Result.ReturnValue;
                Assert.Equal(3, result);
            }
        }
Exemplo n.º 33
0
            public Service()
            {
                // TODO (tomat): we should share the copied files with the host
                _metadataFileProvider = new MetadataShadowCopyProvider(
                    Path.Combine(Path.GetTempPath(), "InteractiveHostShadow"),
                    noShadowCopyDirectories: s_systemNoShadowCopyDirectories);
                _assemblyLoader = new InteractiveAssemblyLoader(_metadataFileProvider);
                _formattingOptions = new ObjectFormattingOptions(
                    memberFormat: MemberDisplayFormat.Inline,
                    quoteStrings: true,
                    useHexadecimalNumbers: false,
                    maxOutputLength: 200,
                    memberIndentation: "  ");

                // We want to be sure to delete the shadow-copied files when the process goes away. Frankly
                // there's nothing we can do if the process is forcefully quit or goes down in a completely
                // uncontrolled manner (like a stack overflow). When the process goes down in a controlled
                // manned, we should generally expect this event to be called.
                AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            }
Exemplo n.º 34
0
        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));
        }
Exemplo n.º 35
0
        internal Func <object, string> GetExec <T>(CsModPermission csScriptsAllowed, T rootObjectCompileTime, string script) where T : IScriptRootData
        {
            var        messages   = new List <string>();
            bool       success    = true;
            MethodInfo mainMethod = null;

            Script <object> csScript = null;
            CsModPermission permissionNeeded;
            var             rootCompileTime = rootObjectCompileTime as IScriptRootData;

            using (var loader = new InteractiveAssemblyLoader())
            {
                var options = ScriptOptions.Default
                              .WithAllowUnsafe(false)
                              .WithEmitDebugInformation(false)
                              .WithCheckOverflow(true)
                              .WithOptimizationLevel(OptimizationLevel.Release)

                              .WithImports(DefaultConfiguration.Current.Usings)
                              .AddImports(Configuration.Current.Usings)

                              .WithReferences(DefaultConfiguration.Current.AssemblyReferences)
                              .AddReferences(Configuration.Current.AssemblyReferences)
                              .AddReferences(typeof(EmpyrionScripting).Assembly.Location, typeof(IScriptRootData).Assembly.Location)
                              .AddReferences(CustomAssemblies.Values.Select(A => A.LoadedAssembly));

                csScript = CSharpScript.Create <object>(script, options, typeof(IScriptModData), loader);
                var compilation = csScript.GetCompilation();

                var WhitelistDiagnosticAnalyzer = new WhitelistDiagnosticAnalyzer(DefaultConfiguration, Configuration);

                var analyzerCompilation = compilation
                                          .WithAnalyzers(ImmutableArray.Create <DiagnosticAnalyzer>(WhitelistDiagnosticAnalyzer))
                                          .GetAnalysisResultAsync(CancellationToken.None)
                                          .GetAwaiter().GetResult().CompilationDiagnostics;

                analyzerCompilation.ForEach(A => AnalyzeDiagnostics(A.Value, messages, ref success));

                if (WhitelistDiagnosticAnalyzer.ConfigurationIsChanged)
                {
                    Configuration.Current.PrepareForSave();
                    Configuration.Save();

                    DefaultConfiguration.Current.PrepareForSave();
                    DefaultConfiguration.Save();
                }

                permissionNeeded = WhitelistDiagnosticAnalyzer.PermissionNeeded;

                Assembly assembly = null;

                if (compilation.Assembly.TypeNames.Contains("ModMain"))
                {
                    using (var assemblyStream = new MemoryStream())
                    {
                        try
                        {
                            var result        = compilation.Emit(assemblyStream);
                            var resultSuccess = result.Success;

                            if (resultSuccess)
                            {
                                assembly = Assembly.ReflectionOnlyLoad(assemblyStream.ToArray());
                                var callMainType = assembly.GetTypes().SingleOrDefault(MT => MT.Name == "ModMain");
                                mainMethod = callMainType.GetMethod("Main");

                                if (mainMethod != null)
                                {
                                    assemblyStream.Seek(0, SeekOrigin.Begin);
                                    assembly = Assembly.Load(assemblyStream.ToArray());

                                    callMainType = assembly.GetTypes().SingleOrDefault(MT => MT.Name == "ModMain");
                                    mainMethod   = callMainType.GetMethod("Main");
                                }
                            }
                        }
                        catch (Exception loadError)
                        {
                            messages.Add($"Assembly:{loadError}");
                        }
                    }
                }
            }

            if (messages.Count > 0)
            {
                Log?.Invoke($"C# Compile [{rootCompileTime.ScriptId}]:{string.Join("\n", messages)}", LogLevel.Error);

                if (EmpyrionScripting.Configuration.Current.ScriptTrackingError)
                {
                    File.AppendAllText(rootObjectCompileTime is ScriptSaveGameRootData root
                        ? EmpyrionScripting.GetTrackingFileName(root)
                        : EmpyrionScripting.GetTrackingFileName(rootObjectCompileTime.E.GetCurrent(), rootObjectCompileTime.Script.GetHashCode().ToString()) + ".error",
                                       string.Join("\n", messages));
                }
            }

            return(rootObject =>
            {
                if (!success)
                {
                    return string.Join("\n", messages);
                }

                var root = rootObject as IScriptRootData;
                if (csScriptsAllowed == CsModPermission.SaveGame && !(root is ScriptSaveGameRootData))
                {
                    return "C# scripts are only allowed in SaveGameScripts";
                }
                if (csScriptsAllowed == CsModPermission.Admin && root.E.GetCurrent().Faction.Group != FactionGroup.Admin)
                {
                    return "C# scripts are only allowed on admin structures";
                }

                if (permissionNeeded == CsModPermission.SaveGame && !(root is ScriptSaveGameRootData))
                {
                    return "This script is only allowed in SaveGameScripts";
                }
                if (permissionNeeded == CsModPermission.Admin && root.E.GetCurrent().Faction.Group != FactionGroup.Admin)
                {
                    return "This script is only allowed on admin structures";
                }

                string exceptionMessage = null;
                using (var output = new StringWriter())
                {
                    root.ScriptOutput = output;

                    try
                    {
                        object result = null;

                        if (mainMethod != null)
                        {
                            if (root.CsRoot is CsScriptFunctions csRoot)
                            {
                                csRoot.ScriptRoot = root;
                            }
                            result = mainMethod.Invoke(null, new[] { root as IScriptModData });
                        }
                        else
                        {
                            result = csScript
                                     .RunAsync(root, ex => { exceptionMessage = $"Exception: {(root.IsElevatedScript ? ex.ToString() : ex.Message)}"; return true; })
                                     .ConfigureAwait(true)
                                     .GetAwaiter()
                                     .GetResult()
                                     .ReturnValue;
                        }

                        if (result is Action action)
                        {
                            action();
                        }
                        else if (result is Action <IScriptModData> simpleaction)
                        {
                            simpleaction(root);
                        }
                        else if (result is Func <IScriptModData, object> func)
                        {
                            output.Write(func(root)?.ToString());
                        }
                        else if (result is Task task)
                        {
                            task.RunSynchronously();
                        }
                        else
                        {
                            output.Write(result?.ToString());
                        }

                        return exceptionMessage == null?output.ToString() : $"{exceptionMessage}\n\nScript output up to exception:\n{output}";
                    }
                    catch (Exception error)
                    {
                        exceptionMessage = error.ToString();
                        return root.IsElevatedScript ? error.ToString() : error.Message;
                    }
                    finally
                    {
                        if (!string.IsNullOrEmpty(exceptionMessage))
                        {
                            Log?.Invoke($"C# Run [{root.ScriptId}]:{exceptionMessage}\n{output}", LogLevel.Error);

                            if (EmpyrionScripting.Configuration.Current.ScriptTrackingError)
                            {
                                File.AppendAllText(root is ScriptSaveGameRootData saveGameRoot
                                    ? EmpyrionScripting.GetTrackingFileName(saveGameRoot)
                                    : EmpyrionScripting.GetTrackingFileName(root.E.GetCurrent(), root.Script.GetHashCode().ToString()) + ".error",
                                                   $"{exceptionMessage}\n\nScript output up to exception:\n{output}");
                            }
                        }
                    }
                }
            });
        }