5

我尝试使用 Roslyn 检查以下示例:

   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);

问题是 GetDiagnostics() 函数无法检测 Line Console.WriteLin* e *(....)上的错误

我究竟做错了什么?

4

2 回答 2

9

这里的问题是SyntaxTree.GetDiagnostics()只会返回语法错误。换句话说,是程序结构上的错误,而不是其含义上的错误。要获得您所期望的特定错误,您需要构造 aCompilation并获取编译的诊断信息,或者从SemanticModel.SyntaxTree

于 2013-09-02T06:58:54.057 回答
1

凯文谢谢你的回答。这是我的解决方案。

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);
        }
    }
}
于 2013-09-02T13:34:49.287 回答