Example #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);
        }
 /// <summary>
 ///   Gets the type signature.
 /// </summary>
 protected static String GetTypeSignature(MethodParameterEntity methodParameterEntity)
 {
     return(String.Format(CultureInfo.CurrentCulture,
                          "{0}{1} {2}",
                          methodParameterEntity.IsOut ? "out " : (!methodParameterEntity.IsBlock && methodParameterEntity.IsByRef) ? "ref " : String.Empty,
                          methodParameterEntity.Type,
                          methodParameterEntity.Name));
 }
 /// <summary>
 ///   Gets the parameter for an invocation.
 /// </summary>
 protected static String GetInvocationParameter(MethodParameterEntity methodParameterEntity, MethodParameterEntity destinationMethodParameterEntity = null)
 {
     if (destinationMethodParameterEntity != null && !methodParameterEntity.Type.Equals(destinationMethodParameterEntity.Type))
     {
         return(String.Format(CultureInfo.CurrentCulture,
                              "{0}({1}) {2}",
                              methodParameterEntity.IsOut ? "out " : methodParameterEntity.IsByRef ? "ref " : String.Empty,
                              destinationMethodParameterEntity.Type,
                              methodParameterEntity.Name));
     }
     return(String.Format(CultureInfo.CurrentCulture,
                          "{0}{1}",
                          methodParameterEntity.IsOut ? "out " : methodParameterEntity.IsByRef ? "ref " : String.Empty,
                          methodParameterEntity.Name));
 }
Example #4
0
        protected static String GetMessageParameterList(MethodEntity methodEntity, MethodEntity innerMethodEntity, bool withColonFirst)
        {
            StringBuilder builder = new StringBuilder();

            int index = 1;

            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                MethodParameterEntity methodParameterEntity      = methodEntity.Parameters [i];
                MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity;

                if (!innerMethodParameterEntity.Generate)
                {
                    continue;
                }

                if (i > 0 || withColonFirst)
                {
                    builder.Append(", ");
                }

                if (innerMethodParameterEntity.IsOut)
                {
                    builder.AppendFormat("__local{0}", index++);
                }
                else if (innerMethodParameterEntity.IsByRef)
                {
                    builder.AppendFormat("__local{0}", index++);
                }
                else if (innerMethodParameterEntity.IsBlock)
                {
                    builder.AppendFormat("__local{0}", index++);
                }
                else
                {
                    if (String.Equals(methodParameterEntity.Type, innerMethodParameterEntity.Type))
                    {
                        builder.AppendFormat("{0}", innerMethodParameterEntity.Name);
                    }
                    else
                    {
                        builder.AppendFormat("({0}) {1}", innerMethodParameterEntity.Type, innerMethodParameterEntity.Name);
                    }
                }
            }

            return(builder.ToString());
        }
Example #5
0
        protected void GenerateLocalsMarshalling(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity)
        {
            int index = 1;

            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                MethodParameterEntity methodParameterEntity      = methodEntity.Parameters [i];
                MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity;

                if (methodParameterEntity.IsOut)
                {
                    if ("bool,char,byte,short,ushort,int,uint,long,ulong".Contains(methodParameterEntity.Type))                        // Boolean
                    // TODO: Add zeroing
                    {
                        index++;
                    }
                    else if ("float,double".Contains(methodParameterEntity.Type))
                    {
                        // TODO: Add zeroing
                        index++;
                    }
                    else if (IsMixedType(methodParameterEntity.Type))
                    {
                        // TODO: Add zeroing
                        index++;
                    }
                    else
                    {
                        this.Writer.WriteLineFormat(indent, "Marshal.WriteIntPtr(__local{0}, IntPtr.Zero);", index++);
                    }
                }
                else if (methodParameterEntity.IsByRef)
                {
                    if (IsMixedType(methodParameterEntity.Type))
                    {
                        this.Writer.WriteLineFormat(indent, "Marshal.StructureToPtr(({0}) {1}, __local{2}, false);", innerMethodParameterEntity.Type, methodParameterEntity.Name, index++);
                    }
                    else
                    {
                        this.Writer.WriteLineFormat(indent, "Marshal.StructureToPtr({0}, __local{1}, false);", methodParameterEntity.Name, index++);
                    }
                }
                else if (methodParameterEntity.IsBlock)
                {
                    index++;
                }
            }
        }
Example #6
0
        protected void GenerateLocalsDeallocation(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity)
        {
            int index = 1;

            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                MethodParameterEntity methodParameterEntity = methodEntity.Parameters [i];
                //MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity;

                if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef)
                {
                    this.Writer.WriteLineFormat(indent, "Marshal.FreeHGlobal(__local{0});", index++);
                }
                else if (methodParameterEntity.IsBlock)
                {
                    this.Writer.WriteLineFormat(indent, "__local{0}.Dispose();", index++);
                }
            }
        }
