예제 #1
0
        private IEnumerable <ParameterDoc> ParseParameters(XElement element)
        {
            List <ParameterDoc> list = new List <ParameterDoc>();

            foreach (XElement paramElement in element.Elements("param"))
            {
                string name        = paramElement.AttributeOrDefault("name")?.Trim();
                string description = paramElement.GetInnerXml().Trim();

                ParameterDoc parameterDoc = new ParameterDoc(name, description: description);
                list.Add(parameterDoc);
            }

            return(list);
        }
예제 #2
0
        private List <Tuple <ParamInfo, ParameterDoc> > GetParameters(IEnumerable <ParameterInfo> parameters)
        {
            List <Tuple <ParamInfo, ParameterDoc> > result = new List <Tuple <ParamInfo, ParameterDoc> >();

            foreach (ParameterInfo parameter in parameters)
            {
                ParameterKind parameterKind = default;
                if (parameter.IsIn)
                {
                    parameterKind |= ParameterKind.In;
                }
                if (parameter.IsOut)
                {
                    parameterKind |= ParameterKind.Out;
                }
                if (parameter.IsOptional)
                {
                    parameterKind |= ParameterKind.Optional;
                }
                if (parameter.HasDefaultValue)
                {
                    parameterKind |= ParameterKind.HasDefaultValue;
                }
                if (parameter.ParameterType.IsByRef)
                {
                    parameterKind |= ParameterKind.Ref;
                }

                ParamInfo paramInfo = new ParamInfo(ConvertTypeToPopulatedType(parameter.ParameterType),
                                                    parameter.Name, parameterKind);
                ParameterDoc parameterDoc = new ParameterDoc(parameter.Name,
                                                             ConvertTypeToNameInfo(parameter.ParameterType), parameterKind);

                result.Add(new Tuple <ParamInfo, ParameterDoc>(paramInfo, parameterDoc));
            }

            return(result);
        }
예제 #3
0
        private static ICollection <ParameterDoc> GetParameterDocs(PythonFunction pf)
        {
            ParameterDoc[] res = new ParameterDoc[pf.ArgNames.Length];

            for (int i = 0; i < res.Length; i++)
            {
                ParameterFlags flags = ParameterFlags.None;
                if (i == pf.ExpandDictPosition)
                {
                    flags |= ParameterFlags.ParamsDict;
                }
                else if (i == pf.ExpandListPosition)
                {
                    flags |= ParameterFlags.ParamsArray;
                }

                res[i] = new ParameterDoc(
                    pf.ArgNames[i],
                    flags
                    );
            }
            return(res);
        }
