/// <summary> /// Parses the specified constant element. /// </summary> /// <param name = "constantElement">The constant element.</param> public List<BaseEntity> Parse(TypedEntity typedEntity, XElement constantElement) { // Get the name String name = constantElement.TrimAll (); // Get the abstract XElement summaryElement = (from el in constantElement.ElementsAfterSelf ("p") where (String)el.Attribute ("class") == "abstract" select el).FirstOrDefault (); String summary = summaryElement.TrimAll (); // Get the declaration XElement declarationElement = (from el in constantElement.ElementsAfterSelf ("pre") where (String)el.Attribute ("class") == "declaration" select el).FirstOrDefault (); String declaration = declarationElement.TrimAll (); // Make various tests bool isDefine = declaration.StartsWith ("#define"); bool isEnum = declaration.StartsWith ("enum") || declaration.StartsWith ("typedef enum") || declaration.Contains (" enum "); if (isDefine) { List<BaseEntity> entities = ExtractDefine (constantElement, name, summary, declaration); return entities; } if (isEnum) { // keep newlines for enum processing List<BaseEntity> entities = this.ExtractEnumeration (constantElement, name, summary, declarationElement.TrimSpaces()); if (entities != null) { return entities; } } return this.ExtractConstants (constantElement, name, summary, declaration); }
/// <summary> /// Generates the specified entity. /// </summary> /// <param name = "framework">The framework.</param> /// <param name = "entity">The entity.</param> public void Generate(TypedEntity typedEntity, ConstantEntity entity) { // Don't generate if required if (!entity.Generate) { return; } // Append static condition if needed this.AppendStartCondition(entity); // Append property comments this.Writer.WriteLineFormat (2, "/// <summary>"); foreach (String line in entity.Summary) { this.Writer.WriteLineFormat (2, "/// <para>{0}</para>", line.EscapeAll ()); } this.AppendAvailability (2, entity); this.Writer.WriteLineFormat (2, "/// </summary>"); if (entity.Static) { // Print the static constant this.Writer.WriteLineFormat (2, "public static readonly {0} {1} = {2};", entity.Type, entity.Name, entity.Value); } else { // Print the extern constant this.Writer.WriteLineFormat (2, "public static readonly {0} {2} = ObjectiveCRuntime.GetExtern<{0}>(\"{1}\", \"{2}\");", entity.Type, typedEntity.Namespace, entity.Name); } // Append static condition if needed this.AppendEndCondition(entity); // Update statistics this.Statistics.Constants++; }
/// <summary> /// Parses the specified notification element. /// </summary> /// <param name = "notificationElement">The notification element.</param> /// <returns></returns> public ConstantEntity Parse(TypedEntity typedEntity, XElement notificationElement) { ConstantEntity notificationEntity = new ConstantEntity(); notificationEntity.Type = "NSString"; // Get the name notificationEntity.Name = notificationElement.TrimAll(); this.Logger.WriteLine(" Notification '" + notificationEntity.Name + "'"); // Get the content and the discussion XElement summaryElement = (from el in notificationElement.ElementsAfterSelf("section") where (String) el.Attribute("class") == "spaceabove" select el).FirstOrDefault(); if (summaryElement != null) { foreach (XElement element in summaryElement.Elements()) { notificationEntity.Summary.Add(element.Value.TrimAll()); } } // Get the availability String minAvailability = (from el in notificationElement.ElementsAfterSelf("div").Elements("ul").Elements("li") where (String) el.Parent.Parent.Attribute("class") == "api availability" select el.Value).FirstOrDefault(); notificationEntity.MinAvailability = CommentHelper.ExtractAvailability(minAvailability.TrimAll()); return notificationEntity; }
public ConstantEntity Parse(TypedEntity typedEntity, XElement constantElement) { ConstantEntity constantEntity = new ConstantEntity (); String kind = constantElement.Attribute ("kind").Value; constantEntity.Name = constantElement.Element ("name").TrimAll (); // Elements for brief description IEnumerable<XElement> abstractElements = constantElement.Element ("briefdescription").Elements ("para"); // Extract for detailed description IEnumerable<XElement> detailsElements = (from el in constantElement.Element ("detaileddescription").Elements ("para") where !el.Elements ("simplesect").Any () && el.Elements ("parameterlist").Any () && el.Elements ("xrefsect").Any () select el); // Add brief description foreach (XElement paragraph in abstractElements) { constantEntity.Summary.Add (paragraph.TrimAll ()); } foreach (XElement paragraph in detailsElements) { constantEntity.Summary.Add (paragraph.TrimAll ()); } switch (kind) { case "define": { constantEntity.Type = "MISSING"; constantEntity.Static = true; constantEntity.Value = constantElement.Element ("initializer").TrimAll (); } break; case "variable": { String type = constantElement.Element ("type").TrimAll (); type = type.Replace ("const", String.Empty).Trim (); bool isOut, isByRef, isBlock; constantEntity.Type = this.TypeManager.ConvertType (type, out isOut, out isByRef, out isBlock, this.Logger); } break; } /* // Get the availability if (availabilityElement != null) { constantEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll()); } */ return constantEntity; }
protected void GenerateFunctionBody(int indent, TypedEntity typedEntity, FunctionEntity methodEntity, FunctionEntity innerMethodEntity, bool needStorage, String suffix = null) { bool hasReturn = !String.Equals (methodEntity.ReturnType, "void"); bool mixed = (innerMethodEntity != null); bool mixedReturnType = mixed && !String.Equals (methodEntity.ReturnType, innerMethodEntity.ReturnType); this.GenerateLocalsAllocation (indent, methodEntity, innerMethodEntity); this.GenerateLocalsMarshalling (indent, methodEntity, innerMethodEntity); String invocation = GetFunctionInvocation (typedEntity, methodEntity, innerMethodEntity, suffix); if (hasReturn) { if (needStorage) { String prefix = methodEntity.ReturnType + " __result = "; if (mixedReturnType) { prefix += "(" + methodEntity.ReturnType + ") "; } invocation = prefix + invocation; } else { String prefix = "return "; if (mixedReturnType) { prefix += "(" + methodEntity.ReturnType + ") "; } invocation = prefix + invocation; } } this.Writer.WriteLineFormat (indent, invocation); this.GenerateLocalsUnmarshalling (indent, methodEntity, innerMethodEntity); this.GenerateLocalsDeallocation (indent, methodEntity, innerMethodEntity); if (hasReturn && needStorage) { this.Writer.WriteLineFormat (indent, "return __result;"); } }
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; }
protected void ExtractNotifications(TypedEntity typedEntity, XElement root) { IEnumerable<XElement> notificationElements = from el in root.Descendants("h3") where (String) el.Attribute("class") == "tight jump notification" select el; foreach (XElement notificationElement in notificationElements) { ConstantEntity notificationEntity = this.NotificationParser.Parse(typedEntity, notificationElement); typedEntity.Constants.Add(notificationEntity); } }
protected void ExtractConstants(TypedEntity typedEntity, XElement root) { IEnumerable<XElement> constantElements = from el in root.Descendants("h3") where (String) el.Attribute("class") == "constantGroup" || (String) el.Attribute("class") == "tight jump typeDef" select el; foreach (XElement constantElement in constantElements) { List<BaseEntity> entities = this.ConstantParser.Parse(typedEntity, constantElement); if (entities != null) { typedEntity.AddRange(entities); } } // Constants constantElements = from el in root.Descendants("h4") select el; foreach (XElement constantElement in constantElements) { List<BaseEntity> entities = this.ConstantParser.Parse(typedEntity, constantElement); if (entities != null) { typedEntity.AddRange(entities); } } }
/// <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; }
/// <summary> /// Extracts the constants. /// </summary> /// <param name = "typedEntity">The typed entity.</param> /// <param name = "root">The root element.</param> protected void ExtractConstants(TypedEntity typedEntity, XElement root) { IEnumerable<XElement> memberDefs = (from el in root.Descendants("memberdef") where el.Attribute("kind").Value == "variable" || el.Attribute("kind").Value == "define" select el); foreach (XElement memberDef in memberDefs) { ConstantEntity constantEntity = this.ConstantParser.Parse(typedEntity, memberDef); typedEntity.Constants.Add(constantEntity); } }
/// <summary> /// Parses the specified method element. /// </summary> /// <param name = "methodElement">The method element.</param> /// <returns></returns> public MethodEntity Parse(TypedEntity typedEntity, XElement methodElement) { MethodEntity methodEntity = new MethodEntity(); XElement selectorElement = methodElement.Element("h3"); methodEntity.Selector = selectorElement.TrimAll(); methodEntity.Name = GetMethodName(methodEntity); this.Logger.WriteLine(" Method '" + methodEntity.Selector + "'"); // Extract signature XElement signatureElement = (from el in methodElement.Elements("div") where (String) el.Attribute("class") == "declaration" select el).FirstOrDefault(); methodEntity.Signature = signatureElement.TrimAll(); methodEntity.Signature = methodEntity.Signature.TrimEnd(';'); methodEntity.Signature = methodEntity.Signature.Replace(", ...", ",..."); // MethodParametersEnumerator needs this format methodEntity.Static = methodEntity.Signature.StartsWith("+"); // Extract abstract XElement abstractElement = (from el in methodElement.Elements("p") where (String) el.Attribute("class") == "abstract" select el).FirstOrDefault(); methodEntity.Summary.Add(abstractElement.TrimAll()); //// Extract discussion //IEnumerable<XElement> paragraphs = (from el in methodElement.Elements("p").Elements("p") // where (String) el.Parent.Attribute("class") == "api discussion" // select el); //foreach (XElement paragraph in paragraphs) //{ // methodEntity.Summary.Add(paragraph.TrimAll()); //} // Extract return type MethodSignatureEnumerator signatureEnumerator = new MethodSignatureEnumerator(methodEntity.Signature); if (signatureEnumerator.MoveNext()) { methodEntity.ReturnType = this.TypeManager.ConvertType(signatureEnumerator.Current.TrimAll(), this.Logger); } else { methodEntity.ReturnType = "Id"; } // Extract parameter type and name MethodParametersEnumerator parameterTypesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, false); MethodParametersEnumerator parameterNamesEnumerator = new MethodParametersEnumerator(methodEntity.Signature, true); while (parameterTypesEnumerator.MoveNext() && parameterNamesEnumerator.MoveNext()) { MethodParameterEntity parameterEntity = new MethodParameterEntity(); bool isOut, isByRef, isBlock; parameterEntity.Type = this.TypeManager.ConvertType(parameterTypesEnumerator.Current, out isOut, out isByRef, out isBlock, this.Logger); parameterEntity.IsOut = isOut; parameterEntity.IsByRef = isByRef; parameterEntity.IsBlock = isBlock; parameterEntity.Name = parameterNamesEnumerator.Current.Trim(); methodEntity.Parameters.Add(parameterEntity); // Correct names that end in a single period if (parameterEntity.Name.EndsWith(".") && !parameterEntity.Name.EndsWith("..")) { parameterEntity.Name = parameterEntity.Name.Substring(0, parameterEntity.Name.Length - 1); } // Handle variadic parameters Match r = VARARG_PARAMETER_REGEX.Match (parameterEntity.Name); if (r.Success) { // Fix the last parameter name by removing "..." parameterEntity.Name = r.Groups [1].Value.Trim (); // Add a new variadic parameter parameterEntity = new MethodParameterEntity(); parameterEntity.Type = "params Object[]"; parameterEntity.Name = "values"; parameterEntity.Summary.Add("Variable argument values"); methodEntity.Parameters.Add(parameterEntity); } } // Extract parameter documentation if (methodEntity.Parameters.Count > 0) { XElement termList = (from el in methodElement.Elements("div").Elements("dl") where (String) el.Parent.Attribute("class") == "api parameters" && (String) el.Attribute("class") == "termdef" select el).FirstOrDefault(); if (termList != null) { IEnumerable<XElement> dtList = from el in termList.Elements("dt") select el; IEnumerable<XElement> ddList = from el in termList.Elements("dd") select el; if (dtList.Count() == ddList.Count()) { // Iterate over definitions for (int i = 0; i < dtList.Count(); i++) { String term = dtList.ElementAt(i).TrimAll(); //String summary = ddList.ElementAt(i).TrimAll(); IEnumerable<String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll()); // Find the parameter MethodParameterEntity parameterEntity = methodEntity.Parameters.Find(p => String.Equals(p.Name, term) || (VARARG_PARAMETER_REGEX.Match(term).Success && term.StartsWith(p.Name))); if (parameterEntity != null) { //parameterEntity.Summary.Add(summary); foreach (string sum in summaries) { parameterEntity.Summary.Add(sum); } } } } } } // Fix the name only after looking for the documentation for (int i = 0; i < methodEntity.Parameters.Count; i++) { methodEntity.Parameters[i].Name = this.TypeManager.ConvertName(methodEntity.Parameters[i].Name); } // Get the summary for return type if (!String.Equals(methodEntity.ReturnType, "void", StringComparison.OrdinalIgnoreCase)) { IEnumerable<String> documentations = (from el in methodElement.Elements("div").Elements("p") where (String) el.Parent.Attribute("class") == "return_value" select el.Value.TrimAll()); methodEntity.ReturnsDocumentation = String.Join(" ", documentations.ToArray()); } // Get the availability String minAvailability = (from el in methodElement.Elements("div").Elements("ul").Elements("li") where (String) el.Parent.Parent.Attribute("class") == "api availability" select el.Value).FirstOrDefault(); methodEntity.MinAvailability = CommentHelper.ExtractAvailability(minAvailability.TrimAll()); return methodEntity; }
/// <summary> /// Parses the specified property element. /// </summary> /// <param name = "propertyElement">The property element.</param> /// <returns></returns> public PropertyEntity Parse(TypedEntity typedEntity, XElement propertyElement) { String name = propertyElement.Element ("name").Value; // Rebuild the signature from the documentation String returnType = propertyElement.Element ("type").TrimAll (); bool isStatic = (propertyElement.Attribute ("static").Value == "yes"); bool readable = (propertyElement.Attribute ("readable").Value == "yes"); bool writable = (propertyElement.Attribute ("writable").Value == "yes"); String accessor = String.Empty; if (propertyElement.Attribute("accessor") != null) { accessor = propertyElement.Attribute ("accessor").Value; } // Remove weak modifier if (returnType.StartsWith ("__weak")) { returnType = returnType.Replace ("__weak", String.Empty).TrimAll (); } // Extract brief description IEnumerable<XElement> abstractElements = propertyElement.Element ("briefdescription").Elements ("para"); // Extract for detailed description IEnumerable<XElement> detailsElements = (from el in propertyElement.Element ("detaileddescription").Elements ("para") where !el.Elements ("simplesect").Any () && el.Elements ("parameterlist").Any () && el.Elements ("xrefsect").Any () select el); // Add brief description List<String> summary = new List<String> (); foreach (XElement paragraph in abstractElements) { summary.Add (paragraph.TrimAll ()); } foreach (XElement paragraph in detailsElements) { summary.Add (paragraph.TrimAll ()); } // Recreate the signature StringBuilder signatureBuilder = new StringBuilder (); signatureBuilder.Append ("@property (nonatomic"); if (readable) { if (!writable) { signatureBuilder.Append (",readonly"); } } signatureBuilder.Append (","); signatureBuilder.Append (accessor); signatureBuilder.Append (") "); signatureBuilder.AppendFormat ("{0} {1};", returnType, name); String signature = signatureBuilder.ToString (); String getterSelector = name; // Alter the name name = name.UpperCaseFirstLetter (); String setterSelector = "set" + name + ":"; bool isOut, isByRef, isBlock; String type = this.TypeManager.ConvertType (returnType, out isOut, out isByRef, out isBlock, this.Logger); PropertyEntity propertyEntity = new PropertyEntity (); //propertyEntity.MinAvailability = minAvailability; propertyEntity.Name = getterSelector.UpperCaseFirstLetter (); propertyEntity.Static = isStatic; // Should always be false... propertyEntity.Summary = summary; propertyEntity.Type = type; propertyEntity.Getter = new MethodEntity (); propertyEntity.Getter.Signature = signature; propertyEntity.Getter.Selector = getterSelector; if (readable && !writable) { propertyEntity.Setter = null; } else { propertyEntity.Setter = new MethodEntity (); propertyEntity.Setter.Signature = signature; propertyEntity.Setter.Selector = setterSelector; } return propertyEntity; }
private void GenerateWrapperFunction(TypedEntity typedEntity, FunctionEntity functionEntity, FunctionEntity functionEntity32, FunctionEntity functionEntity64, bool needStorage) { bool useMixedInvocation = functionEntity32 != null && functionEntity64 != null; // Strip name if the prefix is the same String name = functionEntity.Name; if (name.StartsWith (typedEntity.Name)) { name = name.Substring (typedEntity.Name.Length); } StringBuilder signature = new StringBuilder (); signature.AppendFormat ("public static {0} {1}(", functionEntity.ReturnType, name); // Append parameters List<String> parameters = new List<String> (); foreach (MethodParameterEntity methodParameterEntity in functionEntity.Parameters.Where(p => p.Generate)) { parameters.Add (GetTypeSignature (methodParameterEntity)); } signature.Append (String.Join (", ", parameters.ToArray ())); signature.Append (")"); this.Writer.WriteLineFormat (2, signature.ToString ()); this.Writer.WriteLineFormat (2, "{{"); if (useMixedInvocation) { #if MIXED_MODE this.Writer.WriteLineFormat(3, "if (ObjectiveCRuntime.Is64Bits)"); this.Writer.WriteLineFormat(3, "{{"); this.GenerateFunctionBody(4, typedEntity, functionEntity, functionEntity64, needStorage, SUFFIX_64); this.Writer.WriteLineFormat(3, "}}"); this.Writer.WriteLineFormat(3, "else"); this.Writer.WriteLineFormat(3, "{{"); #endif this.GenerateFunctionBody (4, typedEntity, functionEntity, functionEntity32, needStorage, SUFFIX_32); #if MIXED_MODE this.Writer.WriteLineFormat(3, "}}"); #endif } else { this.GenerateFunctionBody (3, typedEntity, functionEntity, null, needStorage, SUFFIX_INNER); } this.Writer.WriteLineFormat (2, "}}"); this.Writer.WriteLine (); }
private void GenerateNativeFunction(TypedEntity typedEntity, FunctionEntity functionEntity, String suffix, bool isPublic) { // Strip name if the prefix is the same String name = functionEntity.Name; if (name.StartsWith (typedEntity.Name)) { name = name.Substring (typedEntity.Name.Length); } // TODO: Compute proper framework path... // TODO: Test with embedded frameworks... this.Writer.WriteLineFormat (2, "[DllImport(\"{0}\", EntryPoint=\"{1}\")]", GetFrameworkPath (typedEntity.Namespace), functionEntity.Name); // Add custom tag for return type if (TypeManager.HasClass (functionEntity.ReturnType)) { this.Writer.WriteLineFormat (2, "[return : MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (IdMarshaler<{0}>))]", functionEntity.ReturnType); } StringBuilder signature = new StringBuilder (); signature.AppendFormat ("{0} static extern {1} {2}(", isPublic ? "public" : "private", functionEntity.ReturnType, name + suffix ?? String.Empty); // Append parameters List<String> parameters = new List<String> (); foreach (MethodParameterEntity methodParameterEntity in functionEntity.Parameters.Where(p => p.Generate)) { if (methodParameterEntity.IsOut || methodParameterEntity.IsByRef) { parameters.Add ("IntPtr " + methodParameterEntity.Name); } else if (methodParameterEntity.IsBlock) { parameters.Add (String.Format ("[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (BlockMarshaler))] Block {0}", methodParameterEntity.Name)); } else { String parameter = GetTypeSignature (methodParameterEntity); if (TypeManager.HasClass (methodParameterEntity.Type)) { parameter = String.Format ("[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof (IdMarshaler<{0}>))] {1}", methodParameterEntity.Type, parameter); } parameters.Add (parameter); } } signature.Append (String.Join (", ", parameters.ToArray ())); signature.Append (");"); this.Writer.WriteLineFormat (2, signature.ToString ()); this.Writer.WriteLine (); }
private static string GetFunctionInvocation(TypedEntity typedEntity, FunctionEntity functionEntity, FunctionEntity innerFunctionEntity, String suffix = null) { // Strip name if the prefix is the same String name = functionEntity.Name; if (name.StartsWith (typedEntity.Name)) { name = name.Substring (typedEntity.Name.Length); } StringBuilder builder = new StringBuilder (); builder.AppendFormat ("{0}{1}(", name, suffix ?? String.Empty); builder.Append (GetMessageParameterList (functionEntity, innerFunctionEntity, false)); builder.Append (");"); return builder.ToString (); }
private void AddMixedType(Dictionary<String, String> table, TypedEntity entity) { String types = entity.MixedType; if (String.IsNullOrWhiteSpace (types)) { if (!String.IsNullOrEmpty (entity.BaseType)) { types = entity.BaseType + "," + entity.BaseType; } else { types = entity.Name + "," + entity.Name; } } this.AddMixedType (table, entity.Name, types); }
/// <summary> /// Extracts the enumerations. /// </summary> /// <param name = "typedEntity">The typed entity.</param> /// <param name = "root">The root element.</param> protected void ExtractEnumerations(TypedEntity typedEntity, XElement root) { IEnumerable<XElement> memberDefs = (from el in root.Descendants("memberdef") where el.Attribute("kind").Value == "enum" select el); foreach (XElement memberDef in memberDefs) { EnumerationEntity enumerationEntity = this.EnumerationParser.Parse(typedEntity, memberDef); typedEntity.Enumerations.Add(enumerationEntity); } }
/// <summary> /// Extracts the constants. /// </summary> /// <param name = "typedEntity">The typed entity.</param> /// <param name = "root">The root element.</param> protected void ExtractFunctions(TypedEntity typedEntity, XElement root) { XElement listMarker = (from el in root.Descendants("h2") where el.Value == "Functions" select el).FirstOrDefault(); XElement list = listMarker != null ? listMarker.ElementsAfterSelf("dl").FirstOrDefault() : null; if (list != null) { // Collect names List<String> names = new List<string>(); foreach (XElement term in list.Descendants("dt")) { String name = term.Value.TrimAll(); names.Add(name); } // Search for a table with preceding by an anchor containing the name foreach (String name in names) { XElement marker = (from el in list.ElementsAfterSelf("a") where el.Attribute("name") != null && el.Attribute("name").Value.EndsWith("/" + name) select el).FirstOrDefault(); if (marker != null) { //XElement startElement = marker.ElementsAfterSelf("table").FirstOrDefault(); IEnumerable<XElement> elements = marker.ElementsAfterSelf().TakeWhile(el => el.Name != "a"); FunctionEntity entity = this.FunctionParser.Parse(typedEntity, name, elements); if (entity != null) { typedEntity.Functions.Add(entity); } } else { this.Logger.WriteLine("MISSING marker for function " + name); } } } }
public PropertyEntity Parse(TypedEntity typedEntity, string name, IEnumerable<XElement> elements) { XElement declarationElement = (from el in elements where el.Name == "div" && el.Attribute("class") != null && el.Attribute("class").Value == "declaration_indent" 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(); String signature = declarationElement.TrimAll(); // Extract abstract List<String> summary = new List<String>(); 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)) { 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)) { summary.Add(line); } } } // Get the availability String minAvailability = "MISSING"; if (availabilityElement != null) { minAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll()); } // Extract property's attribute List<String> attributes = new List<String>(); int attributesStart = signature.IndexOf('('); int attributesEnd = signature.IndexOf(')'); if (attributesStart > 0 && attributesEnd > attributesStart) { String attributesAll = signature.Substring(attributesStart + 1, attributesEnd - attributesStart - 1); attributes.AddRange(attributesAll.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(attr => attr.Trim())); } int typeStart = attributesEnd > 0 ? (attributesEnd + 1) : "@property".Length; int typeEnd = signature.LastIndexOf(name); string returnType = (typeStart > 0 && typeEnd > typeStart) ? signature.Substring(typeStart, typeEnd - typeStart).Trim() : "MISSING"; // Is the property readonly ? bool readOnly = attributes.Contains("readonly"); // Is there an explicit getter String getterSelector = attributes.Find(a => a.Contains("getter")); if (getterSelector != null) { getterSelector = getterSelector.Substring(getterSelector.IndexOf('=') + 1); } else { getterSelector = name; } // Alter the name name = name.UpperCaseFirstLetter(); // Is there an explicit setter String setterSelector = attributes.Find(a => a.Contains("setter")); if (setterSelector != null) { setterSelector = setterSelector.Substring(setterSelector.IndexOf('=') + 1); } else { setterSelector = "set" + name + ":"; } bool isOut, isByRef, isBlock; String type = this.TypeManager.ConvertType(returnType, out isOut, out isByRef, out isBlock, this.Logger); PropertyEntity propertyEntity = new PropertyEntity(); propertyEntity.MinAvailability = minAvailability; propertyEntity.Name = getterSelector.UpperCaseFirstLetter(); propertyEntity.Static = false; propertyEntity.Summary = summary; propertyEntity.Type = type; propertyEntity.Getter = new MethodEntity(); propertyEntity.Getter.Signature = signature; propertyEntity.Getter.Selector = getterSelector; if (readOnly) { propertyEntity.Setter = null; } else { propertyEntity.Setter = new MethodEntity(); propertyEntity.Setter.Signature = signature; propertyEntity.Setter.Selector = setterSelector; } return propertyEntity; }
public EnumerationEntity Parse(TypedEntity typedEntity, XElement enumerationElement) { EnumerationEntity enumerationEntity = new EnumerationEntity(); String name = enumerationElement.Element("name").TrimAll(); enumerationEntity.Name = name.Trim('_'); enumerationEntity.BaseType = "MISSING"; enumerationEntity.Namespace = "MISSING"; // Elements for brief description IEnumerable<XElement> abstractElements = enumerationElement.Element("briefdescription").Elements("para"); // Extract for detailed description IEnumerable<XElement> detailsElements = (from el in enumerationElement.Element("detaileddescription").Elements("para") where !el.Elements("simplesect").Any() && el.Elements("parameterlist").Any() && el.Elements("xrefsect").Any() select el); // Elements for values IEnumerable<XElement> enumerationValueElements = enumerationElement.Elements("enumvalue"); // Add brief description foreach (XElement paragraph in abstractElements) { enumerationEntity.Summary.Add(paragraph.TrimAll()); } foreach (XElement paragraph in detailsElements) { enumerationEntity.Summary.Add(paragraph.TrimAll()); } // Add each value foreach (XElement enumerationValueElement in enumerationValueElements) { String key = enumerationValueElement.Element("name").TrimAll(); String value; if (enumerationValueElement.Element("initializer") != null) { value = enumerationValueElement.Element("initializer").Value; value = value.Replace("=", String.Empty); value = value.TrimAll(); } else { value = String.Empty; } // Add a new value EnumerationValueEntity enumerationValueEntity = new EnumerationValueEntity(); enumerationValueEntity.Name = key; enumerationValueEntity.Value = value; enumerationEntity.Values.Add(enumerationValueEntity); // Elements for brief description abstractElements = enumerationValueElement.Element("briefdescription").Elements("para"); // Add brief description foreach (XElement paragraph in abstractElements) { enumerationValueEntity.Summary.Add(paragraph.TrimAll()); } } /* // Get the availability if (availabilityElement != null) { enumerationEntity.MinAvailability = CommentHelper.ExtractAvailability(availabilityElement.TrimAll()); } */ return enumerationEntity; }
/// <summary> /// Parses the specified property element. /// </summary> /// <param name = "propertyElement">The property element.</param> /// <returns></returns> public PropertyEntity Parse(TypedEntity typedEntity, XElement propertyElement) { XElement nameElement = propertyElement.Element("h3"); String name = nameElement.TrimAll(); // Extract the declaration XElement signatureElement = (from el in propertyElement.Elements("div") where (String) el.Attribute("class") == "declaration" select el).FirstOrDefault(); // Extract the abstract XElement abstractElement = (from el in propertyElement.Elements("p") where (String) el.Attribute("class") == "abstract" select el).FirstOrDefault(); //// Extract discussion //XElement discussionElement = (from el in propertyElement.Elements("div") // where (String) el.Attribute("class") == "api discussion" // select el).FirstOrDefault(); // Get the availability XElement availabilityElement = (from el in propertyElement.Elements("div") where (String) el.Attribute("class") == "api availability" select el).FirstOrDefault(); String signature = signatureElement.TrimAll(); List<String> summary = new List<String>(); summary.Add(abstractElement.TrimAll()); //if (discussionElement != null) //{ // foreach (XElement paragraph in discussionElement.Elements("p")) // { // summary.Add(paragraph.TrimAll()); // } //} String minAvailability = availabilityElement.Elements("ul").Elements("li").FirstOrDefault().TrimAll(); minAvailability = CommentHelper.ExtractAvailability(minAvailability); // Extract property's attribute List<String> attributes = new List<String>(); int attributesStart = signature.IndexOf('('); int attributesEnd = signature.IndexOf(')'); if (attributesStart > 0 && attributesEnd > attributesStart) { String attributesAll = signature.Substring(attributesStart + 1, attributesEnd - attributesStart - 1); attributes.AddRange(attributesAll.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries).Select(attr => attr.Trim())); } int typeStart = attributesEnd > 0 ? (attributesEnd + 1) : "@property".Length; int typeEnd = signature.LastIndexOf(name); string returnType = (typeStart > 0 && typeEnd > typeStart) ? signature.Substring(typeStart, typeEnd - typeStart).Trim() : "MISSING"; // Is the property readonly ? bool readOnly = attributes.Contains("readonly"); // Is there an explicit getter String getterSelector = attributes.Find(a => a.Contains("getter")); if (getterSelector != null) { getterSelector = getterSelector.Substring(getterSelector.IndexOf('=') + 1); } else { getterSelector = name; } // Alter the name name = name.UpperCaseFirstLetter(); // Is there an explicit setter String setterSelector = attributes.Find(a => a.Contains("setter")); if (setterSelector != null) { setterSelector = setterSelector.Substring(setterSelector.IndexOf('=') + 1); } else { setterSelector = "set" + name + ":"; } bool isOut, isByRef, isBlock; String type = this.TypeManager.ConvertType(returnType, out isOut, out isByRef, out isBlock, this.Logger); PropertyEntity propertyEntity = new PropertyEntity(); propertyEntity.MinAvailability = minAvailability; propertyEntity.Name = getterSelector.UpperCaseFirstLetter(); propertyEntity.Static = false; propertyEntity.Summary = summary; propertyEntity.Type = type; propertyEntity.Getter = new MethodEntity(); propertyEntity.Getter.Signature = signature; propertyEntity.Getter.Selector = getterSelector; if (readOnly) { propertyEntity.Setter = null; } else { propertyEntity.Setter = new MethodEntity(); propertyEntity.Setter.Signature = signature; propertyEntity.Setter.Selector = setterSelector; } return propertyEntity; }
protected void ExtractFunctions(TypedEntity typedEntity, XElement root) { IEnumerable<XElement> functionElements = from el in root.Descendants("h3") where (String) el.Attribute("class") == "tight jump function" select el; foreach (XElement functionElement in functionElements) { FunctionEntity functionEntity = this.FunctionParser.Parse(typedEntity, functionElement); if (functionEntity != null) { typedEntity.Functions.Add(functionEntity); } } }
private void Convert(Framework f, FrameworkEntity e, String sourcePath, String destinationPath, TextWriter writer = null) { switch (e.type) { case FrameworkEntityType.T: { IXhtmlTypeParser parser = this.GetTypeParser (f, e, writer); TypedEntity entity = new TypedEntity (); entity.Namespace = f.name; entity.Name = e.name; entity.Nature = e.type; parser.Parse (entity, sourcePath); entity.SaveTo (destinationPath); } break; case FrameworkEntityType.C: { IXhtmlClassParser parser = this.GetClassParser (f, e, writer); ClassEntity entity = new ClassEntity (); entity.Namespace = f.name; entity.Name = e.name; entity.Nature = e.type; parser.Parse (entity, sourcePath); entity.SaveTo (destinationPath); } break; case FrameworkEntityType.P: { IXhtmlClassParser parser = this.GetProtocolParser (f, e, writer); ProtocolEntity entity = new ProtocolEntity (); entity.Namespace = f.name; entity.Name = e.name; entity.Nature = e.type; parser.Parse (entity, sourcePath); entity.SaveTo (destinationPath); } break; default: break; } }
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 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; }
public EnumerationEntity Parse(TypedEntity typedEntity, String name, IEnumerable<XElement> elements) { EnumerationEntity enumerationEntity = new EnumerationEntity (); 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 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 (); String declaration = declarationElement.TrimAll (); String type = "NOTYPE"; String values = String.Empty; bool result = this.SplitEnumeration (declaration, ref name, ref type, ref values); if (!result) { return null; } enumerationEntity.Name = name; enumerationEntity.BaseType = type; enumerationEntity.Namespace = "MISSING"; // 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)) { enumerationEntity.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)) // { // enumerationEntity.Summary.Add(line); // } // } //} // Parse the values string[] pairs = values.Split (new []{','}, StringSplitOptions.RemoveEmptyEntries); foreach (string pair in pairs) { if (String.Equals (pair.TrimAll (), String.Empty)) { continue; } String key; String value = String.Empty; if (pair.IndexOf ('=') != -1) { string[] parts = pair.Split (new []{'='}, StringSplitOptions.RemoveEmptyEntries); key = parts [0].Trim (); value = parts [1].Trim (); } else { key = pair.Trim (); } // Add a new value EnumerationValueEntity enumerationValueEntity = new EnumerationValueEntity (); enumerationValueEntity.Name = key; if (value.Length == 6 && value.StartsWith ("'") && value.EndsWith ("'")) { String v = value.Trim ('\''); enumerationValueEntity.Value = "0x" + FourCharToInt (v).ToString ("X8"); } else { enumerationValueEntity.Value = value; } enumerationEntity.Values.Add (enumerationValueEntity); } XElement termList = parameterElement != null ? parameterElement.Descendants ("dl").FirstOrDefault () : null; 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 EnumerationValueEntity enumerationValueEntity = enumerationEntity.Values.Find (p => String.Equals (p.Name, term)); if (enumerationValueEntity != null) { foreach (string sum in summaries) { enumerationValueEntity.Summary.Add (sum); } } } } } // Get the availability if (availabilityElement != null) { enumerationEntity.MinAvailability = CommentHelper.ExtractAvailability (availabilityElement.TrimAll ()); } return enumerationEntity; }
// /// <summary> // /// Generates the specified entity. // /// </summary> // /// <param name = "typedEntity">The type entity.</param> // /// <param name = "functionEntity">The function entity.</param> // public void GenerateOpaque (TypedEntity typedEntity, FunctionEntity functionEntity, String opaquePointer) // { // // Don't generate if required // if (!functionEntity.Generate) { // return; // } // // // Append static condition if needed // this.AppendStartCondition (functionEntity); // // // Append documentation // this.AppendDocumentation (functionEntity, false, true); // // // Append Obsolete attribute // this.AppendObsoleteAttribute (functionEntity); // // // Create function signature // StringBuilder signature = new StringBuilder (); // // // Append keywords // String keywords = GetKeywords (functionEntity, true, false, false); // signature.Append (keywords); // // String name = functionEntity.Name; // if (name.StartsWith (typedEntity.Name)) { // name = name.Substring (typedEntity.Name.Length); // } // // // Append return type and name // String returnType = functionEntity.ReturnOpaque ? typedEntity.Name : functionEntity.ReturnType; // signature.AppendFormat ("{0} {1}", returnType, name); // signature.Append ("("); // // // Append parameters // List<String> parameters = new List<String> (); // bool first = true; // foreach (MethodParameterEntity methodParameterEntity in functionEntity.Parameters.Where(p => p.Generate)) { // if (first) { // first = false; // if (methodParameterEntity.IsOpaque) { // continue; // } // } else { // if (methodParameterEntity.IsOpaque) { // methodParameterEntity.Type = typedEntity.Name; // } // } // parameters.Add (GetTypeSignature (methodParameterEntity)); // } // signature.Append (String.Join (", ", parameters.ToArray ())); // signature.Append (")"); // // this.Writer.WriteLineFormat (2, signature.ToString ()); // // // Output the body // this.Writer.WriteLineFormat (2, "{{"); // StringBuilder invocation = new StringBuilder(); // bool hasReturn = !String.Equals (functionEntity.ReturnType, "void"); // if (functionEntity.ReturnOpaque) { // invocation.AppendFormat("IntPtr value = "); // } else if (hasReturn) { // invocation.AppendFormat("return "); // } // invocation.AppendFormat("{0}(", name); // first = true; // foreach (MethodParameterEntity methodParameterEntity in functionEntity.Parameters.Where(p => p.Generate)) { // if (first) { // first = false; // if (methodParameterEntity.IsOpaque) { // invocation.AppendFormat("this.{0}", opaquePointer); // } else { // invocation.AppendFormat("{0}", methodParameterEntity.Name); // } // } else { // invocation.AppendFormat(", {0}", methodParameterEntity.Name); // } // } // invocation.Append(");"); // this.Writer.WriteLineFormat (3, invocation.ToString()); // // if (functionEntity.ReturnOpaque) { // this.Writer.WriteLineFormat (3, "return new {0}(value);", typedEntity.Name); // } // // this.Writer.WriteLineFormat (2, "}}"); // // // Append static condition if needed // this.AppendEndCondition (functionEntity); // } /// <summary> /// Generates the specified entity. /// </summary> /// <param name = "typedEntity">The type entity.</param> /// <param name = "functionEntity">The function entity.</param> public void Generate(TypedEntity typedEntity, FunctionEntity functionEntity) { // Don't generate if required if (!functionEntity.Generate) { return; } if (functionEntity.MinAvailabilityAsVersion.IsGreaterThan(typedEntity.MinAvailabilityAsVersion)) { // Append static condition if needed this.AppendStartCondition(functionEntity); } // Append documentation this.AppendDocumentation (functionEntity); // Collect information bool needStorage = false; bool varargs = false; CollectInformations (functionEntity, ref needStorage, ref varargs); // Collect information on 32/64 bits invocations to check if they differ FunctionEntity functionEntity32 = DeriveFunctionEntity (functionEntity, false); FunctionEntity functionEntity64 = DeriveFunctionEntity (functionEntity, true); bool useMixedInvocation = !AreMethodTypesEqual (functionEntity32, functionEntity64); if (needStorage || useMixedInvocation) { if (useMixedInvocation) { this.GenerateWrapperFunction (typedEntity, functionEntity, functionEntity32, functionEntity64, needStorage); #if MIXED_MODE this.GenerateNativeFunction(typedEntity, functionEntity64, SUFFIX_64, false); #endif this.GenerateNativeFunction (typedEntity, functionEntity32, SUFFIX_32, false); } else { this.GenerateWrapperFunction (typedEntity, functionEntity, null, null, needStorage); this.GenerateNativeFunction (typedEntity, functionEntity, SUFFIX_INNER, false); } } else { this.GenerateNativeFunction (typedEntity, functionEntity, null, true); } if (functionEntity.MinAvailabilityAsVersion.IsGreaterThan(typedEntity.MinAvailabilityAsVersion)) { // Append static condition if needed this.AppendEndCondition(functionEntity); } // Update statistics this.Statistics.Functions++; }