Exemple #1
0
        /// <summary>
        /// Returns comments for the class method. May return null object is comments for method
        /// are missing in XML documentation file.
        /// Returned comments tags:
        /// Summary, Remarks, Parameters (if present), Responses (if present), Returns
        /// </summary>
        /// <param name="methodInfo"></param>
        /// <param name="nullIfNoComment">Return null if comment for method is not available</param>
        /// <returns></returns>
        public MethodComments GetMethodComments(MethodBase methodInfo, bool nullIfNoComment)
        {
            var methodNode = GetXmlMemberNode(methodInfo.MethodId(), methodInfo?.ReflectedType);

            if (nullIfNoComment && methodNode == null)
            {
                return(null);
            }
            var comments = new MethodComments();

            return(GetComments(methodInfo, comments, methodNode));
        }
Exemple #2
0
        protected MethodComments GetComments(MethodBase methodInfo, MethodComments comments, XPathNavigator node)
        {
            if (node == null)
            {
                return(comments);
            }

            GetCommonComments(comments, node);
            comments.Parameters     = GetParametersComments(node);
            comments.TypeParameters = GetNamedComments(node, TypeParamXPath, NameAttribute);
            comments.Returns        = GetReturnsComment(node);
            comments.Responses      = GetNamedComments(node, ResponsesXPath, CodeAttribute);
            comments = ResolveInheritdocComments(comments, methodInfo);
            return(comments);
        }
Exemple #3
0
        private MethodComments ResolveInheritdocComments(MethodComments comments, MethodBase methodInfo)
        {
            if (!NeedsResolving(comments) ||
                comments?.Parameters?.Count > 0 ||
                !string.IsNullOrEmpty(comments?.Returns) ||
                comments?.Responses?.Count > 0 ||
                comments?.TypeParameters?.Count > 0)
            {
                return(comments);
            }

            // If an explicit cref attribute is specified, the documentation from
            // the specified namespace/type/member is inherited.
            if (GetCrefComments(comments.Inheritdoc.Cref, methodInfo.ReflectedType, comments,
                                (node) => GetComments(methodInfo, comments, node)))
            {
                return(comments);
            }

            // For constructors:
            // - Search backwards up the type inheritance chain for a constructor
            //   with a matching signature.
            // - If a match is found, its documentation is inherited.
            if (methodInfo.IsConstructor)
            {
                var baseClass            = methodInfo.ReflectedType.BaseType;
                var constructorSignature = methodInfo.GetParameters()
                                           .Select(p => p.ParameterType).ToArray();
                while (baseClass != null)
                {
                    var baseConstructor = baseClass.GetConstructor(
                        BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                        null, CallingConventions.Any, constructorSignature, null);
                    if (baseConstructor != null)
                    {
                        var newComments = GetMethodComments(baseConstructor);
                        if (newComments == null)
                        {
                            return(comments);
                        }
                        newComments.Inheritdoc = comments.Inheritdoc;
                        return(newComments);
                    }
                    baseClass = baseClass.BaseType;
                }
                return(comments);
            }

            // For virtual members and interface implementations:
            // - If the member is an override, documentation is inherited from the
            //   member it overrides.
            // - If the member is part of an interface, documentation is inherited
            //   from the interface member being implemented.
            var interfaceDeclaration = methodInfo.ReflectedType
                                       .GetTypeInfo()
                                       .ImplementedInterfaces
                                       .Select(ii => methodInfo.ReflectedType.GetInterfaceMap(ii))
                                       .SelectMany(map => Enumerable.Range(0, map.TargetMethods.Length)
                                                   .Where(n => map.TargetMethods[n] == methodInfo)
                                                   .Select(n => map.InterfaceMethods[n]))
                                       .FirstOrDefault();

            if (interfaceDeclaration != null)
            {
                var newComments = GetMethodComments(interfaceDeclaration);
                if (newComments == null)
                {
                    return(comments);
                }
                newComments.Inheritdoc = comments.Inheritdoc;
                return(newComments);
            }

            if (methodInfo.IsVirtual)
            {
                var baseMethod = (methodInfo as MethodInfo)?.GetBaseDefinition();
                if (baseMethod != null)
                {
                    var newComments = GetMethodComments(baseMethod);
                    if (newComments == null)
                    {
                        return(comments);
                    }
                    newComments.Inheritdoc = comments.Inheritdoc;
                    return(newComments);
                }
                return(comments);
            }


            return(comments);
        }