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)); }
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()); }
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++; } } }
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++); } } }
/// <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; }
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); } } }
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); }
/// <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; }
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; }
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; }
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++; } } }
/// <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); }
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; }
/// <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); }