IEnumerable<string> GetCreators(CodeTypeDeclaration type, int n) { for (int i = 0; i < n; ++i) { yield return " <item><term><see cref=\"" + XmlDocs.Cref (DefaultNamespace, type, type.GetMethods (A (i)).First ()) + "\" /></term></item>"; } }
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))) ); }
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; }
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") ); }