コード例 #1
0
        CodeMemberMethod CreateMatchMethod(int n)
        {
            var retType = new CodeTypeReference("TResult");
            var m       = new CodeMemberMethod()
            {
                Attributes = MemberAttributes.Public | MemberAttributes.Static,
                Name       = "Match",
                ReturnType = retType,
            };

            for (int i = 0; i < n; ++i)
            {
                m.TypeParameters.Add(Types.GetTypeParameter(n, i));
            }
            m.TypeParameters.Add("TResult");

            var selfType = new CodeTypeReference("this Tuple", Types.GetTypeParameterReferences(n, false).ToArray());

            m.Parameters.Add(new CodeParameterDeclarationExpression(selfType, "self"));

            var matchersType = new CodeTypeReference(
                new CodeTypeReference(Types.FuncType(n),
                                      Types.GetTypeParameterReferences(n, false)
                                      .Concat(new[] { new CodeTypeReference("Cadenza.Maybe", new[] { new CodeTypeReference("TResult") }) })
                                      .ToArray()),
                1);
            var matchersParam = new CodeParameterDeclarationExpression(matchersType, "matchers");

            matchersParam.CustomAttributes.Add(new CodeAttributeDeclaration("System.ParamArrayAttribute"));
            m.Parameters.Add(matchersParam);

            m.Statements.AddCheck("Self", "self");
            m.Statements.ThrowWhenArgumentIsNull("matchers");

            var loop = new StringBuilder();

            loop.Append("            foreach (var m in matchers) {\n");
            loop.Append("              var r = m (self.Item1");
            for (int i = 1; i < n; ++i)
            {
                loop.Append(", self.").Append(Tuple.Item(n, i));
            }
            loop.Append(");\n");
            loop.Append("              if (r.HasValue)\n");
            loop.Append("                return r.Value;\n");
            loop.Append("            }");
            m.Statements.Add(new CodeSnippetStatement(loop.ToString()));
            m.Statements.Add(
                new CodeThrowExceptionStatement(
                    new CodeObjectCreateExpression(
                        new CodeTypeReference("System.InvalidOperationException"),
                        new CodePrimitiveExpression("no match"))));

            var fref = "<see cref=\"T:System.Func{" + Types.GetTypeParameterList(n) + ",Cadenza.Maybe{TResult}}\" />";
            var tref = "<see cref=\"T:Cadenza.Tuple{" + Types.GetTypeParameterList(n) + "}\" />";

            m.Comments.AddDocs(
                XmlDocs.TypeParams(m.TypeParameters),
                XmlDocs.Param("self", "A " + tref + " to match against."),
                XmlDocs.Param("matchers", "A " + fref,
                              "array containing the conversion routines to use to convert ",
                              "the current " + tref + " instance into a ",
                              "<typeparamref name=\"TResult\" /> value."),
                XmlDocs.Summary(
                    "Converts the current " + tref + " instance into a <typeparamref name=\"TResult\"/>."),
                XmlDocs.Returns(
                    "The <typeparamref name=\"TResult\"/> returned by one of the <paramref name=\"matchers\"/>."),
                XmlDocs.Remarks(
                    "<para>",
                    " <block subset=\"none\" type=\"behaviors\">",
                    "  <para>",
                    "   The current " + tref + " instance is converted into a ",
                    "   <typeparamref name=\"TResult\" /> instance by trying each",
                    "   " + fref,
                    "   within <paramref name=\"matchers\" />.",
                    "  </para>",
                    "  <para>",
                    "   This method returns ",
                    "   <see cref=\"P:Cadenza.Maybe{TResult}.Value\" /> ",
                    "   for the first delegate to return a",
                    "   <see cref=\"T:Cadenza.Maybe{TResult}\" /> instance",
                    "   where <see cref=\"P:Cadenza.Maybe{TResult}.HasValue\" />",
                    "   is <see langword=\"true\" />.",
                    "  </para>",
                    "  <para>",
                    "   If no " + fref,
                    "   returns a ",
                    "   <see cref=\"T:Cadenza.Maybe{TResult}\" /> instance",
                    "   where <see cref=\"P:Cadenza.Maybe{TResult}.HasValue\" />",
                    "   is <see langword=\"true\" />, then an",
                    "   <see cref=\"T:System.InvalidOperationException\" /> is thrown.",
                    "  </para>",
                    " </block>",
                    " <code lang=\"C#\">",
                    "var    a = Tuple.Create (1, 2);",
                    "string b = a.Match (",
                    "    (t, v) =&gt; Match.When ( t + v == 3, \"foo!\"),",
                    "    (t, v) =&gt; \"*default*\".Just ());",
                    "Console.WriteLine (b);  // prints \"foo!\"</code>",
                    "</para>"),
                XmlDocs.ArgumentNullException(new[] { "self", "matchers" }),
                XmlDocs.Exception(typeof(InvalidOperationException),
                                  "None of the ",
                                  "<see cref=\"T:System.Func{TSource,Cadenza.Maybe{TResult}}\" />",
                                  "delegates within <paramref name=\"matchers\" /> returned a ",
                                  "<see cref=\"T:Cadenza.Maybe{TResult}\" /> instance where",
                                  "<see cref=\"P:Cadenza.Maybe{TResult}.HasValue\" /> was",
                                  "<see langword=\"true\" />."));
            return(m);
        }
