void AddFoldDocs(CodeTypeDeclaration type, CodeMemberMethod method, int n) { method.Comments.AddDocs( XmlDocs.TypeParam("TResult", " The type to convert the " + XmlDocs.See(DefaultNamespace, type) + " to." ), GetFoldParametersDocs(type, n), XmlDocs.Summary( " Converts a " + XmlDocs.See(DefaultNamespace, type) + " into a <typeparamref name=\"TResult\" /> value." ), XmlDocs.Returns( " A <typeparamref name=\"TResult\" /> as generated by one", " of the conversion delegate parameters." ), XmlDocs.Remarks( " <para>", " Converts a " + XmlDocs.See(DefaultNamespace, type) + " into a <typeparamref name=\"TResult\" />", " by invoking one of the provided delegate parameters.", " </para>", " <para>", " The parameter which is invoked is predicated upon the internal position of", " the value held. For example, if the internal value is in the first position ", " (i.e. " + XmlDocs.See(DefaultNamespace, type, type.GetMethods(A(0)).First()), " was used to create the " + XmlDocs.See(DefaultNamespace, type) + " instance), then", " <paramref name=\"a\" /> (the first delegate parameter) will be invoked to", " convert the <typeparamref name=\"T1\" /> into a ", " <typeparamref name=\"TResult\" />.", " </para>" ), XmlDocs.ArgumentNullException(Enumerable.Range(0, n).Select(v => a(v))) ); }
void AddEqualsDocs(CodeTypeDeclaration type, CodeMemberMethod method, int n) { var et = XmlDocs.See(DefaultNamespace, type); method.Comments.AddDocs( XmlDocs.Param("obj", "A " + et + "to compare this instance against." ), XmlDocs.Summary( " Determines whether the current instance and the specified " + et + " have the same value." ), XmlDocs.Returns( " <para>", " <see langword=\"true\"/> if each member of <paramref name=\"obj\"/>", " and the current instance have the same value (according to", " <see cref=\"M:System.Object.Equals(System.Object)\"/>); otherwise", " <see langword=\"false\"/> is returned.", " </para>" ), XmlDocs.Remarks( " <para>", " This method checks for value equality", " (<see cref=\"M:System.Object.Equals(System.Object)\"/>), as defined by each", " value type.", " </para>" ) ); }
void AddCreatorDocs(CodeTypeDeclaration type, CodeMemberMethod method, int w, int n) { var tp = Types.GetTypeParameter(w, n); var idx = XmlDocs.GetIndex(tp); var fold = type.GetMethods("Fold").First(); method.Comments.AddDocs( XmlDocs.Param("value", " A <typeparamref name=\"" + tp + "\" /> containing the value", " to provide to the " + idx, " " + XmlDocs.See(DefaultNamespace, type, fold), " delegate." ), XmlDocs.Summary( " Creates a " + XmlDocs.See(DefaultNamespace, type) + " instance which", " holds a <typeparamref name=\"" + tp + "\" /> value." ), XmlDocs.Returns( " A " + XmlDocs.See(DefaultNamespace, type) + " instance which holds a ", " holds a <typeparamref name=\"" + tp + "\" /> value." ), XmlDocs.Remarks( " <para>", " When", " " + XmlDocs.See(DefaultNamespace, type, fold), " is invoked,", " the returned " + XmlDocs.See(DefaultNamespace, type) + " instance", " will invoke the " + idx + " delegate", " for conversions.", " </para>" ), XmlDocs.ArgumentNullException("value") ); }
static CodeMemberMethod XF(int args) { var t = new CodeTypeReference("System.Linq.Expressions.Expression", Types.Func(args)); var m = CreateMethod("XF", t, "expr", args, true); m.Comments.AddDocs( XmlDocs.TypeParams(m.TypeParameters, t), XmlDocs.Param("expr", "The " + XmlDocs.See(t) + " to return."), XmlDocs.Summary("Creates a " + XmlDocs.See(t) + " expression tree."), XmlDocs.Returns("Returns <paramref name=\"expr\" />.") ); return(m); }
static CodeMemberMethod F(int args) { var t = Types.Func(args); var m = CreateMethod("F", t, "lambda", args, true); m.Comments.AddDocs( XmlDocs.TypeParams(m.TypeParameters, t), XmlDocs.Param("lambda", "The " + XmlDocs.See(t) + " to return."), XmlDocs.Summary("Creates a " + XmlDocs.See(t) + " delegate."), XmlDocs.Returns("Returns <paramref name=\"lambda\" />.") ); return(m); }
IEnumerable <string> GetFoldParametersDocs(CodeTypeDeclaration type, int n) { for (int i = 0; i < n; ++i) { var tp = Types.GetTypeParameter(i, n); yield return("<param name=\"" + a(i) + "\">"); yield return(" A <see cref=\"T:System.Func{" + tp + ",TResult}\" /> "); yield return(" used if the " + XmlDocs.See(DefaultNamespace, type) + " stores a "); yield return(" <typeparamref name=\"" + tp + "\" /> value into a "); yield return(" <typeparamref name=\"TResult\" /> value."); yield return("</param>"); } }
static CodeMemberMethod RecFunc(int args) { var t = Types.Func(args); var m = new CodeMemberMethod() { Attributes = MemberAttributes.Static | MemberAttributes.Public, Name = "RecFunc", ReturnType = t, }; m.TypeParameters.AddRange(Types.GetTypeParameters(args, true).ToArray()); var a = "lambda"; m.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("Func", t, t), a)); m.Statements.ThrowWhenArgumentIsNull(a); var expr = AppendArgs(new StringBuilder(), args); expr.Append(" => lambda (RecFunc (lambda))"); AppendArgs(expr, args); m.Statements.Add(new CodeMethodReturnStatement(new CodeSnippetExpression(expr.ToString()))); m.Comments.AddRange("From: http://blogs.msdn.com/madst/archive/2007/05/11/recursive-lambda-expressions.aspx"); m.Comments.AddDocs( XmlDocs.TypeParams(m.TypeParameters, t), XmlDocs.Param("lambda", "The " + XmlDocs.See(t) + " to use."), XmlDocs.Summary("Creates a " + XmlDocs.See(t) + " delegate, which may be recursive."), XmlDocs.Returns("Returns a " + XmlDocs.See(t) + " which (eventually) invokes <paramref name=\"lambda\"/>."), XmlDocs.ArgumentNullException("lambda"), XmlDocs.Remarks( "<para>", " The following example makes use of a recursive lambda:", "</para>", "<code lang=\"C#\">", " Func<int, int> factorial = Lambda.RecFunc<int, int> (".Replace("<", "<"), " fac => x => x == 0 ? 1 : x * fac (x-1));", " Console.WriteLine (factorial (5)); // prints \"120\"", "</code>" ) ); return(m); }
CodeTypeDeclaration CreateEither(int n) { var either = new CodeTypeDeclaration("Either") { TypeAttributes = TypeAttributes.Public | TypeAttributes.Abstract, }; either.BaseTypes.Add(new CodeTypeReference("IEquatable", GetEitherType(n))); either.TypeParameters.AddRange(Types.GetTypeParameters(n, false)); either.Members.Add(new CodeConstructor() { Attributes = MemberAttributes.Private, }); for (int i = 0; i < n; ++i) { either.Members.Add(CreateCreator(either, i, n)); } either.Members.Add(CreateFold(either, n)); either.Members.Add(CreateCheckFolders(n)); either.Members.Add(CreateEqualsObject()); either.Members.Add(CreateEquals(n)); either.Members.Add(CreateGetHashCode()); for (int i = 0; i < n; ++i) { either.Members.Add(CreateHandler(i, n)); } either.Comments.AddDocs( XmlDocs.TypeParams(either.TypeParameters), XmlDocs.Summary("A union of " + n + " values."), "<remarks>", " <para>", " An <c>Either</c> is an immutable, strongly typed union of variously ", " typed values with each value lacking an otherwise meaningful name aside ", " from its position, which is not exposed. It stores only one (non-null) ", " value from a set of types (as determined by the type parameter list).", " </para>", " <para>", " The value held by a " + XmlDocs.See(DefaultNamespace, either) + " instance", " can be converted into a value by using the ", " <see cref=\"" + XmlDocs.Cref(DefaultNamespace, either, either.GetMethods("Fold").First()) + "\" /> method.", " <c>Fold</c> takes a list of delegates to perform the conversion; the", " delegate used to perform the conversion is based upon the internal ", " position of the value stored.", " </para>", " <para>", " <c>Either</c> instances are created through one of the following", " creation methods:", " </para>", " <list type=\"bullet\">", GetCreators(either, n), " </list>", " <code lang=\"C#\">", " var a = Either<double, string>.A (Math.PI); // value stored in 1st position", " ", " int r = a.Fold (", " v => (int) v, // 1st position converter", " v => v.Length); // 2nd position converter", " ", " Console.WriteLine (r); // prints 3</code>", "</remarks>" ); for (int i = 0; i < n; ++i) { AddCreatorDocs(either, either.GetMethods(A(i)).First(), i, n); } AddFoldDocs(either, either.GetMethods("Fold").First(), n); AddEqualsObjectDocs(either, either.GetMethods("Equals").First(m => m.Parameters [0].Type.BaseType == "System.Object"), n); AddEqualsDocs(either, either.GetMethods("Equals").First(m => m.Parameters [0].Type.BaseType != "System.Object"), n); AddGetHashCodeDocs(either, either.GetMethods("GetHashCode").First(), n); return(either); }