Example #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Monobjc.Tools.Generator.Model.Entities.FunctionEntity"/> class.
        /// </summary>
        public FunctionEntity(FunctionEntity functionEntity)
            : this()
        {
            this.MinAvailability = functionEntity.MinAvailability;
            this.Generate = functionEntity.Generate;
            this.Name = functionEntity.Name;
            this.ReturnsDocumentation = functionEntity.ReturnsDocumentation;
            this.ReturnType = functionEntity.ReturnType;
            this.Selector = functionEntity.Selector;
            this.Signature = functionEntity.Signature;
            this.Static = functionEntity.Static;
            this.Summary = new List<String> (functionEntity.Summary);

            foreach (MethodParameterEntity methodParameterEntity in functionEntity.Parameters) {
                MethodParameterEntity parameter = new MethodParameterEntity (methodParameterEntity);
                this.Parameters.Add (parameter);
            }

            this.GenerateConstructor = functionEntity.GenerateConstructor;
            this.SharedLibrary = functionEntity.SharedLibrary;
            this.EntryPoint = functionEntity.EntryPoint;
        }
Example #8
0
        protected void GenerateLocalsAllocation(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity)
        {
            int index = 1;

            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                MethodParameterEntity methodParameterEntity      = methodEntity.Parameters [i];
                MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity;

                if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef)
                {
                    if ("bool,char,byte,short,ushort,int,uint,long,ulong".Contains(methodParameterEntity.Type))
                    {
                        this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, methodParameterEntity.Type);
                    }
                    else if ("IntPtr".Contains(methodParameterEntity.Type))
                    {
                        this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(IntPtr.Size);", index++);
                    }
                    else if ("float,double".Contains(methodParameterEntity.Type))
                    {
                        this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, methodParameterEntity.Type);
                    }
                    else if (IsMixedType(methodParameterEntity.Type))
                    {
                        this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof ({1})));", index++, innerMethodParameterEntity.Type);
                    }
                    else
                    {
                        this.Writer.WriteLineFormat(indent, "IntPtr __local{0} = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (IntPtr)));", index++);
                    }
                }
                else if (methodParameterEntity.IsBlock)
                {
                    this.Writer.WriteLineFormat(indent, "Block __local{0} = ObjectiveCRuntime.CreateBlock({1});", index++, methodParameterEntity.Name);
                }
            }
        }
Example #9
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);
        }
