Search code examples
c#diagnostics

How to get error line using Microsoft.CodeAnalysis.Diagnostic


I have this piece of code for evaluating code on runtime:

SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText("Code goes here...");
string assemblyName = Path.GetRandomFileName();

            string corePath = Path.GetDirectoryName(typeof(object).GetTypeInfo().Assembly.Location);
            MetadataReference[] references = new MetadataReference[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
                MetadataReference.CreateFromFile("Newtonsoft.Json.dll"),
                MetadataReference.CreateFromFile(Path.Combine(corePath, "System.Net.dll")),
                MetadataReference.CreateFromFile(Path.Combine(corePath, "System.Text.RegularExpressions.dll"))
            };

            CSharpCompilation compilation = CSharpCompilation.Create(
                assemblyName,
                syntaxTrees: new[] { syntaxTree },
                references: references,
                options: 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);

                    string errors = "";

                    foreach (Diagnostic diagnostic in failures)
                    {
                        errors += "<span style=\"text-align: center;\">Error <b>" + diagnostic.Id + "</b>: " + diagnostic.GetMessage() + "</span><br>";
                    }

                    return errors;
                }
                else
                {
                    ms.Seek(0, SeekOrigin.Begin);
                    Assembly assembly = Assembly.Load(ms.ToArray());

                    Type type = assembly.GetType("NoteBoxCode.Program");
                    object obj = Activator.CreateInstance(type);
                    return type.InvokeMember("Main", BindingFlags.InvokeMethod, null, obj, null);
                }
            }

And when i get an error, for example it just shows this: Error CS1520: Method must have a return type

How can i get an output like Error on line 2 CS1520: Method must have a return type?

I have tried diagnostic.Location, but i think it returns assembly line location, which i do not need. Any help?


Solution

  • So, CSharpCompilationOptions cannot return an error line, as it is a runtime error. I will need an advanced debugging class, to debug and run each line of code seperately, which is what ( i think ) visual studio does.

    You can use SyntaxTree.GetDiagnostics() to get an overview of the syntax errors. however this does not return compilation errors, such as Console.WritLine instead of Console.WriteLine.