private static string Heading(MemberInfo info) { var ret = String.Empty; if (info is MethodBase) { var method = (MethodBase)info; if (method is ConstructorInfo) { return(TypeNameUtil.UndecorateTypeName(method.ReflectedType.Name) + " Constructor"); } return(MethodNameHeading(method.Name)); } if (info is Type) { var type = (Type)info; return(FormatType(type)); } else if (info is PropertyInfo) { var property = (PropertyInfo)info; return(property.Name); } else if (info is FieldInfo) { var field = (FieldInfo)info; return(field.Name); } return(ret); }
public void HandleType(Type currentType, XmlDoc xdoc) { if (!(currentType.IsNested ? currentType.IsNestedPublic : currentType.IsPublic)) { return; } var typeFullName = currentType.FullName; if (!this.docs.ContainsKey(typeFullName)) { var docVisitor = new TypeLinkAndBuilder(currentType); this.docs[typeFullName] = docVisitor; } var summary = GetSummary( currentType, xdoc, TypeNameUtil.XmlDocMemberName(currentType)); if (summary == null) { Console.WriteLine("no summary for " + typeFullName); } else { this.docs[typeFullName].Builder.Append(summary) .Append("\r\n"); } }
public void VisitSee(INode see) { string cref = see.GetAttribute("cref"); if (cref == null) { cref = String.Empty; Console.WriteLine("Warning: cref attribute absent in <see>"); } if (cref.Substring(0, 2).Equals("T:", StringComparison.Ordinal)) { string typeName = TypeNameUtil.UndecorateTypeName(cref.Substring(2)); string content = DocGenUtil.HtmlEscape(see.GetContent()); if (String.IsNullOrEmpty(content)) { content = typeName; } this.Write("[" + content + "]"); this.Write("(" + typeName + ".md)"); XmlDoc.VisitInnerNode(see, this); } else if (cref.Substring(0, 2).Equals("M:", StringComparison.Ordinal)) { string content = DocGenUtil.HtmlEscape(see.GetContent()); if (String.IsNullOrEmpty(content)) { content = cref; } this.Write("**" + content + "**"); } else { XmlDoc.VisitInnerNode(see, this); } }
public static string FormatTypeRaw(Type type) { var name = TypeNameUtil.UndecorateTypeName(type.Name); if (type.IsGenericParameter) { return(name); } name = type.Namespace + "." + name; return(name.Equals("System.Int32") ? "int" : (name.Equals("System.Int64") ? "long" : (name.Equals("System.Int16") ? "short" : (name.Equals("System.UInt32") ? "uint" : (name.Equals("System.UInt64") ? "ulong" : (name.Equals("System.UInt16") ? "ushort" : (name.Equals("System.Char") ? "char" : (name.Equals("System.Object") ? "object" : (name.Equals("System.Void") ? "void" : (name.Equals("System.Byte") ? "byte" : (name.Equals("System.SByte") ? "sbyte" : (name.Equals("System.String") ? "string" : (name.Equals("System.Boolean") ? "bool" : (name.Equals("System.Single") ? "float" : (name.Equals("System.Double") ? "double" : name))))))))))))))); }
public static string FormatTypeRaw(Type type) { var name = TypeNameUtil.UndecorateTypeName(type.Name); if (type.IsGenericParameter) { return(name); } name = TypeNameUtil.SimpleTypeName(type); if (name.Equals("System.Decimal", StringComparison.Ordinal)) { return("decimal"); } return(name.Equals("System.Int32", StringComparison.Ordinal) ? "int" : (name.Equals("System.Int64", StringComparison.Ordinal) ? "long" : (name.Equals("System.Int16", StringComparison.Ordinal) ? "short" : (name.Equals("System.UInt32", StringComparison.Ordinal) ? "uint" : (name.Equals("System.UInt64", StringComparison.Ordinal) ? "ulong" : (name.Equals("System.UInt16", StringComparison.Ordinal) ? "ushort" : (name.Equals("System.Char", StringComparison.Ordinal) ? "char" : (name.Equals("System.Object", StringComparison.Ordinal) ? "object" : (name.Equals("System.Void", StringComparison.Ordinal) ? "void" : (name.Equals("System.Byte", StringComparison.Ordinal) ? "byte" : (name.Equals("System.SByte", StringComparison.Ordinal) ? "sbyte" : (name.Equals("System.String", StringComparison.Ordinal) ? "string" : (name.Equals("System.Boolean", StringComparison.Ordinal) ? "bool" : (name.Equals("System.Single", StringComparison.Ordinal) ? "float" : (name.Equals("System.Double", StringComparison.Ordinal) ? "double" : name))))))))))))))); }
public void HandleMember(object info, XmlDoc xmldoc) { var isPublicOrProtected = false; var typeInfo = info as Type; var methodInfo = info as MethodInfo; var propertyInfo = info as PropertyInfo; var fieldInfo = info as FieldInfo; if (methodInfo != null) { isPublicOrProtected = methodInfo.IsPublic || methodInfo.IsFamily; } if (propertyInfo != null) { isPublicOrProtected = (propertyInfo.CanRead && (propertyInfo.GetGetMethod().IsPublic || propertyInfo.GetGetMethod().IsFamily)) || (propertyInfo.CanWrite && (propertyInfo.GetSetMethod().IsPublic || propertyInfo.GetSetMethod().IsFamily)); } if (fieldInfo != null) { isPublicOrProtected = fieldInfo.IsPublic || fieldInfo.IsFamily; } if (!isPublicOrProtected) { return; } string memberAnchor = MemberAnchor(info); this.memberFormats[memberAnchor] = FormatMember(info); if (!this.docs.ContainsKey(memberAnchor)) { var docVisitor = new StringBuilder(); this.docs[memberAnchor] = docVisitor; } string memberFullName = TypeNameUtil.XmlDocMemberName(info); var summary = SummaryVisitor.GetSummary( info as MemberInfo, xmldoc, memberFullName); if (summary == null) { Console.WriteLine("no summary for " + memberFullName); } else { this.docs[memberAnchor].Append(summary) .Append("\r\n"); } }
public override void VisitSee(See see) { string cref = see.Cref; if (cref.Substring(0, 2).Equals("T:")) { string typeName = TypeNameUtil.UndecorateTypeName(cref.Substring(2)); string content = HtmlEscape(see.Content); if (String.IsNullOrEmpty(content)) { content = HtmlEscape(see.ToText()); } this.Write("[" + content + "]"); this.Write("(" + typeName + ".md)"); base.VisitSee(see); } else { base.VisitSee(see); } }
public static string SimpleTypeName(Type t) { if (!t.IsNested) { return(t.Namespace + "." + TypeNameUtil.UndecorateTypeName(t.Name)); } else { Type nt = t; var types = new List <Type>(); types.Add(t); var sb = new StringBuilder().Append(t.Namespace); while (nt != null && nt.IsNested) { types.Add(nt.DeclaringType); nt = nt.DeclaringType; } for (var i = types.Count - 1; i >= 0; --i) { sb.Append(".").Append(UndecorateTypeName(types[i].Name)); } return(sb.ToString()); } }
public static string FormatTypeSig(Type typeInfo) { var builder = new StringBuilder(); builder.Append(FourSpaces); if (typeInfo.IsPublic) { builder.Append("public "); } else { builder.Append("internal "); } if (typeInfo.IsAbstract && typeInfo.IsSealed) { builder.Append("static "); } else if (typeInfo.IsAbstract && !typeInfo.IsInterface) { builder.Append("abstract "); } else if (typeInfo.IsSealed) { builder.Append("sealed "); } if (typeInfo.IsValueType) { builder.Append("struct "); } else if (typeInfo.IsClass) { builder.Append("class "); } else { builder.Append("interface "); } builder.Append(TypeNameUtil.UndecorateTypeName(typeInfo.Name)); bool first; if (typeInfo.GetGenericArguments().Length > 0) { builder.Append('<'); first = true; foreach (var arg in typeInfo.GetGenericArguments()) { if (!first) { builder.Append(", "); } builder.Append(FormatType(arg)); first = false; } builder.Append('>'); } first = true; var ifaces = typeInfo.GetInterfaces(); var derived = typeInfo.BaseType; if (typeInfo.BaseType != null && typeInfo.BaseType.Equals(typeof(object))) { derived = null; } if (derived != null || ifaces.Length > 0) { builder.Append(" :\r\n" + FourSpaces); if (derived != null) { builder.Append(FourSpaces + FormatType(derived)); first = false; } if (ifaces.Length > 0) { foreach (var iface in ifaces) { if (!first) { builder.Append(",\r\n" + FourSpaces); } builder.Append(FourSpaces + FormatType(iface)); first = false; } } } AppendConstraints(typeInfo.GetGenericArguments(), builder); return(builder.ToString()); }
public static void AppendConstraints( Type[] genericArguments, StringBuilder builder) { foreach (var arg in genericArguments) { if (arg.IsGenericParameter) { var constraints = arg.GetGenericParameterConstraints(); if (constraints.Length == 0 && (arg.GenericParameterAttributes & (GenericParameterAttributes.ReferenceTypeConstraint | GenericParameterAttributes.NotNullableValueTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint)) == GenericParameterAttributes.None) { continue; } builder.Append("\r\n" + FourSpaces + FourSpaces + "where "); builder.Append(TypeNameUtil.UndecorateTypeName(arg.Name)); builder.Append(" : "); var first = true; if ((arg.GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != GenericParameterAttributes.None) { if (!first) { builder.Append(", "); } builder.Append("class"); first = false; } if ((arg.GenericParameterAttributes & GenericParameterAttributes.NotNullableValueTypeConstraint) != GenericParameterAttributes.None) { if (!first) { builder.Append(", "); } builder.Append("struct"); first = false; } if ((arg.GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != GenericParameterAttributes.None) { if (!first) { builder.Append(", "); } builder.Append("new()"); first = false; } foreach (var constr in constraints) { if (!first) { builder.Append(", "); } builder.Append(FormatType(constr)); first = false; } } builder.Append(FormatType(arg)); } }
public static string FormatMethod(MethodBase method) { var builder = new StringBuilder(); builder.Append(FourSpaces); if (!method.ReflectedType.IsInterface) { if (method.IsPublic) { builder.Append("public "); } if (method.IsAssembly) { builder.Append("internal "); } if (method.IsFamily) { builder.Append("protected "); } if (method.IsStatic) { builder.Append("static "); } if (method.IsAbstract) { builder.Append("abstract "); } if (method.IsFinal) { builder.Append("sealed "); } else if (method is MethodInfo && IsMethodOverride((MethodInfo)method)) { builder.Append("override "); } else if (method.IsVirtual) { builder.Append("virtual "); } } var methodInfo = method as MethodInfo; var isExtension = false; Attribute attr; if (methodInfo != null) { attr = methodInfo.GetCustomAttribute( typeof(System.Runtime.CompilerServices.ExtensionAttribute)); isExtension = attr != null; if (method.Name.Equals("op_Explicit")) { builder.Append("explicit operator "); builder.Append(FormatType(methodInfo.ReturnType)); } else if (method.Name.Equals("op_Implicit")) { builder.Append("implicit operator "); builder.Append(FormatType(methodInfo.ReturnType)); } else if (ValueOperators.ContainsKey(method.Name)) { builder.Append(FormatType(methodInfo.ReturnType)); builder.Append(" operator "); builder.Append(ValueOperators[method.Name]); } else { builder.Append(FormatType(methodInfo.ReturnType)); builder.Append(" "); builder.Append(method.Name); } } else { builder.Append(TypeNameUtil.UndecorateTypeName(method.ReflectedType.Name)); } bool first; if (method is MethodInfo && method.GetGenericArguments().Length > 0) { builder.Append('<'); first = true; foreach (var arg in method.GetGenericArguments()) { if (!first) { builder.Append(", "); } builder.Append(FormatType(arg)); first = false; } builder.Append('>'); } builder.Append("("); first = true; foreach (var param in method.GetParameters()) { if (!first) { builder.Append(",\r\n" + FourSpaces + FourSpaces); } else { builder.Append("\r\n" + FourSpaces + FourSpaces); } if (first && isExtension) { builder.Append("this "); } attr = param.GetCustomAttribute(typeof(ParamArrayAttribute)); if (attr != null) { builder.Append("params "); } builder.Append(FormatType(param.ParameterType)); builder.Append(" "); builder.Append(param.Name); first = false; } builder.Append(")"); if (method is MethodInfo && method.GetGenericArguments().Length > 0) { AppendConstraints(method.GetGenericArguments(), builder); } builder.Append(";"); return(builder.ToString()); }
public void HandleMember(MemberInfo info, XmlDoc xmldoc) { var signature = String.Empty; var mnu = TypeNameUtil.XmlDocMemberName(info); var mnm = xmldoc.GetMemberNode(mnu); if (info is MethodBase) { var method = (MethodBase)info; if (!method.IsPublic && !method.IsFamily) { // Ignore methods other than public and protected // methods return; } if (mnm == null) { Console.WriteLine("member info not found: " + mnu); return; } using (var ch = this.AddMember(info)) { signature = FormatMethod(method, false); this.WriteLine("<a id=\"" + MemberSummaryVisitor.MemberAnchor(info) + "\"></a>"); this.WriteLine("### " + Heading(info) + "\r\n\r\n" + signature + "\r\n\r\n"); var attr = method.GetCustomAttribute(typeof(ObsoleteAttribute)) as ObsoleteAttribute; if (attr != null) { this.WriteLine("<b>Deprecated.</b> " + DocGenUtil.HtmlEscape(attr.Message) + "\r\n\r\n"); } var cattr = method.GetCustomAttribute(typeof(CLSCompliantAttribute)) as CLSCompliantAttribute; if (cattr != null && !cattr.IsCompliant) { this.WriteLine("<b>This API is not CLS-compliant.</b>\r\n\r\n"); } this.paramStr.Clear(); this.returnStr.Clear(); this.exceptionStr.Clear(); XmlDoc.VisitInnerNode(mnm, this); if (this.paramStr.Length > 0) { this.Write("<b>Parameters:</b>\r\n\r\n"); var paramString = this.paramStr.ToString(); // Decrease spacing between list items paramString = paramString.Replace("\r\n * ", " * "); this.Write(paramString); } this.Write(this.returnStr.ToString()); if (this.exceptionStr.Length > 0) { this.Write("<b>Exceptions:</b>\r\n\r\n"); this.Write(this.exceptionStr.ToString()); } } } else if (info is Type) { var type = (Type)info; if (!(type.IsNested ? type.IsNestedPublic : type.IsPublic)) { // Ignore nonpublic types return; } if (mnm == null) { Console.WriteLine("member info not found: " + mnu); return; } using (var ch = this.AddMember(info)) { this.WriteLine("## " + Heading(type) + "\r\n\r\n"); this.WriteLine(FormatTypeSig(type) + "\r\n\r\n"); var attr = type.GetCustomAttribute(typeof(ObsoleteAttribute)) as ObsoleteAttribute; if (attr != null) { this.WriteLine("<b>Deprecated.</b> " + attr.Message + "\r\n\r\n"); } var cattr = type.GetCustomAttribute(typeof(CLSCompliantAttribute)) as CLSCompliantAttribute; if (cattr != null && !cattr.IsCompliant) { this.WriteLine("<b>This API is not CLS-compliant.</b>\r\n\r\n"); } this.paramStr.Clear(); XmlDoc.VisitInnerNode(mnm, this); this.Write("\r\n\r\n"); this.WriteLine("<<<MEMBER_SUMMARY>>>"); if (this.paramStr.Length > 0) { this.Write("<b>Parameters:</b>\r\n\r\n"); var paramString = this.paramStr.ToString(); // Decrease spacing between list items paramString = paramString.Replace("\r\n * ", " * "); this.Write(paramString); } } } else if (info is PropertyInfo) { var property = (PropertyInfo)info; if (!PropertyIsPublicOrFamily(property)) { // Ignore methods other than public and protected // methods return; } if (mnm == null) { Console.WriteLine("member info not found: " + mnu); return; } using (var ch = this.AddMember(info)) { signature = FormatProperty(property); this.WriteLine("<a id=\"" + MemberSummaryVisitor.MemberAnchor(info) + "\"></a>"); this.WriteLine("### " + property.Name + "\r\n\r\n" + signature + "\r\n\r\n"); var attr = property.GetCustomAttribute(typeof(ObsoleteAttribute)) as ObsoleteAttribute; if (attr != null) { this.WriteLine("<b>Deprecated.</b> " + attr.Message + "\r\n\r\n"); } var cattr = property.GetCustomAttribute(typeof(CLSCompliantAttribute)) as CLSCompliantAttribute; if (cattr != null && !cattr.IsCompliant) { this.WriteLine("<b>This API is not CLS-compliant.</b>\r\n\r\n"); } this.paramStr.Clear(); this.returnStr.Clear(); this.exceptionStr.Clear(); XmlDoc.VisitInnerNode(mnm, this); if (this.paramStr.Length > 0) { this.Write("<b>Parameters:</b>\r\n\r\n"); this.Write(this.paramStr.ToString()); } this.Write(this.returnStr.ToString()); if (this.exceptionStr.Length > 0) { this.Write("<b>Exceptions:</b>\r\n\r\n"); this.Write(this.exceptionStr.ToString()); } } } else if (info is FieldInfo) { var field = (FieldInfo)info; if (!field.IsPublic && !field.IsFamily) { // Ignore nonpublic, nonprotected fields return; } if (mnm == null) { Console.WriteLine("member info not found: " + mnu); return; } using (var ch = this.AddMember(info)) { signature = FormatField(field); this.WriteLine("<a id=\"" + MemberSummaryVisitor.MemberAnchor(info) + "\"></a>"); this.WriteLine("### " + field.Name + "\r\n\r\n" + signature + "\r\n\r\n"); var attr = field.GetCustomAttribute(typeof(ObsoleteAttribute)) as ObsoleteAttribute; if (attr != null) { this.WriteLine("<b>Deprecated.</b> " + attr.Message + "\r\n\r\n"); } var cattr = field.GetCustomAttribute(typeof(CLSCompliantAttribute)) as CLSCompliantAttribute; if (cattr != null && !cattr.IsCompliant) { this.WriteLine("<b>This API is not CLS-compliant.</b>\r\n\r\n"); } XmlDoc.VisitInnerNode(mnm, this); } } }
public static string FormatTypeSig(Type typeInfo) { var builder = new StringBuilder(); builder.Append(FourSpaces); if (typeInfo.IsNested ? typeInfo.IsNestedPublic : typeInfo.IsPublic) { builder.Append("public "); } else { builder.Append("internal "); } if (typeInfo.IsAbstract && typeInfo.IsSealed) { builder.Append("static "); } else if (typeInfo.IsAbstract && !typeInfo.IsInterface) { builder.Append("abstract "); } else if (typeInfo.IsSealed) { builder.Append("sealed "); } if (typeInfo.IsValueType) { builder.Append("struct "); } else if (typeInfo.IsClass) { builder.Append("class "); } else { builder.Append("interface "); } builder.Append(TypeNameUtil.UndecorateTypeName(typeInfo.Name)); bool first; if (typeInfo.GetGenericArguments().Length > 0) { builder.Append('<'); first = true; foreach (var arg in typeInfo.GetGenericArguments()) { if (!first) { builder.Append(", "); } builder.Append(FormatType(arg)); first = false; } builder.Append('>'); } first = true; var ifaces = typeInfo.GetInterfaces(); var derived = typeInfo.BaseType; if (typeInfo.BaseType != null && typeInfo.BaseType.Equals(typeof(object))) { derived = null; } if (derived != null || ifaces.Length > 0) { builder.Append(" :\r\n" + FourSpaces); if (derived != null) { builder.Append(FourSpaces + FormatType(derived)); first = false; } if (ifaces.Length > 0) { // Sort interface names to ensure they are // displayed in a consistent order. Apparently, GetInterfaces // can return such interfaces in an unspecified order. var ifacenames = new List <string>(); foreach (var iface in ifaces) { ifacenames.Add(FormatType(iface)); } ifacenames.Sort(); foreach (var ifacename in ifacenames) { if (!first) { builder.Append(",\r\n" + FourSpaces); } builder.Append(FourSpaces + ifacename); first = false; } } } AppendConstraints(typeInfo.GetGenericArguments(), builder); return(builder.ToString()); }
public static void GenerateTests(Type type, string directory) { if (type == null) { throw new ArgumentNullException(nameof(type)); } var name = TypeNameUtil.UndecorateTypeName(type.Name); var builder = new StringBuilder(); Directory.CreateDirectory(directory); builder.Append("using System;\n"); builder.Append("using System.Collections.Generic;\n"); builder.Append("using System.Text;\n"); builder.Append("using " + type.Namespace + ";\n"); builder.Append("using Microsoft.VisualStudio.TestTools.UnitTesting;\n"); builder.Append("namespace Test {\n"); builder.Append(" [TestClass]\n"); builder.Append(" public partial class " + name + "Test {\n"); var methods = new SortedSet <string>(); var hasPublicConstructor = false; foreach (var method in type.GetConstructors()) { if (!method.IsPublic) { continue; } hasPublicConstructor = true; break; } if (hasPublicConstructor) { methods.Add("Constructor"); } foreach (var method in type.GetMethods()) { if (!method.IsPublic) { continue; } if (!method.DeclaringType.Equals(method.ReflectedType)) { continue; } var methodName = method.Name; if (methodName.StartsWith("get_", StringComparison.Ordinal)) { methodName = methodName.Substring(4); } else if (methodName.StartsWith("set_", StringComparison.Ordinal)) { methodName = methodName.Substring(4); } else if (methodName.StartsWith("op_", StringComparison.Ordinal)) { methodName = "Operator" + methodName.Substring(3); } if (methodName.StartsWith(".ctor", StringComparison.Ordinal)) { methodName = "Constructor"; } if (methodName.StartsWith(".cctor", StringComparison.Ordinal)) { methodName = "StaticConstructor"; } if (methodName.Length == 0) { continue; } methodName = PeterO.DataUtilities.ToUpperCaseAscii( methodName.Substring(0, 1)) + methodName.Substring(1); methods.Add(methodName); } if (methods.Count == 0) { // no tests to write return; } if (methods.Contains("Constructor")) { builder.Append(" [TestMethod]\n"); builder.Append(" public void TestConstructor() {\n"); builder.Append(" // not implemented yet\n"); builder.Append(" }\n"); } foreach (var methodName in methods) { if (methodName.Equals("Constructor", StringComparison.Ordinal)) { continue; } builder.Append(" [TestMethod]\n"); builder.Append(" public void Test" + methodName + "() {\n"); builder.Append(" // not implemented yet\n"); builder.Append(" }\n"); } builder.Append(" }\n"); builder.Append('}'); var filename = Path.Combine(directory, name + "Test.cs"); if (!File.Exists(filename)) { File.WriteAllText(filename, builder.ToString()); } }