Example #10
0
        /// <summary>
        ///   Parses the specified method element.
        /// </summary>
        /// <param name = "functionElement">The function element.</param>
        /// <returns></returns>
        public FunctionEntity Parse(TypedEntity typedEntity, XElement functionElement)
        {
            FunctionEntity functionEntity = new FunctionEntity();

            // Extract name
            String name = functionElement.TrimAll();

            functionEntity.Name = name;

            this.Logger.WriteLine("  Function '" + name + "'");

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

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

            // Extract declaration
            XElement declarationElement = (from el in functionElement.ElementsAfterSelf("pre")
                                           where (String)el.Attribute("class") == "declaration"
                                           select el).FirstOrDefault();

            String signature = declarationElement.TrimAll();

            if (signature.StartsWith("#define"))
            {
                this.Logger.WriteLine("SKIPPING define statement: " + name);
                return(null);
            }
            if (signature.StartsWith("typedef"))
            {
                this.Logger.WriteLine("SKIPPING define statement: " + name);
                return(null);
            }
            if (!signature.Contains("("))                // e.g. NS_DURING
            {
                this.Logger.WriteLine("SKIPPING non-function statement: " + name);
                return(null);
            }

            // Trim down signature
            while (signature.IndexOf("  ") != -1)
            {
                signature = signature.Replace("  ", " ");
            }
            functionEntity.Signature = signature;
            //Console.WriteLine("signature='" + signature + "'");

            // Parse signature
            int pos = signature.IndexOf(name);

            if (pos == -1)
            {
                this.Logger.WriteLine("MISMATCH between name and declaration: " + name);
                return(null);
            }
            String returnType   = signature.Substring(0, pos).Trim();
            int    paramsIndex  = pos + name.Length;
            int    paramsLength = signature.IndexOf(')') + 1 - paramsIndex;          // Stop before getting to function body
            String parameters   = signature.Substring(paramsIndex, paramsLength).Trim();

            parameters = parameters.Trim(';', '(', ')').Trim();
            if (parameters != "void")
            {
                foreach (string parameter in parameters.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    String parameterType = "NOTYPE";
                    String parameterName = "NONAME";

                    //Console.WriteLine("parameter='" + parameter + "'");
                    Match r = PARAMETER_REGEX.Match(parameter);
                    if (r.Success)
                    {
                        parameterType = r.Groups [2].Value.Trim();
                        parameterName = r.Groups [3].Value.Trim();
                    }
                    else if (parameter.Trim() == "...")
                    {
                        parameterType = "params Object[]";
                        parameterName = "values";
                    }
                    else
                    {
                        this.Logger.WriteLine("FAILED to parse parameter: " + parameter);
                        return(null);
                    }
                    parameterType = parameterType.Trim();

                    MethodParameterEntity parameterEntity = new MethodParameterEntity();
                    bool isOut, isByRef, isBlock;
                    parameterEntity.Type    = this.TypeManager.ConvertType(parameterType, out isOut, out isByRef, out isBlock, this.Logger);
                    parameterEntity.IsOut   = isOut;
                    parameterEntity.IsByRef = isByRef;
                    parameterEntity.IsBlock = isBlock;
                    parameterEntity.Name    = TypeManager.ConvertName(parameterName);
                    functionEntity.Parameters.Add(parameterEntity);
                }
            }

            // Extract return type
            functionEntity.ReturnType = this.TypeManager.ConvertType(returnType, this.Logger);

            // Extract parameter documentation
            if (functionEntity.Parameters.Count > 0)
            {
                XElement termList = (from el in functionElement.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();
                            IEnumerable <String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll());

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

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

            // Get the summary for return type
            if (!String.Equals(functionEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase))
            {
                XElement returnValueElement = (from el in functionElement.ElementsAfterSelf("div")
                                               where (String)el.Attribute("class") == "return_value"
                                               select el).FirstOrDefault();
                if (returnValueElement != null)
                {
                    IEnumerable <String> documentations = returnValueElement.Elements("p").Select(p => p.Value.TrimAll());
                    functionEntity.ReturnsDocumentation = String.Join(String.Empty, documentations.ToArray());
                }
            }

            //// Extract discussion
            //XElement discussionElement = (from el in functionElement.ElementsAfterSelf("div")
            //                              where (String) el.Attribute("class") == "api discussion"
            //                              select el).FirstOrDefault();
            //if (discussionElement != null)
            //{
            //    foreach (XElement paragraph in discussionElement.Elements("p"))
            //    {
            //        functionEntity.Summary.Add(paragraph.TrimAll());
            //    }
            //}

            // Get the availability
            XElement availabilityElement = (from el in functionElement.ElementsAfterSelf("div")
                                            where (String)el.Attribute("class") == "api availability"
                                            select el).FirstOrDefault();
            String minAvailability = availabilityElement.Elements("ul").Elements("li").FirstOrDefault().TrimAll();

            functionEntity.MinAvailability = CommentHelper.ExtractAvailability(minAvailability);

            return(functionEntity);
        }
        public FunctionEntity Parse(TypedEntity typedEntity, string name, IEnumerable<XElement> elements)
        {
            FunctionEntity functionEntity = new FunctionEntity ();

            XElement declarationElement = (from el in elements
                                           where el.Name == "div" &&
                el.Attribute ("class") != null &&
                el.Attribute ("class").Value == "declaration_indent"
                                           select el).FirstOrDefault ();
            declarationElement = declarationElement ?? (from el in elements
                                                        where el.Name == "pre"
                                                        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 ();

            functionEntity.Name = name;

            String signature = declarationElement.TrimAll ();
            if (signature.StartsWith ("#define")) {
                this.Logger.WriteLine ("SKIPPING define statement: " + name);
                return null;
            }
            if (!signature.Contains ("(")) { // e.g. NS_DURING
                this.Logger.WriteLine ("SKIPPING non-function statement: " + name);
                return null;
            }

            // Trim down signature
            while (signature.IndexOf("  ") != -1) {
                signature = signature.Replace ("  ", " ");
            }
            functionEntity.Signature = signature;
            //Console.WriteLine("signature='" + signature + "'");

            // 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)) {
                    functionEntity.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);
            //        }
            //    }
            //}

            // Parse signature
            signature = signature.Replace ("extern", String.Empty).Trim ();
            int pos = signature.IndexOf (name);
            if (pos == -1) {
                this.Logger.WriteLine ("MISMATCH between name and declaration: " + name);
                return null;
            }

            String returnType = signature.Substring (0, pos).Trim ();
            int paramsIndex = pos + name.Length;
            int paramsLength = signature.IndexOf(')') + 1 - paramsIndex; // Stop before getting to function body
            String parameters = signature.Substring (paramsIndex, paramsLength).Trim ();
            parameters = parameters.Trim (';', '(', ')').Trim();
            if (parameters != "void") {
                foreach (string parameter in parameters.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries)) {
                    String parameterType = "NOTYPE";
                    String parameterName = "NONAME";

                    //Console.WriteLine("parameter='" + parameter + "'");
                    Match r = PARAMETER_REGEX.Match (parameter);
                    if (r.Success) {
                        parameterType = r.Groups [2].Value.Trim ();
                        parameterName = r.Groups [3].Value.Trim ();
                    } else if (parameter.Trim () == "...") {
                        parameterType = "params Object[]";
                        parameterName = "values";
                    } else {
                        this.Logger.WriteLine ("FAILED to parse parameter: " + parameter);
                        return null;
                    }

                    MethodParameterEntity parameterEntity = new MethodParameterEntity ();
                    bool isOut, isByRef, isBlock;
                    parameterEntity.Type = this.TypeManager.ConvertType (parameterType, out isOut, out isByRef, out isBlock, this.Logger);
                    parameterEntity.IsOut = isOut;
                    parameterEntity.IsByRef = isByRef;
                    parameterEntity.IsBlock = isBlock;
                    parameterEntity.Name = TypeManager.ConvertName(parameterName);
                    functionEntity.Parameters.Add (parameterEntity);
                }
            }

            // Extract return type
            functionEntity.ReturnType = this.TypeManager.ConvertType (returnType, this.Logger);

            if (functionEntity.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 = functionEntity.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 < functionEntity.Parameters.Count; i++) {
                functionEntity.Parameters [i].Name = this.TypeManager.ConvertName (functionEntity.Parameters [i].Name);
            }

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

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

            return functionEntity;
        }
