Exemplo n.º 1
0
 /// <summary>
 /// Adds a new method with has return to the type, with the specified name.
 /// </summary>
 /// <typeparam name="T">The type of the tag.</typeparam>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <param name="returnType">The return type</param>
 /// <returns></returns>
 public static MethodBuilder CreateReutrnMethod <T>(this CompileContext ctx, Type returnType)
 {
     if (returnType.FullName == "System.Void")
     {
         return(CreateReutrnMethod(ctx.TypeBuilder, $"Execute{typeof(T).Name}{ctx.Seed}", returnType));
     }
     return(CreateReutrnMethod(ctx.TypeBuilder, $"Get{typeof(T).Name}{ctx.Seed}", returnType));
 }
Exemplo n.º 2
0
        /// <summary>
        /// calling the tag.
        /// </summary>
        /// <param name="il">The <see cref="ILGenerator"/></param>
        /// <param name="ctx">The <see cref="CompileContext"/></param>
        /// <param name="tag">The <see cref="ITag"/></param>
        /// <param name="before">The action.</param>
        /// <param name="completed">The action of the completed.</param>
        public static void CallTag(this ILGenerator il,
                                   CompileContext ctx,
                                   ITag tag,
                                   Action <ILGenerator, bool, bool> before,//hasReturn,call
                                   Action <ILGenerator, Type> completed)
        {
            if (tag is EndTag _ ||
                tag is CommentTag _)
            {
                return;
            }
            if (tag is TextTag textTag)
            {
                if (string.IsNullOrEmpty(textTag.Text))
                {
                    return;
                }
                before?.Invoke(il, true, false);
                var text = textTag.ToString(ctx.OutMode);
                il.Emit(OpCodes.Ldstr, text);
                completed?.Invoke(il, typeof(string));
                return;
            }
            if (tag is ITypeTag typeTag)
            {
                if (typeTag.Value == null)
                {
                    return;
                }
                before?.Invoke(il, true, false);
                Type returnType = il.CallTypeTag(typeTag);
                completed?.Invoke(il, returnType);
                return;
            }
            if (tag is SetTag setTag)
            {
                ctx.Set(setTag.Name, ctx.GuessType(setTag.Value));
            }
            var m = ctx.CompileTag(tag);

            if (m.ReturnType.FullName != "System.Void")
            {
                before?.Invoke(il, true, true);
                il.Emit(OpCodes.Call, m);
                completed?.Invoke(il, m.ReturnType);
            }
            else
            {
                before?.Invoke(il, false, true);
                il.Emit(OpCodes.Call, m);
                completed?.Invoke(il, null);
            }
        }
Exemplo n.º 3
0
 /// <summary>
 /// Gets the <see cref="Type"/> with the specified tag.
 /// </summary>
 /// <param name="name">The tag name of the type to get.</param>
 /// <param name="tag">The tag of the type to get.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns>The type with the specified tag, if found; otherwise, null.</returns>
 public Type GetType(string name, ITag tag, CompileContext ctx)
 {
     if (dict.TryGetValue(name, out var func))
     {
         var type = func(tag, ctx);
         if (type != null)
         {
             return(type);
         }
     }
     throw new CompileException(tag, $"[{name}]:\"{tag.ToSource()}\" is not defined!");
 }
Exemplo n.º 4
0
        /// <summary>
        /// Compiles the specified tag into a method.
        /// </summary>
        /// <param name="name">The name of the tag.</param>
        /// <param name="tag">The <see cref="ITag"/>.</param>
        /// <param name="context">The <see cref="CompileContext"/>.</param>
        /// <returns></returns>
        public static MethodInfo Compile(string name, ITag tag, CompileContext context)
        {
            string tagKey = GetTagKey(tag);

            if (tagKey != null &&
                context.Methods.TryGetValue(tagKey, out MethodInfo mi))
            {
                return(mi);
            }
            var func = context.CompileBuilder.Build(name);

            return(func(tag, context));
        }
