Beispiel #1
0
        public void DocumentFunction(Function function)
        {
            if (!this.functionNodes.ContainsKey(function.OriginalName))
            {
                return;
            }

            var lineStart = function.LineNumberStart.ToString();
            var lineEnd = function.LineNumberEnd.ToString();
            var functions = this.functionNodes[function.OriginalName];
            var node = functions.Find(
                f => f.Attribute("location").Value == function.TranslationUnit.FileName &&
                     (f.Attribute("lineno").Value == lineStart || f.Attribute("lineno").Value == lineEnd));
            // HACK: functions in qglobal.h have weird additional definitions just for docs
            if ((node == null || node.Attribute("href") == null) && function.TranslationUnit.FileName == "qglobal.h")
            {
                node = functions.Find(
                    c => c.Attribute("location").Value == function.TranslationUnit.FileName &&
                         c.Attribute("name").Value == function.OriginalName);
            }
            // HACK: some functions are "located" in a cpp, go figure...
            var @params = function.Parameters.Where(p => p.Kind == ParameterKind.Regular).ToList();
            if ((node == null || node.Attribute("href") == null) && function.Signature != null)
            {
                var qualifiedOriginalName = function.GetQualifiedName(decl => decl.OriginalName,
                    decl =>
                    {
                        var @class = decl.OriginalNamespace as Class;
                        return @class != null ? (@class.OriginalClass ?? @class) : decl.OriginalNamespace;
                    });
                var nodes = functions.Where(f => f.Attribute("fullname") != null &&
                                                 f.Attribute("fullname").Value == qualifiedOriginalName &&
                                                 f.Descendants("parameter").Count() == @params.Count).ToList();
                if (nodes.Count == 0)
                {
                    @params.RemoveAll(p => string.IsNullOrEmpty(p.OriginalName) && p.DefaultArgument != null);
                }
                nodes = functions.Where(f => f.Attribute("fullname") != null &&
                                             f.Attribute("fullname").Value == qualifiedOriginalName &&
                                             f.Descendants("parameter").Count() == @params.Count).ToList();
                if (nodes.Count == 0)
                {
                    var method = function as Method;
                    if (method != null && !method.IsStatic && function.OriginalFunction == null)
                    {
                        return;
                    }
                    nodes = functions.Where(f => f.Attribute("name").Value == function.OriginalName &&
                                                 f.Descendants("parameter").Count() == @params.Count).ToList();
                }
                if (nodes.Count == 1)
                {
                    node = nodes[0];
                }
                else
                {
                    if (function.Signature.Contains('('))
                    {
                        var startArgs = function.Signature.IndexOf('(') + 1;
                        var signature = function.Signature;
                        if (signature.Contains(": "))
                        {
                            signature = signature.Substring(0, signature.IndexOf(": ", StringComparison.Ordinal));
                        }
                        signature = signature.Substring(startArgs, signature.LastIndexOf(')') - startArgs);
                        signature = this.regexSpaceBetweenArgs.Replace(this.regexArgName.Replace(signature, "$1$3$5"), " ");
                        node = nodes.Find(f => string.Join(", ",
                            f.Descendants("parameter").Select(d => d.Attribute("left").Value.Replace(" *", "*").Replace(" &", "&"))) == signature);
                    }
                }
            }
            if (node != null && node.Attribute("href") != null)
            {
                var link = node.Attribute("href").Value.Split('#');
                var file = link[0];
                if (this.membersDocumentation.ContainsKey(file))
                {
                    var id = link[1].Split('-');
                    var key = EscapeId(function.IsAmbiguous && node.Attribute("access").Value == "private" ? id[0] : link[1]);
                    if (this.membersDocumentation[file].ContainsKey(key))
                    {
                        var docs = this.membersDocumentation[file][key];
                        var i = 0;
                        // HACK: work around bugs of the type of https://bugreports.qt.io/browse/QTBUG-46148
                        if ((function.OperatorKind == CXXOperatorKind.Greater && function.Namespace.Name == "QLatin1String" &&
                            @params[0].Type.ToString() == "QLatin1String") ||
                            ((function.OriginalName == "flush" || function.OriginalName == "reset") &&
                            function.Namespace.Name == "QTextStream" && @params.Count > 0))
                        {
                            docs = this.membersDocumentation[file][key + "-hack"];
                        }
                        foreach (Match match in Regex.Matches(docs[0].InnerHtml, @"<i>\s*(.+?)\s*</i>"))
                        {
                            @params[i].Name = Helpers.SafeIdentifier(match.Groups[1].Value);
                            i++;
                        }
                        // TODO: create links in the "See Also" section
                        function.Comment = new RawComment
                        {
                            BriefText = StripTags(ConstructDocumentText(docs.Skip(1)))
                        };
                        if (node.Attribute("status").Value == "obsolete")
                        {
                            AddObsoleteAttribute(function);
                        }
                    }
                }
            }
        }