Example #12
0
        public FunctionEntity Parse(TypedEntity typedEntity, string name, IEnumerable <XElement> elements)
        {
            FunctionEntity functionEntity = new FunctionEntity();

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

            declarationElement = declarationElement ?? (from el in elements
                                                        where el.Name == "pre"
                                                        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();

            functionEntity.Name = name;

            String signature = declarationElement.TrimAll();

            if (signature.StartsWith("#define"))
            {
                this.Logger.WriteLine("SKIPPING define statement: " + name);
                return(null);
            }
            functionEntity.Signature = signature;

            // 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))
                {
                    functionEntity.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);
            //        }
            //    }
            //}

            // Parse signature
            signature = signature.Replace("extern", String.Empty).Trim();
            int pos = signature.IndexOf(name);

            if (pos == -1)
            {
                this.Logger.WriteLine("MISMATCH between name and declaration: " + name);
                return(null);
            }

            String returnType = signature.Substring(0, pos).Trim();
            String parameters = signature.Substring(pos + name.Length).Trim();

            parameters = parameters.Trim(';', '(', ')');
            if (parameters != "void")
            {
                foreach (string parameter in parameters.Split(new [] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    String parameterType = "NOTYPE";
                    String parameterName = "NONAME";

                    Match r = PARAMETER_REGEX.Match(parameter);
                    if (r.Success)
                    {
                        parameterType = r.Groups [2].Value.Trim();
                        parameterName = r.Groups [3].Value.Trim();
                    }
                    else if (parameter.Trim() == "...")
                    {
                        parameterType = "params Object[]";
                        parameterName = "values";
                    }
                    else
                    {
                        this.Logger.WriteLine("FAILED to parse parameter: " + parameter);
                        return(null);
                    }

                    MethodParameterEntity parameterEntity = new MethodParameterEntity();
                    bool isOut, isByRef, isBlock;
                    parameterEntity.Type    = this.TypeManager.ConvertType(parameterType, out isOut, out isByRef, out isBlock, this.Logger);
                    parameterEntity.IsOut   = isOut;
                    parameterEntity.IsByRef = isByRef;
                    parameterEntity.IsBlock = isBlock;
                    parameterEntity.Name    = TypeManager.ConvertName(parameterName);
                    functionEntity.Parameters.Add(parameterEntity);
                }
            }

            // Extract return type
            functionEntity.ReturnType = this.TypeManager.ConvertType(returnType, this.Logger);

            if (functionEntity.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 = functionEntity.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 < functionEntity.Parameters.Count; i++)
            {
                functionEntity.Parameters [i].Name = this.TypeManager.ConvertName(functionEntity.Parameters [i].Name);
            }

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

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

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

            // Extract name
            String name = functionElement.TrimAll ();
            functionEntity.Name = name;

            this.Logger.WriteLine ("  Function '" + name + "'");

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

            // Extract declaration
            XElement declarationElement = (from el in functionElement.ElementsAfterSelf ("pre")
                                           where (String)el.Attribute ("class") == "declaration"
                                           select el).FirstOrDefault ();

            String signature = declarationElement.TrimAll ();
            if (signature.StartsWith ("#define")) {
                this.Logger.WriteLine ("SKIPPING define statement: " + name);
                return null;
            }
            if (signature.StartsWith ("typedef")) {
                this.Logger.WriteLine ("SKIPPING define statement: " + name);
                return null;
            }
            if (!signature.Contains ("(")) { // e.g. NS_DURING
                this.Logger.WriteLine ("SKIPPING non-function statement: " + name);
                return null;
            }

            // Trim down signature
            while (signature.IndexOf("  ") != -1) {
                signature = signature.Replace ("  ", " ");
            }
            while (signature.IndexOf(" (") != -1) {
                signature = signature.Replace (" (", "(");
            }
            functionEntity.Signature = signature;
            //Console.WriteLine("name='" + name + "' signature='" + signature + "'");

            // Parse signature
            int pos = signature.IndexOf (name + "(");
            if (pos == -1) {
                this.Logger.WriteLine ("MISMATCH between name and declaration: " + name);
                return null;
            }
            String returnType = signature.Substring (0, pos).Trim ();
            int paramsIndex = pos + name.Length;
            int paramsLength = signature.IndexOf(')') + 1 - paramsIndex; // Stop before getting to function body
            String parameters = signature.Substring (paramsIndex, paramsLength).Trim ();
            parameters = parameters.Trim (';', '(', ')').Trim();
            if (parameters != "void") {
                foreach (string parameter in parameters.Split(new []{','}, StringSplitOptions.RemoveEmptyEntries)) {
                    String parameterType = "NOTYPE";
                    String parameterName = "NONAME";

                    //Console.WriteLine("parameter='" + parameter + "'");
                    Match r = PARAMETER_REGEX.Match (parameter);
                    if (r.Success) {
                        parameterType = r.Groups [2].Value.Trim ();
                        parameterName = r.Groups [3].Value.Trim ();
                    } else if (parameter.Trim () == "...") {
                        parameterType = "params Object[]";
                        parameterName = "values";
                    } else {
                        this.Logger.WriteLine ("FAILED to parse parameter: " + parameter);
                        return null;
                    }
                    parameterType = parameterType.Trim ();

                    MethodParameterEntity parameterEntity = new MethodParameterEntity ();
                    bool isOut, isByRef, isBlock;
                    parameterEntity.Type = this.TypeManager.ConvertType (parameterType, out isOut, out isByRef, out isBlock, this.Logger);
                    parameterEntity.IsOut = isOut;
                    parameterEntity.IsByRef = isByRef;
                    parameterEntity.IsBlock = isBlock;
                    parameterEntity.Name = TypeManager.ConvertName(parameterName);
                    functionEntity.Parameters.Add (parameterEntity);
                }
            }

            // Extract return type
            functionEntity.ReturnType = this.TypeManager.ConvertType (returnType, this.Logger);

            // Extract parameter documentation
            if (functionEntity.Parameters.Count > 0) {
                XElement termList = (from el in functionElement.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 ();
                            IEnumerable<String> summaries = ddList.ElementAt (i).Elements ("p").Select (p => p.Value.TrimAll ());

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

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

            // Get the summary for return type
            if (!String.Equals (functionEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase)) {
                XElement returnValueElement = (from el in functionElement.ElementsAfterSelf ("div")
                                               where (String)el.Attribute ("class") == "return_value"
                                               select el).FirstOrDefault ();
                if (returnValueElement != null) {
                    IEnumerable<String> documentations = returnValueElement.Elements ("p").Select (p => p.Value.TrimAll ());
                    functionEntity.ReturnsDocumentation = String.Join (String.Empty, documentations.ToArray ());
                }
            }

            //// Extract discussion
            //XElement discussionElement = (from el in functionElement.ElementsAfterSelf("div")
            //                              where (String) el.Attribute("class") == "api discussion"
            //                              select el).FirstOrDefault();
            //if (discussionElement != null)
            //{
            //    foreach (XElement paragraph in discussionElement.Elements("p"))
            //    {
            //        functionEntity.Summary.Add(paragraph.TrimAll());
            //    }
            //}

            // Get the availability
            XElement availabilityElement = (from el in functionElement.ElementsAfterSelf ("div")
                                            where (String)el.Attribute ("class") == "api availability"
                                            select el).FirstOrDefault ();
            XElement minAvailabilityElement = null;
            if (availabilityElement != null) {
                minAvailabilityElement = availabilityElement.Elements("ul").Elements("li").FirstOrDefault();
            }
            String minAvailability = "";
            if (minAvailabilityElement != null) {
                minAvailability = minAvailabilityElement.TrimAll();
            }
            functionEntity.MinAvailability = CommentHelper.ExtractAvailability (minAvailability);

            return functionEntity;
        }
        public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement)
        {
            MethodEntity methodEntity = new MethodEntity ();

            bool isStatic = (methodElement.Attribute ("static").Value == "yes");
            String selector = methodElement.Element ("name").TrimAll ();
            String returnType = methodElement.Element ("type").TrimAll ();

            // Elements for brief description
            IEnumerable<XElement> abstractElements = methodElement.Element ("briefdescription").Elements ("para");

            // Extract for detailed description
            IEnumerable<XElement> detailsElements = (from el in methodElement.Element ("detaileddescription").Elements ("para")
                                                     where !el.Elements ("simplesect").Any ()
                && el.Elements ("parameterlist").Any ()
                && el.Elements ("xrefsect").Any ()
                                                     select el);

            // Element for parameters
            IEnumerable<XElement> parameterElements = methodElement.Elements ("param");

            // Element for detailed description
            XElement detailedDescriptionElement = methodElement.Element ("detaileddescription");

            // Sets some data
            methodEntity.Selector = selector;
            methodEntity.Name = GetMethodName (methodEntity);
            methodEntity.Static = isStatic;

            // Add brief description
            foreach (XElement paragraph in abstractElements) {
                methodEntity.Summary.Add (paragraph.TrimAll ());
            }
            foreach (XElement paragraph in detailsElements) {
                methodEntity.Summary.Add (paragraph.TrimAll ());
            }

            // Recreate the signature
            StringBuilder signature = new StringBuilder ();
            signature.Append (isStatic ? "+ " : "- ");
            signature.AppendFormat ("({0})", returnType);
            if (selector.IndexOf (":") != -1) {
                String[] parts = selector.Split (':');
                for (int i = 0; i < parameterElements.Count(); i++) {
                    XElement parameterElement = parameterElements.ElementAt (i);
                    String parameterType = parameterElement.Element ("type").TrimAll ();

                    String parameterName;
                    if (parameterType.Equals ("...")) {
                        parameterName = String.Empty;
                    } else {
                        parameterName = parameterElement.Element ("declname").TrimAll ();
                        if (parameterElement.Element ("defname") != null) {
                            parameterName = parameterElement.Element ("defname").TrimAll ();
                        }
                    }

                    signature.Append (parts [i]);
                    signature.AppendFormat (":({0}){1} ", parameterType, parameterName);
                }
            } else {
                signature.Append (selector);
            }
            methodEntity.Signature = signature.ToString ().Trim () + ";";

            // Set the return type
            methodEntity.ReturnType = this.TypeManager.ConvertType (returnType, this.Logger);

            // Extract documentation for return type
            if (!String.Equals (returnType, "void", StringComparison.OrdinalIgnoreCase)) {
                XElement returnTypeSectionElement = (from el in detailedDescriptionElement.Descendants ("simplesect")
                                                     where el.Attribute ("kind") != null
                    && el.Attribute ("kind").Value == "return"
                                                     select el).FirstOrDefault ();
                if (returnTypeSectionElement != null) {
                    IEnumerable<String> documentations = (from el in returnTypeSectionElement.Elements ("para")
                                                          select el.TrimAll ());
                    methodEntity.ReturnsDocumentation = String.Join (" ", documentations.ToArray ());
                }
            }

            // Create the parameters
            for (int i = 0; i < parameterElements.Count(); i++) {
                XElement parameterElement = parameterElements.ElementAt (i);
                String parameterType = parameterElement.Element ("type").TrimAll ();

                String parameterName;
                if (parameterType.Equals ("...")) {
                    parameterType = "params Object[]";
                    parameterName = "values";
                } else {
                    parameterName = parameterElement.Element ("declname").TrimAll ();
                    if (parameterElement.Element ("defname") != null) {
                        parameterName = parameterElement.Element ("defname").TrimAll ();
                    }
                }

                MethodParameterEntity parameterEntity = new MethodParameterEntity ();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type = this.TypeManager.ConvertType (parameterType, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name = parameterName;
                methodEntity.Parameters.Add (parameterEntity);
            }

            // Extract documentation for parameters
            XElement parameterSectionElement = (from el in detailedDescriptionElement.Descendants ("parameterlist")
                                                where el.Attribute ("kind") != null
                && el.Attribute ("kind").Value == "param"
                                                select el).FirstOrDefault ();
            if (parameterSectionElement != null) {
                IEnumerable<XElement> parameterItemElements = parameterSectionElement.Elements ("parameteritem");
                for (int i = 0; i < parameterElements.Count(); i++) {
                    XElement parameterElement = parameterElements.ElementAt (i);
                    String parameterType = parameterElement.Element ("type").TrimAll ();
                    String parameterName;
                    if (parameterType.Equals ("...")) {
                        continue;
                    } else {
                        parameterName = parameterElement.Element ("declname").TrimAll ();
                        if (parameterElement.Element ("defname") != null) {
                            parameterName = parameterElement.Element ("defname").TrimAll ();
                        }
                    }

                    MethodParameterEntity parameterEntity = methodEntity.Parameters.Find (p => String.Equals (p.Name, parameterName));

                    IEnumerable<XElement> documentations = (from el in parameterItemElements
                                                            let filter = el.Element ("parameternamelist").Value.TrimAll ()
                                                            where String.Equals (filter, parameterName)
                                                            select el);
                    if (documentations.Count () > 0) {
                        XElement documentation = documentations.Elements ("parameterdescription").First ();
                        foreach (XElement element in documentation.Elements("para")) {
                            parameterEntity.Summary.Add (element.TrimAll ());
                        }
                    }
                }
            }

            // 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 availability
            if (availabilityElement != null)
            {
                methodEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll());
            }
             */

            return methodEntity;
        }
        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;
        }
Example #16
0
        public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement)
        {
            MethodEntity methodEntity = new MethodEntity();

            bool   isStatic   = (methodElement.Attribute("static").Value == "yes");
            String selector   = methodElement.Element("name").TrimAll();
            String returnType = methodElement.Element("type").TrimAll();

            // Elements for brief description
            IEnumerable <XElement> abstractElements = methodElement.Element("briefdescription").Elements("para");

            // Extract for detailed description
            IEnumerable <XElement> detailsElements = (from el in methodElement.Element("detaileddescription").Elements("para")
                                                      where !el.Elements("simplesect").Any() &&
                                                      el.Elements("parameterlist").Any() &&
                                                      el.Elements("xrefsect").Any()
                                                      select el);

            // Element for parameters
            IEnumerable <XElement> parameterElements = methodElement.Elements("param");

            // Element for detailed description
            XElement detailedDescriptionElement = methodElement.Element("detaileddescription");

            // Sets some data
            methodEntity.Selector = selector;
            methodEntity.Name     = GetMethodName(methodEntity);
            methodEntity.Static   = isStatic;

            // Add brief description
            foreach (XElement paragraph in abstractElements)
            {
                methodEntity.Summary.Add(paragraph.TrimAll());
            }
            foreach (XElement paragraph in detailsElements)
            {
                methodEntity.Summary.Add(paragraph.TrimAll());
            }

            // Recreate the signature
            StringBuilder signature = new StringBuilder();

            signature.Append(isStatic ? "+ " : "- ");
            signature.AppendFormat("({0})", returnType);
            if (selector.IndexOf(":") != -1)
            {
                String[] parts = selector.Split(':');
                for (int i = 0; i < parameterElements.Count(); i++)
                {
                    XElement parameterElement = parameterElements.ElementAt(i);
                    String   parameterType    = parameterElement.Element("type").TrimAll();

                    String parameterName;
                    if (parameterType.Equals("..."))
                    {
                        parameterName = String.Empty;
                    }
                    else
                    {
                        parameterName = parameterElement.Element("declname").TrimAll();
                        if (parameterElement.Element("defname") != null)
                        {
                            parameterName = parameterElement.Element("defname").TrimAll();
                        }
                    }

                    signature.Append(parts [i]);
                    signature.AppendFormat(":({0}){1} ", parameterType, parameterName);
                }
            }
            else
            {
                signature.Append(selector);
            }
            methodEntity.Signature = signature.ToString().Trim() + ";";

            // Set the return type
            methodEntity.ReturnType = this.TypeManager.ConvertType(returnType, this.Logger);

            // Extract documentation for return type
            if (!String.Equals(returnType, "void", StringComparison.OrdinalIgnoreCase))
            {
                XElement returnTypeSectionElement = (from el in detailedDescriptionElement.Descendants("simplesect")
                                                     where el.Attribute("kind") != null &&
                                                     el.Attribute("kind").Value == "return"
                                                     select el).FirstOrDefault();
                if (returnTypeSectionElement != null)
                {
                    IEnumerable <String> documentations = (from el in returnTypeSectionElement.Elements("para")
                                                           select el.TrimAll());
                    methodEntity.ReturnsDocumentation = String.Join(" ", documentations.ToArray());
                }
            }

            // Create the parameters
            for (int i = 0; i < parameterElements.Count(); i++)
            {
                XElement parameterElement = parameterElements.ElementAt(i);
                String   parameterType    = parameterElement.Element("type").TrimAll();

                String parameterName;
                if (parameterType.Equals("..."))
                {
                    parameterType = "params Object[]";
                    parameterName = "values";
                }
                else
                {
                    parameterName = parameterElement.Element("declname").TrimAll();
                    if (parameterElement.Element("defname") != null)
                    {
                        parameterName = parameterElement.Element("defname").TrimAll();
                    }
                }

                MethodParameterEntity parameterEntity = new MethodParameterEntity();
                bool isOut, isByRef, isBlock;
                parameterEntity.Type    = this.TypeManager.ConvertType(parameterType, out isOut, out isByRef, out isBlock, this.Logger);
                parameterEntity.IsOut   = isOut;
                parameterEntity.IsByRef = isByRef;
                parameterEntity.IsBlock = isBlock;
                parameterEntity.Name    = parameterName;
                methodEntity.Parameters.Add(parameterEntity);
            }

            // Extract documentation for parameters
            XElement parameterSectionElement = (from el in detailedDescriptionElement.Descendants("parameterlist")
                                                where el.Attribute("kind") != null &&
                                                el.Attribute("kind").Value == "param"
                                                select el).FirstOrDefault();

            if (parameterSectionElement != null)
            {
                IEnumerable <XElement> parameterItemElements = parameterSectionElement.Elements("parameteritem");
                for (int i = 0; i < parameterElements.Count(); i++)
                {
                    XElement parameterElement = parameterElements.ElementAt(i);
                    String   parameterType    = parameterElement.Element("type").TrimAll();
                    String   parameterName;
                    if (parameterType.Equals("..."))
                    {
                        continue;
                    }
                    else
                    {
                        parameterName = parameterElement.Element("declname").TrimAll();
                        if (parameterElement.Element("defname") != null)
                        {
                            parameterName = parameterElement.Element("defname").TrimAll();
                        }
                    }

                    MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, parameterName));

                    IEnumerable <XElement> documentations = (from el in parameterItemElements
                                                             let filter = el.Element("parameternamelist").Value.TrimAll()
                                                                          where String.Equals(filter, parameterName)
                                                                          select el);
                    if (documentations.Count() > 0)
                    {
                        XElement documentation = documentations.Elements("parameterdescription").First();
                        foreach (XElement element in documentation.Elements("para"))
                        {
                            parameterEntity.Summary.Add(element.TrimAll());
                        }
                    }
                }
            }

            // 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 availability
             * if (availabilityElement != null)
             * {
             * methodEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.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;
        }
