/// <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); } }
private void GenerateEnumerationEntity(String baseFolder, IList <FrameworkEntity> entities, Framework f, FrameworkEntity e, String sourcePath, String destinationPath) { String file; EnumerationEntity entity = BaseEntity.LoadFrom <EnumerationEntity> (sourcePath); if (!entity.Generate) { return; } this.Log(Level.Info, String.Format("Generating '{0}'...", e.name)); file = destinationPath + ".cs"; this.Generate <EnumerationGenerator> (f, entity, file); }
/// <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) { foreach (string title in new[] { "Typedefs", "Enumerated Types" }) { XElement listMarker = (from el in root.Descendants("h2") where el.Value == title 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) { String n = name.Replace(" ", String.Empty); XElement marker = (from el in list.ElementsAfterSelf("a") where el.Attribute("name") != null && el.Attribute("name").Value.EndsWith("/" + n) select el).FirstOrDefault(); if (marker != null) { //XElement startElement = marker.ElementsAfterSelf("table").FirstOrDefault(); IEnumerable <XElement> elements = marker.ElementsAfterSelf().TakeWhile(el => el.Name != "a"); EnumerationEntity entity = this.EnumerationParser.Parse(typedEntity, name, elements); if (entity != null) { typedEntity.Enumerations.Add(entity); } } else { this.Logger.WriteLine("MISSING marker for constant " + name); } } } } }
private List <BaseEntity> ExtractEnumeration(XElement constantElement, String name, String summary, String declaration) { declaration = declaration.Trim(';'); // Default values String type = "NOTYPE"; String values = String.Empty; // Match the enumeration definition bool result = this.SplitEnumeration(declaration, ref name, ref type, ref values); if (!result) { return(null); } if (type == "NOTYPE") { type = RefineEnumBaseType(values); } // Create the enumeration EnumerationEntity enumerationEntity = new EnumerationEntity(); enumerationEntity.Name = name; enumerationEntity.BaseType = type; enumerationEntity.Namespace = "MISSING"; enumerationEntity.Summary.Add(summary); // Parse the values var pairs = values.Split(new [] { '\n' }, StringSplitOptions.RemoveEmptyEntries); foreach (string immutablePair in pairs) { String key; String value = String.Empty; String pair = immutablePair.Replace(",", ""); // Handle value assignment 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; } // Convert number qualifiers from native to managed enumerationValueEntity.Value = ConvertNumericQualifier(enumerationValueEntity.Value); enumerationEntity.Values.Add(enumerationValueEntity); } // Get the definitions XElement termList = (from el in constantElement.ElementsAfterSelf("dl") where (String)el.Attribute("class") == "termdef" select el).FirstOrDefault(); if (termList != null) { IEnumerable <XElement> dtList = termList.Elements("dt"); IEnumerable <XElement> ddList = termList.Elements("dd"); if (dtList.Count() == ddList.Count()) { // Iterate over definitions for (int i = 0; i < dtList.Count(); i++) { String term = dtList.ElementAt(i).Value.TrimAll(); IEnumerable <String> summaries = ddList.ElementAt(i).Elements("p").Select(p => p.Value.TrimAll()); // Find the enumeration value EnumerationValueEntity enumerationValueEntity = enumerationEntity.Values.Find(v => v.Name == term); if (enumerationValueEntity != null) { foreach (string sum in summaries) { if (CommentHelper.IsAvailability(sum)) { enumerationValueEntity.MinAvailability = CommentHelper.ExtractAvailability(sum); break; } enumerationValueEntity.Summary.Add(sum); } } else { this.Logger.WriteLine("Term with no match '" + term + "'"); } } } else { this.Logger.WriteLine("MISMATCH in terms"); } } // Make sure availability is ok enumerationEntity.AdjustAvailability(); return(new List <BaseEntity> { enumerationEntity }); }
/// <summary> /// Generates the specified entity. /// </summary> /// <param name = "entity">The entity.</param> /// <param name = "standlone">if set to <c>true</c>, generate a standlone file.</param> public void Generate(BaseEntity entity, bool standlone) { // Don't generate if required if (!entity.Generate) { return; } EnumerationEntity enumerationEntity = (EnumerationEntity)entity; if (standlone) { // Append License this.Writer.WriteLineFormat(0, License); // Append usings this.AppendStandardNamespaces(); // Append namespace starter this.Writer.WriteLineFormat(0, "namespace Monobjc.{0}", enumerationEntity.Namespace); this.Writer.WriteLineFormat(0, "{{"); } // Append static condition if needed this.AppendStartCondition(entity); // Append class starter this.Writer.WriteLineFormat(1, "/// <summary>"); foreach (String line in enumerationEntity.Summary) { this.Writer.WriteLineFormat(1, "/// <para>{0}</para>", line.EscapeAll()); } this.AppendAvailability(1, enumerationEntity); this.Writer.WriteLineFormat(1, "/// </summary>"); // If the type is a mixed type, then output the attributes String type32 = this.GetRealType(enumerationEntity.BaseType, false); String type64 = this.GetRealType(enumerationEntity.BaseType, true); if (!String.IsNullOrEmpty(enumerationEntity.MixedType) /*!String.Equals(type32, type64)*/) { #if MIXED_MODE type32 = GetRealType(enumerationEntity.Name, false); type64 = GetRealType(enumerationEntity.Name, true); this.Writer.WriteLineFormat(1, "[ObjectiveCUnderlyingTypeAttribute(typeof({0}), Is64Bits = false)]", type32); this.Writer.WriteLineFormat(1, "[ObjectiveCUnderlyingTypeAttribute(typeof({0}), Is64Bits = true)]", type64); #endif } #if GENERATED_ATTRIBUTE this.Writer.WriteLineFormat(1, "[GeneratedCodeAttribute(\"{0}\", \"{1}\")]", GenerationHelper.ToolName, GenerationHelper.ToolVersion); #endif if (enumerationEntity.Flags) { this.Writer.WriteLineFormat(1, "[Flags]"); } // Append enumeration declaration this.Writer.WriteLineFormat(1, "public enum {0} : {1}", enumerationEntity.Name, GetRealType(enumerationEntity.BaseType, false)); this.Writer.WriteLineFormat(1, "{{"); // Append methods foreach (EnumerationValueEntity enumerationValueEntity in enumerationEntity.Values) { // Don't generate if required if (!enumerationValueEntity.Generate) { continue; } if (enumerationValueEntity.MinAvailabilityAsVersion.IsGreaterThan(enumerationEntity.MinAvailabilityAsVersion)) { // Append static condition if needed this.AppendStartCondition(enumerationValueEntity); } this.Writer.WriteLineFormat(2, "/// <summary>"); foreach (String line in enumerationValueEntity.Summary) { this.Writer.WriteLineFormat(2, "/// <para>{0}</para>", line.EscapeAll()); } this.AppendAvailability(2, enumerationValueEntity); this.Writer.WriteLineFormat(2, "/// </summary>"); if (String.IsNullOrEmpty(enumerationValueEntity.Value)) { this.Writer.WriteLineFormat(2, "{0},", enumerationValueEntity.Name); } else { String value = enumerationValueEntity.Value; value = value.Replace("<<", "<<"); this.Writer.WriteLineFormat(2, "{0} = {1},", enumerationValueEntity.Name, value); } if (enumerationValueEntity.MinAvailabilityAsVersion.IsGreaterThan(enumerationEntity.MinAvailabilityAsVersion)) { // Append static condition if needed this.AppendEndCondition(enumerationValueEntity); } } // Append class ender this.Writer.WriteLineFormat(1, "}}"); // Append static condition if needed this.AppendEndCondition(entity); if (standlone) { // Append namespace ender this.Writer.WriteLineFormat(0, "}}"); } // Update statistics this.Statistics.Enumerations++; }
/// <summary> /// Executes the task. /// </summary> protected override void ExecuteTask() { String baseFolder = this.CreateBaseDir(); DocSet docSet = this.CreateDocSet(); IEnumerable <Framework> frameworks = this.CreateFrameworks(docSet); IList <FrameworkEntity> entities = frameworks.SelectMany(f => f.GetEntities()).ToList(); String mixedTypesFile = this.MixedTypesFile.ToString(); Dictionary <String, String> mixedTypesTable = new Dictionary <String, String> (); this.LoadMixedTypes(mixedTypesFile, mixedTypesTable); foreach (var e in entities) { String sourcePath = e.GetPath(baseFolder, DocumentType.Model); if (sourcePath == null || !File.Exists(sourcePath)) { continue; } if (sourcePath.IsOlderThan(mixedTypesFile)) { continue; } this.Log(Level.Verbose, String.Format("Scanning '{0}' for mixed types...", e.name)); switch (e.type) { case FrameworkEntityType.T: { TypedEntity entity = BaseEntity.LoadFrom <TypedEntity> (sourcePath); if (entity.Generate) { foreach (EnumerationEntity enumerationEntity in entity.Enumerations) { if (!enumerationEntity.Generate) { continue; } this.AddMixedType(mixedTypesTable, enumerationEntity); } } } break; case FrameworkEntityType.C: { ClassEntity entity = BaseEntity.LoadFrom <ClassEntity> (sourcePath); if (entity.Generate) { foreach (EnumerationEntity enumerationEntity in entity.Enumerations) { if (!enumerationEntity.Generate) { continue; } this.AddMixedType(mixedTypesTable, enumerationEntity); } } } break; case FrameworkEntityType.P: { ProtocolEntity entity = BaseEntity.LoadFrom <ProtocolEntity> (sourcePath); if (entity.Generate) { foreach (EnumerationEntity enumerationEntity in entity.Enumerations) { if (!enumerationEntity.Generate) { continue; } this.AddMixedType(mixedTypesTable, enumerationEntity); } } } break; case FrameworkEntityType.S: { StructureEntity entity = BaseEntity.LoadFrom <StructureEntity> (sourcePath); if (entity.Generate) { this.AddMixedType(mixedTypesTable, entity); } } break; case FrameworkEntityType.E: { EnumerationEntity entity = BaseEntity.LoadFrom <EnumerationEntity> (sourcePath); if (entity.Generate) { this.AddMixedType(mixedTypesTable, entity); } } break; default: throw new NotSupportedException("Entity type not support: " + e.type); } } this.SaveMixedTypes(mixedTypesFile, mixedTypesTable); }
private Dictionary <String, String> LoadMixedTypes(String baseFolder, IList <FrameworkEntity> entities) { this.Log(Level.Info, "Loading mixed types..."); Dictionary <String, String> table = new Dictionary <String, String> (); foreach (var e in entities) { String sourcePath = e.GetPath(baseFolder, DocumentType.Model); if (sourcePath == null || !File.Exists(sourcePath)) { continue; } this.Log(Level.Verbose, String.Format("Scanning '{0}' for mixed types...", e.name)); switch (e.type) { case FrameworkEntityType.T: { TypedEntity entity = BaseEntity.LoadFrom <TypedEntity> (sourcePath); this.AddMixedType(table, entity.Name, entity.MixedType); foreach (EnumerationEntity enumerationEntity in entity.Enumerations) { this.AddMixedType(table, enumerationEntity.Name, enumerationEntity.MixedType); } } break; case FrameworkEntityType.C: { ClassEntity entity = BaseEntity.LoadFrom <ClassEntity> (sourcePath); this.AddMixedType(table, entity.Name, entity.MixedType); foreach (EnumerationEntity enumerationEntity in entity.Enumerations) { this.AddMixedType(table, enumerationEntity.Name, enumerationEntity.MixedType); } } break; case FrameworkEntityType.P: { ProtocolEntity entity = BaseEntity.LoadFrom <ProtocolEntity> (sourcePath); this.AddMixedType(table, entity.Name, entity.MixedType); foreach (EnumerationEntity enumerationEntity in entity.Enumerations) { this.AddMixedType(table, enumerationEntity.Name, enumerationEntity.MixedType); } } break; case FrameworkEntityType.S: { StructureEntity entity = BaseEntity.LoadFrom <StructureEntity> (sourcePath); this.AddMixedType(table, entity.Name, entity.MixedType); } break; case FrameworkEntityType.E: { EnumerationEntity entity = BaseEntity.LoadFrom <EnumerationEntity> (sourcePath); this.AddMixedType(table, entity.Name, entity.MixedType); } break; default: throw new NotSupportedException("Entity type not support: " + e.type); } } this.Log(Level.Info, "Loaded {0} mixed types", table.Count); return(table); }
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); }
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 entity. /// </summary> /// <param name = "entity">The entity.</param> /// <param name = "reader">The reader.</param> public override void Parse(BaseEntity entity, TextReader reader) { EnumerationEntity enumerationEntity = (EnumerationEntity)entity; if (enumerationEntity == null) { throw new ArgumentException("EnumerationEntity expected", "entity"); } IParser parser = ParserFactory.CreateParser(SupportedLanguage.CSharp, reader); parser.Parse(); // Extract the special nodes (comment, etc) List <ISpecial> specials = parser.Lexer.SpecialTracker.RetrieveSpecials(); this.CodeDomSpecialParser = new CodeDomSpecialParser(specials); // Parse the compilation unit CompilationUnit cu = parser.CompilationUnit; foreach (INode child1 in cu.Children) { NamespaceDeclaration namespaceDeclaration = child1 as NamespaceDeclaration; if (namespaceDeclaration == null) { continue; } foreach (INode child2 in child1.Children) { TypeDeclaration declaration = child2 as TypeDeclaration; if (declaration == null) { continue; } if (declaration.Type != ClassType.Enum) { continue; } // Extract basic informations enumerationEntity.BaseType = declaration.BaseTypes.Count > 0 ? declaration.BaseTypes [0].Type : "int"; // Extract attributes Attribute attribute = FindAttribute(declaration, "Flags"); enumerationEntity.Flags = (attribute != null); IEnumerable <Comment> comments = this.GetDocumentationCommentsBefore(declaration); AppendComment(entity, comments); // Append each values foreach (INode child3 in declaration.Children) { FieldDeclaration fieldDeclaration = child3 as FieldDeclaration; if (fieldDeclaration == null) { continue; } EnumerationValueEntity valueEntity = new EnumerationValueEntity(); valueEntity.Name = fieldDeclaration.Fields [0].Name; Expression expression = fieldDeclaration.Fields [0].Initializer; if (expression != null) { CodeDomExpressionPrinter printer = new CodeDomExpressionPrinter(); expression.AcceptVisitor(printer, null); valueEntity.Value = printer.ToString(); } comments = this.GetDocumentationCommentsBefore(fieldDeclaration); AppendComment(valueEntity, comments); enumerationEntity.Values.Add(valueEntity); } } } // Ensure that availability is set on entity. entity.AdjustAvailability(); }