Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microsoft Roslyn GetDiagnostics() can't dectect error

Tags:

c#

roslyn

I tried to use Roslyn to check the following example:

   static void Main(string[] args)
    {
        string sScriptCsx = @"
            using System;

            namespace HelloWorld
            {
                class Program
                {
                    static void Main(string[] args)
                    {
                        Console.WriteLin(""Hello, World!"");
                    }
                }
            }";

        string strDetail = "";
        Diagnostic obj;

        SyntaxTree stTree = SyntaxTree.ParseText(sScriptCsx);

        if (stTree.GetDiagnostics().Count == 0) 
        {
            strDetail += "La génération a réussi. Aucune erreur détectée.";
            Environment.Exit(0);
        }

        for (int i = 0; i < stTree.GetDiagnostics().Count; i++)
        {
            obj = stTree.GetDiagnostics()[i];
            strDetail += "<b>" + (i + 1).ToString() + ". Info: </b>" + obj.Info.ToString() + Environment.NewLine;
            strDetail += " <b>Warning Level: </b>" + obj.Info.WarningLevel.ToString() + Environment.NewLine;
            strDetail += " <b>Severity Level: </b>" + obj.Info.Severity.ToString() + Environment.NewLine;
            strDetail += " <b>Location: </b>" + obj.Location.Kind.ToString() + Environment.NewLine;
            strDetail += " <b>Character at: </b>" + obj.Location.GetLineSpan(true).StartLinePosition.Character.ToString() + Environment.NewLine;
            strDetail += " <b>On Line: </b>" + obj.Location.GetLineSpan(true).StartLinePosition.Line.ToString() + Environment.NewLine;
            strDetail += Environment.NewLine;
        }

        Console.WriteLine(strDetail);

Problem is that GetDiagnostics() function can't dectect error on Line Console.WriteLin*e*(....)

What am I doing wrong?

like image 900
LeMoussel Avatar asked Sep 02 '13 05:09

LeMoussel


2 Answers

The problem here is that SyntaxTree.GetDiagnostics() will only return syntax errors. In other words, errors in the structure of the program, not errors in its meaning. To get the specific error you are expecting, you will need to construct a Compilation and get the diagnostics for the compilation, or from the SemanticModel for your SyntaxTree.

like image 186
Kevin Pilch Avatar answered Nov 14 '22 21:11

Kevin Pilch


Kevin thank you for your answer. Here is my solution.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
using Roslyn.Compilers.Common;
using Roslyn.Scripting;
using Roslyn.Scripting.CSharp;

//
// To install Roslyn, run the following command in the Package Manager Console :  PM> Install-Package Roslyn
//

namespace WebScriptChecker
{
    class Program
    {
        static void Error(params string[] errors)
        {
            var oldColor = Console.ForegroundColor;
            Console.ForegroundColor = ConsoleColor.Red;
            foreach (var o in errors) { Console.Write(o.ToString()); }
            Console.Write(Environment.NewLine);
            Console.ForegroundColor = oldColor;
        }

        public static void Execute(string code) 
        {
            CommonScriptEngine engine = new ScriptEngine();
            Session session = engine.CreateSession();

            try {
                Submission<object> submission = session.CompileSubmission<object>(code);

                object result = submission.Execute();
                bool hasValue;
                ITypeSymbol resultType = submission.Compilation.GetSubmissionResultType(out hasValue);
            }
            catch (CompilationErrorException e) {
                Error(e.Diagnostics.Select(d => d.ToString()).ToArray());
            }
            catch (Exception e) {
                Error(e.ToString());
            }
        }


        static void Main(string[] args)
        {
            string sScriptCsx = @"
                using System;

                    class Program
                    {
                        static void Main(string[] args)
                        {
                            Console.WriteLine(""Hello, World!"");
                        }
                    }
                ";

            Execute(sScriptCsx);

            Console.WriteLine();
            Console.Write("Presser une touche pour continuer ... ");
            Console.ReadKey();

            Environment.Exit(1);
        }
    }
}
like image 39
LeMoussel Avatar answered Nov 14 '22 21:11

LeMoussel