Exemplo n.º 5
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tag"></param>
        /// <param name="ctx"></param>
        /// <returns></returns>
        internal static MethodInfo IfCompile <T>(this CompileContext ctx, T tag) where T : ElseifTag
        {
            var stringBuilderType = typeof(StringBuilder);
            var t        = tag;
            var type     = ctx.GuessType(t);
            var mb       = ctx.CreateReutrnMethod <T>(type);
            var il       = mb.GetILGenerator();
            var labelEnd = il.DefineLabel();

            il.DeclareLocal(type);
            il.DeclareLocal(stringBuilderType);
            il.Emit(OpCodes.Newobj, stringBuilderType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_1);
            for (var i = 0; i < t.Children.Count; i++)
            {
                il.CallTag(ctx, t.Children[i], (nil, hasReturn, needCall) =>
                {
                    if (hasReturn)
                    {
                        nil.Emit(OpCodes.Ldloc_1);
                    }
                    if (needCall)
                    {
                        nil.Emit(OpCodes.Ldarg_0);
                        nil.Emit(OpCodes.Ldarg_1);
                    }
                }, (nil, returnType) =>
                {
                    if (returnType == null)
                    {
                        return;
                    }
                    nil.StringAppend(ctx, returnType);
                    nil.Emit(OpCodes.Pop);
                });
            }
            il.Emit(OpCodes.Ldloc_1);
            il.Call(stringBuilderType, stringBuilderType.GetMethodInfo("ToString", Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_0);

            il.MarkLabel(labelEnd);
            il.Emit(OpCodes.Ldloc_0);
            il.Emit(OpCodes.Ret);
            return(mb.GetBaseDefinition());
        }
Exemplo n.º 6
0
        /// <summary>
        /// Compiles the specified tag into a method.
        /// </summary>
        /// <param name="name">The name of the tag.</param>
        /// <param name="tag">The <see cref="ITag"/>.</param>
        /// <param name="context">The <see cref="CompileContext"/>.</param>
        /// <returns></returns>
        public static MethodInfo Compile(this CompileContext context, string name, ITag tag)
        {
            string tagKey = GetTagKey(tag);

            if (tagKey != null &&
                context.Methods.TryGetValue(tagKey, out MethodInfo mi))
            {
                return(mi);
            }
            var func   = context.CompileBuilder.Build(name);
            var method = func(tag, context);

            if (tagKey != null)
            {
                context.Methods[tagKey] = method;
            }
            return(method);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Compile the array into a dynamic class.
        /// </summary>
        /// <param name="tags">The array of the tag.</param>
        /// <param name="ctx">The <see cref="CompileContext"/>.</param>
        /// <returns></returns>
        private static ICompilerResult Compile(this CompileContext ctx, ITag[] tags)
        {
            var baseType        = typeof(CompilerResult);
            var typeBuilder     = ObjectBuilder.DefineType(baseType.GetInterface(nameof(ICompilerResult)), baseType, $"{baseType.Namespace}.Template{ctx.Name.GetHashCode()}");
            var targetMethod    = baseType.GetMethodInfo("Render", new Type[] { typeof(TextWriter), typeof(TemplateContext) });
            var method          = typeBuilder.DefineMethod(targetMethod.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, targetMethod.ReturnType, new Type[] { typeof(TextWriter), typeof(TemplateContext) });
            var methodGenerator = method.GetILGenerator();

            ctx.TypeBuilder = typeBuilder;
            var il        = ctx.Generator = methodGenerator;
            var labelPass = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Ceq);
            il.Emit(OpCodes.Brfalse_S, labelPass);
            il.Emit(OpCodes.Ldstr, "writer cannot be null!");
            il.Emit(OpCodes.Newobj, typeof(System.ArgumentNullException).GetConstructor(new Type[] { typeof(string) }));
            il.Emit(OpCodes.Throw);

            il.MarkLabel(labelPass);

            for (var i = 0; i < tags.Length; i++)
            {
                CompileToRender(ctx, tags[i]);
            }

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ret);


            Type type =
#if NETSTANDARD2_0
                ctx.TypeBuilder.AsType();
#else
                ctx.TypeBuilder.CreateType();
#endif
            if (type == null)
            {
                return(null);
            }
            var instance = type.CreateInstance <ICompilerResult>();
            return(instance);
        }