예제 #4
0
        /// <summary>
        /// Creates a DLR OverloadDoc object which describes information about this overload.
        /// </summary>
        /// <param name="info">The method to document</param>
        /// <param name="name">The name of the method if it should override the name in the MethodBase</param>
        /// <param name="endParamSkip">Parameters to skip at the end - used for removing the value on a setter method</param>
        /// <param name="includeSelf">true to include self on instance methods</param>
        public static OverloadDoc GetOverloadDoc(MethodBase info, string name, int endParamSkip, bool includeSelf)
        {
            string summary = null, returns = null;
            List <KeyValuePair <string, string> > parameters = null;

#if FEATURE_XMLDOC
            GetXmlDoc(info, out summary, out returns, out parameters);
#endif

            StringBuilder retType = new StringBuilder();

            int        returnCount = 0;
            MethodInfo mi          = info as MethodInfo;
            if (mi != null)
            {
                if (mi.ReturnType != typeof(void))
                {
                    retType.Append(GetPythonTypeName(mi.ReturnType));
                    returnCount++;

                    try {
                        var typeAttrs = mi.ReturnParameter.GetCustomAttributes(typeof(SequenceTypeInfoAttribute), true);
                        if (typeAttrs.Any())
                        {
                            retType.Append(" (of ");
                            SequenceTypeInfoAttribute typeAttr = (SequenceTypeInfoAttribute)typeAttrs.First();
                            for (int curTypeAttr = 0; curTypeAttr < typeAttr.Types.Count; curTypeAttr++)
                            {
                                if (curTypeAttr != 0)
                                {
                                    retType.Append(", ");
                                }

                                retType.Append(GetPythonTypeName(typeAttr.Types[curTypeAttr]));
                            }
                            retType.Append(")");
                        }
                    }
                    catch (IndexOutOfRangeException) { } // swallow bug in .NET Core

                    try {
                        var dictTypeAttrs = mi.ReturnParameter.GetCustomAttributes(typeof(DictionaryTypeInfoAttribute), true);
                        if (dictTypeAttrs.Any())
                        {
                            var dictTypeAttr = (DictionaryTypeInfoAttribute)dictTypeAttrs.First();
                            retType.Append(String.Format(" (of {0} to {1})", GetPythonTypeName(dictTypeAttr.KeyType), GetPythonTypeName(dictTypeAttr.ValueType)));
                        }
                    }
                    catch (IndexOutOfRangeException) { } // swallow bug in .NET Core
                }

                if (name == null)
                {
                    var hashIndex = mi.Name.IndexOf('#');
                    if (hashIndex == -1)
                    {
                        name = mi.Name;
                    }
                    else
                    {
                        name = mi.Name.Substring(0, hashIndex);
                    }
                }
            }
            else if (name == null)
            {
                name = "__new__";
            }

            // For generic methods display either type parameters (for unbound methods) or
            // type arguments (for bound ones).
            if (mi != null && mi.IsGenericMethod)
            {
                Type[]        typePars = mi.GetGenericArguments();
                bool          unbound  = mi.ContainsGenericParameters;
                StringBuilder tmp      = new StringBuilder();
                tmp.Append(name);
                tmp.Append("[");
                if (typePars.Length > 1)
                {
                    tmp.Append("(");
                }

                bool insertComma = false;
                foreach (Type t in typePars)
                {
                    if (insertComma)
                    {
                        tmp.Append(", ");
                    }
                    if (unbound)
                    {
                        tmp.Append(t.Name);
                    }
                    else
                    {
                        tmp.Append(GetPythonTypeName(t));
                    }
                    insertComma = true;
                }

                if (typePars.Length > 1)
                {
                    tmp.Append(")");
                }
                tmp.Append("]");
                name = tmp.ToString();
            }

            List <ParameterDoc> paramDoc = new List <ParameterDoc>();
            if (mi == null)
            {
                if (name == "__new__")
                {
                    // constructor, auto-insert cls
                    paramDoc.Add(new ParameterDoc("cls", "type"));
                }
            }
            else if (!mi.IsStatic && includeSelf)
            {
                paramDoc.Add(new ParameterDoc("self", GetPythonTypeName(mi.DeclaringType)));
            }

            ParameterInfo[] pis = info.GetParameters();
            for (int i = 0; i < pis.Length - endParamSkip; i++)
            {
                ParameterInfo pi = pis[i];
                if (i == 0 && pi.ParameterType == typeof(CodeContext))
                {
                    // hide CodeContext parameters
                    continue;
                }

                if ((pi.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out || pi.ParameterType.IsByRef)
                {
                    if (returnCount == 1)
                    {
                        retType.Insert(0, "(");
                    }

                    if (returnCount != 0)
                    {
                        retType.Append(", ");
                    }

                    returnCount++;

                    retType.Append(GetPythonTypeName(pi.ParameterType));

                    if ((pi.Attributes & ParameterAttributes.Out) == ParameterAttributes.Out)
                    {
                        continue;
                    }
                }

                ParameterFlags flags = ParameterFlags.None;
                if (pi.IsDefined(typeof(ParamArrayAttribute), false))
                {
                    flags |= ParameterFlags.ParamsArray;
                }
                else if (pi.IsDefined(typeof(ParamDictionaryAttribute), false))
                {
                    flags |= ParameterFlags.ParamsDict;
                }

                string paramDocString = null;
                if (parameters != null)
                {
                    foreach (var paramXmlDoc in parameters)
                    {
                        if (paramXmlDoc.Key == pi.Name)
                        {
                            paramDocString = paramXmlDoc.Value;
                            break;
                        }
                    }
                }

                paramDoc.Add(
                    new ParameterDoc(
                        pi.Name ?? "",  // manufactured methods, such as string[].ctor(int) can have no parameter names.
                        pi.ParameterType.IsGenericParameter ? pi.ParameterType.Name : GetPythonTypeName(pi.ParameterType),
                        paramDocString,
                        flags
                        )
                    );
            }

            if (returnCount > 1)
            {
                retType.Append(')');
            }

            ParameterDoc retDoc = new ParameterDoc(String.Empty, retType.ToString(), returns);

            return(new OverloadDoc(
                       name,
                       summary,
                       paramDoc,
                       retDoc
                       ));
        }
예제 #5
0
        public static void Main(string[] args)
        {
            try {
                // load .dll files in the current directory to
                foreach (var file in Directory.GetFiles(Environment.CurrentDirectory, "*", SearchOption.AllDirectories))
                {
                    if (file.ToLowerInvariant().EndsWith(".dll"))
                    {
                        Assembly.LoadFile(file);
                    }
                }
                foreach (var file in Directory.GetFiles(Environment.CurrentDirectory, "*", SearchOption.AllDirectories))
                {
                    if (file.ToLowerInvariant().EndsWith(".xml"))
                    {
                        string xmlStr = File.ReadAllText(file);

                        xmlStr = Regex.Replace(xmlStr,
                                               "<see cref=\"[A-Z?]:(.*)\" \\/>",
                                               m => "&lt;a href=\"#" +
                                               m.Groups[1].Value.ToLower().Replace('.', '-') + "\"&gt;" +
                                               m.Groups[1].Value.Split('.').Last() +
                                               "&lt;/a&gt;"
                                               );

                        xmlStr = Regex.Replace(xmlStr,
                                               @"<(c|code)>([^<])*<\/(c|code)>",
                                               m => "&lt;" +
                                               m.Groups[1].Value +
                                               "&gt;" +
                                               m.Groups[2].Captures.Join() +
                                               "&lt;/" +
                                               m.Groups[1].Value +
                                               "&gt;"
                                               );

                        using (var stream = xmlStr.ToStream()) {
                            // TODO: Add reflection stuff, to:
                            // * determine if properties has setters or only getters

                            using (var xml = System.Xml.XmlReader.Create(stream)) {
                                while (xml.Read())
                                {
                                    if (xml.IsStartElement())
                                    {
                                        BaseDoc CurrentDoc = null;

                                        switch (xml.Name)
                                        {
                                        case "assembly":
                                            CurrentAssembly = new AssemblyDoc();
                                            CurrentDoc      = CurrentAssembly;
                                            break;

                                        case "name":
                                            xml.Read();
                                            CurrentAssembly.Name = xml.Value;
                                            reflectedAssembly    = AppDomain.CurrentDomain.GetAssemblies().ToList().First(a => a.GetName().Name == xml.Value);
                                            break;

                                        case "member":
                                            var  memberName = xml["name"];
                                            char type       = memberName[0];

                                            if (memberName.Contains("Hooks"))
                                            {
                                                PreviousDoc = null;
                                                break;
                                            }

                                            switch (type)
                                            {
                                            case 'T':
                                                CurrentDoc    = new TypeDoc(CurrentAssembly);
                                                CurrentType   = CurrentDoc;
                                                reflectedType = reflectedAssembly.GetType(memberName.Substring(2));
                                                break;

                                            case 'P':
                                            case 'F':
                                                if (CurrentType == null || !memberName.Contains(CurrentType.Name.Substring(2)))
                                                {
                                                    string typename = memberName.GetTypeName();
                                                    CurrentType = new TypeDoc(CurrentAssembly)
                                                    {
                                                        Name = typename
                                                    };
                                                    reflectedType = reflectedAssembly.GetType(typename);
                                                }

                                                // if type == p => add property documentation else => add field doc.

                                                CurrentDoc = type == 'P' ? (new PropertyDoc(CurrentType as TypeDoc)
                                                {
                                                    Name = memberName.Substring(2),
                                                    Type = (from pinfo in reflectedType.GetProperties()
                                                            where pinfo.Name == memberName.GetMemberName()
                                                            select pinfo.PropertyType).FirstOrDefault()
                                                } as BaseDoc)
                                                            : (new FieldDoc(CurrentType as TypeDoc)
                                                {
                                                    Name = memberName.Substring(2),
                                                    Type = (from finfo in reflectedType.GetFields()
                                                            where finfo.Name == memberName.GetMemberName()
                                                            select finfo.FieldType).FirstOrDefault()
                                                } as BaseDoc);
                                                break;

                                            case 'M':
                                                // check if the method is a method of the _current_ type, if it's not then it means the type of this method is not _documented_
                                                // so we add an empty doc for it here
                                                if (CurrentType == null || !memberName.Contains(CurrentType.Name.Substring(2)))
                                                {
                                                    string typename = memberName.GetTypeName();
                                                    CurrentType = new TypeDoc(CurrentAssembly)
                                                    {
                                                        Name = typename
                                                    };
                                                    reflectedType = reflectedAssembly.GetType(typename);
                                                }

                                                reflectedMethodParams = new List <Type>();

                                                string methodname = memberName.GetMemberName();

                                                string paramtypes = Regex.Match(memberName, "\\(([\\.,A-z0-9])*\\)").Groups[1].Captures.Join();

                                                foreach (var paramtype in paramtypes.Split(','))
                                                {
                                                    Type typ = null;
                                                    if (!TryFindType(paramtype, out typ))
                                                    {
                                                        var paramtype2 = Regex.Replace(paramtype, "(.*)\\.([A-z]*)$", "$1+$2");
                                                        TryFindType(paramtype2, out typ);
                                                    }
                                                    if (typ != null)
                                                    {
                                                        reflectedMethodParams.Add(typ);
                                                    }
                                                }

                                                if (!methodname.Contains('#'))
                                                {
                                                    reflectedMethod = reflectedType.GetMethod(methodname, reflectedMethodParams.ToArray());
                                                }
                                                else
                                                {
                                                    reflectedMethod = reflectedType.GetConstructor(reflectedMethodParams.ToArray());
                                                }

                                                // the method's name for constructors is #ctor, lets change that to the name of the Type
                                                if (memberName.Contains("#ctor"))
                                                {
                                                    CurrentDoc      = new ConstructorDoc(CurrentType as TypeDoc);
                                                    CurrentDoc.Name = memberName.Replace("#ctor", Regex.Match(memberName, ".([A-z]+).#").Groups[1].Value).Substring(2);
                                                    CurrentDoc.Name = CurrentDoc.Name.Substring(0, CurrentDoc.Name.IndexOf("("));
                                                }
                                                else
                                                {
                                                    CurrentDoc = new MethodDoc(CurrentType as TypeDoc);
                                                }

                                                CurrentMethod = CurrentDoc;
                                                currentParam  = 0;

                                                if (reflectedMethod is MethodInfo)
                                                {
                                                    CurrentMethod["ReturnType"] = (reflectedMethod as MethodInfo).ReturnType;
                                                }
                                                else
                                                {
                                                    CurrentMethod["ReturnType"] = reflectedType;
                                                }

                                                break;
                                            }
                                            if (CurrentDoc.Name == null)
                                            {
                                                if (memberName.Contains("("))
                                                {
                                                    CurrentDoc.Name = memberName.Substring(2, memberName.IndexOf("(") - 2);
                                                }
                                                else
                                                {
                                                    CurrentDoc.Name = memberName.Substring(2);
                                                }
                                            }
                                            break;

                                        case "summary":
                                            xml.Read();
                                            if (PreviousDoc != null)
                                            {
                                                PreviousDoc["Summary"] = xml.Value.Trim();
                                            }

                                            break;

                                        case "param":
                                            string name = xml["name"];
                                            xml.Read();
                                            CurrentDoc = new ParameterDoc(CurrentMethod)
                                            {
                                                Name    = name,
                                                Summary = xml.Value,
                                                Type    = reflectedMethodParams[currentParam]
                                            };
                                            currentParam++;
                                            break;

                                        case "csharp":
                                        case "javascript":
                                        case "python":
                                        case "lua":
                                            if (PreviousDoc is TypeDoc)
                                            {
                                                var cdoc = PreviousDoc as TypeDoc;
                                                var lang = xml.Name;
                                                xml.Read();

                                                cdoc.CodeExamples.Add(new CodeExample {
                                                    Code     = xml.Value,
                                                    Language = (Language)Enum.Parse(typeof(Language), lang)
                                                });
                                            }
                                            else if (PreviousDoc is MethodDoc)
                                            {
                                                var cdoc = PreviousDoc as MethodDoc;
                                                var lang = xml.Name;
                                                xml.Read();

                                                cdoc.CodeExamples.Add(new CodeExample {
                                                    Code     = xml.Value,
                                                    Language = (Language)Enum.Parse(typeof(Language), lang)
                                                });
                                            }
                                            break;

                                        case "value":
                                            xml.Read();
                                            PreviousDoc["defaultValue"] = xml.Value;
                                            break;
                                        }

                                        if (CurrentDoc != null)
                                        {
                                            PreviousDoc = CurrentDoc;
                                        }
                                    }
                                }
                            }
                            #if DEBUG
                            Console.WriteLine("CurrentAssembly is: " + Environment.NewLine + CurrentAssembly);
                            #endif
                            CurrentAssembly.ToFile();
                        }
                    }
                }
            } catch (Exception ex) {
                Console.WriteLine(ex.ToString());
                Console.WriteLine(ex.StackTrace);
            }
        }