コード例 #2
0
ファイル: Delegates.cs プロジェクト: rikkus/cadenza
        CodeMemberMethod AddTimingsDocs(CodeMemberMethod m, int n, CodeTypeDeclaration t, CodeMemberMethod full)
        {
            m.Comments.AddDocs(
                GetTypeParameters(n, m.Parameters [0].Type),
                XmlDocs.Summary("Get timing information for delegate invocations."),
                XmlDocs.Param("self", "The " + XmlDocs.See(m.Parameters [0].Type) + " to generate timings for."),
                GetTimingsParameters(n),
                XmlDocs.Param("runs", "An <see cref=\"T:System.Int32\" /> containing the number of <see cref=\"T:System.TimeSpan\" /> values to return."),
                full == null
                                                ? XmlDocs.Param("loopsPerRun",
                                                                "An <see cref=\"T:System.Int32\" /> containing the number of " +
                                                                "times to invoke <paramref name=\"self\" /> for each " +
                                                                "<see cref=\"T:System.TimeSpan\" /> value returned.")
                                                : new[] { "" },
                XmlDocs.Returns(
                    "An " + XmlDocs.See(m.ReturnType),
                    "which will return the timing information for <paramref name=\"self\" />."));
            if (full != null)
            {
                var alt = new StringBuilder().Append("self.Timing (");
                Values(alt, n, 0, n);
                if (n > 0)
                {
                    alt.Append(", ");
                }
                alt.Append("runs, 1)");
                m.Comments.AddDocs(
                    XmlDocs.Remarks(
                        "<para>",
                        " This is equivalent to calling",
                        " " + XmlDocs.See(DefaultNamespace, t, full),
                        " with a <paramref name=\"loopsPerRun\" /> value of <c>1</c>,",
                        " e.g. as if by calling <c>" + alt.ToString() + "</c>.",
                        "</para>"),
                    "<seealso cref=\"" + XmlDocs.Cref(DefaultNamespace, t, full) + "\" />");
            }
            else
            {
                m.Comments.AddDocs(XmlDocs.Remarks(
                                       "<para>",
                                       " Generates <paramref name=\"runs\" /> <see cref=\"T:System.TimeSpan\" />",
                                       " instances, in which each <c>TimeSpan</c> instance is the amount of time",
                                       " required to execute <paramref name=\"self\" /> for",
                                       " <paramref name=\"loopsPerRun\" /> times.",
                                       "</para>"));
            }
            m.Comments.AddDocs(
                XmlDocs.Exception(typeof(ArgumentException),
                                  "<para>",
                                  " <paramref name=\"runs\" /> is negative.",
                                  "</para>",
                                  full != null ? new object[0] : new object[] {
                "<para>-or-</para>",
                "<para>",
                " <paramref name=\"loopsPerRun\" /> is negative.",
                "</para>"
            }),
                XmlDocs.ArgumentNullException("self"));

            return(m);
        }