Exemplo n.º 8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="context"></param>
        public static void CompileToRender(ITag tag, CompileContext context)
        {
            var tagType = tag.GetType();

            if (tag is EndTag _ ||
                tag is CommentTag _)
            {
                return;
            }

            if (tag is TextTag textTag)
            {
                var text = textTag.Text;
                if (context.StripWhiteSpace)
                {
                    text = text?.Trim();
                }
                if (!string.IsNullOrEmpty(text))
                {
                    context.Generator.Emit(OpCodes.Ldarg_1);
                    context.Generator.Emit(OpCodes.Ldstr, text);
                    context.Generator.Emit(OpCodes.Callvirt, typeof(TextWriter).GetMethod("Write", new Type[] { typeof(string) }));
                }
                return;
            }

            if (tag is ITypeTag value)
            {
                context.Generator.Emit(OpCodes.Ldarg_1);
                if (value.Value == null)
                {
                    context.Generator.Emit(OpCodes.Ldstr, string.Empty);
                }
                else
                {
                    context.Generator.Emit(OpCodes.Ldstr, value.Value.ToString());
                }
                context.Generator.Emit(OpCodes.Callvirt, typeof(TextWriter).GetMethod("Write", new Type[] { typeof(string) }));
                return;
            }

            CompileToRender(tag, context, tagType);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Appends the string representation of a specified object to <see cref="StringBuilder"/>.
        /// </summary>
        /// <param name="il">The <see cref="ILGenerator"/></param>
        /// <param name="c">The <see cref="CompileContext"/></param>
        /// <param name="returnType"></param>\
        public static void StringAppend(this ILGenerator il, CompileContext c, Type returnType)
        {
            var        stringBuilderType = typeof(StringBuilder);
            MethodInfo appendMethod;

            switch (returnType.FullName)
            {
            case "System.Object":
            case "System.String":
            case "System.Decimal":
            case "System.Single":
            case "System.UInt64":
            case "System.Int64":
            case "System.UInt32":
            case "System.Boolean":
            case "System.Double":
            case "System.Char":
            case "System.UInt16":
            case "System.Int16":
            case "System.Byte":
            case "System.SByte":
            case "System.Int32":
                appendMethod = DynamicHelpers.GetMethod(stringBuilderType, "Append", new Type[] { returnType });
                break;

            default:
                if (returnType.IsValueType)
                {
                    var p = il.DeclareLocal(returnType);
                    il.Emit(OpCodes.Stloc, p.LocalIndex);
                    LoadVariable(il, returnType, p.LocalIndex);
                    il.Call(returnType, DynamicHelpers.GetMethod(typeof(object), "ToString", Type.EmptyTypes));
                    appendMethod = DynamicHelpers.GetMethod(stringBuilderType, "Append", new Type[] { typeof(string) });
                }
                else
                {
                    appendMethod = DynamicHelpers.GetMethod(stringBuilderType, "Append", new Type[] { typeof(object) });
                }
                break;
            }
            il.Emit(OpCodes.Callvirt, appendMethod);
        }
Exemplo n.º 10
0
        private static void CompileToRender(this CompileContext context, ITag tag, Type tagType)
        {
            if (tag == null)
            {
                return;
            }
            MethodInfo method = null;

            try
            {
                if (tag is ReferenceTag)
                {
                    method = Compile(context, (tag as ReferenceTag).Child);
                }
                else
                {
                    method = Compile(context, tag);
                }
                if (method == null)
                {
                    throw new CompileException(tag, $"Cannot compile the {tag.GetType().Name} on {tag.ToSource()}[line:{tag.FirstToken?.BeginLine ?? 0},col:{tag.FirstToken?.BeginColumn ?? 0}]:");
                }
            }
            catch (System.Exception exception)
            {
                if (context.ThrowExceptions)
                {
                    throw;
                }
                context.Generator.Emit(OpCodes.Ldarg_2);
                context.Generator.Emit(OpCodes.Ldstr, exception.ToString());
                context.Generator.Emit(OpCodes.Newobj, typeof(CompileException).GetConstructor(new Type[] { typeof(string) }));
                //context.Generator.Emit(OpCodes.Throw);
                context.Generator.Emit(OpCodes.Callvirt, typeof(TemplateContext).GetMethod("AddError", new Type[] { typeof(System.Exception) }));
                return;
            }

            CompileToRender(context, tag, tagType, method);
        }
Exemplo n.º 11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="il"></param>
        /// <param name="ctx"></param>
        /// <param name="tags"></param>
        /// <returns></returns>
        internal static void BlockCompile(this CompileContext ctx, ILGenerator il, ITag[] tags)
        {
            var stringBuilderType = typeof(StringBuilder);

            il.DeclareLocal(stringBuilderType);
            il.DeclareLocal(typeof(string));
            il.Emit(OpCodes.Newobj, stringBuilderType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_0);
            for (var i = 0; i < tags.Length; i++)
            {
                il.CallTag(ctx, tags[i], (nil, hasReturn, needCall) =>
                {
                    if (hasReturn)
                    {
                        nil.Emit(OpCodes.Ldloc_0);
                    }
                    if (needCall)
                    {
                        nil.Emit(OpCodes.Ldarg_0);
                        nil.Emit(OpCodes.Ldarg_1);
                    }
                }, (nil, returnType) =>
                {
                    if (returnType == null)
                    {
                        return;
                    }
                    nil.StringAppend(ctx, returnType);
                    nil.Emit(OpCodes.Pop);
                });
            }
            il.Emit(OpCodes.Ldloc_0);
            il.Call(stringBuilderType, stringBuilderType.GetMethodInfo("ToString", Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_1);
            il.Emit(OpCodes.Ldloc_1);
        }
Exemplo n.º 12
0
 /// <summary>
 /// Compiles the specified tag into a method.
 /// </summary>
 /// <param name="tag">The <see cref="ITag"/>.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public static MethodInfo CompileTag(this CompileContext ctx, ITag tag)
 {
     return(TagCompiler.Compile(tag, ctx));
 }
Exemplo n.º 13
0
        private static void CompileToRender(ITag tag, CompileContext context, Type tagType, MethodInfo method)
        {
            var        type              = method.ReturnType;
            var        isAsync           = false;
            var        taskType          = typeof(System.Threading.Tasks.Task);
            MethodInfo taskAwaiterMethod = null;
            MethodInfo resultMethod      = null;

            var mb         = context.CreateRenderMethod(tagType.Name);
            var il         = mb.GetILGenerator();
            var exBlock    = il.BeginExceptionBlock();
            var lableThrow = il.DefineLabel();
            var labelPass  = il.DefineLabel();

            var index = 0;


            if (DynamicHelpers.IsMatchType(type, taskType))
            {
                isAsync           = true;
                taskAwaiterMethod = DynamicHelpers.GetMethod(method.ReturnType, "GetAwaiter", Type.EmptyTypes);
                resultMethod      = DynamicHelpers.GetMethod(taskAwaiterMethod.ReturnType, "GetResult", Type.EmptyTypes);
                type = resultMethod.ReturnType;
            }
            if (type.FullName != "System.Void")
            {
                il.DeclareLocal(type);
                index = 1;
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Call, method);

                if (isAsync)
                {
                    il.DeclareLocal(taskAwaiterMethod.ReturnType);
                    il.Emit(OpCodes.Callvirt, taskAwaiterMethod);
                    il.Emit(OpCodes.Stloc, index);
                    il.Emit(OpCodes.Ldloca, index);
                    il.Emit(OpCodes.Call, resultMethod);
                    index++;
                }
                il.Emit(OpCodes.Stloc_0);
                il.Emit(OpCodes.Ldarg_1);
                MethodInfo writeMethod;
                switch (type.FullName)
                {
                case "System.Object":
                case "System.String":
                case "System.Decimal":
                case "System.Single":
                case "System.UInt64":
                case "System.Int64":
                case "System.UInt32":
                case "System.Int32":
                case "System.Boolean":
                case "System.Double":
                case "System.Char":
                    il.Emit(OpCodes.Ldloc_0);
                    writeMethod = typeof(TextWriter).GetMethod("Write", new Type[] { type });
                    break;

                default:
                    if (type.IsValueType)
                    {
                        il.Emit(OpCodes.Ldloca_S, 0);
                        il.Call(type, typeof(object).GetMethod("ToString", Type.EmptyTypes));
                        writeMethod = typeof(TextWriter).GetMethod("Write", new Type[] { typeof(string) });
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldloc_0);
                        writeMethod = typeof(TextWriter).GetMethod("Write", new Type[] { typeof(object) });
                    }
                    break;
                }
                il.Emit(OpCodes.Callvirt, writeMethod);
            }
            else
            {
                if (isAsync)
                {
                    il.DeclareLocal(taskAwaiterMethod.ReturnType);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Call, method);
                    il.Emit(OpCodes.Callvirt, taskAwaiterMethod);
                    il.Emit(OpCodes.Stloc_0);
                    il.Emit(OpCodes.Ldloca, 0);
                    il.Emit(OpCodes.Call, resultMethod);
                    index = 1;
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Call, method);
                }
            }

            il.DeclareLocal(typeof(System.Exception));
            il.DeclareLocal(typeof(bool));

            il.BeginCatchBlock(typeof(System.Exception));
            il.Emit(OpCodes.Stloc, index);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetPropertyGetMethod(typeof(Context), "ThrowExceptions"));
            il.Emit(OpCodes.Stloc, index + 1);
            il.Emit(OpCodes.Ldloc, index + 1);
            il.Emit(OpCodes.Brfalse, lableThrow);

            il.Emit(OpCodes.Ldloc, index);
            il.Emit(OpCodes.Throw);

            il.MarkLabel(lableThrow);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldloc, index);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetMethod(typeof(TemplateContext), "AddError", new Type[] { typeof(System.Exception) }));
            //il.Emit(OpCodes.Leave_S, labelPass);
            il.EndExceptionBlock();

            il.MarkLabel(labelPass);
            il.Emit(OpCodes.Ret);

            context.Generator.Emit(OpCodes.Ldarg_0);
            context.Generator.Emit(OpCodes.Ldarg_1);
            context.Generator.Emit(OpCodes.Ldarg_2);
            context.Generator.Emit(OpCodes.Call, mb.GetBaseDefinition());
        }
