Exemplo n.º 1
0
        private PropertyEntity ExtractProperty(PropertyDeclaration propertyDeclaration)
        {
            PropertyEntity propertyEntity = new PropertyEntity();

            propertyEntity.Name   = propertyDeclaration.Name;
            propertyEntity.Static = (propertyDeclaration.Modifier & Modifiers.Static) == Modifiers.Static;

            // Get the method's comment
            IEnumerable <Comment> comments = this.GetDocumentationCommentsBefore(propertyDeclaration);

            AppendComment(propertyEntity, comments);

            // Extract getter
            MethodEntity getterEntity = new MethodEntity();

            propertyEntity.Getter = getterEntity;

            // Extract signature from comments
            Comment signatureComment = comments.FirstOrDefault(c => CommentHelper.IsSignature(c.CommentText.Trim()));

            if (signatureComment != null)
            {
                getterEntity.Signature = signatureComment.Trim("Original signature is", "'", ";", "private");
            }

            // Extract selector
            MethodSelectorExtractor extractor = new MethodSelectorExtractor(getterEntity.Signature);

            getterEntity.Selector = extractor.Extract();

            // Parse the signature for return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(getterEntity.Signature);

            if (signatureEnumerator.MoveNext())
            {
                bool isOut, isByRef, isBlock;
                propertyEntity.Type = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), out isOut, out isByRef, out isBlock, this.Logger);
            }
            else
            {
                propertyEntity.Type = "Id";
            }

            if (propertyDeclaration.HasSetRegion)
            {
                MethodEntity setterEntity = new MethodEntity();
                setterEntity.Selector = "MISSING";

                MethodParameterEntity methodParameterEntity = new MethodParameterEntity();
                methodParameterEntity.Name = "value";
                methodParameterEntity.Type = propertyEntity.Type;
                setterEntity.Parameters.Add(methodParameterEntity);
                setterEntity.ReturnType = "void";

                propertyEntity.Setter = setterEntity;
            }

            return(propertyEntity);
        }
        public MethodEntity Parse(TypedEntity typedEntity, String selector, IEnumerable<XElement> elements)
        {
            MethodEntity methodEntity = new MethodEntity();

            XElement declarationElement = (from el in elements
                                           where el.Name == "div" &&
                                                 el.Attribute("class") != null &&
                                                 el.Attribute("class").Value == "declaration_indent"
                                           select el).FirstOrDefault();

            XElement parameterElement = (from el in elements
                                         where el.Name == "div" &&
                                               el.Attribute("class") != null &&
                                               el.Attribute("class").Value == "param_indent"
                                         select el).FirstOrDefault();

            XElement returnValueElement = (from el in elements
                                           where el.Name == "h5" && el.Value.Trim() == "Return Value"
                                           select el).FirstOrDefault();

            //XElement discussionElement = (from el in elements
            //                              where el.Name == "h5" && el.Value.Trim() == "Discussion"
            //                              select el).FirstOrDefault();

            XElement availabilityElement = (from el in elements
                                            let term = el.Descendants("dt").FirstOrDefault()
                                            let definition = el.Descendants("dd").FirstOrDefault()
                                            where el.Name == "dl" &&
                                                  term != null &&
                                                  term.Value.Trim() == "Availability"
                                            select definition).FirstOrDefault();

            methodEntity.Selector = selector;
            methodEntity.Name = GetMethodName(methodEntity);

            methodEntity.Signature = declarationElement.TrimAll();
            methodEntity.Signature = methodEntity.Signature.TrimEnd(';');

            methodEntity.Static = methodEntity.Signature.StartsWith("+");

            // Extract abstract
            IEnumerable<XElement> abstractElements = elements.SkipWhile(el => el.Name != "p").TakeWhile(el => el.Name == "p");
            foreach (XElement element in abstractElements)
            {
                String line = element.TrimAll();
                if (!String.IsNullOrEmpty(line))
                {
                    methodEntity.Summary.Add(line);
                }
            }

            //// Extract discussion
            //if (discussionElement != null)
            //{
            //    IEnumerable<XElement> discussionElements = discussionElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p");
            //    foreach (XElement element in discussionElements)
            //    {
            //        String line = element.TrimAll();
            //        if (!String.IsNullOrEmpty(line))
            //        {
            //            methodEntity.Summary.Add(line);
            //        }
            //    }
            //}

            // Extract return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature);
            if (signatureEnumerator.MoveNext())
            {
                methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger);
            }
            else
            {
                methodEntity.ReturnType = "Id";
            }

            // Extract parameter type and name
            MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false);
            MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true);
            while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext())
            {
                MethodParameterEntity parameterEntity = new MethodParameterEntity();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name = parameterNamesEnumerator.Current.Trim();
                methodEntity.Parameters.Add(parameterEntity);
            }

            if (methodEntity.Parameters.Count > 0 && parameterElement != null)
            {
                XElement termList = parameterElement.Descendants("dl").FirstOrDefault();
                if (termList != null)
                {
                    IEnumerable<XElement> dtList = from el in termList.Elements("dt") select el;
                    IEnumerable<XElement> ddList = from el in termList.Elements("dd") select el;

                    if (dtList.Count() == ddList.Count())
                    {
                        // Iterate over definitions
                        for (int i = 0; i < dtList.Count(); i++)
                        {
                            String term = dtList.ElementAt(i).TrimAll();
                            //String summary = ddList.ElementAt(i).TrimAll();
                            IEnumerable<String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll());

                            // Find the parameter
                            MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term));
                            if (parameterEntity != null)
                            {
                                //parameterEntity.Summary.Add(summary);
                                foreach (string sum in summaries)
                                {
                                    parameterEntity.Summary.Add(sum);
                                }
                            }
                        }
                    }
                }
            }

            // Fix the name only after looking for the documentation
            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name);
            }

            // Get the summary for return type
            if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase) && returnValueElement != null)
            {
                IEnumerable<XElement> returnTypeElements = returnValueElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p");
                methodEntity.ReturnsDocumentation = String.Empty;
                foreach (XElement element in returnTypeElements)
                {
                    String line = element.TrimAll();
                    if (!String.IsNullOrEmpty(line))
                    {
                        methodEntity.ReturnsDocumentation += line;
                    }
                }
            }

            // Get the availability
            if (availabilityElement != null)
            {
                methodEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll());
            }

            return methodEntity;
        }
