public async Task <bool> ParseCode() { bool retValue = true; if (_codeSyntaxTree is null) { _codeSyntaxTree = await SyntaxTreeHelpers.ParseTextTaskAsync(_codetext); _baseType = GetEntryPoint((CompilationUnitSyntax)_codeSyntaxTree.GetRoot()); if (String.IsNullOrEmpty(_baseType)) { throw new ApplicationException("Cannot found entry point for code execution. Add static method Main to the first class"); } _entryPoint = GetEntryPoint((CompilationUnitSyntax)_codeSyntaxTree.GetRoot()); } return(retValue); }
public async Task <bool> CompileAndRunCodeAsync() { bool retValue = true; ResetStatus(); if (_codeSyntaxTree == null) { _codeSyntaxTree = await SyntaxTreeHelpers.ParseTextTaskAsync(_codeText); } string baseType = GetEntryPoint((CompilationUnitSyntax)_codeSyntaxTree.GetRoot()); if (String.IsNullOrEmpty(baseType)) { throw new ApplicationException("Cannot found entry point for code execution. Add static method Main to the first class"); } string assemblyName = Path.GetRandomFileName(); MetadataReference[] references = new MetadataReference[] { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location) }; var compilation = CSharpCompilation.Create(assemblyName, new[] { _codeSyntaxTree }, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); using (var ms = new MemoryStream()) { EmitResult result = compilation.Emit(ms); if (!result.Success) { IEnumerable <Diagnostic> failures = result.Diagnostics.Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error); var errorsTmp = new StringBuilder(); foreach (Diagnostic diagnostic in failures) { errorsTmp.AppendLine($"{diagnostic.Id}: {diagnostic.GetMessage()}"); } _lastErrors = errorsTmp.ToString(); retValue = false; } else { ms.Seek(0, SeekOrigin.Begin); Assembly assembly = Assembly.Load(ms.ToArray()); Type type = assembly.GetType(baseType); TextWriter tmp = Console.Out; var codeoutput = new StringWriter(); Console.SetOut(codeoutput); object obj = Activator.CreateInstance(type); // Calculationg execution time. Another solution is - to use https://benchmarkdotnet.org/index.html System.Diagnostics.Stopwatch sw = new Stopwatch(); sw.Start(); type.InvokeMember("Main", BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null); sw.Stop(); _executionTime = sw.Elapsed; Console.SetOut(tmp); _codeOutput = codeoutput.ToString(); } } return(retValue); }