Exemplo n.º 14
0
 /// <summary>
 /// Gets the <see cref="Type"/> with the specified tag.
 /// </summary>
 /// <param name="tag">The tag of the type to get.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public Type GetType(ITag tag, CompileContext ctx)
 {
     return(GetType(tag.GetType().Name, tag, ctx));
 }
Exemplo n.º 15
0
 /// <summary>
 /// Compiles the specified tag into a method.
 /// </summary>
 /// <param name="tag">The <see cref="ITag"/>.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public static MethodInfo Compile(ITag tag, CompileContext ctx)
 {
     return(Compile(tag.GetType().Name, tag, ctx));
 }
Exemplo n.º 16
0
 /// <summary>
 /// Gets the <see cref="Type"/> with the specified tag.
 /// </summary>
 /// <param name="tag">The tag of the type to get.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public static Type GuessType(this CompileContext ctx, ITag tag)
 {
     return(ctx.TypeGuesser.GetType(tag, ctx));
 }
Exemplo n.º 17
0
 /// <summary>
 /// Compiles the specified tag into a method.
 /// </summary>
 /// <param name="tag">The <see cref="ITag"/>.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public static MethodInfo CompileTag(this CompileContext ctx, ITag tag)
 {
     return(Compile(ctx, tag));
 }
