Ejemplo n.º 1
0
        /// <summary>
        /// Generate a javascript "class"
        /// </summary>
        private static void GenerateTypeDocumentation(TextWriter writer, Type type, XmlDocument xmlDoc, ConsoleParameters parms, List <Type> enumerationTypes, List <Type> alreadyGenerated)
        {
            if (alreadyGenerated.Contains(type))
            {
                return;
            }
            else
            {
                alreadyGenerated.Add(type);
            }

            writer.WriteLine("// {0}", type.AssemblyQualifiedName);
            writer.WriteLine("/**");
            writer.WriteLine(" * @class");
            writer.WriteLine(" * @memberof {0}", parms.Namespace);
            writer.WriteLine(" * @public");
            if (type.IsAbstract)
            {
                writer.WriteLine(" * @abstract");
            }
            var jobject = type.GetCustomAttribute <JsonObjectAttribute>();

            if (type.BaseType != typeof(Object))
            {
                writer.WriteLine(" * @extends {0}.{1}", parms.Namespace, type.BaseType.GetCustomAttribute <JsonObjectAttribute>().Id);
            }

            // Lookup the summary information
            var typeDoc = xmlDoc.SelectSingleNode(String.Format("//*[local-name() = 'member'][@name = 'T:{0}']", type.FullName));

            if (typeDoc != null)
            {
                if (typeDoc.SelectSingleNode(".//*[local-name() = 'summary']") != null)
                {
                    writer.WriteLine(" * @summary {0}", typeDoc.SelectSingleNode(".//*[local-name() = 'summary']").InnerText.Replace("\r\n", ""));
                }
                if (typeDoc.SelectSingleNode(".//*[local-name() = 'remarks']") != null)
                {
                    writer.WriteLine(" * @description {0}", typeDoc.SelectSingleNode(".//*[local-name() = 'remarks']").InnerText.Replace("\r\n", "\r\n * ").Replace("()", ""));
                }
                if (typeDoc.SelectSingleNode(".//*[local-name() = 'example']") != null)
                {
                    writer.WriteLine(" * @example {0}", typeDoc.SelectSingleNode(".//*[local-name() = 'example']").InnerText.Replace("\r\n", ""));
                }
            }

            List <String> copyCommands = new List <string>();

            // Get all properties and document them
            foreach (var itm in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                if (itm.GetCustomAttribute <JsonPropertyAttribute>() == null && itm.GetCustomAttribute <SerializationReferenceAttribute>() == null)
                {
                    continue;
                }

                Type itmType = itm.PropertyType;
                if (itmType.IsGenericType)
                {
                    itmType = itmType.GetGenericArguments()[0];
                }

                var itmJobject = itmType.GetCustomAttribute <JsonObjectAttribute>();
                if (itmJobject == null)
                {
                    if (itmType.StripNullable().IsEnum)
                    {
                        itmJobject = new JsonObjectAttribute(String.Format("{0}.{1}", parms.Namespace, itmType.Name));
                    }
                    else if (!primitives.TryGetValue(itmType, out itmJobject))
                    {
                        itmJobject = new JsonObjectAttribute(itmType.Name);
                    }
                }
                else
                {
                    itmJobject = new JsonObjectAttribute(String.Format("{0}.{1}", parms.Namespace, itmJobject.Id));
                }

                var simpleAtt = itmType.GetCustomAttribute <SimpleValueAttribute>();
                if (simpleAtt != null)
                {
                    var simpleProperty = itmType.GetProperty(simpleAtt.ValueProperty);
                    if (!primitives.TryGetValue(simpleProperty.PropertyType, out itmJobject))
                    {
                        itmJobject = new JsonObjectAttribute(simpleProperty.PropertyType.Name);
                    }
                }

                var originalType = itmJobject.Id;

                // Is this a classified object? if so then the classifier values act as properties themselves
                var classAttr = itmType.GetCustomAttribute <ClassifierAttribute>();
                if (classAttr != null && itm.PropertyType.IsGenericType)
                {
                    itmJobject = new JsonObjectAttribute("object");
                }

                writer.Write(" * @property {{{0}}} ", itmJobject.Id);
                var jprop = itm.GetCustomAttribute <JsonPropertyAttribute>();
                var redir = itm.GetCustomAttribute <SerializationReferenceAttribute>();
                if (jprop != null)
                {
                    writer.Write(jprop.PropertyName);
                    copyCommands.Add(jprop.PropertyName);
                }
                else if (redir != null)
                {
                    var backingProperty = type.GetProperty(redir.RedirectProperty);
                    jprop = backingProperty.GetCustomAttribute <JsonPropertyAttribute>();
                    writer.Write("{0}Model [Delay loaded from {0}], ", jprop.PropertyName);
                    copyCommands.Add(jprop.PropertyName + "Model");
                }
                else
                {
                    writer.Write(itm.Name + "Model");
                    copyCommands.Add(itm.Name + "Model");
                }

                // Output documentation
                typeDoc = xmlDoc.SelectSingleNode(String.Format("//*[local-name() = 'member'][@name = 'P:{0}.{1}']", itm.DeclaringType.FullName, itm.Name));
                if (typeDoc != null)
                {
                    if (typeDoc.SelectSingleNode(".//*[local-name() = 'summary']") != null)
                    {
                        writer.Write(typeDoc.SelectSingleNode(".//*[local-name() = 'summary']").InnerText.Replace("\r\n", ""));
                    }
                }

                var bindAttr = itm.GetCustomAttribute <BindingAttribute>();
                if (itmType.StripNullable().IsEnum)
                {
                    bindAttr = new BindingAttribute(itmType.StripNullable());
                }

                if (bindAttr != null)
                {
                    enumerationTypes.Add(bindAttr.Binding);
                    writer.Write("(see: {{@link {0}.{1}}} for values)", parms.Namespace, bindAttr.Binding.Name);
                }
                writer.WriteLine();

                // Classified object? If so we need to clarify how the object is propogated
                if (classAttr != null && itm.PropertyType.IsGenericType)
                {
                    // Does the classifier have a binding
                    var classProperty = itmType.GetProperty(classAttr.ClassifierProperty);
                    if (classProperty.GetCustomAttribute <SerializationReferenceAttribute>() != null)
                    {
                        classProperty = itmType.GetProperty(classProperty.GetCustomAttribute <SerializationReferenceAttribute>().RedirectProperty);
                    }
                    bindAttr = classProperty.GetCustomAttribute <BindingAttribute>();
                    if (bindAttr != null)
                    {
                        enumerationTypes.Add(bindAttr.Binding);

                        // Binding attribute found so lets enumerate it
                        foreach (var fi in bindAttr.Binding.GetFields(BindingFlags.Public | BindingFlags.Static))
                        {
                            writer.Write(" * @property {{{0}}} {1}.{2} ", originalType, jprop.PropertyName, fi.Name, classProperty.GetCustomAttribute <JsonPropertyAttribute>()?.PropertyName);
                            typeDoc = xmlDoc.SelectSingleNode(String.Format("//*[local-name() = 'member'][@name = 'F:{0}.{1}']", fi.DeclaringType.FullName, fi.Name));
                            if (typeDoc != null)
                            {
                                if (typeDoc.SelectSingleNode(".//*[local-name() = 'summary']") != null)
                                {
                                    writer.Write(typeDoc.SelectSingleNode(".//*[local-name() = 'summary']").InnerText.Replace("\r\n", ""));
                                }
                            }
                            writer.WriteLine();
                        }
                        writer.WriteLine(" * @property {{{0}}} {1}.$other Unclassified", originalType, jprop.PropertyName);
                    }
                    else
                    {
                        writer.Write(" * @property {{{0}}} {1}.{2} ", originalType, jprop.PropertyName, "classifier");
                        writer.Write(" where classifier is from {{@link {0}.{1}}} {2}", parms.Namespace, classProperty.DeclaringType.GetCustomAttribute <JsonObjectAttribute>().Id, classProperty.GetCustomAttribute <JsonPropertyAttribute>()?.PropertyName);
                        writer.WriteLine();
                    }
                }
            }
            writer.WriteLine(" * @param {{{0}.{1}}} copyData Copy constructor (if present)", parms.Namespace, jobject.Id);

            writer.WriteLine(" */");
            writer.WriteLine("{0} : function(copyData) {{ ", jobject.Id);

            writer.WriteLine("\tthis.$type = '{0}';", jobject.Id);
            writer.WriteLine("\tif(copyData) {");
            copyCommands.Reverse();
            // Get all properties and document them
            foreach (var itm in copyCommands.Where(o => o != "$type"))
            {
                writer.WriteLine("\tthis.{0} = copyData.{0};", itm);
            }
            writer.WriteLine("\t}");

            writer.WriteLine("}},  // {0} ", jobject.Id);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generate enumeration documentation
        /// </summary>
        private static void GenerateEnumerationDocumentation(TextWriter writer, Type type, XmlDocument xmlDoc, ConsoleParameters parms)
        {
            writer.WriteLine("// {0}", type.AssemblyQualifiedName);
            writer.WriteLine("/**");
            writer.WriteLine(" * @enum {uuid}");
            writer.WriteLine(" * @memberof {0}", parms.Namespace);
            writer.WriteLine(" * @public");
            writer.WriteLine(" * @readonly");
            var jobject = type.GetCustomAttribute <JsonObjectAttribute>();

            if (jobject == null)
            {
                jobject = new JsonObjectAttribute(type.Name);
            }

            // Lookup the summary information
            var typeDoc = xmlDoc.SelectSingleNode(String.Format("//*[local-name() = 'member'][@name = 'T:{0}']", type.FullName));

            if (typeDoc != null)
            {
                if (typeDoc.SelectSingleNode(".//*[local-name() = 'summary']") != null)
                {
                    writer.WriteLine(" * @summary {0}", typeDoc.SelectSingleNode(".//*[local-name() = 'summary']").InnerText.Replace("\r\n", ""));
                }
                if (typeDoc.SelectSingleNode(".//*[local-name() = 'remarks']") != null)
                {
                    writer.WriteLine(" * @description {0}", typeDoc.SelectSingleNode(".//*[local-name() = 'remarks']").InnerText.Replace("\r\n", ""));
                }
                if (typeDoc.SelectSingleNode(".//*[local-name() = 'example']") != null)
                {
                    writer.WriteLine(" * @example {0}", typeDoc.SelectSingleNode(".//*[local-name() = 'example']").InnerText.Replace("\r\n", ""));
                }
            }
            writer.WriteLine(" */");
            writer.WriteLine("{0} : {{ ", jobject.Id);

            // Enumerate fields
            foreach (var fi in type.GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                writer.WriteLine("\t/** ");
                writer.Write("\t * ");
                typeDoc = xmlDoc.SelectSingleNode(String.Format("//*[local-name() = 'member'][@name = 'F:{0}.{1}']", fi.DeclaringType.FullName, fi.Name));
                if (typeDoc != null)
                {
                    if (typeDoc.SelectSingleNode(".//*[local-name() = 'summary']") != null)
                    {
                        writer.Write(typeDoc.SelectSingleNode(".//*[local-name() = 'summary']").InnerText.Replace("\r\n", ""));
                    }
                }
                writer.WriteLine();
                writer.WriteLine("\t */");


                writer.WriteLine("\t{0} : '{1}',", fi.Name, fi.GetValue(null));
            }

            writer.WriteLine("}},  // {0} ", jobject.Id);
        }