Ejemplo n.º 1
0
        private static FunctionDocIndexNode GetFunctionDocumentationNode(XmlReader xmlReader)
        {
            var functionDocumentationNode = new FunctionDocIndexNode
            {
                Name       = xmlReader.GetAttribute("name"),
                FullName   = xmlReader.GetAttribute("fullname"),
                Access     = xmlReader.GetAttribute("access"),
                Location   = xmlReader.GetAttribute("location"),
                LineNumber = int.Parse(xmlReader.GetAttribute("lineno")),
                HRef       = xmlReader.GetAttribute("href"),
                IsObsolete = xmlReader.GetAttribute("status") == "obsolete"
            };

            using (var xmlSubReader = xmlReader.ReadSubtree())
            {
                while (xmlSubReader.Read())
                {
                    if (xmlSubReader.NodeType == XmlNodeType.Element && xmlSubReader.Name == "parameter")
                    {
                        functionDocumentationNode.ParametersModifiers.Add(xmlSubReader.GetAttribute("left"));
                    }
                }
            }
            return(functionDocumentationNode);
        }
Ejemplo n.º 2
0
        public void DocumentFunction(Function function)
        {
            var nodeKey = function.OriginalName;

            if (function.IsDependent && !function.IsOperator && nodeKey.Contains('<'))
            {
                nodeKey = nodeKey.Substring(0, nodeKey.IndexOf('<'));
            }
            if (!this.functionNodes.ContainsKey(nodeKey))
            {
                return;
            }

            var lineStart             = function.LineNumberStart;
            var lineEnd               = function.LineNumberEnd;
            var functions             = this.functionNodes[nodeKey];
            var unit                  = function.OriginalNamespace.TranslationUnit;
            var location              = unit.FileName;
            FunctionDocIndexNode node = null;
            var nodes                 = functions.FindAll(
                f => f.Location == location &&
                (f.LineNumber == lineStart || f.LineNumber == lineEnd));

            // incredible but we actually have a case of different functions with the same name in headers with the same name at the same line
            if (nodes.Count > 0)
            {
                if (nodes.Count == 1)
                {
                    node = nodes[0];
                }
                else
                {
                    node = nodes.Find(n => n.FullName == function.QualifiedOriginalName);
                }
            }
            var @params         = function.Parameters.Where(p => p.Kind == ParameterKind.Regular).ToList();
            int realParamsCount = @params.Count(p => !string.IsNullOrWhiteSpace(p.OriginalName) || p.DefaultArgument == null);

            // functions can have different line numbers because of #defines
            if (node == null || node.HRef == null)
            {
                nodes = functions.FindAll(
                    f => CheckLocation(f.Location, location) &&
                    (f.FullName == function.QualifiedOriginalName || f.Name == function.OriginalName) &&
                    f.Access != "private" && f.ParametersModifiers.Count == realParamsCount);
                // HACK: work around https://bugreports.qt.io/browse/QTBUG-53994
                if (nodes.Count == 1)
                {
                    node = nodes[0];
                }
                else
                {
                    var paramTypes = @params.Select(p => p.Type.ToString()).ToList();
                    node = nodes.Find(
                        f => f.ParametersModifiers.SequenceEqual(paramTypes, new TypeInIndexEqualityComparer()));
                }
            }
            if (node != null && node.HRef != null)
            {
                var link = node.HRef.Split('#');
                var file = link[0];
                if (this.membersDocumentation.ContainsKey(file))
                {
                    var id  = link[1].Split('-');
                    var key = EscapeId(function.IsAmbiguous && node.Access == "private" ? id[0] : link[1]);
                    if (this.membersDocumentation[file].ContainsKey(key))
                    {
                        var docs = this.membersDocumentation[file][key];
                        var i    = 0;
                        // HACK: work around https://bugreports.qt.io/browse/QTBUG-53941
                        if (function.Namespace.Name == "QByteArray" &&
                            function.OriginalName == "qCompress" && @params.Count == 2)
                        {
                            docs = this.membersDocumentation[file][key + "-hack"];
                        }
                        foreach (Match match in regexParameters.Matches(docs[0].InnerHtml))
                        {
                            // variadic and void "parameters" are invalid
                            if (function.IsVariadic && @params.Count == i || match.Groups[1].Value == "void")
                            {
                                break;
                            }
                            var param = csharpSources.SafeIdentifier(match.Groups[1].Value);

                            if (i >= @params.Count)
                            {
                                break;
                            }
                            @params[i].Name = param;
                            if (function.IsDependent && function is Method && function.Namespace.IsDependent)
                            {
                                foreach (var specialization in ((Class)function.Namespace).Specializations)
                                {
                                    var specializedFunction = specialization.Methods.First(m => m.InstantiatedFrom == function);
                                    specializedFunction.Parameters.Where(p => p.Kind == ParameterKind.Regular).ElementAt(i).Name = param;
                                }
                            }
                            i++;
                        }
                        // TODO: create links in the "See Also" section
                        function.Comment = new RawComment
                        {
                            BriefText = StripTags(ConstructDocumentText(docs.Skip(1)))
                        };
                        if (node.IsObsolete)
                        {
                            AddObsoleteAttribute(function);
                        }
                        var @event = function.Namespace.Events.FirstOrDefault(e => e.OriginalDeclaration == function);
                        if (@event != null)
                        {
                            for (i = 0; i < function.Parameters.Count; i++)
                            {
                                @event.Parameters[i].Name = function.Parameters[i].Name;
                            }
                        }
                    }
                }
            }
        }