Exemplo n.º 18
0
        /// <summary>
        /// Compile the text into a dynamic class.
        /// </summary>
        /// <param name="content">the context of the text</param>
        /// <param name="ctx">The <see cref="CompileContext"/>.</param>
        /// <returns></returns>
        public static ICompilerResult Compile(this CompileContext ctx, string content)
        {
            var tags = TemplateContextExtensions.Lexer(ctx, content);

            return(Compile(ctx, tags));
        }
Exemplo n.º 19
0
        private static void CompileToRender(this CompileContext context, ITag tag, Type tagType, MethodInfo method)
        {
            var        type              = method.ReturnType;
            var        isAsync           = false;
            var        taskType          = typeof(System.Threading.Tasks.Task);
            MethodInfo taskAwaiterMethod = null;
            MethodInfo resultMethod      = null;

            var mb      = context.CreateRenderMethod(tagType.Name);
            var il      = mb.GetILGenerator();
            var exBlock = il.BeginExceptionBlock();
            //var lableThrow = il.DefineLabel();
            var labelPass = il.DefineLabel();

            if (type.IsMatchType(taskType))
            {
                isAsync           = true;
                taskAwaiterMethod = method.ReturnType.GetMethodInfo("GetAwaiter", Type.EmptyTypes);
                resultMethod      = taskAwaiterMethod.ReturnType.GetMethodInfo("GetResult", Type.EmptyTypes);
                type = resultMethod.ReturnType;
            }
            if (type.FullName != "System.Void")
            {
                il.DeclareLocal(type);
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Call, method);

                if (isAsync)
                {
                    var returnVar = il.DeclareLocal(taskAwaiterMethod.ReturnType);
                    il.Emit(OpCodes.Callvirt, taskAwaiterMethod);
                    il.Emit(OpCodes.Stloc, returnVar.LocalIndex);
                    il.Emit(OpCodes.Ldloca, returnVar.LocalIndex);
                    il.Emit(OpCodes.Call, resultMethod);
                }
                il.Emit(OpCodes.Stloc_0);
                il.Emit(OpCodes.Ldarg_1);
                MethodInfo writeMethod;
                switch (type.FullName)
                {
                case "System.Object":
                case "System.String":
                case "System.Decimal":
                case "System.Single":
                case "System.UInt64":
                case "System.Int64":
                case "System.UInt32":
                case "System.Int32":
                case "System.Boolean":
                case "System.Double":
                case "System.Char":
                    il.Emit(OpCodes.Ldloc_0);
                    writeMethod = typeof(TextWriter).GetMethod("Write", new Type[] { type });
                    break;

                default:
                    if (type.IsValueType)
                    {
                        il.Emit(OpCodes.Ldloca_S, 0);
                        il.Call(type, typeof(object).GetMethod("ToString", Type.EmptyTypes));
                        writeMethod = typeof(TextWriter).GetMethod("Write", new Type[] { typeof(string) });
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldloc_0);
                        writeMethod = typeof(TextWriter).GetMethod("Write", new Type[] { typeof(object) });
                    }
                    break;
                }
                il.Emit(OpCodes.Callvirt, writeMethod);
            }
            else
            {
                if (isAsync)
                {
                    il.DeclareLocal(taskAwaiterMethod.ReturnType);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Call, method);
                    il.Emit(OpCodes.Callvirt, taskAwaiterMethod);
                    il.Emit(OpCodes.Stloc_0);
                    il.Emit(OpCodes.Ldloca, 0);
                    il.Emit(OpCodes.Call, resultMethod);
                }
                else
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldarg_2);
                    il.Emit(OpCodes.Call, method);
                }
            }
            var exceptionVar = il.DeclareLocal(typeof(System.Exception));

            //il.DeclareLocal(typeof(bool));

            il.BeginCatchBlock(typeof(System.Exception));
            il.Emit(OpCodes.Stloc, exceptionVar.LocalIndex);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldloc, exceptionVar.LocalIndex);
            il.Emit(OpCodes.Ldc_I4, tag.FirstToken?.BeginLine ?? 0);
            il.Emit(OpCodes.Ldc_I4, tag.FirstToken?.BeginColumn ?? 0);
            if (context.Debug)
            {
                il.Emit(OpCodes.Ldstr, tag.ToSource());
            }
            else
            {
                il.Emit(OpCodes.Ldnull);
            }
            il.Emit(OpCodes.Call, typeof(CompilerResult).GetMethodInfo("ThrowException", null));
            il.EndExceptionBlock();

            il.MarkLabel(labelPass);
            il.Emit(OpCodes.Ret);

            context.Generator.Emit(OpCodes.Ldarg_0);
            context.Generator.Emit(OpCodes.Ldarg_1);
            context.Generator.Emit(OpCodes.Ldarg_2);
            context.Generator.Emit(OpCodes.Call, mb.GetBaseDefinition());
        }
