private TemplateElement CreateCodeSnippet(Match match) { Group memberInvoke = match.Groups["invoke"]; Group funcParam = match.Groups["func_param"]; string name = match.Groups["name"].Value; TemplateElement result = null; if (funcParam.Success) { result = new TemplateElement(this.Document, TemplateElementTypes.Function, match.Index, match.Length, null); TemplateElement funcParamNode = new TemplateElement(this.Document, TemplateElementTypes.FunctionInvokeParam, funcParam.Index, funcParam.Length, null); result.ChildNodes.Add(funcParamNode); } else { result = new TemplateElement(this.Document, TemplateElementTypes.Variable, match.Index, match.Length, null); } result.Items[KEY_NAME] = name; if (memberInvoke.Success && memberInvoke.Length > 0) { result.ParseMemberInvoke(memberInvoke.Index, memberInvoke.Length); } result.Document = this.Document; return(result); }
private TemplateElement(TemplateElement document, TemplateElementTypes type, int index, int length, IDictionary items) { this.Document = document; this.TemplateFile = document.TemplateFile; Type = type; Index = index; Length = length; m_Items = items; SourceTemplate = document.SourceTemplate; if (SourceTemplate == string.Empty || length == 0) { return; } switch (type) { case TemplateElementTypes.Tag: if ((bool)Items[KEY_CLOSED] == false) { ParseTemplateTag(Index, Length); } break; case TemplateElementTypes.Document: case TemplateElementTypes.AjaxPanel: case TemplateElementTypes.IfExpression: case TemplateElementTypes.LoopExpression: ParseTemplateTag(Index, Length); break; case TemplateElementTypes.AttributeList: ParseAttributeList(Index, Length); break; case TemplateElementTypes.IndexInvokeParam: case TemplateElementTypes.FunctionInvokeParam: ParseTemplateCode(Index, Length, false, true); break; case TemplateElementTypes.CodeBlock: case TemplateElementTypes.DoubleQuteString: case TemplateElementTypes.SingleQuteString: case TemplateElementTypes.AttributeListItem: case TemplateElementTypes.ConditionExpression: ParseTemplateCode(Index, Length); break; case TemplateElementTypes.LoopExpressionParam: ParseLoopExpressionParam(Index, Length); break; } }
private TemplateElement CreateAttributeListItem(int index, Match match) { Group name = match.Groups["name"]; Group value = match.Groups["value"]; TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.AttributeListItem, value.Index, value.Length, null); result.Items[KEY_NAME] = name.Value; return(result); }
private TemplateElement CreateLoopExpressionParam(Group param) { int index = param.Index; int length = param.Length; TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.LoopExpressionParam, index, length, null); result.Document = this.Document; return(result); }
private TemplateElement(TemplateElement document, TemplateElementTypes type, int index, int length, IDictionary items) { this.Document = document; this.TemplateFile = document.TemplateFile; Type = type; Index = index; Length = length; m_Items = items; SourceTemplate = document.SourceTemplate; if (SourceTemplate == string.Empty || length == 0) return; switch (type) { case TemplateElementTypes.Tag: if ((bool)Items[KEY_CLOSED] == false) ParseTemplateTag(Index, Length); break; case TemplateElementTypes.Document: case TemplateElementTypes.AjaxPanel: case TemplateElementTypes.IfExpression: case TemplateElementTypes.LoopExpression: ParseTemplateTag(Index, Length); break; case TemplateElementTypes.AttributeList: ParseAttributeList(Index, Length); break; case TemplateElementTypes.IndexInvokeParam: case TemplateElementTypes.FunctionInvokeParam: ParseTemplateCode(Index, Length, false, true); break; case TemplateElementTypes.CodeBlock: case TemplateElementTypes.DoubleQuteString: case TemplateElementTypes.SingleQuteString: case TemplateElementTypes.AttributeListItem: case TemplateElementTypes.ConditionExpression: ParseTemplateCode(Index, Length); break; case TemplateElementTypes.LoopExpressionParam: ParseLoopExpressionParam(Index, Length); break; } }
private TemplateElement CreateCodeBlock(Match match) { Group content = match.Groups["content"]; TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.CodeBlock, content.Index, content.Length, null); result.Items.Add(KEY_OUTPUT, match.Groups["out"].Success); result.Document = this.Document; return(result); }
private TemplateElement CreateConditionExpression(Group param, bool isElseIf) { int index = param.Index; int length = param.Length; if (isElseIf) { index += 3; length -= 3; } TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.ConditionExpression, index, length, null); result.Document = this.Document; return(result); }
private TemplateElement CreateMemberInvokeListItem(Match match) { Group memberInvoke = match.Groups["invoke"]; Group funcParam = match.Groups["func_param"]; Group indexParam = match.Groups["index_param"]; TemplateElement result = null; if (funcParam.Success) { result = new TemplateElement(this.Document, TemplateElementTypes.FunctionInvoke, match.Index, match.Length, null); TemplateElement funcParamNode = new TemplateElement(this.Document, TemplateElementTypes.FunctionInvokeParam, funcParam.Index, funcParam.Length, null); result.ChildNodes.Add(funcParamNode); } else if (indexParam.Success) { result = new TemplateElement(this.Document, TemplateElementTypes.IndexInvoke, match.Index, match.Length, null); TemplateElement indexParamNode = new TemplateElement(this.Document, TemplateElementTypes.IndexInvokeParam, indexParam.Index, indexParam.Length, null); result.ChildNodes.Add(indexParamNode); } else { result = new TemplateElement(this.Document, TemplateElementTypes.PropertyInvoke, match.Index, match.Length, null); } result.Items[KEY_NAME] = match.Groups["name"].Value; if (memberInvoke.Success && memberInvoke.Length > 0) { result.ParseMemberInvoke(memberInvoke.Index, memberInvoke.Length); } return(result); }
/// <summary> /// 获取模板标签所对应的方法 /// </summary> /// <param name="tag">模板标签</param> /// <returns></returns> private MethodInfo SearchMethodForTag(TemplateElement tag) { string name = ((string)tag.Items[TemplateElement.KEY_NAME]); if (m_MethodBasedTags.ContainsKey(name)) { return SearchMethod(m_MethodBasedTags[name], tag.ChildNodes[0], true); } else if (TemplateMembers.CachedInstance.MethodBasedTags.ContainsKey(name)) { return SearchMethod(TemplateMembers.CachedInstance.MethodBasedTags[name], tag.ChildNodes[0], true); } else { //TODO: Report Error } return null; }
private TemplateElement CreateDoubleQuteString(Match match) { TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.DoubleQuteString, match.Index + 1, match.Length - 2, null); return result; }
private void GeneratePropertyInvokeAspxCode(StringBuffer codeBody, TemplateElement propertyInvoke, Type type, out Type returnType, ScopeData scopeData) { returnType = null; string name = propertyInvoke.Items[TemplateElement.KEY_NAME] as string; MethodInfo extensionProperty = SearchExtensionProperty(name, type); if (extensionProperty != null) { StringBuffer sb = new StringBuffer(ReflectionUtil.GetCSharpTypeName(extensionProperty.DeclaringType)); sb += "." + extensionProperty.Name + "(("; codeBody.InnerBuilder.Insert(0, sb); codeBody += "),\"" + name + "\")"; if (propertyInvoke.ChildNodes.Count > 0) GenerateMemberInvokeAspxCode(codeBody, propertyInvoke.ChildNodes[0], extensionProperty.ReturnType, out returnType, scopeData); if(returnType == null) returnType = extensionProperty.ReturnType; } else { MemberInfo member = SearchPropertyAndField(name, type); Type magicPropertyType = null; if (member != null) { codeBody += "." + member.Name; Type memberType; if (member.MemberType == MemberTypes.Property) memberType = ((PropertyInfo)member).PropertyType; else memberType = ((FieldInfo)member).FieldType; if (propertyInvoke.ChildNodes.Count > 0) GenerateMemberInvokeAspxCode(codeBody, propertyInvoke.ChildNodes[0], memberType, out returnType, scopeData); if(returnType == null) returnType = memberType; } else if (HasMagicProperty(type, out magicPropertyType)) { codeBody += "[\"" + name + "\"]"; if (propertyInvoke.ChildNodes.Count > 0) GenerateMemberInvokeAspxCode(codeBody, propertyInvoke.ChildNodes[0], magicPropertyType, out returnType, scopeData); if(returnType == null) returnType = magicPropertyType; } } }
private TemplateElement CreateCodeSnippet(Match match) { Group memberInvoke = match.Groups["invoke"]; Group funcParam = match.Groups["func_param"]; string name = match.Groups["name"].Value; TemplateElement result = null; if (funcParam.Success) { result = new TemplateElement(this.Document, TemplateElementTypes.Function, match.Index, match.Length, null); TemplateElement funcParamNode = new TemplateElement(this.Document, TemplateElementTypes.FunctionInvokeParam, funcParam.Index, funcParam.Length, null); result.ChildNodes.Add(funcParamNode); } else { result = new TemplateElement(this.Document, TemplateElementTypes.Variable, match.Index, match.Length, null); } result.Items[KEY_NAME] = name; if (memberInvoke.Success && memberInvoke.Length > 0) result.ParseMemberInvoke(memberInvoke.Index, memberInvoke.Length); result.Document = this.Document; return result; }
private TemplateElement CreateAttributeList(Capture capture) { TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.AttributeList, capture.Index, capture.Length, null); return result; }
private void GenerateAspxCode(TemplateElement element, ScopeData scopeData) { foreach (TemplateElement node in element.ChildNodes) { switch (node.Type) { case TemplateElementTypes.Tag: GenerateTagAspxCode(node, scopeData); break; case TemplateElementTypes.Literal: GenerateLiteralAspxCode(node); break; case TemplateElementTypes.Variable: GenerateVariableAspxCode(node, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(node, scopeData); break; case TemplateElementTypes.CodeBlock: GenerateCodeBlockAspxCode(node, scopeData); break; case TemplateElementTypes.IfExpression: case TemplateElementTypes.ElseExpression: case TemplateElementTypes.ElseIfExpression: GenerateIfElseEpxressionAspxCode(node, scopeData); break; case TemplateElementTypes.LoadExpression: GenerateIncludeExpressionAspxCode(node, scopeData); break; //case TemplateElementTypes.PreIncludeExpression: // GenerateAspxCode(node.ChildNodes[1], scopeData); // break; case TemplateElementTypes.LoopExpression: GenerateLoopExpressionAspxCode(node, scopeData); break; case TemplateElementTypes.AjaxPanel: GenerateAjaxPanelAspxCode(node, scopeData); break; } } }
public void Dispose() { m_Document = null; m_CodeBody = null; m_CodeHead = null; m_DeclaredVariables = null; m_ExtensionFunctions = null; m_ExtensionProperties = null; m_MethodBasedFunctions = null; m_MethodBasedTags = null; m_PropertyBasedVariables = null; try { System.GC.Collect(); } catch { LogHelper.CreateDebugLog("模板处理完毕,垃圾回收失败,可能会占用较高内存"); } }
private void GenerateDoubleQuteStringAspxCode(StringBuffer codeBody, TemplateElement node, ScopeData scopeData) { if (node.ChildNodes.Count == 0) { codeBody += "\"\""; return; } for (int j = 0; j < node.ChildNodes.Count; j++) { TemplateElement element2 = node.ChildNodes[j]; Type returnType = null; switch (element2.Type) { case TemplateElementTypes.Literal: codeBody += "\""; GenerateLiteralAspxCode(codeBody, element2); codeBody += "\""; break; case TemplateElementTypes.Variable: GenerateVariableAspxCode(codeBody, element2, out returnType, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(codeBody, element2, out returnType, scopeData); break; case TemplateElementTypes.CodeBlock: GenerateCodeBlockAspxCode(codeBody, element2, scopeData); break; } if (j < node.ChildNodes.Count - 1) codeBody += " + "; } }
private TemplateElement CreateAttributeList(Capture capture) { TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.AttributeList, capture.Index, capture.Length, null); return(result); }
private void GenerateIncludeExpressionAspxCode(TemplateElement node, ScopeData scopeData) { m_CodeBody += "<%\r\n Include(__w, "; for (int i = 0; i < node.ChildNodes[0].ChildNodes.Count; i++) { TemplateElement element = node.ChildNodes[0].ChildNodes[i]; m_CodeBody += "\"" + element.Items[TemplateElement.KEY_NAME] + "\","; for (int j = 0; j < element.ChildNodes.Count; j++) { TemplateElement element2 = element.ChildNodes[j]; Type returnType = null; switch (element2.Type) { case TemplateElementTypes.Literal: m_CodeBody += "\""; GenerateLiteralAspxCode(element2); m_CodeBody += "\""; break; case TemplateElementTypes.Variable: GenerateVariableAspxCode(m_CodeBody, element2, out returnType, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(m_CodeBody, element2, out returnType, scopeData); break; case TemplateElementTypes.CodeBlock: GenerateCodeBlockAspxCode(m_CodeBody, element2, scopeData); break; } if (j < element.ChildNodes.Count - 1) m_CodeBody += "+"; } if (i < node.ChildNodes[0].ChildNodes.Count - 1) m_CodeBody += ","; } m_CodeBody += "); %>"; }
private void GenerateLoopExpressionAspxCode(TemplateElement node, ScopeData scopeData) { switch(node.ChildNodes[0].Type) { case TemplateElementTypes.LoopExpressionParam: GenerateLoopExpressionParamAspxCode(node.ChildNodes[0], scopeData); break; case TemplateElementTypes.LoopExpressionParam2: GenerateLoopExpressionParam2AspxCode(node.ChildNodes[0], scopeData); break; } }
private void GenerateIfElseEpxressionAspxCode(TemplateElement expression, ScopeData scopeData) { if (expression.Type == TemplateElementTypes.IfExpression) { m_CodeBody += "<%\r\n if ("; GenerateAspxCode(m_CodeBody, expression.ChildNodes[0], scopeData); m_CodeBody += ") { %>"; GenerateAspxCode(expression, scopeData); m_CodeBody += "<%\r\n } %>"; } else if (expression.Type == TemplateElementTypes.ElseExpression) { m_CodeBody += "<%\r\n } else { %>"; } else if (expression.Type == TemplateElementTypes.ElseIfExpression) { m_CodeBody += "<%\r\n } else if("; GenerateAspxCode(m_CodeBody, expression.ChildNodes[0], scopeData); m_CodeBody += ") { %>"; } }
private void GenerateTagAspxCode(TemplateElement tag, ScopeData scopeData) { string name = ((string)tag.Items[TemplateElement.KEY_NAME]); if (string.Compare(name, "page", true) == 0) return; else if (string.Compare(name, "break", true) == 0) { m_CodeBody += "<% break; %>"; return; } else if (string.Compare(name, "continue", true) == 0) { m_CodeBody += "<% continue; %>"; return; } MethodInfo method = SearchMethodForTag(tag); if (method != null) { string instanceName = DeclaringVariable(method.DeclaringType); m_CodeBody += "<%\r\n" + instanceName + "." + method.Name + "("; int templateIndex = -1; //模板委托类型参数的起始索引 int templateCount = 0; //模板委托类型参数的个数 bool needRemoveDot = false; ParameterInfo[] parameters = method.GetParameters(); #region 将模板标签属性输出为方法参数 for (int i = 0; i < parameters.Length; i++) { if (parameters[i].ParameterType.IsSubclassOf(typeof(Delegate)) == false) { TemplateElement attributeListItem = GetAttributeListItem(parameters[i], tag.ChildNodes[0]); if (attributeListItem != null) { GenerateAttributeListItemAspxCode(parameters[i], attributeListItem, scopeData); } m_CodeBody += ","; needRemoveDot = true; } else { if (templateIndex == -1) templateIndex = i; templateCount++; } } if (needRemoveDot == true) m_CodeBody.InnerBuilder.Remove(m_CodeBody.InnerBuilder.Length - 1, 1); #endregion #region 将模板标签的模板内容输出为匿名委托 for (int i = templateIndex; i - templateIndex < templateCount; i++) { ScopeData scope = new ScopeData(scopeData); if (needRemoveDot == true) { m_CodeBody += ","; } else { needRemoveDot = true; } m_CodeBody += "delegate("; ParameterInfo[] args = parameters[i].ParameterType.GetMethod("Invoke").GetParameters(); for (int j = 0; j < args.Length; j++) { m_CodeBody += ReflectionUtil.GetCSharpTypeName(args[j].ParameterType) + " " + scope.DeclaringScopeVariable(args[j]); if (j < args.Length - 1) m_CodeBody += ","; } m_CodeBody += "){\r\n%>"; if (templateCount == 1) { GenerateAspxCode(tag, scope); } else { for (int j = 1; j < tag.ChildNodes.Count; j++) { TemplateElement element = tag.ChildNodes[j]; if (element.Type == TemplateElementTypes.Tag) { string tagName = (string)element.Items[TemplateElement.KEY_NAME]; if (StringUtil.EqualsIgnoreCase(parameters[i].Name, tagName)) { GenerateAspxCode(element, scope); break; } } } } m_CodeBody += "<%\r\n}"; //for (int j = 0; j < args.Length; j++) //{ // UndeclaringScopeVariable(args[j]); //} } #endregion m_CodeBody += ");%>"; } else { //未能找到合适的注册标签,直接输出 //if (tag.Index != tag.Length) // m_CodeBody += tag.SourceTemplate.Substring(tag.Index, tag.Length); //string name = tag.Items[TemplateElement.KEY_NAME] as string; //if (StringUtil.EqualsIgnoreCase(name, "ajaxpanel")) //{ //} } }
private void GenerateAspxCode(StringBuffer codeBody, TemplateElement element, ScopeData scopeData) { foreach (TemplateElement node in element.ChildNodes) { Type returnType = null; switch (node.Type) { case TemplateElementTypes.Literal: GenerateLiteralAspxCode(codeBody, node); break; case TemplateElementTypes.Variable: GenerateVariableAspxCode(codeBody, node, out returnType, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(codeBody, node, out returnType, scopeData); break; case TemplateElementTypes.CodeBlock: GenerateCodeBlockAspxCode(codeBody, node, scopeData); break; case TemplateElementTypes.DoubleQuteString: GenerateDoubleQuteStringAspxCode(codeBody, node, scopeData); break; case TemplateElementTypes.SingleQuteString: GenerateSingleQuteStringAspxCode(codeBody, node, scopeData); break; } } }
/// <summary> /// 获取对应于指定参数的模板标签属性 /// </summary> /// <param name="parameterInfo">参数信息</param> /// <param name="attributeList">模板标签属性列表</param> /// <returns></returns> private static TemplateElement GetAttributeListItem(ParameterInfo parameterInfo, TemplateElement attributeList) { foreach (TemplateElement attributeListItem in attributeList.ChildNodes) { string name = (string)attributeListItem.Items[TemplateElement.KEY_NAME]; if (StringUtil.EqualsIgnoreCase(name, parameterInfo.Name)) { return attributeListItem; } } return null; }
private TemplateElement CreateDoubleQuteString(Match match) { TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.DoubleQuteString, match.Index + 1, match.Length - 2, null); return(result); }
private void GenerateLoopExpressionParamAspxCode(TemplateElement node, ScopeData scopeData) { if (node.ChildNodes.Count == 2) { if (node.ChildNodes[0].Type == TemplateElementTypes.Variable) { TemplateElement variable = node.ChildNodes[0]; TemplateElement target = node.ChildNodes[1]; StringBuffer codeBody = new StringBuffer(); Type returnType = null; switch (target.Type) { case TemplateElementTypes.Variable: GenerateVariableAspxCode(codeBody, target, out returnType, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(codeBody, target, out returnType, scopeData); break; } if (returnType != null) { Type enumerType = returnType.GetInterface("IEnumerable`1"); if (enumerType == null) enumerType = returnType.GetInterface("IEnumerator`1"); Type varType = null; if (enumerType != null) varType = enumerType.GetGenericArguments()[0]; else { if (returnType == s_TypeOfStringCollection || returnType.IsSubclassOf(s_TypeOfStringCollection)) varType = typeof(string); } if (varType != null) { string varName = variable.Items[TemplateElement.KEY_NAME] as string; string i = node.Items["i"] as string; if (varName != null) { ScopeData scope = new ScopeData(scopeData); string iVarName = null; if(i != null) iVarName = scope.DeclaringScopeVariable(i, typeof(int)); m_CodeBody += "<%\r\nif(" + codeBody + " != null)\r\n{%>"; if (iVarName != null) m_CodeBody += "<%\r\nint " + iVarName + "=0;\r\n%>"; m_CodeBody += "<%\r\nforeach(" + ReflectionUtil.GetCSharpTypeName(varType) + " " + scope.DeclaringScopeVariable(varName, varType) + " in " + codeBody + "){%>"; GenerateAspxCode(node.Parent, scope); m_CodeBody += "<%"; if (iVarName != null) m_CodeBody += "\r\n" + iVarName + "+=1;"; m_CodeBody += "\r\n}\r\n}"; m_CodeBody += "%>"; } } } } } }
public void GenerateAspxCode(string skinID, TemplateFile templateFile, string[] templateImports) { string template = templateFile.GetFullTemplate(skinID); string checkString = ReadCheckString(templateFile); string newCheckString = GetNewCheckString(template); if (checkString != newCheckString) { #region 需要重新解析模板 m_Document = TemplateElement.CreateDocument(template, templateFile); m_CodeHead = new StringBuffer(); m_CodeBody = new StringBuffer(template.Length); GenerateAspxCodeHead1(templateFile); GenerateAspxCode(m_Document, new ScopeData(null)); GenerateAspxCodeHead2(templateFile, templateImports, skinID); string aspxCode = string.Concat("<%--", newCheckString, "--%>\r\n", m_CodeHead.ToString(), m_CodeBody.ToString()); try { using (StreamWriter writer = new StreamWriter(templateFile.ParsedFilePath, false, Encoding.UTF8)) { writer.Write(aspxCode); } } catch (Exception ex) { LogHelper.CreateErrorLog(ex, templateFile.FileName + "写入文件时出错"); } LogHelper.CreateDebugLog(templateFile.FileName + "发生了重新解析,并写入磁盘"); #endregion } TryBuildTempWebConfig(); }
public static TemplateElement CreateDocument(string template, TemplateFile templateFile) { TemplateElement doc = new TemplateElement(template, templateFile); return doc; }
private TemplateElement CreateTag(Match match) { Group param = match.Groups["param"]; string name = match.Groups["name"].Value; bool closed = false; TemplateElementTypes type = TemplateElementTypes.Tag; name = name.ToLower(); switch(name) { case "if": type = TemplateElementTypes.IfExpression; break; case "else": if (SourceTemplate.IndexOf("if ", param.Index, param.Length, StringComparison.OrdinalIgnoreCase) == param.Index) type = TemplateElementTypes.ElseIfExpression; else type = TemplateElementTypes.ElseExpression; break; case "load": type = TemplateElementTypes.LoadExpression; break; //case "pre-include": // type = TemplateElementTypes.PreIncludeExpression; // break; case "loop": type = TemplateElementTypes.LoopExpression; break; case "ajaxpanel": type = TemplateElementTypes.AjaxPanel; break; } closed = match.Groups["close"].Success || type == TemplateElementTypes.ElseExpression || type == TemplateElementTypes.ElseIfExpression || type == TemplateElementTypes.LoadExpression; //|| type == TemplateElementTypes.PreIncludeExpression; Hashtable items = new Hashtable(2); items.Add(KEY_NAME, name); items.Add(KEY_CLOSED, closed); int index = match.Index + match.Length; int contentLength = closed ? match.Length : SourceTemplate.Length - index; if (closed) items.Add("END", index); TemplateElement result = new TemplateElement(this.Document, type, index, contentLength, items); if (type == TemplateElementTypes.IfExpression || type == TemplateElementTypes.ElseIfExpression) result.ChildNodes.Insert(0, CreateConditionExpression(param, type == TemplateElementTypes.ElseIfExpression)); else if (type == TemplateElementTypes.LoopExpression) result.ChildNodes.Insert(0, CreateLoopExpressionParam(param)); else result.ChildNodes.Insert(0, CreateAttributeList(param)); return result; }
private void GenerateFunctionInvokeAspxCode(StringBuffer codeBody, TemplateElement functionInvoke, Type type, out Type returnType, ScopeData scopeData) { returnType = null; string name = functionInvoke.Items[TemplateElement.KEY_NAME] as string; if (name == null) { #region 委托数组的调用 if (type.IsSubclassOf(typeof(Delegate)) == false) { codeBody.InnerBuilder.Append(functionInvoke.SourceTemplate, functionInvoke.Index, functionInvoke.Length); } else { codeBody += "("; GenerateAspxCode(codeBody, functionInvoke.ChildNodes[0], scopeData); codeBody += ")"; if (functionInvoke.ChildNodes.Count > 1) GenerateMemberInvokeAspxCode(codeBody, functionInvoke.ChildNodes[1], type.GetMethod("Invoke").ReturnType, out returnType, scopeData); if(returnType == null) returnType = type.GetMethod("Invoke").ReturnType; } #endregion } else { MethodInfo extensionFunction = SearchExtensionFunction(name, type); if (extensionFunction != null) { #region 扩展函数的调用 StringBuffer sb = new StringBuffer(ReflectionUtil.GetCSharpTypeName(extensionFunction.DeclaringType)); sb += "." + extensionFunction.Name + "("; codeBody.InnerBuilder.Insert(0, sb); codeBody += ",\"" + name + "\""; if (extensionFunction.GetParameters().Length > 2) { codeBody += ","; GenerateAspxCode(codeBody, functionInvoke.ChildNodes[0], scopeData); } codeBody += ")"; if (functionInvoke.ChildNodes.Count > 1) GenerateMemberInvokeAspxCode(codeBody, functionInvoke.ChildNodes[1], extensionFunction.ReturnType, out returnType, scopeData); if(returnType == null) returnType = extensionFunction.ReturnType; #endregion } else { #region 普通函数调用 MethodInfo method = SearchMethod(name, type); if (method != null) { codeBody += "." + method.Name + "("; GenerateAspxCode(codeBody, functionInvoke.ChildNodes[0], scopeData); codeBody += ")"; if (functionInvoke.ChildNodes.Count > 1) GenerateMemberInvokeAspxCode(codeBody, functionInvoke.ChildNodes[1], method.ReturnType, out returnType, scopeData); if(returnType == null) returnType = method.ReturnType; } #endregion } } }
private TemplateElement CreateLoopExpressionParam(Group param) { int index = param.Index; int length = param.Length; TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.LoopExpressionParam, index, length, null); result.Document = this.Document; return result; }
private void GenerateLoopExpressionParam2AspxCode(TemplateElement node, ScopeData scopeData) { if (node.ChildNodes.Count == 2) { TemplateElement from = node.ChildNodes[0]; TemplateElement to = node.ChildNodes[1]; StringBuffer fromCode = new StringBuffer(); Type fromType = null; switch (from.Type) { case TemplateElementTypes.Variable: GenerateVariableAspxCode(fromCode, from, out fromType, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(fromCode, from, out fromType, scopeData); break; case TemplateElementTypes.Literal: string fromValue = from.SourceTemplate.Substring(from.Index, from.Length); int temp = -1; if (int.TryParse(fromValue, out temp)) { fromCode += fromValue; fromType = typeof(int); } break; } StringBuffer toCode = new StringBuffer(); Type toType = null; switch (to.Type) { case TemplateElementTypes.Variable: GenerateVariableAspxCode(toCode, to, out toType, scopeData); break; case TemplateElementTypes.Function: GenerateFunctionAspxCode(toCode, to, out toType, scopeData); break; case TemplateElementTypes.Literal: string toValue = to.SourceTemplate.Substring(to.Index, to.Length); int temp = -1; if (int.TryParse(toValue, out temp)) { toCode += toValue; toType = typeof(int); } break; } if (fromType == typeof(int) && toType == typeof(int)) { string i = node.Items["i"] as string; string step = node.Items["step"] as string; uint temp = 0; if (i != null && (step == null || (uint.TryParse(step, out temp) && temp > 0))) { if (step == null) step = "1"; ScopeData scope = new ScopeData(scopeData); string iVarName = scope.DeclaringScopeVariable(i, typeof(int)); //example: for (int i = a; a > b ? i >= b : i <= b; i += a > b ? -c : c) m_CodeBody += "<%\r\nfor(int " + iVarName + "=" + fromCode + ";" + fromCode + " > " + toCode + " ? " + iVarName + " >= " + toCode + " : " + iVarName + " <= " + toCode + ";" + iVarName + " += " + fromCode + " > " + toCode + " ? -" + step + " : " + step + "){%>"; GenerateAspxCode(node.Parent, scope); m_CodeBody += "<%\r\n}%>"; } } } }
/// <summary> /// 在一组方法中寻找参数和模板标签属性列表一致的方法 /// </summary> /// <param name="methods">方法集合</param> /// <param name="attributeList">模板标签属性列表</param> /// <param name="ignoreDelegate">是否忽略委托类型参数</param> /// <returns></returns> private static MethodInfo SearchMethod(IList<RuntimeMethodHandle> methodHandles, TemplateElement attributeList, bool ignoreDelegate) { foreach (RuntimeMethodHandle methodHandle in methodHandles) { MethodInfo method = (MethodInfo)MethodInfo.GetMethodFromHandle(methodHandle); ParameterInfo[] parameters = method.GetParameters(); if (ignoreDelegate) { List<ParameterInfo> noDelegateParameters = new List<ParameterInfo>(); foreach (ParameterInfo param in parameters) { if (param.ParameterType.IsSubclassOf(typeof(Delegate))) continue; noDelegateParameters.Add(param); } parameters = noDelegateParameters.ToArray(); } if (parameters.Length != attributeList.ChildNodes.Count) continue; if (parameters.Length == 0 && attributeList.ChildNodes.Count == 0) return method; bool foundMethod = true; foreach (ParameterInfo parameter in parameters) { bool foundParam = false; foreach (TemplateElement attributeListItem in attributeList.ChildNodes) { string name = (string)attributeListItem.Items[TemplateElement.KEY_NAME]; if (StringUtil.EqualsIgnoreCase(name, parameter.Name)) { foundParam = true; break; } } if (foundParam == false) { foundMethod = false; break; } } if (foundMethod) return method; } return null; }
public TemplateElement CreateLiteral(int index, int length) { TemplateElement lit = new TemplateElement(this.Document, TemplateElementTypes.Literal, index, length, null); return lit; }
private void GenerateAjaxPanelAspxCode(TemplateElement node, ScopeData scopeData) { TemplateElement attributeList = node.ChildNodes[0]; string autoID = NewAjaxPanelID(); string id = null; string tag = null; string onUpdate = null; string idOnly = "false"; string ajaxOnly = "false"; Hashtable others = new Hashtable(2); foreach (TemplateElement item in attributeList.ChildNodes) { string name = item.Items[TemplateElement.KEY_NAME] as string; name = name.ToLower(); switch (name) { case "id": StringBuffer sb = new StringBuffer(); GenerateDoubleQuteStringAspxCode(sb, item, scopeData); id = sb.ToString(); break; case "tag": tag = item.SourceTemplate.Substring(item.Index, item.Length); break; case "idonly": idOnly = "true"; break; case "ajaxonly": ajaxOnly = "true"; break; case "onupdate": StringBuffer jscode = new StringBuffer(); GenerateAspxCode(jscode, item, scopeData); onUpdate = jscode.ToString(); break; default: StringBuffer code = new StringBuffer(); GenerateAspxCode(code, item, scopeData); others.Add(name, code.ToString()); break; } } if (id == null) id = "\"" + autoID + "\""; if (tag == null) tag = "div"; m_CodeBody += "<" + tag + " id=\"<%=" + id + "%>\""; if (others.Count > 0) { foreach (DictionaryEntry item in others) { m_CodeBody += " " + item.Key + "=\"" + item.Value + "\""; } } m_CodeBody += ">"; m_CodeBody += "<%\r\nusing(MaxLabs.WebEngine.AjaxPanel " + autoID + " = new MaxLabs.WebEngine.AjaxPanel(" + id + ", " + idOnly + ", " + ajaxOnly + ", this.AjaxPanelContext, this.HtmlTextWriter)){%>"; m_CodeBody += "<%\r\nHtmlTextWriter " + autoID + "__w = __w; if(__w.InnerWriter is AjaxPanelWriter == false) __w = " + autoID + ".Writer; %>"; GenerateAspxCode(node, scopeData); m_CodeBody += "<%\r\n__w = " + autoID + "__w; }%>"; m_CodeBody += "</" + tag + ">"; if (onUpdate != null) { m_CodeBody += "<script type=\"text/javascript\">var __<%=" + id + "%>__ = document.getElementById('<%=" + id + "%>'); __<%=" + id + "%>__.onUpdate = function(panel){ " + onUpdate + " }</script>"; } }
private TemplateElement CreateConditionExpression(Group param, bool isElseIf) { int index = param.Index; int length = param.Length; if (isElseIf) { index += 3; length -= 3; } TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.ConditionExpression, index, length, null); result.Document = this.Document; return result; }
private void ParseTemplateTag(int index, int length) { int tagBegin = SourceTemplate.IndexOf(TAG_BEGIN, index, length); if (tagBegin >= 0) { ParseTemplateCode(index, tagBegin - index, true, false); length = length - (tagBegin - index); index = tagBegin; Match match = null; if ((match = TemplateTagBeginRegex.Match(SourceTemplate, index, length)).Success) { TemplateElement tag = CreateTag(match); ChildNodes.Add(tag); //if (tag.Type == TemplateElementTypes.PreIncludeExpression) //{ // if (tag.ChildNodes[0].ChildNodes.Count >= 1) // { // TemplateElement element = tag.ChildNodes[0].ChildNodes[0]; // if (element.ChildNodes[0].Type == TemplateElementTypes.Literal) // { // string path = element.ChildNodes[0].Text; // if (path.StartsWith("/") == false && path.StartsWith("~/") == false) // { // path = this.Document.TemplateFile.Owner.VirtualPath + path; // } // path = HttpContext.Current.Server.MapPath(path); // if (File.Exists(path)) // { // string content = File.ReadAllText(path); // TemplateElement doc = CreateDocument(content, null); // tag.ChildNodes.Add(doc); // this.Document.TemplateFile.AddWatcher(path); // } // } // } //} if (tag.Items.Contains("END") == false) { throw new TemplateTagNotCloseException(tag.Items["name"].ToString(), TemplateFile.FilePath, SourceTemplate, index); } int tagEndIndex = (int)tag.Items["END"]; if (tagEndIndex > 0) { int leavingLength = SourceTemplate.Length - tagEndIndex; if (leavingLength > 0) { ParseTemplateTag(tagEndIndex, leavingLength); } } } else if ((match = TemplateTagEndRegex.Match(SourceTemplate, index, length)).Success) { if ((Type == TemplateElementTypes.Tag || Type == TemplateElementTypes.IfExpression || Type == TemplateElementTypes.LoopExpression || Type == TemplateElementTypes.AjaxPanel) && StringUtil.EqualsIgnoreCase(match.Groups["name"].Value, (string)Items[KEY_NAME])) { Length = match.Index - Index; Items["END"] = match.Index + match.Length; } else { ChildNodes.Add(CreateLiteral(match.Index, match.Length)); int tagEnd = match.Index + match.Length; ParseTemplateTag(tagEnd, length - (tagEnd - index)); } } else { ChildNodes.Add(CreateLiteral(tagBegin, TAG_BEGIN.Length)); ParseTemplateTag(tagBegin + TAG_BEGIN.Length, length - TAG_BEGIN.Length); } } else { ParseTemplateCode(index, length, true, false); } }
private TemplateElement CreateCodeBlock(Match match) { Group content = match.Groups["content"]; TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.CodeBlock, content.Index, content.Length, null); result.Items.Add(KEY_OUTPUT, match.Groups["out"].Success); result.Document = this.Document; return result; }
private void ParseTemplateCode(int index, int length, bool output, bool processString) { if (length == 0) { return; } string b = string.Empty; string blkBegin = OUT_BEGIN; // output ? OUT_BEGIN : BLK_BEGIN; string[] beginTokens = null; if (processString) { beginTokens = new string[] { blkBegin, SNP_BEGIN, STR_BEGIN, CHR_BEGIN } } ; else { beginTokens = new string[] { blkBegin, SNP_BEGIN } }; int begin = StringUtil.FirstIndexOf(SourceTemplate, index, length, out b, beginTokens); if (begin >= 0) { if (begin - index > 0) { ChildNodes.Add(CreateLiteral(index, begin - index)); } length = length - (begin - index); index = begin; Match match = null; TemplateElement node = null; switch (b) { case STR_BEGIN: if ((match = TemplateDoubleQuteStringRegex.Match(SourceTemplate, index, length)).Success) { node = CreateDoubleQuteString(match); } break; case CHR_BEGIN: if ((match = TemplateSingleQuteStringRegex.Match(SourceTemplate, index, length)).Success) { node = CreateSingleQuteString(match); } break; case SNP_BEGIN: if ((match = TemplateCodeSnippetRegex.Match(SourceTemplate, index, length)).Success) { node = CreateCodeSnippet(match); } break; default: if ((match = TemplateCodeBlockRegex.Match(SourceTemplate, index, length)).Success) { node = CreateCodeBlock(match); } break; } if (node != null) { ChildNodes.Add(node); int endIndex = match.Index + match.Length; int leavingLength = length - (endIndex - index); if (leavingLength > 0) { ParseTemplateCode(endIndex, leavingLength, output, processString); } } else { ChildNodes.Add(CreateLiteral(index, b.Length)); ParseTemplateCode(index + 1, length - 1, output, processString); } } else { ChildNodes.Add(CreateLiteral(index, length)); } }
private TemplateElement CreateMemberInvokeListItem(Match match) { Group memberInvoke = match.Groups["invoke"]; Group funcParam = match.Groups["func_param"]; Group indexParam = match.Groups["index_param"]; TemplateElement result = null; if (funcParam.Success) { result = new TemplateElement(this.Document, TemplateElementTypes.FunctionInvoke, match.Index, match.Length, null); TemplateElement funcParamNode = new TemplateElement(this.Document, TemplateElementTypes.FunctionInvokeParam, funcParam.Index, funcParam.Length, null); result.ChildNodes.Add(funcParamNode); } else if (indexParam.Success) { result = new TemplateElement(this.Document, TemplateElementTypes.IndexInvoke, match.Index, match.Length, null); TemplateElement indexParamNode = new TemplateElement(this.Document, TemplateElementTypes.IndexInvokeParam, indexParam.Index, indexParam.Length, null); result.ChildNodes.Add(indexParamNode); } else { result = new TemplateElement(this.Document, TemplateElementTypes.PropertyInvoke, match.Index, match.Length, null); } result.Items[KEY_NAME] = match.Groups["name"].Value; if (memberInvoke.Success && memberInvoke.Length > 0) result.ParseMemberInvoke(memberInvoke.Index, memberInvoke.Length); return result; }
public static TemplateElement CreateDocument(string template, TemplateFile templateFile) { TemplateElement doc = new TemplateElement(template, templateFile); return(doc); }
private TemplateElement CreateAttributeListItem(int index, Match match) { Group name = match.Groups["name"]; Group value = match.Groups["value"]; TemplateElement result = new TemplateElement(this.Document, TemplateElementTypes.AttributeListItem, value.Index, value.Length, null); result.Items[KEY_NAME] = name.Value; return result; }
public TemplateElement CreateLiteral(int index, int length) { TemplateElement lit = new TemplateElement(this.Document, TemplateElementTypes.Literal, index, length, null); return(lit); }
private TemplateElement CreateTag(Match match) { Group param = match.Groups["param"]; string name = match.Groups["name"].Value; bool closed = false; TemplateElementTypes type = TemplateElementTypes.Tag; name = name.ToLower(); switch (name) { case "if": type = TemplateElementTypes.IfExpression; break; case "else": if (SourceTemplate.IndexOf("if ", param.Index, param.Length, StringComparison.OrdinalIgnoreCase) == param.Index) { type = TemplateElementTypes.ElseIfExpression; } else { type = TemplateElementTypes.ElseExpression; } break; case "load": type = TemplateElementTypes.LoadExpression; break; //case "pre-include": // type = TemplateElementTypes.PreIncludeExpression; // break; case "loop": type = TemplateElementTypes.LoopExpression; break; case "ajaxpanel": type = TemplateElementTypes.AjaxPanel; break; } closed = match.Groups["close"].Success || type == TemplateElementTypes.ElseExpression || type == TemplateElementTypes.ElseIfExpression || type == TemplateElementTypes.LoadExpression; //|| type == TemplateElementTypes.PreIncludeExpression; Hashtable items = new Hashtable(2); items.Add(KEY_NAME, name); items.Add(KEY_CLOSED, closed); int index = match.Index + match.Length; int contentLength = closed ? match.Length : SourceTemplate.Length - index; if (closed) { items.Add("END", index); } TemplateElement result = new TemplateElement(this.Document, type, index, contentLength, items); if (type == TemplateElementTypes.IfExpression || type == TemplateElementTypes.ElseIfExpression) { result.ChildNodes.Insert(0, CreateConditionExpression(param, type == TemplateElementTypes.ElseIfExpression)); } else if (type == TemplateElementTypes.LoopExpression) { result.ChildNodes.Insert(0, CreateLoopExpressionParam(param)); } else { result.ChildNodes.Insert(0, CreateAttributeList(param)); } return(result); }
private void GenerateIndexInvokeAspxCode(StringBuffer codeBody, TemplateElement indexInvoke, Type type, out Type returnType, ScopeData scopeData) { returnType = null; Type indexType = null; string name = indexInvoke.Items[TemplateElement.KEY_NAME] as string; if (type.IsArray) { indexType = type.GetElementType(); } else { PropertyInfo property = type.GetProperty("Item", BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy); if (property != null) indexType = property.PropertyType; } if (indexType != null) { codeBody += "["; GenerateAspxCode(codeBody, indexInvoke.ChildNodes[0], scopeData); codeBody += "]"; if (indexInvoke.ChildNodes.Count > 1) GenerateMemberInvokeAspxCode(codeBody, indexInvoke.ChildNodes[1], indexType, out returnType, scopeData); if (returnType == null) returnType = indexType; } }