From 55324777ca85d4840935d38f968b77ba2615480d Mon Sep 17 00:00:00 2001 From: the_fiddler Date: Wed, 20 Jul 2011 10:10:33 +0000 Subject: [PATCH] Added documentation comments to generated enums. Improved ISpecWriter API by removing low-level implementation details. Made Constant implement IComparable so it can be sorted before being written to output. --- Source/Bind/CSharpSpecWriter.cs | 64 +++++++++++++++++++++++++++--- Source/Bind/EnumProcessor.cs | 2 +- Source/Bind/ISpecWriter.cs | 10 ++--- Source/Bind/Structures/Constant.cs | 28 ++++++++++--- 4 files changed, 86 insertions(+), 18 deletions(-) diff --git a/Source/Bind/CSharpSpecWriter.cs b/Source/Bind/CSharpSpecWriter.cs index 96addfa6..cede9000 100644 --- a/Source/Bind/CSharpSpecWriter.cs +++ b/Source/Bind/CSharpSpecWriter.cs @@ -82,7 +82,7 @@ namespace Bind sw.WriteLine("{"); sw.Indent(); - WriteEnums(sw, enums); + WriteEnums(sw, enums, wrappers); sw.Unindent(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) @@ -169,7 +169,7 @@ namespace Bind #region WriteDelegates - public void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) + void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates) { Trace.WriteLine(String.Format("Writing delegates to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.DelegatesClass)); @@ -405,13 +405,41 @@ namespace Bind #endregion + #region WriteConstants + + void WriteConstants(BindStreamWriter sw, IEnumerable constants) + { + // Make sure everything is sorted. This will avoid random changes between + // consecutive runs of the program. + constants = constants.OrderBy(c => c); + + foreach (var c in constants) + { + if (!Settings.IsEnabled(Settings.Legacy.NoDocumentation)) + { + sw.WriteLine("/// "); + sw.WriteLine("/// Original was " + Settings.ConstantPrefix + c.OriginalName + " = " + c.Value); + sw.WriteLine("/// "); + } + + var str = String.Format("{0} = {1}((int){2}{3})", c.Name, c.Unchecked ? "unchecked" : "", + !String.IsNullOrEmpty(c.Reference) ? c.Reference + Settings.NamespaceSeparator : "", c.Value); + + sw.Write(str); + if (!String.IsNullOrEmpty(str)) + sw.WriteLine(","); + } + } + + #endregion + #region WriteEnums - public void WriteEnums(BindStreamWriter sw, EnumCollection enums) + void WriteEnums(BindStreamWriter sw, EnumCollection enums, FunctionCollection wrappers) { //sw.WriteLine("#pragma warning disable 3019"); // CLSCompliant attribute - sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments - sw.WriteLine(); + //sw.WriteLine("#pragma warning disable 1591"); // Missing doc comments + //sw.WriteLine(); if ((Settings.Compatibility & Settings.Legacy.NestedEnums) != Settings.Legacy.None) Trace.WriteLine(String.Format("Writing enums to:\t{0}.{1}.{2}", Settings.OutputNamespace, Settings.OutputClass, Settings.NestedEnumsClass)); @@ -430,7 +458,31 @@ namespace Bind foreach (Enum @enum in enums.Values) { - sw.Write(@enum); + if (!Settings.IsEnabled(Settings.Legacy.NoDocumentation)) + { + // Document which functions use this enum. + var functions = + (from wrapper in wrappers + from function in wrapper.Value + from param in function.Parameters + where param.CurrentType == @enum.Name + select Settings.GLClass + (function.Extension != "Core" ? ("." + function.Extension) : "") + "." + function.TrimmedName) + .Distinct(); + + sw.WriteLine("/// "); + sw.WriteLine(String.Format("/// {0}", functions.Count() > 0 ? + ("Used in " + String.Join(", ", functions.ToArray())) : "Not used directly.")); + sw.WriteLine("/// "); + } + + if (@enum.IsFlagCollection) + sw.WriteLine("[Flags]"); + sw.WriteLine("public enum " + @enum.Name + " : " + @enum.Type); + sw.WriteLine("{"); + sw.Indent(); + WriteConstants(sw, @enum.ConstantCollection.Values); + sw.Unindent(); + sw.WriteLine("}"); sw.WriteLine(); } diff --git a/Source/Bind/EnumProcessor.cs b/Source/Bind/EnumProcessor.cs index 829c9e96..3aec114b 100644 --- a/Source/Bind/EnumProcessor.cs +++ b/Source/Bind/EnumProcessor.cs @@ -183,7 +183,7 @@ namespace Bind { if (enum_override != null) { - XPathNavigator constant_override = enum_override.SelectSingleNode(String.Format("token[@name='{0}']", c.PreviousName)) ?? + XPathNavigator constant_override = enum_override.SelectSingleNode(String.Format("token[@name='{0}']", c.OriginalName)) ?? enum_override.SelectSingleNode(String.Format("token[@name={0}]", c.Name)); if (constant_override != null) { diff --git a/Source/Bind/ISpecWriter.cs b/Source/Bind/ISpecWriter.cs index df2f503d..06a62da2 100644 --- a/Source/Bind/ISpecWriter.cs +++ b/Source/Bind/ISpecWriter.cs @@ -12,10 +12,10 @@ namespace Bind interface ISpecWriter { void WriteBindings(IBind generator); - void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates); - void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, Dictionary CSTypes); - void WriteEnums(BindStreamWriter sw, EnumCollection enums); - void WriteTypes(BindStreamWriter sw, Dictionary CSTypes); - void WriteLicense(BindStreamWriter sw); +// void WriteDelegates(BindStreamWriter sw, DelegateCollection delegates); +// void WriteWrappers(BindStreamWriter sw, FunctionCollection wrappers, Dictionary CSTypes); +// void WriteEnums(BindStreamWriter sw, EnumCollection enums); +// void WriteTypes(BindStreamWriter sw, Dictionary CSTypes); +// void WriteLicense(BindStreamWriter sw); } } diff --git a/Source/Bind/Structures/Constant.cs b/Source/Bind/Structures/Constant.cs index 3ae17637..77f2f34a 100644 --- a/Source/Bind/Structures/Constant.cs +++ b/Source/Bind/Structures/Constant.cs @@ -17,7 +17,7 @@ namespace Bind.Structures /// can be retrieved or set. The value can be either a number, another constant /// or an alias to a constant /// - public class Constant + public class Constant : IComparable { static StringBuilder translator = new StringBuilder(); static readonly int MaxReferenceDepth = 8; @@ -25,13 +25,13 @@ namespace Bind.Structures #region PreviousName - string previous_name; + string original_name; // Gets the name prior to translation. - public string PreviousName + public string OriginalName { - get { return previous_name; } - private set { previous_name = value; } + get { return original_name; } + private set { original_name = value; } } #endregion @@ -51,7 +51,10 @@ namespace Bind.Structures { if (String.IsNullOrEmpty(value)) throw new ArgumentNullException("value"); - PreviousName = _name; + + if (OriginalName == null) + OriginalName = _name; + _name = value; } } @@ -259,6 +262,7 @@ namespace Bind.Structures /// (eg GL_XXX_YYY = (int)0xDEADBEEF or GL_XXX_YYY = GL_ZZZ.FOOBAR). /// /// + [Obsolete("This belongs to the language-specific ISpecWriter implementations.")] public override string ToString() { if (String.IsNullOrEmpty(Name)) @@ -271,5 +275,17 @@ namespace Bind.Structures } #endregion + + #region IComparable Members + + public int CompareTo(Constant other) + { + int ret = Value.CompareTo(other.Value); + if (ret == 0) + return Name.CompareTo(other.Name); + return ret; + } + + #endregion } }