/// <inheritdoc /> public override Func <ITag, CompileContext, MethodInfo> BuildCompileMethod() { return((tag, c) => { var t = tag as LayoutTag; var type = c.GuessType(t); var mb = c.CreateReutrnMethod <LayoutTag>(type); var il = mb.GetILGenerator(); var strTag = t.Path as StringTag; if (strTag == null) { throw new Exception.CompileException($"[LayoutTag] : path must be a string."); } var res = c.Load(strTag.Value); if (res == null) { throw new Exception.CompileException($"[LayoutTag] : \"{strTag.Value}\" cannot be found."); } var lexer = c.CreateTemplateLexer(res.Content); var ts = lexer.Execute(); var parser = c.CreateTemplateParser(ts); var tags = parser.Execute(); for (int i = 0; i < tags.Length; i++) { if (tags[i] is BodyTag) { BodyTag body = (BodyTag)tags[i]; for (int j = 0; j < t.Children.Count; j++) { body.AddChild(t.Children[j]); } } } c.BlockCompile(il, tags); il.Emit(OpCodes.Ret); return mb.GetBaseDefinition(); }); }
/// <inheritdoc /> public override Func <ITag, TemplateContext, object> BuildExcuteMethod() { return((tag, context) => { var t = tag as LayoutTag; object path = TagExecutor.Execute(t.Path, context); if (path == null) { return null; } var res = context.Load(path.ToString()); if (res != null) { var render = new TemplateRender(); render.Context = context; //render.TemplateContent = res.Content; var tags = render.ReadAll(res.Content); for (int i = 0; i < tags.Length; i++) { if (tags[i] is BodyTag) { BodyTag body = (BodyTag)tags[i]; for (int j = 0; j < t.Children.Count; j++) { body.AddChild(t.Children[j]); } tags[i] = body; } } using (System.IO.StringWriter writer = new StringWriter()) { render.Render(writer, tags); return writer.ToString(); } } return null; }); }
/// <summary> /// 初始化 /// </summary> public void Initialize() { Register <VariableTag>((tag, context) => { var t = tag as VariableTag; object baseValue = null; if (t.Parent != null) { baseValue = Executor.Exec(t.Parent, context); } if (baseValue == null) { return(context.TempData[t.Name]); } return(Runtime.Actuator.CallPropertyOrField(baseValue, t.Name)); }); Register <ArithmeticTag>((tag, context) => { var t = tag as ArithmeticTag; List <object> parameters = new List <object>(); for (int i = 0; i < t.Children.Count; i++) { var opt = t.Children[i] as OperatorTag; if (opt != null) { parameters.Add(opt.Value); } else { parameters.Add(Executor.Exec(t.Children[i], context)); } } var stack = ExpressionEvaluator.ProcessExpression(parameters.ToArray()); return(ExpressionEvaluator.Calculate(stack)); }); Register <BodyTag>((tag, context) => { var t = tag as BodyTag; if (t.Children.Count == 0) { return(null); } if (t.Children.Count == 1) { return(Executor.Exec(t.Children[0], context)); } var sb = new System.Text.StringBuilder(); for (int i = 0; i < t.Children.Count; i++) { sb.Append(Executor.Exec(t.Children[i], context)); } return(sb.ToString()); }); Register <BooleanTag>((tag, context) => { var t = tag as BooleanTag; return(t.Value); }); Register <CommentTag>((tag, context) => { var t = tag as CommentTag; return(null); }); Register <ElseifTag>((tag, context) => { var t = tag as ElseifTag; var condition = Executor.Exec(t.Condition, context); if (Utility.ToBoolean(condition)) { if (t.Children.Count == 0) { return(null); } if (t.Children.Count == 1) { return(Executor.Exec(t.Children[0], context)); } var sb = new System.Text.StringBuilder(); for (int i = 0; i < t.Children.Count; i++) { sb.Append(Executor.Exec(t.Children[i], context)); } return(sb.ToString()); } return(null); }); Register <ElseTag>((tag, context) => { var t = tag as ElseTag; if (t.Children.Count == 0) { return(null); } if (t.Children.Count == 1) { return(Executor.Exec(t.Children[0], context)); } var sb = new System.Text.StringBuilder(); for (int i = 0; i < t.Children.Count; i++) { sb.Append(Executor.Exec(t.Children[i], context)); } return(sb.ToString()); }); Register <EndTag>((tag, context) => { var t = tag as EndTag; return(null); }); Register <ForeachTag>((tag, context) => { var t = tag as ForeachTag; if (t.Source != null) { using (var writer = new StringWriter()) { object value = Executor.Exec(t.Source, context); var enumerable = ForeachTag.ToIEnumerable(value); TemplateContext ctx; if (enumerable != null) { var ienum = enumerable.GetEnumerator(); ctx = TemplateContext.CreateContext(context); int i = 0; while (ienum.MoveNext()) { i++; ctx.TempData.Set(t.Name, ienum.Current, ienum.Current == null ? typeof(object) : ienum.Current.GetType()); //为了兼容以前的用户 foreachIndex 保留 ctx.TempData.Set("foreachIndex", i); for (int n = 0; n < t.Children.Count; n++) { object result = Executor.Exec(t.Children[n], ctx); if (i == 0 && t.Children.Count == 1) { return(result); } if (result != null) { writer.Write(result.ToString()); } } } } return(writer.ToString()); } } return(null); }); Register <ForTag>((tag, context) => { var t = tag as ForTag; Executor.Exec(t.Initial, context); //如果标签为空,则直接为false,避免死循环以内存溢出 bool run; if (t.Condition == null) { run = false; } else { run = Utility.ToBoolean(Executor.Exec(t.Condition, context)); } using (var writer = new StringWriter()) { while (run) { for (int i = 0; i < t.Children.Count; i++) { var obj = Executor.Exec(t.Children[i], context); if (obj != null) { writer.Write(obj.ToString()); } } if (t.Do != null) { //执行计算,不需要输出,比如i++ Executor.Exec(t.Do, context); } run = Utility.ToBoolean(Executor.Exec(t.Condition, context)); } return(writer.ToString()); } }); Register <FunctaionTag>((tag, context) => { var t = tag as FunctaionTag; object[] args = new object[t.Children.Count]; for (int i = 0; i < t.Children.Count; i++) { args[i] = Executor.Exec(t.Children[i], context); } object parentValue; if (t.Parent == null) { parentValue = context.TempData[t.Name]; } else { parentValue = Executor.Exec(t.Parent, context); } if (parentValue == null) { return(null); } if (t.Parent == null || (t.Parent != null && string.IsNullOrEmpty(t.Name))) { if (parentValue is FuncHandler) { return((parentValue as FuncHandler)(args)); } if (parentValue is Delegate) { return((parentValue as Delegate).DynamicInvoke(args)); } return(null); } var result = Runtime.Actuator.CallMethod(parentValue, t.Name, args); if (result != null) { return(result); } result = Runtime.Actuator.CallPropertyOrField(parentValue, t.Name); if (result != null && result is Delegate) { return((result as Delegate).DynamicInvoke(args)); } return(null); }); Register <IfTag>((tag, context) => { var t = tag as IfTag; for (int i = 0; i < t.Children.Count - 1; i++) { var c = (ElseifTag)t.Children[i]; if (tag == null) { continue; } if (t.Children[i] is ElseTag) { return(Executor.Exec(t.Children[i], context)); } var condition = Executor.Exec(c.Condition, context); if (Utility.ToBoolean(condition)) { return(Executor.Exec(t.Children[i], context)); } } return(null); }); Register <IncludeTag>((tag, context) => { var t = tag as IncludeTag; object path = Executor.Exec(t.Path, context); if (path == null) { return(null); } var res = context.Load(path.ToString()); if (res != null) { return(res.Content); } return(null); }); Register <IndexValueTag>((tag, context) => { var t = tag as IndexValueTag; object obj = Executor.Exec(t.Parent, context); object index = Executor.Exec(t.Index, context); return(Runtime.Actuator.CallIndexValue(obj, index)); }); Register <JsonTag>((tag, context) => { var t = tag as JsonTag; var result = new Dictionary <object, object>(); foreach (var kv in t.Dict) { var key = kv.Key == null ? null : Executor.Exec(kv.Key, context); var value = kv.Value == null ? null : Executor.Exec(kv.Value, context); result.Add(key, value); } return(result); }); Register <LayoutTag>((tag, context) => { var t = tag as LayoutTag; object path = Executor.Exec(t.Path, context); if (path == null) { return(null); } var res = context.Load(path.ToString()); if (res != null) { var render = new TemplateRender(); render.Context = context; //render.TemplateContent = res.Content; var tags = render.ReadAll(res.Content); for (int i = 0; i < tags.Length; i++) { if (tags[i] is BodyTag) { BodyTag body = (BodyTag)tags[i]; for (int j = 0; j < t.Children.Count; j++) { body.AddChild(t.Children[j]); } tags[i] = body; } } using (System.IO.StringWriter writer = new StringWriter()) { render.Render(writer, tags); return(writer.ToString()); } } return(null); }); Register <LoadTag>((tag, context) => { var t = tag as LoadTag; object path = Executor.Exec(t.Path, context); if (path == null) { return(null); } var res = context.Load(path.ToString()); if (res != null) { var render = new TemplateRender(); render.Context = context; using (System.IO.StringWriter writer = new StringWriter()) { render.Render(writer, render.ReadAll(res.Content)); return(writer.ToString()); } } return(null); }); Register <LogicTag>((tag, context) => { var t = tag as LogicTag; List <object> parameters = new List <object>(); for (int i = 0; i < t.Children.Count; i++) { bool isOperator = t.Children[i] is OperatorTag; object result = Executor.Exec(t.Children[i], context); if (Eval(parameters, isOperator, result)) { return(parameters[parameters.Count - 1]); } } var stack = ExpressionEvaluator.ProcessExpression(parameters.ToArray()); return(ExpressionEvaluator.Calculate(stack)); }); Register <NullTag>((tag, context) => { return(null); }); Register <NumberTag>((tag, context) => { var t = tag as NumberTag; return(t.Value); }); Register <OperatorTag>((tag, context) => { var t = tag as OperatorTag; return(t.Value); }); Register <ReferenceTag>((tag, context) => { var t = tag as ReferenceTag; if (t.Child != null) { return(Executor.Exec(t.Child, context)); } return(null); }); Register <SetTag>((tag, context) => { var t = tag as SetTag; object value = Executor.Exec(t.Value, context); if (value != null) { if (!context.TempData.Update(t.Name, value)) { context.TempData.Set(t.Name, value, value.GetType()); } } return(null); }); Register <StringTag>((tag, context) => { var t = tag as StringTag; return(t.Value); }); Register <TextTag>((tag, context) => { var t = tag as TextTag; if (context.StripWhiteSpace) { return((t.Text ?? string.Empty).Trim()); } return(t.Text); }); }