private string GetDocumentation(MethodInfo method, XmlDocCommentReader commentReader) { var methodComments = commentReader.GetComments(method); // We are going to take the comments verbatim, but remove the <buildermethod/> tag var builderNode = methodComments.Descendants().Single(f => f.Name == "buildermethod"); builderNode.Remove(); return "///" + string.Join("\n///", methodComments.Nodes().SelectMany( n => n.ToString().Split('\n').Where(f => !string.IsNullOrWhiteSpace(f)).Select(f => f.TrimStart()))); }
/// <summary> /// Formats the text to be displayed in the tooltip using information from the object's member and from the XML documentation, if existing. /// </summary> /// <param name="scintilla"></param> /// <param name="member">Reflected member to display information from.</param> /// <param name="reader">Jolt's XmlDocCommentReader instance, to get and display comments from assembly-generated XML file.</param> /// <returns>The formatted text to display in the tooltip.</returns> /// <remarks></remarks> private static string FormatHelpTip(this ScintillaNET.Scintilla scintilla, MemberInfo member, Jolt.XmlDocCommentReader reader) { switch (member.MemberType) { case MemberTypes.Method: dynamic methods = Type.GetType(member.DeclaringType.FullName).GetMethods().Where(m => m.Name == member.Name).ToList(); dynamic method = methods[0]; string summary = ""; string returntype = ""; string returndescription = ""; string remarks = ""; Dictionary <string, string> argumentdescriptions = new Dictionary <string, string>(); string txthelp = method.DeclaringType.Name + " method '" + member.Name + "'" + "\r\n"; dynamic xmlhelp = reader.GetComments(method); if ((xmlhelp != null)) { dynamic @params = xmlhelp.Elements("param").ToList; foreach (var p_loopVariable in @params) { var p = p_loopVariable; if (p.Value.ToString.Length > 70) { argumentdescriptions.Add(p.Attribute("name"), p.Value.ToString.Substring(0, 70).Trim("\n") + " [...]"); } else { argumentdescriptions.Add(p.Attribute("name"), p.Value.ToString.Trim("\r\n")); } } if (method.ReturnType.Name != "Void") { dynamic rdesc = xmlhelp.Elements("returns").FirstOrDefault; if ((rdesc != null)) { returndescription = rdesc.Value; } } dynamic redesc = xmlhelp.Elements("remarks").FirstOrDefault; if ((redesc != null)) { if (redesc.Value.Length > 1000) { remarks = redesc.Value.Substring(0, 1000) + " [...]"; } else { remarks = redesc.Value; } } redesc = xmlhelp.Elements("summary").FirstOrDefault; if ((redesc != null)) { summary = redesc.Value; txthelp += summary + "\r\n"; } } if (method.GetParameters.Count > 0) { txthelp += "Parameters:" + "\r\n" + "\r\n"; txthelp += "Type".PadRight(18) + "Name".PadRight(15) + "Description" + "\r\n"; foreach (var par_loopVariable in method.GetParameters) { var par = par_loopVariable; if (argumentdescriptions.ContainsKey(par.Name)) { txthelp += par.ParameterType.Name.PadRight(18) + par.Name.PadRight(15) + argumentdescriptions[par.Name] + "\r\n"; } else { txthelp += par.ParameterType.Name.PadRight(18) + par.Name.PadRight(15) + "\r\n"; } } txthelp += "\r\n"; } txthelp += "Return Type: " + method.ReturnType.ToString; if (!string.IsNullOrEmpty(returndescription)) { txthelp += "\r\n" + "Return Parameter Description: " + returndescription; } if (!string.IsNullOrEmpty(remarks)) { txthelp += "\r\n" + "\r\n" + "Remarks: " + remarks; } return(txthelp); case MemberTypes.Property: dynamic props = Type.GetType(member.DeclaringType.FullName).GetProperties().Where(p => p.Name == member.Name).ToList(); dynamic prop = props(0); summary = ""; string proptype = ""; txthelp = prop.DeclaringType.Name + " property '" + prop.Name + "'" + "\r\n"; txthelp += "Type: " + prop.PropertyType.ToString; xmlhelp = reader.GetComments(prop); if ((xmlhelp != null)) { dynamic redesc = xmlhelp.Elements("summary").FirstOrDefault; if ((redesc != null)) { txthelp += "\r\n" + "Description: " + redesc.Value; } } return(txthelp); default: return(""); } }
private BuilderMethod GetBuilderMethod(MethodInfo methodInfo, XmlDocCommentReader commentReader) { var comments = commentReader.GetComments(methodInfo); if (comments != null) { // Look for a buildermethod subnode. If this is found create a BuilderMethod instance var builderMethodNode = comments.Descendants().SingleOrDefault(f => f.Name == "buildermethod"); if (builderMethodNode != null) { Func<string, string, string> attributeValueOrDefault = (attributeName, defaultValue) => { var attribute = builderMethodNode.Attributes().SingleOrDefault(n => n.Name == attributeName); return attribute == null ? defaultValue : attribute.Value; }; string fluentName = attributeValueOrDefault("name", methodInfo.Name); string dslName = attributeValueOrDefault("dslname", fluentName); bool useProperty = Convert.ToBoolean(attributeValueOrDefault("useproperty", "true")); return new BuilderMethod { FluentName = fluentName, DslName = dslName, UseProperty = useProperty }; } } return null; }
static void Main(string[] args) { string assemblyPath = null; string docPath = null; string outputPath = null; var optionSet = new OptionSet { { "a=|assembly=", "Path to assembly to use", f => assemblyPath = f }, { "d=|doc=", "Path to documentation to use", f => docPath = f }, { "o=|output=", "Output path", f => outputPath = f } }; try { optionSet.Parse(args); } catch (OptionException) { Usage(optionSet); return; } if (assemblyPath == null) { Usage(optionSet); return; } assemblyPath = Path.GetFullPath(assemblyPath); if (docPath == null) { docPath = Path.Combine(Path.GetDirectoryName(assemblyPath),Path.GetFileNameWithoutExtension(assemblyPath) + ".xml"); } if (outputPath == null) { outputPath = Directory.GetCurrentDirectory(); } Console.WriteLine("Generating DSL from assembly {0}", assemblyPath); var targetAssembly = Assembly.LoadFile(assemblyPath); Console.WriteLine("Loading documentation from {0}", docPath); var commentReader = new XmlDocCommentReader(docPath); foreach (var type in targetAssembly.GetTypes()) { var comments = commentReader.GetComments(type); if (comments != null) { var builderClassNode = comments.Descendants().FirstOrDefault(f => f.Name == "builderclass"); if (builderClassNode != null) { var outputFile = string.Format("{0}.cs", builderClassNode.Attributes().Single(f => f.Name == "name").Value); var dslBuilder = new DslBuilder(builderClassNode, commentReader, type); string dslCode = dslBuilder.CreateDslCode(); using (var fileWriter = new StreamWriter(new FileStream(Path.Combine(outputPath, outputFile), FileMode.Create, FileAccess.Write))) { fileWriter.Write(dslCode); } } } } }