Exemplo n.º 3
0
        private MethodEntity ExtractMethod(MethodDeclaration methodDeclaration)
        {
            MethodEntity methodEntity = new MethodEntity();

            methodEntity.Name = methodDeclaration.Name;

            // Get the method's comment
            IEnumerable <Comment> comments = this.GetDocumentationCommentsBefore(methodDeclaration);

            // Extract signature from comments
            Comment signatureComment = comments.FirstOrDefault(c => CommentHelper.IsSignature(c.CommentText.Trim()));

            if (signatureComment != null)
            {
                methodEntity.Signature = signatureComment.Trim("Original signature is", "'", ";", "private");
            }
            AppendComment(methodEntity, comments);

            methodEntity.Static = (methodDeclaration.Modifier & Modifiers.Static) == Modifiers.Static;

            // Extract selector
            MethodSelectorExtractor extractor = new MethodSelectorExtractor(methodEntity.Signature);

            methodEntity.Selector = extractor.Extract();

            // Parse the signature for return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature);

            if (signatureEnumerator.MoveNext())
            {
                bool isOut, isByRef, isBlock;
                methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), out isOut, out isByRef, out isBlock, this.Logger);
            }
            else
            {
                methodEntity.ReturnType = "Id";
            }

            // Parse signature for parameter names and types
            MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false);
            MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true);

            while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext())
            {
                MethodParameterEntity parameterEntity = new MethodParameterEntity();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type    = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut   = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name    = parameterNamesEnumerator.Current.Trim();
                methodEntity.Parameters.Add(parameterEntity);
            }

            // Extract the corresponding comments
            foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters)
            {
                String s = comments.GetParameterDescription(methodParameterEntity.Name);
                methodParameterEntity.Summary.Add(s);
            }
            return(methodEntity);
        }
