Item CreateNewItem(string itemString) { var parsedComment = new ParsedComment(itemString); if (parsedComment.Name.EndsWith("Item") || parsedComment.Name.EndsWith("Items")) { var name = $"AideDeJeuLib.{parsedComment.Name}, AideDeJeu"; var type = Type.GetType(name); if (type != null) { var item = Activator.CreateInstance(type) as Item; foreach (var attribute in parsedComment.Attributes) { var prop = item.GetType().GetProperty(attribute.Key, BindingFlags.Public | BindingFlags.Instance); if (prop?.CanWrite == true) { prop.SetValue(item, prop.GetValue(item) + attribute.Value, null); } else { item.SetAttribute(attribute.Key, attribute.Value); //item.Attributes[attribute.Key] = attribute.Value; } } return(item); } } return(null); }
/// <summary> /// Generates a doxygen comment block for the given code element. /// </summary> /// <param name="spaces">Indentation for the whole comment block</param> /// <param name="codeElement">The code element.</param> /// <param name="existingComment">Existing comment for the code element. Empty if not found.</param> /// <returns>Generated doxygen comment block</returns> public string GenerateComment(string spaces, CodeElement codeElement, string existingComment) { ThreadHelper.ThrowIfNotOnUIThread(); // Parse existing comment. ParsedComment parsedComment = ParseComment(existingComment); // Start writing a new one. StringBuilder sb = new StringBuilder(m_config.FirstLineString); // Write brief summary. WriteBriefComment(sb, spaces, codeElement, parsedComment); if (codeElement != null) { // Write comments for template parameters, if any. WriteTemplateParamComments(sb, spaces, codeElement, parsedComment); // Write comments for function parameters and return value. if (codeElement is CodeFunction) { CodeFunction function = codeElement as CodeFunction; WriteParamComments(sb, spaces, function, parsedComment); WriteReturnComment(sb, spaces, function, parsedComment); } } // Write other sections that were in the existing comments. foreach (ParsedSection section in parsedComment.TagSections) { string tagLine = GenerateTagString(section.TagName); sb.Append("\r\n" + spaces + " *"); sb.Append("\r\n" + spaces + " * " + tagLine); AppendComments(sb, section.Comments, spaces, tagLine.Length); } sb.Append("\r\n" + spaces + " */"); if (UseSingleLineComment(codeElement)) { sb.Replace("\r\n", ""); } return(sb.ToString()); }
bool CheckNewItem(string itemString) { var parsedComment = new ParsedComment(itemString); if (parsedComment.Type == ParsedCommentType.Item) { var name = $"AideDeJeuLib.{parsedComment.Name}, AideDeJeu"; var type = Type.GetType(name); if (type != null) { return(true); } } else if (parsedComment.Type == ParsedCommentType.Property) { Debug.WriteLine(parsedComment.Name); } return(false); }
/// <summary> /// Parse the next element /// </summary> public ParsedToken Parse() { CharInfo c; // If end of stream when stop here if (EOF) { return(null); } // Current token defined if (_CurrentToken != null) { // End tag out Doctype : error while end tag or doctype parsing, reset parser if (_CurrentToken.TokenType == ParsedTokenType.EndTag || _CurrentToken.TokenType == ParsedTokenType.Doctype) { _CurrentRead = null; _State = ParseState.Content; ResetTagBuffer(); LastParsed = _CurrentToken; _CurrentToken = null; return(LastParsed); } } // Current Attribute defined if (_CurrentAttr != null) { LastParsed = _CurrentAttr; _CurrentAttr = null; return(LastParsed); } // Current Read not empty ? if (_CurrentRead != null) { bool returnLast = true; switch (_State) { // Returns a non closed comment case ParseState.Comment: String comment = GetCurrentRead(true); comment = comment.Substring(4).TrimStart(); LastParsed = new ParsedComment() { Position = _CurrentPosition, Text = HEntity.HtmlDecode(comment, RemoveUnknownOrInvalidEntities) }; break; // Returns a text case ParseState.Content: LastParsed = new ParsedText() { Position = _CurrentPosition, Text = HEntity.HtmlDecode(GetCurrentRead(true), RemoveUnknownOrInvalidEntities) }; break; // Returns a text case ParseState.Doctype: case ParseState.ProcessInstruction: case ParseState.EndTag: case ParseState.Tag: //LastParsed = new ParsedText() { // Position = _CurrentPosition, // Text = GetCurrentRead(true) //}; _State = ParseState.Content; LastParsed = ParseText(); break; // We forget the result //default: // returnLast = false; // break; } _State = ParseState.Content; ResetTagBuffer(); if (returnLast) { return(LastParsed); } } // Read loop while (true) { // Read next char c = ReadChar(); // EOF ? if (c == CharInfo.EOF) { // Check unexpected EOF if (_State != ParseState.Content) { _State = ParseState.Content; ResetTagBuffer(); throw new ParseError("End of file unexpected.", ReadPosition); } // Stop the parsing LastParsed = null; EOF = true; return(null); } // Other case switch (_State) { // In text case ParseState.Content: if (c == '<') { LastParsed = ParseStartTag(); } else { LastParsed = ParseText(); } return(LastParsed); // In tag or process instruction case ParseState.Tag: case ParseState.Doctype: case ParseState.ProcessInstruction: SaveChar(c); LastParsed = ParseInTag(); return(LastParsed); default: break; } } }
public Item ParseItem(string source, ref ContainerBlock.Enumerator enumerator, Dictionary <string, Item> allItems) { var currentItem = GetNewItem(enumerator.Current); Debug.Assert(currentItem != null, $"Item invalide : {source} {enumerator.Current.ToMarkdownString()}"); var currentProps = new Dictionary <string, PropertyInfo>(); currentItem.Markdown = string.Empty; currentProps["Markdown"] = currentItem.GetType().GetProperty("Markdown", BindingFlags.Public | BindingFlags.Instance); if (currentItem != null) { enumerator.MoveNext(); while (enumerator.Current != null) { var block = enumerator.Current; if (block is HtmlBlock) { var htmlBlock = block as HtmlBlock; if (htmlBlock.Type == HtmlBlockType.Comment) { var tag = htmlBlock.Lines.Lines.FirstOrDefault().Slice.ToString(); var parsedComment = new ParsedComment(tag, withSigns: true); if (parsedComment.Type == ParsedCommentType.Item) { if (parsedComment.IsClosing) { currentItem.Id = GetNewAnchorId(source, currentItem.Name, allItems); if (currentItem.Id != null && allItems != null) { allItems[currentItem.Id] = currentItem; } return(currentItem); } else { var subItem = ParseItem(source, ref enumerator, allItems); subItem.ParentLink = GetNewAnchorId(source, currentItem.Name, allItems); subItem.ParentName = currentItem.Name; subItem.Markdown = $"> {subItem.ParentNameLink}\n\n---\n\n{subItem.Markdown}"; var propertyName = subItem.GetType().Name; if (currentItem.GetType().GetProperty(propertyName) != null) { PropertyInfo prop = currentItem.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); if (null != prop && prop.CanWrite) { prop.SetValue(currentItem, subItem, null); } } else { if (allItems != null && currentItem.GetNewFilterViewModel() == null) { var name = subItem.Name; var level = Math.Max(1, Math.Min(6, subItem.NameLevel)); var link = (subItem is LinkItem ? (subItem as LinkItem).Link : subItem.Id); currentItem.Markdown += $"\n\n{new String('#', level)} [{name}]({link})"; if (!string.IsNullOrEmpty(subItem.AltNameText)) { var altname = subItem.AltNameText; var altlevel = Math.Max(1, Math.Min(6, subItem.NameLevel + 3)); currentItem.Markdown += $"\n\n{new String('#', altlevel)} _[{altname}]({link})_"; } currentItem.Markdown += "\n\n"; currentItem.AddChild(subItem); } else { currentItem.AddChild(subItem); } } enumerator.MoveNext(); } } else if (parsedComment.Type == ParsedCommentType.Property) { if (!parsedComment.IsClosing) { PropertyInfo prop = currentItem.GetType().GetProperty(parsedComment.Name, BindingFlags.Public | BindingFlags.Instance); if (null != prop && prop.CanWrite) { prop.SetValue(currentItem, string.Empty, null); currentProps[parsedComment.Name] = prop; } enumerator.MoveNext(); } else { currentProps.Remove(parsedComment.Name); enumerator.MoveNext(); } } else // comment html différent de item et property { AddBlockContent(currentItem, currentProps, enumerator.Current); enumerator.MoveNext(); } } else // autre chose qu'un comment html { AddBlockContent(currentItem, currentProps, enumerator.Current); enumerator.MoveNext(); } } else // autre chose qu'un block html { ParseItemProperties(source, currentItem, block); AddBlockContent(currentItem, currentProps, enumerator.Current); enumerator.MoveNext(); } } currentItem.Id = GetNewAnchorId(source, currentItem.Name, allItems); if (allItems != null) { allItems[currentItem.Id] = currentItem; } } return(currentItem); }
public void ParseItemProperties(string source, Item item, ContainerInline inlines, HeadingBlock headingBlock = null) { if (inlines == null) { return; } var properties = new HashSet <string>(); //PropertyInfo prop = null; //string propertyName = null; //var ilist = inlines.ToList(); foreach (var inline in inlines.ToList()) { if (inline is ContainerInline) { var containerInline = inline as ContainerInline; ParseItemProperties(source, item, containerInline, headingBlock); } if (inline is HtmlInline) { var tag = (inline as HtmlInline).Tag; //Debug.WriteLine(tag); //if(tag.EndsWith("Key-->")) //{ // Debug.WriteLine("break"); //} if (tag.StartsWith("<!--")) { var parsedComment = new ParsedComment(tag, true); if (parsedComment.Type == ParsedCommentType.Property) { //if(parsedComment.Name.EndsWith("Value")) //{ // Debug.WriteLine("break"); //} if (!parsedComment.IsClosing) { properties.Add(parsedComment.Name); //propertyName = parsedComment.Name; if (parsedComment.Name == "Name") { if (headingBlock != null) { item.NameLevel = headingBlock.Level; } } //prop = item.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance); } else { properties.Remove(parsedComment.Name); //prop = null; //propertyName = null; } } } } else { foreach (var prop in properties) { item.SetAttribute(prop, inline.ToMarkdownString()); } //if (null != prop && prop.CanWrite) //{ // prop.SetValue(item, prop.GetValue(item) + inline.ToMarkdownString(), null); //} //else if(propertyName != null) //{ // Debug.WriteLine(propertyName); // if (item.Attributes.ContainsKey(propertyName)) // { // item.Attributes[propertyName] += inline.ToMarkdownString(); // } // else // { // item.Attributes[propertyName] = inline.ToMarkdownString(); // } //} } } }
/// <summary> /// Parses the given Doxygen comment. /// </summary> /// <param name="comment">The comment to parse.</param> /// <returns>Parsed comment structure.</returns> private ParsedComment ParseComment(string comment) { ParsedComment parsedComment = new ParsedComment(); if (comment.Length > 0) { string[] lines = comment.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); // Trim leading and trailing whitespace before any parsing. for (int i = 0; i < lines.Length; ++i) { lines[i] = lines[i].Trim(); } for (int i = 0; i < lines.Length; ++i) { // Skip empty lines and comment start/end lines. string line = lines[i]; if (line.Length == 0 || line == "*" || line == "/*!" || line == "*/") { continue; } // Check if this is a template parameter line. Match tparamMatch = m_regexTParam.Match(line); if (tparamMatch.Success) { string name = tparamMatch.Groups[1].Value; string firstComment = tparamMatch.Groups[2].Value; if (!parsedComment.TemplateParameters.ContainsKey(name) && firstComment.Length > 0) { ParsedParam param = new ParsedParam(); param.Name = name; param.Comments.Add(firstComment); i = ParseExtraComments(lines, i + 1, param.Comments); parsedComment.TemplateParameters.Add(param.Name, param); } } else { // Check if this is a parameter line. Match paramMatch = m_regexParam.Match(line); if (paramMatch.Success) { string name = paramMatch.Groups[2].Value; string firstComment = paramMatch.Groups[3].Value; if (!parsedComment.Parameters.ContainsKey(name) && firstComment.Length > 0) { ParsedParam param = new ParsedParam(); param.Name = name; param.Direction = ToDirection(paramMatch.Groups[1].Value); param.Comments.Add(firstComment); i = ParseExtraComments(lines, i + 1, param.Comments); parsedComment.Parameters.Add(param.Name, param); } } else { // Otherwise check if it is some other tag. Match sectionMatch = m_regexTagSection.Match(line); if (sectionMatch.Success) { string tagName = sectionMatch.Groups[1].Value; string firstComment = sectionMatch.Groups[2].Value; if (firstComment.Length > 0) { ParsedSection section = new ParsedSection(); section.TagName = tagName; section.Comments.Add(firstComment); i = ParseExtraComments(lines, i + 1, section.Comments); if (section.TagName == "return" || section.TagName == "returns") { parsedComment.Returns = section; } else { parsedComment.TagSections.Add(section); } } } else { // If the line doesn't contain any tag, we try to extract text out of it. Match textMatch = m_regexText.Match(line); if (textMatch.Success) { parsedComment.BriefComments.Add(textMatch.Groups[1].Value); } } } } } } return(parsedComment); }
/// <summary> /// Writes a comment for the function return value. /// </summary> /// <param name="sb">String builder.</param> /// <param name="spaces">Indentation spaces.</param> /// <param name="function">Code function.</param> /// <param name="parsedComment">Parsed existing comment, if found.</param> private void WriteReturnComment(StringBuilder sb, string spaces, CodeFunction function, ParsedComment parsedComment) { ThreadHelper.ThrowIfNotOnUIThread(); if (function.Type.AsString != "void") { sb.Append("\r\n" + spaces + " *"); string tagLine = m_indentString + Config.TagChar + "return "; sb.Append("\r\n" + spaces + " * " + tagLine); if (parsedComment.Returns != null) { AppendComments(sb, parsedComment.Returns.Comments, spaces, tagLine.Length); } else if (Config.SmartComments) { sb.Append(TryGenerateReturnDesc(function)); } } }
/// <summary> /// Writes comments for function parameters. /// </summary> /// <param name="sb">String builder to write comments into.</param> /// <param name="spaces">Indentation spaces.</param> /// <param name="codeElement">Function code element.</param> /// <param name="parsedComment">Parsed existing comment, if any.</param> private void WriteParamComments(StringBuilder sb, string spaces, CodeFunction function, ParsedComment parsedComment) { ThreadHelper.ThrowIfNotOnUIThread(); int maxTypeDirectionLength = 0; int maxParamNameLength = 0; foreach (CodeElement child in function.Children) { CodeParameter param = child as CodeParameter; if (param != null) { // Check if the existing comment contained this parameter. ParsedParam parsedParam = null; if (parsedComment.Parameters.ContainsKey(param.Name)) { parsedParam = parsedComment.Parameters[param.Name]; } string typeDirName = DirectionToString(GetParamDirection(function, param, parsedParam)); maxTypeDirectionLength = Math.Max(maxTypeDirectionLength, typeDirName.Length); maxParamNameLength = Math.Max(maxParamNameLength, param.Name.Length); } } // Create doxygen lines for each parameter. if (function.Children.Count > 0) { sb.Append("\r\n" + spaces + " *"); foreach (CodeElement child in function.Children) { CodeParameter param = child as CodeParameter; if (param != null) { // Check if the existing comment contained this parameter. ParsedParam parsedParam = null; if (parsedComment.Parameters.ContainsKey(param.Name)) { parsedParam = parsedComment.Parameters[param.Name]; } // Determine type of parameter (in, out or inout). string typeDirName = DirectionToString(GetParamDirection(function, param, parsedParam)); string paramAlignSpaces = new string(' ', maxParamNameLength - param.Name.Length + 1); string typeAlignSpaces = new string(' ', maxTypeDirectionLength - typeDirName.Length + 1); string tagLine = m_indentString + Config.TagChar + "param " + typeDirName + typeAlignSpaces + param.Name + paramAlignSpaces; sb.Append("\r\n" + spaces + " * " + tagLine); // Add existing comments. if (parsedParam != null) { AppendComments(sb, parsedParam.Comments, spaces, tagLine.Length); } else if (Config.SmartComments && function.Children.Count == 1) { sb.Append(TryGenerateParamDesc(function, param)); } } } } }
/// <summary> /// Writes comments for function parameters. /// </summary> /// <param name="sb">String builder to write comments into.</param> /// <param name="spaces">Indentation spaces.</param> /// <param name="codeElement">Function code element.</param> /// <param name="parsedComment">Parsed existing comment, if any.</param> private void WriteTemplateParamComments(StringBuilder sb, string spaces, CodeElement codeElement, ParsedComment parsedComment) { ThreadHelper.ThrowIfNotOnUIThread(); // Parse template parameters from the full function name. string[] tparams = ParseTemplateParams(codeElement.FullName); if (tparams.Length == 0) { return; } // Calculate maximum template parameter name length. int maxParamNameLength = 0; foreach (string tparamName in tparams) { maxParamNameLength = Math.Max(maxParamNameLength, tparamName.Length); } // Create doxygen lines for each parameter. sb.Append("\r\n" + spaces + " *"); foreach (string tparamName in tparams) { // Check if the existing comment contained this parameter. ParsedParam parsedParam = null; if (parsedComment.TemplateParameters.ContainsKey(tparamName)) { parsedParam = parsedComment.TemplateParameters[tparamName]; } string paramAlignSpaces = new string(' ', maxParamNameLength - tparamName.Length + 1); string tagLine = m_indentString + Config.TagChar + "tparam " + tparamName + paramAlignSpaces; sb.Append("\r\n" + spaces + " * " + tagLine); // Add existing comments. if (parsedParam != null) { AppendComments(sb, parsedParam.Comments, spaces, tagLine.Length); } // TODO: Any smart comments possible? } }
/// <summary> /// Writes a brieft comment about the code element. /// </summary> /// <param name="sb">String builder</param> /// <param name="spaces">Indentation spaces.</param> /// <param name="codeElement">Code element.</param> /// /// <param name="parsedComment">Parsed existing comment, if found.</param> private void WriteBriefComment(StringBuilder sb, string spaces, CodeElement codeElement, ParsedComment parsedComment) { ThreadHelper.ThrowIfNotOnUIThread(); // Write main comment from existing comments, if found. if (parsedComment.BriefComments.Count > 0) { foreach (string line in parsedComment.BriefComments) { sb.Append("\r\n" + spaces + " * " + line); } } else { // Write placeholder for main comment. sb.Append("\r\n" + spaces + " * "); // Try to determine initial main comment if comment auto-generation is enabled. if (Config.SmartComments) { sb.Append(TryGenerateBriefDesc(codeElement)); } } }
/// <summary> /// Writes a brieft comment about the code element. /// </summary> /// <param name="sb">String builder</param> /// <param name="spaces">Indentation spaces.</param> /// <param name="codeElement">Code element.</param> /// /// <param name="parsedComment">Parsed existing comment, if found.</param> private void WriteBriefComment(StringBuilder sb, string spaces, CodeElement codeElement, ParsedComment parsedComment) { ThreadHelper.ThrowIfNotOnUIThread(); if (m_config.UseBriefTag) { string tagLine = string.Empty; if (!UseSingleLineComment(codeElement)) { tagLine = GenerateTagString("brief"); sb.Append("\r\n" + spaces + " * " + tagLine); } else if (m_config.UseSingleLineBrief) { tagLine = GenerateTagString("brief"); sb.Append(" " + tagLine); } if (parsedComment.BriefComments.Count > 0) { AppendComments(sb, parsedComment.BriefComments, spaces, tagLine.Length); } else { if (m_config.SmartComments) { sb.Append(TryGenerateBriefDesc(codeElement)); } } } else { // Write main comment from existing comments, if found. if (parsedComment.BriefComments.Count > 0) { foreach (string line in parsedComment.BriefComments) { sb.Append("\r\n" + spaces + " * " + line); } } else { // Write placeholder for main comment. sb.Append("\r\n" + spaces + " * "); // Try to determine initial main comment if comment auto-generation is enabled. if (m_config.SmartComments) { sb.Append(TryGenerateBriefDesc(codeElement)); } } } }