Exemplo n.º 20
0
 /// <summary>
 /// Adds a new render method to the type, with the specified name.
 /// </summary>
 /// <param name="name">The name of the method.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns>The <see cref="MethodBuilder"/>.</returns>
 public static MethodBuilder CreateRenderMethod(this CompileContext ctx, string name)
 {
     return(ctx.TypeBuilder.DefineMethod($"Render{name}{ctx.Seed}", MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.Standard | CallingConventions.HasThis, typeof(void), new Type[] { typeof(TextWriter), typeof(TemplateContext) }));
 }
Exemplo n.º 21
0
 /// <summary>
 /// Adds a new method to the type, with the specified name.
 /// </summary>
 /// <typeparam name="T">The type of the tag.</typeparam>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public static MethodBuilder CreateRenderMethod <T>(this CompileContext ctx)
 {
     return(CreateRenderMethod(ctx, typeof(T).Name));
 }
Exemplo n.º 22
0
 /// <summary>
 /// Compiles the specified tag into a method.
 /// </summary>
 /// <param name="tag">The <see cref="ITag"/>.</param>
 /// <param name="ctx">The <see cref="CompileContext"/>.</param>
 /// <returns></returns>
 public static MethodInfo Compile(this CompileContext ctx, ITag tag)
 {
     return(Compile(ctx, tag.GetType().Name, tag));
 }