Exemplo n.º 4
0
        private PropertyEntity ExtractProperty(PropertyDeclaration propertyDeclaration)
        {
            PropertyEntity propertyEntity = new PropertyEntity ();
            propertyEntity.Name = propertyDeclaration.Name;
            propertyEntity.Static = (propertyDeclaration.Modifier & Modifiers.Static) == Modifiers.Static;

            // Get the method's comment
            IEnumerable<Comment> comments = this.GetDocumentationCommentsBefore (propertyDeclaration);
            AppendComment (propertyEntity, comments);

            // Extract getter
            MethodEntity getterEntity = new MethodEntity ();
            propertyEntity.Getter = getterEntity;

            // Extract signature from comments
            Comment signatureComment = comments.FirstOrDefault (c => CommentHelper.IsSignature (c.CommentText.Trim ()));
            if (signatureComment != null) {
                getterEntity.Signature = signatureComment.Trim ("Original signature is", "'", ";", "private");
            }

            // Extract selector
            MethodSelectorExtractor extractor = new MethodSelectorExtractor (getterEntity.Signature);
            getterEntity.Selector = extractor.Extract ();

            // Parse the signature for return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator (getterEntity.Signature);
            if (signatureEnumerator.MoveNext ()) {
                bool isOut, isByRef, isBlock;
                propertyEntity.Type = this.TypeManager.ConvertType (signatureEnumerator.Current.TrimAll (), out isOut, out isByRef, out isBlock, this.Logger);
            } else {
                propertyEntity.Type = "Id";
            }

            if (propertyDeclaration.HasSetRegion) {
                MethodEntity setterEntity = new MethodEntity ();
                setterEntity.Selector = "MISSING";

                MethodParameterEntity methodParameterEntity = new MethodParameterEntity ();
                methodParameterEntity.Name = "value";
                methodParameterEntity.Type = propertyEntity.Type;
                setterEntity.Parameters.Add (methodParameterEntity);
                setterEntity.ReturnType = "void";

                propertyEntity.Setter = setterEntity;
            }

            return propertyEntity;
        }
Exemplo n.º 5
0
        private MethodEntity ExtractMethod(MethodDeclaration methodDeclaration)
        {
            MethodEntity methodEntity = new MethodEntity ();
            methodEntity.Name = methodDeclaration.Name;

            // Get the method's comment
            IEnumerable<Comment> comments = this.GetDocumentationCommentsBefore (methodDeclaration);

            // Extract signature from comments
            Comment signatureComment = comments.FirstOrDefault (c => CommentHelper.IsSignature (c.CommentText.Trim ()));
            if (signatureComment != null) {
                methodEntity.Signature = signatureComment.Trim ("Original signature is", "'", ";", "private");
            }
            AppendComment (methodEntity, comments);

            methodEntity.Static = (methodDeclaration.Modifier & Modifiers.Static) == Modifiers.Static;

            // Extract selector
            MethodSelectorExtractor extractor = new MethodSelectorExtractor (methodEntity.Signature);
            methodEntity.Selector = extractor.Extract ();

            // Parse the signature for return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator (methodEntity.Signature);
            if (signatureEnumerator.MoveNext ()) {
                bool isOut, isByRef, isBlock;
                methodEntity.ReturnType = this.TypeManager.ConvertType (signatureEnumerator.Current.TrimAll (), out isOut, out isByRef, out isBlock, this.Logger);
            } else {
                methodEntity.ReturnType = "Id";
            }

            // Parse signature for parameter names and types
            MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator (methodEntity.Signature, false);
            MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator (methodEntity.Signature, true);
            while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext()) {
                MethodParameterEntity parameterEntity = new MethodParameterEntity ();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type = this.TypeManager.ConvertType (parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name = parameterNamesEnumerator.Current.Trim ();
                methodEntity.Parameters.Add (parameterEntity);
            }

            // Extract the corresponding comments
            foreach (MethodParameterEntity methodParameterEntity in methodEntity.Parameters) {
                String s = comments.GetParameterDescription (methodParameterEntity.Name);
                methodParameterEntity.Summary.Add (s);
            }
            return methodEntity;
        }
