public static void ParseSymbols(string[] tokens, ref int index, SymbolDecl parent, Access access = Access.Public) { if (parent.Children == null) { parent.Children = new List<SymbolDecl>(); } while (true) { int oldIndex = index; var decls = ParseSymbol(tokens, ref index); if (decls != null) { foreach (var decl in decls) { decl.Access = access; } parent.Children.AddRange(decls); } else if (index == oldIndex) { break; } } }
static IEnumerable<SymbolDecl> ExpandChildren(SymbolDecl decl) { yield return decl; if (decl.Children != null) { foreach (var child in decl.Children.SelectMany(ExpandChildren)) { yield return child; } } }
public override void BuildSymbolTree(SymbolDecl parent, string tag) { foreach (var decl in ((FunctionTypeDecl)this.Type).Parameters) { if (decl.Name != "") { if (this.Children == null) { this.Children = new List<SymbolDecl>(); } this.Children.Add(decl); } } base.BuildSymbolTree(parent, tag); }
public virtual void BuildSymbolTree(SymbolDecl parent, string tag) { this.Parent = parent; if (tag != null) { this.Tags = tag; } if (this.NameKey == null) { this.NameKey = GenerateNameKey(); } if (this.OverloadKey == null) { this.OverloadKey = GenerateOverloadKey(); } this.ContentKey = (this.Document == null ? "" : this.Document) + GenerateContentKey(); if (this.Children != null) { foreach (var decl in this.Children) { decl.BuildSymbolTree(this, tag); } } }
private void Serialize(SymbolDecl decl, bool serializeChildren = true) { this.Element.Add(new XAttribute("Access", decl.Access.ToString())); if (decl.Name != null) { this.Element.Add(new XAttribute("Name", decl.Name)); } if (decl.Document != null) { this.Element.Add(new XElement("Document", decl.Document)); } if (decl.Tags != null) { this.Element.Add(new XAttribute("Tags", decl.Tags)); } if (decl.NameKey != null) { this.Element.Add(new XAttribute("NameKey", decl.NameKey)); } if (decl.OverloadKey != null) { this.Element.Add(new XAttribute("OverloadKey", decl.OverloadKey)); } if (serializeChildren && decl.Children != null) { this.Element.Add(new XElement("Children", decl.Children.Select(x => x.Serialize()))); } }
internal static List <SymbolDecl> FindSymbolInContent(ResolveEnvironment environment, SymbolDecl symbol, TypeDecl decl, string name, Dictionary <string, List <SymbolDecl> > content, bool typeAndNamespaceOnly, bool addError) { if (content == null) { return(null); } List <SymbolDecl> decls = null; if (content.TryGetValue(name, out decls)) { if (typeAndNamespaceOnly) { decls = decls .Where(x => !(x is FuncDecl) && !(x is VarDecl) && !(x is EnumDecl)) .ToList(); if (decls.Count == 0) { return(null); } } var nameKeys = decls.Select(x => x.NameKey).Distinct().ToList(); var overloadKeys = decls.Select(x => x.OverloadKey).Distinct().ToList(); if (overloadKeys.Count > 0) { decl.ReferencingOverloadKeys = overloadKeys; } if (nameKeys.Count > 1) { if (addError) { var printingKeys = overloadKeys.Aggregate("", (a, b) => a + "\r\n" + b); environment.AddError(false, "Found multiple symbols for {0} in {1}: " + printingKeys, name, symbol); } return(null); } decl.ReferencingNameKey = nameKeys[0]; return(decls); } return(null); }
private void FillNamespaceReferences(SymbolDecl decl) { var ns = decl as NamespaceDecl; if (ns != null) { this.Namespaces.Add(ns); if (decl.Children != null) { foreach (var child in decl.Children) { FillNamespaceReferences(child); } } } }
static void TestSymbolDeclSerialization(SymbolDecl decl) { var xml = decl.Serialize(); var newDecl = SymbolDecl.Deserialize(xml); Assert.AreEqual(decl.ToString(), newDecl.ToString()); if (decl.Children != null) { foreach (var child in decl.Children) { TestSymbolDeclSerialization(child); } } }
public void AddError(bool error, string messageFormat, string name, SymbolDecl symbol) { var template = symbol as TemplateDecl; if (template != null) { symbol = template.Element; } this.Errors.Add((error ? "(Error) " : "(Warning) ") + string.Format(messageFormat, name, symbol.OverloadKey)); }
public void Resolve(SymbolDecl symbol, ResolveEnvironment environment, bool supressError = false) { if (this.ReferencingNameKey == null) { var visitor = new ResolveTypeDeclVisitor() { Symbol = symbol, Environment = environment, SupressError = supressError, }; Accept(visitor); } }
private XElement ResolveCommentSymbol(SymbolDecl decl, string name) { var type = name .Split(new[] { "::" }, StringSplitOptions.RemoveEmptyEntries) .Aggregate<string, TypeDecl>(null, (a, b) => { return a == null ? (TypeDecl)new RefTypeDecl { Name = b } : (TypeDecl)new SubTypeDecl { Parent = a, Name = b } ; }) ; type.Resolve(decl, this.Environment, true); if (type.ReferencingOverloadKeys == null) { this.Environment.AddXmlError("Failed to resolve symbol \"" + name + "\" in XML comment for {0}.", null, decl); return null; } else { return new XElement("links", type.ReferencingOverloadKeys .Select(x => new XElement("link", new XAttribute("cref", x))) ); } }
private IEnumerable<XNode> ResolveCommentText(SymbolDecl decl, string text) { var matches = regexSymbol.Matches(text).Cast<Match>().ToArray(); var linkXmls = new List<XElement>(); foreach (var match in matches) { var type = match.Groups["type"].Value; var symbol = match.Groups["symbol"].Value; var symbolName = symbol .Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries) .Select(x => { int index = x.IndexOf('`'); return index == -1 ? x : x.Substring(0, index); }) .Aggregate((a, b) => a + "::" + b) ; var links = ResolveCommentSymbol(decl, symbolName); linkXmls.Add(links); } int lastIndex = 0; for (int i = 0; i < matches.Length; i++) { var match = matches[i]; if (match.Index != lastIndex) { yield return new XText(text.Substring(lastIndex, match.Index - lastIndex)); lastIndex = match.Index + match.Length; } if (linkXmls[i] == null) { yield return new XText(match.Value); } else { yield return linkXmls[i]; } } if (text.Length != lastIndex) { yield return new XText(text.Substring(lastIndex, text.Length - lastIndex)); } }
private IEnumerable<XNode> ResolveCommentNode(SymbolDecl decl, XNode node) { var text = node as XText; var cdata = node as XCData; var element = node as XElement; if (text != null) { var replacement = ResolveCommentText(decl, text.Value).ToArray(); return replacement; } if (cdata != null) { var replacement = ResolveCommentText(decl, cdata.Value).ToArray(); return replacement; } if (element != null) { if (element.Name == "see") { var att = element.Attribute("cref"); var replacement = ResolveCommentSymbol(decl, att.Value); return new XNode[] { replacement == null ? element : replacement }; } else { foreach (var child in element.Nodes().ToArray()) { ResolveCommentNode(decl, child); } var replacement = element.Nodes() .SelectMany(x => ResolveCommentNode(decl, x)) .ToArray(); element.ReplaceNodes(replacement); return new XNode[] { element }; } } else { return new XNode[] { node }; } }
public void ResolveComment(SymbolDecl decl) { if (decl.Document != null) { try { var xml = XElement.Parse("<Document>" + decl.Document + "</Document>", LoadOptions.PreserveWhitespace); var template = decl as TemplateDecl; var symbol = decl; if (template == null) { template = decl.Parent as TemplateDecl; } else { symbol = template.Element; } var typeparamXmls = xml.Elements("typeparam").ToArray(); var expectedTypeparamNames = template == null ? new string[0] : template.TypeParameters.Select(x => x.Name).ToArray(); var actualTypeparamNames = typeparamXmls.Select(x => x.Attribute("name").Value).ToArray(); if (!expectedTypeparamNames.SequenceEqual(actualTypeparamNames)) { this.Environment.AddXmlError("<typeparam> elements do not match type parameter names in order in {0}", null, symbol); } var paramXmls = xml.Elements("param").ToArray(); var func = symbol as FuncDecl; var expectedParamNames = func == null || func.Children == null ? new string[0] : func.Children.Select(x => x.Name).ToArray(); var actualParamNames = paramXmls.Select(x => x.Attribute("name").Value).ToArray(); if (!expectedParamNames.SequenceEqual(actualParamNames)) { this.Environment.AddXmlError("<param> elements do not match parameter names in order in {0}", null, symbol); } var returnXmls = xml.Elements("returns").ToArray(); if (returnXmls.Length == 1 ^ (func != null && ((FunctionTypeDecl)func.Type).ReturnType.ToString() != "void")) { this.Environment.AddXmlError("<returns> element does not math the function return type in {0}", null, symbol); } ResolveCommentNode(symbol, xml); decl.Document = xml.ToString(); } catch (XmlException ex) { this.Environment.AddXmlError("Failed to parse XML comment for {0}.", ex.Message, decl); } } }
private void AddSymbol(string key, SymbolDecl symbol) { if (this.Content == null) { this.Content = new Dictionary<string, List<SymbolDecl>>(); } List<SymbolDecl> decls = null; if (!this.Content.TryGetValue(key, out decls)) { decls = new List<SymbolDecl>(); this.Content.Add(key, decls); } if (!decls.Contains(symbol)) { decls.Add(symbol); } }
public override void Accept(SymbolDecl.IVisitor visitor) { visitor.Visit(this); }
public Dictionary<string, List<SymbolDecl>> GetSymbolContent(SymbolDecl symbol) { if (symbol is NamespaceDecl) { return this.NamespaceContents[symbol.NameKey]; } else { Dictionary<string, List<SymbolDecl>> content = null; if (!this.SymbolContents.TryGetValue(symbol, out content)) { var template = symbol as TemplateDecl; var typedef = (template == null ? symbol : template.Element) as TypedefDecl; if (typedef != null) { typedef.Type.Resolve(typedef.Parent, this); var refType = FindRefType(typedef.Type); if (refType.ReferencingNameKey == null) { content = null; } else { var symbols = this.ResolvedTypes[refType]; content = symbols .Select(x => GetSymbolContent(x)) .Where(x => x != null) .SelectMany(x => x) .GroupBy(x => x.Key) .ToDictionary(x => x.Key, x => x.SelectMany(y => y.Value).Distinct().ToList()) ; } } else { var visitor = new ResolveSymbolDeclContentVisitor { Environment = this, }; symbol.Accept(visitor); content = visitor.Content; } this.SymbolContents.Add(symbol, content); } return content; } }
public override void BuildSymbolTree(SymbolDecl parent, string tag) { base.BuildSymbolTree(parent, tag); foreach (var type in this.BaseTypes) { type.Parent = this; type.BuildSymbolTree(this, tag); } }
public void AddXmlError(string messageFormat, string exception, SymbolDecl symbol) { var template = symbol as TemplateDecl; if (template != null) { symbol = template.Element; } this.Errors.Add("(Xml) " + string.Format(messageFormat, symbol.OverloadKey) + (exception == null ? "" : "\r\n" + exception)); }
internal static List<SymbolDecl> FindSymbolInContent(ResolveEnvironment environment, SymbolDecl symbol, TypeDecl decl, string name, Dictionary<string, List<SymbolDecl>> content, bool typeAndNamespaceOnly, bool addError) { if (content == null) { return null; } List<SymbolDecl> decls = null; if (content.TryGetValue(name, out decls)) { if (typeAndNamespaceOnly) { decls = decls .Where(x => !(x is FuncDecl) && !(x is VarDecl) && !(x is EnumDecl)) .ToList(); if (decls.Count == 0) { return null; } } var nameKeys = decls.Select(x => x.NameKey).Distinct().ToList(); var overloadKeys = decls.Select(x => x.OverloadKey).Distinct().ToList(); if (overloadKeys.Count > 0) { decl.ReferencingOverloadKeys = overloadKeys; } if (nameKeys.Count > 1) { if (addError) { var printingKeys = overloadKeys.Aggregate("", (a, b) => a + "\r\n" + b); environment.AddError(false, "Found multiple symbols for {0} in {1}: " + printingKeys, name, symbol); } return null; } decl.ReferencingNameKey = nameKeys[0]; return decls; } return null; }
private void FillAvailableNames(SymbolDecl symbol) { if (symbol.Name != null) { List<SymbolDecl> decls = null; if (!this.AvailableNames.TryGetValue(symbol.Name, out decls)) { decls = new List<SymbolDecl>(); this.AvailableNames.Add(symbol.Name, decls); } decls.Add(symbol); } if (symbol.Children != null) { foreach (var child in symbol.Children) { FillAvailableNames(child); } } }