private static string GetGeneratedOutput(string source) { var syntaxTree = CSharpSyntaxTree.ParseText(source); var references = new List <MetadataReference>(); Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { if (!assembly.IsDynamic) { references.Add(MetadataReference.CreateFromFile(assembly.Location)); } } var compilation = CSharpCompilation.Create("foo", new SyntaxTree[] { syntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); System.Collections.Immutable.ImmutableArray <Diagnostic> diagnostics = compilation.GetDiagnostics(); Assert.False(diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error), "Failed: " + diagnostics.FirstOrDefault()?.GetMessage()); var generator = new Generator(); var output = generator.GetGeneratedSource(compilation); return(output); }
public async Task EvaluateAsync(CommandContext ctx, [RemainingText, Description("Code to evaluate.")] string code) { if (string.IsNullOrWhiteSpace(code)) { throw new InvalidCommandUsageException("Code missing."); } int cs1 = code.IndexOf("```") + 3; int cs2 = code.LastIndexOf("```"); if (cs1 == -1 || cs2 == -1) { throw new InvalidCommandUsageException("You need to wrap the code into a code block."); } code = code.Substring(cs1, cs2 - cs1); var emb = new DiscordEmbedBuilder { Title = "Evaluating...", Color = this.ModuleColor }; DiscordMessage msg = await ctx.RespondAsync(embed : emb.Build()); var globals = new EvaluationEnvironment(ctx); ScriptOptions sopts = ScriptOptions.Default .WithImports("System", "System.Collections.Generic", "System.Linq", "System.Net.Http", "System.Net.Http.Headers", "System.Reflection", "System.Text", "System.Text.RegularExpressions", "System.Threading.Tasks", "DSharpPlus", "DSharpPlus.CommandsNext", "DSharpPlus.Entities", "DSharpPlus.Interactivity") .WithReferences(AppDomain.CurrentDomain.GetAssemblies().Where(xa => !xa.IsDynamic && !string.IsNullOrWhiteSpace(xa.Location))); var sw1 = Stopwatch.StartNew(); Script <object> snippet = CSharpScript.Create(code, sopts, typeof(EvaluationEnvironment)); System.Collections.Immutable.ImmutableArray <Diagnostic> diag = snippet.Compile(); sw1.Stop(); if (diag.Any(d => d.Severity == DiagnosticSeverity.Error)) { emb = new DiscordEmbedBuilder { Title = "Compilation failed", Description = $"Compilation failed after {sw1.ElapsedMilliseconds.ToString("#,##0")}ms with {diag.Length} errors.", Color = DiscordColor.Red }; foreach (Diagnostic d in diag.Take(3)) { FileLinePositionSpan ls = d.Location.GetLineSpan(); emb.AddField($"Error at line: {ls.StartLinePosition.Line}, {ls.StartLinePosition.Character}", Formatter.InlineCode(d.GetMessage())); } if (diag.Length > 3) { emb.AddField("Some errors were omitted", $"{diag.Length - 3} errors not displayed"); } if (!(msg is null)) { msg = await msg.ModifyAsync(embed : emb.Build()); } return; } Exception exc = null; ScriptState <object> css = null; var sw2 = Stopwatch.StartNew(); try { css = await snippet.RunAsync(globals); exc = css.Exception; } catch (Exception e) { exc = e; } sw2.Stop(); if (!(exc is null)) { emb = new DiscordEmbedBuilder { Title = "Execution failed", Description = $"Execution failed after {sw2.ElapsedMilliseconds.ToString("#,##0")}ms with {Formatter.InlineCode($"{exc.GetType()} : {exc.Message}")}.", Color = this.ModuleColor }; if (!(msg is null)) { msg = await msg.ModifyAsync(embed : emb.Build()); } return; } emb = new DiscordEmbedBuilder { Title = "Evaluation successful", Color = DiscordColor.Aquamarine }; emb.AddField("Result", css.ReturnValue is null ? "No value returned" : css.ReturnValue.ToString(), false); emb.AddField("Compilation time", string.Concat(sw1.ElapsedMilliseconds.ToString("#,##0"), "ms"), true); emb.AddField("Execution time", string.Concat(sw2.ElapsedMilliseconds.ToString("#,##0"), "ms"), true); if (!(css.ReturnValue is null)) { emb.AddField("Return type", css.ReturnValue.GetType().ToString(), true); } if (!(msg is null)) { await msg.ModifyAsync(embed : emb.Build()); }