Ejemplo n.º 1
0
        /// <summary>
        /// Add <paramref name="typeparam"/> element to <paramref name="comment"/>
        /// Replace if a summary element exists.
        /// If the comment is attached to a method the param element is inserted at the correct position.
        /// </summary>
        /// <param name="comment">The <see cref="DocumentationCommentTriviaSyntax"/>.</param>
        /// <param name="typeparam"> The <see cref="XmlElementSyntax"/>.</param>
        /// <returns><paramref name="comment"/> with <paramref name="typeparam"/>.</returns>
        public static DocumentationCommentTriviaSyntax WithTypeParam(this DocumentationCommentTriviaSyntax comment, XmlElementSyntax typeparam)
        {
            if (comment is null)
            {
                throw new ArgumentNullException(nameof(comment));
            }

            if (typeparam.TryGetNameAttribute(out var attribute) &&
                attribute.Identifier is { } identifierName)
            {
                if (comment.TryGetTypeParam(identifierName.Identifier.ValueText, out var old))
                {
                    return(comment.ReplaceNode(old, typeparam));
                }

                if (TryGetPositionFromTypeParam(out var before, out var after))
                {
                    if (after is { })
                    {
                        return(comment.InsertBefore(after, typeparam));
                    }

                    return(comment.InsertAfter(before, typeparam));
                }

                foreach (var node in comment.Content)
                {
                    if (node is XmlElementSyntax e &&
                        (e.HasLocalName("param") ||
                         e.HasLocalName("returns") ||
                         e.HasLocalName("exception")))
                    {
                        return(comment.InsertBefore(e, typeparam));
                    }
                }

                return(comment.InsertAfter(comment.Content.OfType <XmlElementSyntax>().Last(), typeparam));
            }
Ejemplo n.º 2
0
        /// <summary>
        /// Add <paramref name="typeparam"/> element to <paramref name="comment"/>
        /// Replace if a summary element exists.
        /// If the comment is attached to a method the param element is inserted at the correct position.
        /// </summary>
        /// <param name="comment">The <see cref="DocumentationCommentTriviaSyntax"/>.</param>
        /// <param name="typeparam"> The <see cref="XmlElementSyntax"/>.</param>
        /// <returns><paramref name="comment"/> with <paramref name="typeparam"/>.</returns>
        public static DocumentationCommentTriviaSyntax WithTypeParam(this DocumentationCommentTriviaSyntax comment, XmlElementSyntax typeparam)
        {
            if (comment is null)
            {
                throw new ArgumentNullException(nameof(comment));
            }

            if (typeparam.TryGetNameAttribute(out var attribute) &&
                attribute.Identifier is IdentifierNameSyntax identifierName)
            {
                if (comment.TryGetTypeParam(identifierName.Identifier.ValueText, out var old))
                {
                    return(comment.ReplaceNode(old, typeparam));
                }

                if (TryGetPositionFromTypeParam(out var before, out var after))
                {
                    if (after != null)
                    {
                        return(comment.InsertBefore(after, typeparam));
                    }

                    return(comment.InsertAfter(before, typeparam));
                }

                foreach (var node in comment.Content)
                {
                    if (node is XmlElementSyntax e &&
                        (e.HasLocalName("param") ||
                         e.HasLocalName("returns") ||
                         e.HasLocalName("exception")))
                    {
                        return(comment.InsertBefore(e, typeparam));
                    }
                }

                return(comment.InsertAfter(comment.Content.OfType <XmlElementSyntax>().Last(), typeparam));
            }

            throw new ArgumentException("Element does not have a name attribute.", nameof(typeparam));

            bool TryGetPositionFromTypeParam(out XmlElementSyntax before, out XmlElementSyntax after)
            {
                before = null !;
                after  = null !;
                if (comment.TryFirstAncestor(out MemberDeclarationSyntax? member) &&
                    TryGetTypeParameterList(member, out var typeParameterList) &&
                    typeParameterList.Parameters.TrySingle(x => x.Identifier.ValueText == identifierName.Identifier.ValueText, out var parameter) &&
                    typeParameterList.Parameters.IndexOf(parameter) is var ordinal &&
                    ordinal >= 0)
                {
                    foreach (var node in comment.Content)
                    {
                        if (node is XmlElementSyntax e &&
                            e.HasLocalName("typeparam") &&
                            e.TryGetNameAttribute(out var nameAttribute) &&
                            typeParameterList.Parameters.TrySingle(x => x.Identifier.ValueText == nameAttribute.Identifier.Identifier.ValueText, out var other))
                        {
                            before = e;
                            if (ordinal < typeParameterList.Parameters.IndexOf(other))
                            {
                                after = e;
                                return(true);
                            }
                        }
                    }
                }

                return(before != null);