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);
        }
Esempio n. 2
0
        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);
        }