Example #18
0
        protected void GenerateLocalsUnmarshalling(int indent, MethodEntity methodEntity, MethodEntity innerMethodEntity)
        {
            int index = 1;

            for (int i = 0; i < methodEntity.Parameters.Count; i++)
            {
                MethodParameterEntity methodParameterEntity      = methodEntity.Parameters [i];
                MethodParameterEntity innerMethodParameterEntity = innerMethodEntity != null ? innerMethodEntity.Parameters [i] : methodParameterEntity;

                if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef)
                {
                    switch (methodParameterEntity.Type)
                    {
                    case "bool":
                    case "byte":
                        this.Writer.WriteLineFormat(indent, "{0} = (Marshal.ReadByte(__local{1}) != 0);", methodParameterEntity.Name, index++);
                        break;

                    case "short":
                        this.Writer.WriteLineFormat(indent, "{0} = Marshal.ReadInt16(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "ushort":
                        this.Writer.WriteLineFormat(indent, "{0} = (ushort) Marshal.ReadInt16(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "int":
                        this.Writer.WriteLineFormat(indent, "{0} = Marshal.ReadInt32(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "uint":
                        this.Writer.WriteLineFormat(indent, "{0} = (uint) Marshal.ReadInt32(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "long":
                        this.Writer.WriteLineFormat(indent, "{0} = Marshal.ReadInt64(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "ulong":
                        this.Writer.WriteLineFormat(indent, "{0} = (ulong) Marshal.ReadInt64(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "IntPtr":
                        this.Writer.WriteLineFormat(indent, "{0} = Marshal.ReadIntPtr(__local{1});", methodParameterEntity.Name, index++);
                        break;

                    case "float":
                    case "double":
                        this.Writer.WriteLineFormat(indent, "{0} = ({1}) Marshal.PtrToStructure(__local{2}, typeof({1}));", methodParameterEntity.Name, methodParameterEntity.Type, index++);
                        break;

                    default:
                        if (IsMixedType(methodParameterEntity.Type) || methodParameterEntity.IsStruct)
                        {
                            if (methodParameterEntity.Type.Equals(innerMethodParameterEntity.Type))
                            {
                                this.Writer.WriteLineFormat(indent, "{0} = ({1}) Marshal.PtrToStructure(__local{2}, typeof({1}));", methodParameterEntity.Name, methodParameterEntity.Type, index++, innerMethodParameterEntity.Type);
                            }
                            else
                            {
                                this.Writer.WriteLineFormat(indent, "{0} = ({1}) ({3}) Marshal.PtrToStructure(__local{2}, typeof({3}));", methodParameterEntity.Name, methodParameterEntity.Type, index++, innerMethodParameterEntity.Type);
                            }
                        }
                        else
                        {
                            this.Writer.WriteLineFormat(indent, "{0} = ObjectiveCRuntime.GetInstance<{1}>(Marshal.ReadIntPtr(__local{2}));", methodParameterEntity.Name, methodParameterEntity.Type, index++);
                        }
                        break;
                    }
                }
                else if (methodParameterEntity.IsBlock)
                {
                    index++;
                }
            }
        }
Example #19
0
 /// <summary>
 ///   Gets the type signature.
 /// </summary>
 protected static String GetTypeSignature(MethodParameterEntity methodParameterEntity)
 {
     return String.Format (CultureInfo.CurrentCulture,
                          "{0}{1} {2}",
                          methodParameterEntity.IsOut ? "out " : (!methodParameterEntity.IsBlock && methodParameterEntity.IsByRef) ? "ref " : String.Empty,
                          methodParameterEntity.Type,
                          methodParameterEntity.Name);
 }
Example #20
0
 /// <summary>
 ///   Gets the parameter for an invocation.
 /// </summary>
 protected static String GetInvocationParameter(MethodParameterEntity methodParameterEntity, MethodParameterEntity destinationMethodParameterEntity = null)
 {
     if (destinationMethodParameterEntity != null && !methodParameterEntity.Type.Equals (destinationMethodParameterEntity.Type)) {
         return String.Format (CultureInfo.CurrentCulture,
                              "{0}({1}) {2}",
                              methodParameterEntity.IsOut ? "out " : methodParameterEntity.IsByRef ? "ref " : String.Empty,
                              destinationMethodParameterEntity.Type,
                              methodParameterEntity.Name);
     }
     return String.Format (CultureInfo.CurrentCulture,
                          "{0}{1}",
                          methodParameterEntity.IsOut ? "out " : methodParameterEntity.IsByRef ? "ref " : String.Empty,
                          methodParameterEntity.Name);
 }
        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;
        }
Example #22
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);
        }
        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;
        }
        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);
        }