Exemplo n.º 6
0
        /// <summary>
        ///   Parses the specified method element.
        /// </summary>
        /// <param name = "methodElement">The method element.</param>
        /// <returns></returns>
        public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement)
        {
            MethodEntity methodEntity = new MethodEntity();

            XElement selectorElement = methodElement.Element("h3");

            methodEntity.Selector = selectorElement.TrimAll();
            methodEntity.Name     = GetMethodName(methodEntity);

            this.Logger.WriteLine("  Method '" + methodEntity.Selector + "'");

            // Extract signature
            XElement signatureElement = (from el in methodElement.Elements("div")
                                         where (String)el.Attribute("class") == "declaration"
                                         select el).FirstOrDefault();

            methodEntity.Signature = signatureElement.TrimAll();
            methodEntity.Signature = methodEntity.Signature.TrimEnd(';');
            methodEntity.Signature = methodEntity.Signature.Replace(", ...", ",..."); // MethodParametersEnumerator needs this format

            methodEntity.Static = methodEntity.Signature.StartsWith("+");

            // Extract abstract
            XElement abstractElement = (from el in methodElement.Elements("p")
                                        where (String)el.Attribute("class") == "abstract"
                                        select el).FirstOrDefault();

            methodEntity.Summary.Add(abstractElement.TrimAll());

            //// Extract discussion
            //IEnumerable<XElement> paragraphs = (from el in methodElement.Elements("p").Elements("p")
            //                                    where (String) el.Parent.Attribute("class") == "api discussion"
            //                                    select el);
            //foreach (XElement paragraph in paragraphs)
            //{
            //    methodEntity.Summary.Add(paragraph.TrimAll());
            //}

            // Extract return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature);

            if (signatureEnumerator.MoveNext())
            {
                methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger);
            }
            else
            {
                methodEntity.ReturnType = "Id";
            }

            // Extract parameter type and name
            MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false);
            MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true);

            while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext())
            {
                MethodParameterEntity parameterEntity = new MethodParameterEntity();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type    = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut   = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name    = parameterNamesEnumerator.Current.Trim();
                methodEntity.Parameters.Add(parameterEntity);

                // Correct names that end in a single period
                if (parameterEntity.Name.EndsWith(".") && !parameterEntity.Name.EndsWith(".."))
                {
                    parameterEntity.Name = parameterEntity.Name.Substring(0, parameterEntity.Name.Length - 1);
                }

                // Handle variadic parameters
                Match r = VARARG_PARAMETER_REGEX.Match(parameterEntity.Name);
                if (r.Success)
                {
                    // Fix the last parameter name by removing "..."
                    parameterEntity.Name = r.Groups [1].Value.Trim();

                    // Add a new variadic parameter
                    parameterEntity      = new MethodParameterEntity();
                    parameterEntity.Type = "params Object[]";
                    parameterEntity.Name = "values";
                    parameterEntity.Summary.Add("Variable argument values");
                    methodEntity.Parameters.Add(parameterEntity);
                }
            }

            // Extract parameter documentation
            if (methodEntity.Parameters.Count > 0)
            {
                XElement termList = (from el in methodElement.Elements("div").Elements("dl")
                                     where (String)el.Parent.Attribute("class") == "api parameters" &&
                                     (String)el.Attribute("class") == "termdef"
                                     select el).FirstOrDefault();
                if (termList != null)
                {
                    IEnumerable <XElement> dtList = from el in termList.Elements("dt") select el;
                    IEnumerable <XElement> ddList = from el in termList.Elements("dd") select el;

                    if (dtList.Count() == ddList.Count())
                    {
                        // Iterate over definitions
                        for (int i = 0; i < dtList.Count(); i++)
                        {
                            String term = dtList.ElementAt(i).TrimAll();
                            //String summary = ddList.ElementAt(i).TrimAll();
                            IEnumerable <String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll());

                            // Find the parameter
                            MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term) || (VARARG_PARAMETER_REGEX.Match(term).Success&& term.StartsWith(p.Name)));
                            if (parameterEntity != null)
                            {
                                //parameterEntity.Summary.Add(summary);
                                foreach (string sum in summaries)
                                {
                                    parameterEntity.Summary.Add(sum);
                                }
                            }
                        }
                    }
                }
            }

            // Fix the name only after looking for the documentation
            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name);
            }

            // Get the summary for return type
            if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase))
            {
                IEnumerable <String> documentations = (from el in methodElement.Elements("div").Elements("p")
                                                       where (String)el.Parent.Attribute("class") == "return_value"
                                                       select el.Value.TrimAll());
                methodEntity.ReturnsDocumentation = String.Join(" ", documentations.ToArray());
            }

            // Get the availability
            String minAvailability = (from el in methodElement.Elements("div").Elements("ul").Elements("li")
                                      where (String)el.Parent.Parent.Attribute("class") == "api availability"
                                      select el.Value).FirstOrDefault();

            methodEntity.MinAvailability = CommentHelper.ExtractAvailability(minAvailability.TrimAll());

            return(methodEntity);
        }
        /// <summary>
        ///   Parses the specified method element.
        /// </summary>
        /// <param name = "methodElement">The method element.</param>
        /// <returns></returns>
        public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement)
        {
            MethodEntity methodEntity = new MethodEntity();

            XElement selectorElement = methodElement.Element("h3");
            methodEntity.Selector = selectorElement.TrimAll();
            methodEntity.Name = GetMethodName(methodEntity);

            this.Logger.WriteLine("  Method '" + methodEntity.Selector + "'");

            // Extract signature
            XElement signatureElement = (from el in methodElement.Elements("div")
                                         where (String) el.Attribute("class") == "declaration"
                                         select el).FirstOrDefault();
            methodEntity.Signature = signatureElement.TrimAll();
            methodEntity.Signature = methodEntity.Signature.TrimEnd(';');
            methodEntity.Signature = methodEntity.Signature.Replace(", ...", ",..."); // MethodParametersEnumerator needs this format

            methodEntity.Static = methodEntity.Signature.StartsWith("+");

            // Extract abstract
            XElement abstractElement = (from el in methodElement.Elements("p")
                                        where (String) el.Attribute("class") == "abstract"
                                        select el).FirstOrDefault();
            methodEntity.Summary.Add(abstractElement.TrimAll());

            //// Extract discussion
            //IEnumerable<XElement> paragraphs = (from el in methodElement.Elements("p").Elements("p")
            //                                    where (String) el.Parent.Attribute("class") == "api discussion"
            //                                    select el);
            //foreach (XElement paragraph in paragraphs)
            //{
            //    methodEntity.Summary.Add(paragraph.TrimAll());
            //}

            // Extract return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature);
            if (signatureEnumerator.MoveNext())
            {
                methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger);
            }
            else
            {
                methodEntity.ReturnType = "Id";
            }

            // Extract parameter type and name
            MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false);
            MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true);
            while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext())
            {
                MethodParameterEntity parameterEntity = new MethodParameterEntity();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name = parameterNamesEnumerator.Current.Trim();
                methodEntity.Parameters.Add(parameterEntity);

                // Correct names that end in a single period
                if (parameterEntity.Name.EndsWith(".") && !parameterEntity.Name.EndsWith("..")) {
                    parameterEntity.Name = parameterEntity.Name.Substring(0, parameterEntity.Name.Length - 1);
                }

                // Handle variadic parameters
                Match r = VARARG_PARAMETER_REGEX.Match (parameterEntity.Name);
                if (r.Success)
                {
                    // Fix the last parameter name by removing "..."
                    parameterEntity.Name = r.Groups [1].Value.Trim ();

                    // Add a new variadic parameter
                    parameterEntity = new MethodParameterEntity();
                    parameterEntity.Type = "params Object[]";
                    parameterEntity.Name = "values";
                    parameterEntity.Summary.Add("Variable argument values");
                    methodEntity.Parameters.Add(parameterEntity);
                }
            }

            // Extract parameter documentation
            if (methodEntity.Parameters.Count > 0)
            {
                XElement termList = (from el in methodElement.Elements("div").Elements("dl")
                                     where (String) el.Parent.Attribute("class") == "api parameters"
                                           && (String) el.Attribute("class") == "termdef"
                                     select el).FirstOrDefault();
                if (termList != null)
                {
                    IEnumerable<XElement> dtList = from el in termList.Elements("dt") select el;
                    IEnumerable<XElement> ddList = from el in termList.Elements("dd") select el;

                    if (dtList.Count() == ddList.Count())
                    {
                        // Iterate over definitions
                        for (int i = 0; i < dtList.Count(); i++)
                        {
                            String term = dtList.ElementAt(i).TrimAll();
                            //String summary = ddList.ElementAt(i).TrimAll();
                            IEnumerable<String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll());

                            // Find the parameter
                            MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term) || (VARARG_PARAMETER_REGEX.Match(term).Success && term.StartsWith(p.Name)));
                            if (parameterEntity != null)
                            {
                                //parameterEntity.Summary.Add(summary);
                                foreach (string sum in summaries)
                                {
                                    parameterEntity.Summary.Add(sum);
                                }
                            }
                        }
                    }
                }
            }

            // Fix the name only after looking for the documentation
            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name);
            }

            // Get the summary for return type
            if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase))
            {
                IEnumerable<String> documentations = (from el in methodElement.Elements("div").Elements("p")
                                                      where (String) el.Parent.Attribute("class") == "return_value"
                                                      select el.Value.TrimAll());
                methodEntity.ReturnsDocumentation = String.Join(" ", documentations.ToArray());
            }

            // Get the availability
            String minAvailability = (from el in methodElement.Elements("div").Elements("ul").Elements("li")
                                      where (String) el.Parent.Parent.Attribute("class") == "api availability"
                                      select el.Value).FirstOrDefault();
            methodEntity.MinAvailability = CommentHelper.ExtractAvailability(minAvailability.TrimAll());

            return methodEntity;
        }
        public MethodEntity Parse(TypedEntity typedEntity, String selector, IEnumerable <XElement> elements)
        {
            MethodEntity methodEntity = new MethodEntity();

            XElement declarationElement = (from el in elements
                                           where el.Name == "div" &&
                                           el.Attribute("class") != null &&
                                           el.Attribute("class").Value == "declaration_indent"
                                           select el).FirstOrDefault();

            XElement parameterElement = (from el in elements
                                         where el.Name == "div" &&
                                         el.Attribute("class") != null &&
                                         el.Attribute("class").Value == "param_indent"
                                         select el).FirstOrDefault();

            XElement returnValueElement = (from el in elements
                                           where el.Name == "h5" && el.Value.Trim() == "Return Value"
                                           select el).FirstOrDefault();

            //XElement discussionElement = (from el in elements
            //                              where el.Name == "h5" && el.Value.Trim() == "Discussion"
            //                              select el).FirstOrDefault();

            XElement availabilityElement = (from el in elements
                                            let term = el.Descendants("dt").FirstOrDefault()
                                                       let definition = el.Descendants("dd").FirstOrDefault()
                                                                        where el.Name == "dl" &&
                                                                        term != null &&
                                                                        term.Value.Trim() == "Availability"
                                                                        select definition).FirstOrDefault();

            methodEntity.Selector = selector;
            methodEntity.Name     = GetMethodName(methodEntity);

            methodEntity.Signature = declarationElement.TrimAll();
            methodEntity.Signature = methodEntity.Signature.TrimEnd(';');

            methodEntity.Static = methodEntity.Signature.StartsWith("+");

            // Extract abstract
            IEnumerable <XElement> abstractElements = elements.SkipWhile(el => el.Name != "p").TakeWhile(el => el.Name == "p");

            foreach (XElement element in abstractElements)
            {
                String line = element.TrimAll();
                if (!String.IsNullOrEmpty(line))
                {
                    methodEntity.Summary.Add(line);
                }
            }

            //// Extract discussion
            //if (discussionElement != null)
            //{
            //    IEnumerable<XElement> discussionElements = discussionElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p");
            //    foreach (XElement element in discussionElements)
            //    {
            //        String line = element.TrimAll();
            //        if (!String.IsNullOrEmpty(line))
            //        {
            //            methodEntity.Summary.Add(line);
            //        }
            //    }
            //}

            // Extract return type
            MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature);

            if (signatureEnumerator.MoveNext())
            {
                methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger);
            }
            else
            {
                methodEntity.ReturnType = "Id";
            }

            // Extract parameter type and name
            MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false);
            MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true);

            while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext())
            {
                MethodParameterEntity parameterEntity = new MethodParameterEntity();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type    = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut   = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name    = parameterNamesEnumerator.Current.Trim();
                methodEntity.Parameters.Add(parameterEntity);
            }

            if (methodEntity.Parameters.Count > 0 && parameterElement != null)
            {
                XElement termList = parameterElement.Descendants("dl").FirstOrDefault();
                if (termList != null)
                {
                    IEnumerable <XElement> dtList = from el in termList.Elements("dt") select el;
                    IEnumerable <XElement> ddList = from el in termList.Elements("dd") select el;

                    if (dtList.Count() == ddList.Count())
                    {
                        // Iterate over definitions
                        for (int i = 0; i < dtList.Count(); i++)
                        {
                            String term = dtList.ElementAt(i).TrimAll();
                            //String summary = ddList.ElementAt(i).TrimAll();
                            IEnumerable <String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll());

                            // Find the parameter
                            MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term));
                            if (parameterEntity != null)
                            {
                                //parameterEntity.Summary.Add(summary);
                                foreach (string sum in summaries)
                                {
                                    parameterEntity.Summary.Add(sum);
                                }
                            }
                        }
                    }
                }
            }

            // Fix the name only after looking for the documentation
            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name);
            }

            // Get the summary for return type
            if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase) && returnValueElement != null)
            {
                IEnumerable <XElement> returnTypeElements = returnValueElement.ElementsAfterSelf().TakeWhile(el => el.Name == "p");
                methodEntity.ReturnsDocumentation = String.Empty;
                foreach (XElement element in returnTypeElements)
                {
                    String line = element.TrimAll();
                    if (!String.IsNullOrEmpty(line))
                    {
                        methodEntity.ReturnsDocumentation += line;
                    }
                }
            }

            // Get the availability
            if (availabilityElement != null)
            {
                methodEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll());
            }

            return(methodEntity);
        }