/// <summary>
        /// 执行占位符对 <see cref="Placeholder"/> 中外部方法(extern)的调用,得到代码片段字符串。
        /// </summary>
        /// <param name="placeholderInfo">包含表达式树中解析出来的占位符信息。</param>
        /// <param name="context">编译期代码执行所需的上下文信息。</param>
        /// <returns>占位符中的编译期代码执行后得到的代码片段字符串。</returns>
        internal static string Execute(this PlaceholderVisitor.PlaceholderInfo placeholderInfo, ICompilingContext context)
        {
            var lambda      = placeholderInfo.Compile();
            var codeSnippet = lambda(context);

            codeSnippet = placeholderInfo.Wrap(codeSnippet);
            return(codeSnippet);
        }
        /// <summary>
        /// 根据占位符中调用的 <see cref="Placeholder"/> 中方法的不同,进行不同的执行结果包装。
        /// </summary>
        /// <param name="placeholderInfo">包含表达式树中解析出来的占位符信息。</param>
        /// <param name="text">占位符中的编译期代码执行后得到的代码片段字符串。</param>
        /// <returns>被 <see cref="Placeholder"/> 中的 extern 方法执行后的实际返回代码片段字符串。</returns>
        private static string Wrap(this PlaceholderVisitor.PlaceholderInfo placeholderInfo, string text)
        {
            switch (placeholderInfo.MethodName)
            {
            case nameof(Placeholder.Array):
                return($@" new {placeholderInfo.ReturnType}[]
{{
{text}}}");

            default:
                throw new MissingMethodException($"{nameof(Placeholder)} 中不包含名为 {placeholderInfo.MethodName} 的方法。");
            }
        }
        /// <summary>
        /// 将占位符中的在编译期执行的 Lambda 表达式编译成可执行函数。
        /// </summary>
        /// <param name="placeholderInfo">包含表达式树中解析出来的占位符信息。</param>
        /// <returns>用于调用占位符中编译期可执行代码的委托。</returns>
        private static Func <ICompilingContext, string> Compile(this PlaceholderVisitor.PlaceholderInfo placeholderInfo)
        {
            var builder = new StringBuilder(ClassTemplate)
                          .Replace("{parameterName}", placeholderInfo.InvocationParameterName)
                          .Replace("{body}", placeholderInfo.InvocationBody);
            var syntaxTree      = CSharpSyntaxTree.ParseText(builder.ToString());
            var types           = syntaxTree.Compile("PlaceholderInvoking.g");
            var placeholderImpl = types.First(x => x.Name == "PlaceholderImpl");
            var method          = placeholderImpl.GetMethod("InvokePlaceholder");
            var func            = (Func <ICompilingContext, string>)method.CreateDelegate(typeof(Func <ICompilingContext, string>));

            return(func);
        }