Moved more transformations into the *Processor classes.

An EnumProcessor or FuncProcessor instance is now required in order to
call their Translate*() methods. A number of transformations that
relied on calling the static methods have now been moved inside the
processor classes.
This commit is contained in:
Stefanos A. 2013-10-27 01:30:45 +02:00
parent 5e06c14607
commit 51f52d7fc4
9 changed files with 79 additions and 138 deletions

View file

@ -58,7 +58,7 @@ namespace Bind
return enums;
}
static EnumCollection ProcessNames(EnumCollection enums, XPathNavigator nav)
EnumCollection ProcessNames(EnumCollection enums, XPathNavigator nav)
{
EnumCollection processed_enums = new EnumCollection();
foreach (var e in enums.Values)
@ -89,8 +89,11 @@ namespace Bind
return name;
}
public static string TranslateEnumName(string name)
public string TranslateEnumName(string name)
{
if (String.IsNullOrEmpty(name))
return name;
if (Utilities.Keywords.Contains(name))
return name;
@ -99,7 +102,7 @@ namespace Bind
StringBuilder translator = new StringBuilder(name);
// Split on IHV names, to ensure that characters appearing after these name are uppercase.
// Split on IHV names and acronyms, to ensure that characters appearing after these name are uppercase.
var match = Utilities.Acronyms.Match(name);
int offset = 0; // Everytime we insert a match, we must increase offset to compensate.
while (match.Success)
@ -162,7 +165,7 @@ namespace Bind
return name;
}
static EnumCollection ProcessConstants(EnumCollection enums, XPathNavigator nav)
EnumCollection ProcessConstants(EnumCollection enums, XPathNavigator nav)
{
foreach (var e in enums.Values)
{
@ -171,6 +174,7 @@ namespace Bind
{
c.Name = TranslateConstantName(c.Name, false);
c.Value = TranslateConstantValue(c.Value);
c.Reference = TranslateEnumName(c.Reference);
if (!processed_constants.ContainsKey(c.Name))
processed_constants.Add(c.Name, c);
}
@ -215,6 +219,9 @@ namespace Bind
public static string TranslateConstantName(string s, bool isValue)
{
if (String.IsNullOrEmpty(s))
return s;
StringBuilder translator = new StringBuilder(s.Length);
if (isValue)
@ -319,7 +326,7 @@ namespace Bind
// Note that we have the removal must be a separate step, since
// we cannot modify a collection while iterating with foreach.
var broken_references = e.ConstantCollection.Values
.Where(c => !Constant.TranslateConstantWithReference(c, enums, null))
.Where(c => !Constant.TranslateConstantWithReference(c, enums))
.Select(c => c).ToList();
foreach (var c in broken_references)
{

View file

@ -56,14 +56,15 @@ namespace Bind
Overrides = overrides;
}
public FunctionCollection Process(DelegateCollection delegates, EnumCollection enums)
public FunctionCollection Process(EnumProcessor enum_processor, DelegateCollection delegates, EnumCollection enums)
{
Console.WriteLine("Processing delegates.");
var nav = new XPathDocument(Overrides).CreateNavigator();
foreach (var d in delegates.Values)
{
TranslateReturnType(nav, d, enums);
TranslateParameters(nav, d, enums);
TranslateExtension(d);
TranslateReturnType(enum_processor, nav, d, enums);
TranslateParameters(enum_processor, nav, d, enums);
TranslateAttributes(nav, d, enums);
}
@ -76,11 +77,33 @@ namespace Bind
return MarkCLSCompliance(wrappers);
}
// Trims unecessary suffices from the specified OpenGL function name.
public static string TrimName(string name, bool keep_extension)
void TranslateExtension(Delegate d)
{
string trimmed_name = Utilities.StripGL2Extension(name);
string extension = Utilities.GetGL2Extension(name);
var extension = d.Extension.ToUpper();
if (extension.Length > 2)
{
extension = extension[0] + extension.Substring(1).ToLower();
}
d.Extension = extension;
}
static string GetTrimmedExtension(string name, string extension)
{
// Extensions are always uppercase
int index = name.LastIndexOf(extension.ToUpper());
if (index >= 0)
{
name = name.Remove(index);
}
return name;
}
// Trims unecessary suffices from the specified OpenGL function name.
static string GetTrimmedName(Delegate d)
{
string name = d.Name;
string extension = d.Extension;
string trimmed_name = GetTrimmedExtension(name, extension);
// Note: some endings should not be trimmed, for example: 'b' from Attrib.
// Check the endingsNotToTrim regex for details.
@ -117,16 +140,20 @@ namespace Bind
static XPathNavigator GetFuncOverride(XPathNavigator nav, Delegate d)
{
string name = TrimName(d.Name, false);
string trimmed_name = GetTrimmedName(d);
string ext = d.Extension;
var function_override =
nav.SelectSingleNode(String.Format(Path, d.Name, ext)) ??
nav.SelectSingleNode(String.Format(Path, Utilities.StripGL2Extension(d.Name), ext)) ??
nav.SelectSingleNode(String.Format(Path, name, ext));
nav.SelectSingleNode(String.Format(Path, trimmed_name, ext));
return function_override;
}
void TrimName(Function f)
{
f.TrimmedName = GetTrimmedName(f);
}
// Translates the opengl return type to the equivalent C# type.
//
// First, we use the official typemap (gl.tm) to get the correct type.
@ -136,7 +163,7 @@ namespace Bind
// 3) A generic object or void* (translates to IntPtr)
// 4) A GLenum (translates to int on Legacy.Tao or GL.Enums.GLenum otherwise).
// Return types must always be CLS-compliant, because .Net does not support overloading on return types.
static void TranslateReturnType(XPathNavigator nav, Delegate d, EnumCollection enums)
void TranslateReturnType(EnumProcessor enum_processor, XPathNavigator nav, Delegate d, EnumCollection enums)
{
var function_override = GetFuncOverride(nav, d);
@ -149,7 +176,7 @@ namespace Bind
}
}
d.ReturnType.Translate(nav, d.Category, enums);
d.ReturnType.Translate(enum_processor, nav, d.Category, enums);
if (d.ReturnType.CurrentType.ToLower().Contains("void") && d.ReturnType.Pointer != 0)
{
@ -181,7 +208,7 @@ namespace Bind
d.ReturnType.CurrentType = d.ReturnType.GetCLSCompliantType();
}
static void TranslateParameters(XPathNavigator nav, Delegate d, EnumCollection enums)
void TranslateParameters(EnumProcessor enum_processor, XPathNavigator nav, Delegate d, EnumCollection enums)
{
var function_override = GetFuncOverride(nav, d);
@ -216,7 +243,7 @@ namespace Bind
}
}
d.Parameters[i].Translate(nav, d.Category, enums);
d.Parameters[i].Translate(enum_processor, nav, d.Category, enums);
if (d.Parameters[i].CurrentType == "UInt16" && d.Name.Contains("LineStipple"))
d.Parameters[i].WrapperType = WrapperTypes.UncheckedParameter;
}
@ -242,7 +269,7 @@ namespace Bind
}
}
static FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums)
FunctionCollection CreateWrappers(DelegateCollection delegates, EnumCollection enums)
{
var wrappers = new FunctionCollection();
foreach (var d in delegates.Values)
@ -347,9 +374,11 @@ namespace Bind
return collection;
}
static IEnumerable<Function> CreateNormalWrappers(Delegate d, EnumCollection enums)
IEnumerable<Function> CreateNormalWrappers(Delegate d, EnumCollection enums)
{
Function f = new Function(d);
TrimName(f);
WrapReturnType(f);
foreach (var wrapper in WrapParameters(f, enums))
{

View file

@ -82,8 +82,11 @@ namespace Bind.GL2
SpecReader.ReadDelegates(Path.Combine(Settings.InputPath, glSpec), Delegates);
SpecReader.ReadDelegates(overrides, Delegates);
Enums = new EnumProcessor(overrides).Process(Enums);
Wrappers = new FuncProcessor(overrides).Process(Delegates, Enums);
var enum_processor = new EnumProcessor(overrides);
var func_processor = new FuncProcessor(overrides);
Enums = enum_processor.Process(Enums);
Wrappers = func_processor.Process(enum_processor, Delegates, Enums);
}
#endregion

View file

@ -215,9 +215,6 @@ namespace Bind
valid = true;
var sb = new StringBuilder();
if (f.TrimmedName == "ExtGetBufferPointer")
;// Debugger.Break();
if (f.Parameters.Count > 0)
{
foreach (var p in f.Parameters)

View file

@ -98,9 +98,7 @@ namespace Bind.Structures
get { return _reference; }
set
{
if (!String.IsNullOrEmpty(value))
_reference = EnumProcessor.TranslateEnumName(value.Trim());
else _reference = value;
_reference = value;
}
}
@ -145,51 +143,6 @@ namespace Bind.Structures
#endregion
#region Translate
[Obsolete]
public static string Translate(string s, bool isValue)
{
translator.Remove(0, translator.Length);
// Translate the constant's name to match .Net naming conventions
bool name_is_all_caps = s.AsEnumerable().All(c => Char.IsLetter(c) ? Char.IsUpper(c) : true);
bool name_contains_underscore = s.Contains("_");
if ((Settings.Compatibility & Settings.Legacy.NoAdvancedEnumProcessing) == Settings.Legacy.None &&
(name_is_all_caps || name_contains_underscore))
{
bool next_char_uppercase = true;
bool is_after_digit = false;
if (!isValue && Char.IsDigit(s[0]))
translator.Insert(0, Settings.ConstantPrefix);
foreach (char c in s)
{
if (c == '_')
next_char_uppercase = true;
else if (Char.IsDigit(c))
{
is_after_digit = true;
translator.Append(c);
}
else
{
translator.Append(next_char_uppercase || (is_after_digit && c == 'd') ? Char.ToUpper(c) : Char.ToLower(c));
is_after_digit = next_char_uppercase = false;
}
}
translator[0] = Char.ToUpper(translator[0]);
}
else
translator.Append(s);
return translator.ToString();
}
#endregion
/// <summary>
/// Replces the Value of the given constant with the value referenced by the [c.Reference, c.Value] pair.
/// </summary>
@ -197,7 +150,7 @@ namespace Bind.Structures
/// <param name="enums">The list of enums to check.</param>
/// <param name="auxEnums">The list of auxilliary enums to check.</param>
/// <returns>True if the reference was found; false otherwise.</returns>
public static bool TranslateConstantWithReference(Constant c, EnumCollection enums, EnumCollection auxEnums)
public static bool TranslateConstantWithReference(Constant c, EnumCollection enums)
{
if (c == null)
throw new ArgumentNullException("c");
@ -218,16 +171,9 @@ namespace Bind.Structures
// Transitively translate the referenced token
// Todo: this may cause loops if two tokens reference each other.
// Add a max reference depth and bail out?
TranslateConstantWithReference(enums[c.Reference].ConstantCollection[c.Value], enums, auxEnums);
TranslateConstantWithReference(enums[c.Reference].ConstantCollection[c.Value], enums);
referenced_constant = (enums[c.Reference].ConstantCollection[c.Value]);
}
else if (auxEnums != null && auxEnums.ContainsKey(c.Reference) && auxEnums[c.Reference].ConstantCollection.ContainsKey(c.Value))
{
// Legacy from previous generator incarnation.
// Todo: merge everything into enums and get rid of auxEnums.
TranslateConstantWithReference(auxEnums[c.Reference].ConstantCollection[c.Value], enums, auxEnums);
referenced_constant = (auxEnums[c.Reference].ConstantCollection[c.Value]);
}
else if (enums.ContainsKey(Settings.CompleteEnumName) &&
enums[Settings.CompleteEnumName].ConstantCollection.ContainsKey(c.Value))
{

View file

@ -43,6 +43,7 @@ namespace Bind.Structures
public Delegate(Delegate d)
{
Category = d.Category;
Extension = d.Extension;
Name = d.Name;
Parameters = new ParameterCollection(d.Parameters);
ReturnType = new Type(d.ReturnType);
@ -226,22 +227,10 @@ namespace Bind.Structures
#region public bool Extension
string _extension;
public string Extension
{
get
{
if (!String.IsNullOrEmpty(Name))
{
_extension = Utilities.GetGL2Extension(Name);
return String.IsNullOrEmpty(_extension) ? "Core" : _extension;
}
else
{
return null;
}
}
get;
set;
}
#endregion

View file

@ -24,7 +24,7 @@ namespace Bind.Structures
public Function(Delegate d)
: base(d)
{
Name = d.Name;
TrimmedName = Name = d.Name;
Body = new FunctionBody();
WrappedDelegate = d;
}
@ -34,6 +34,7 @@ namespace Bind.Structures
{
Parameters = new ParameterCollection(f.Parameters);
ReturnType = new Type(f.ReturnType);
TrimmedName = f.TrimmedName;
Body.AddRange(f.Body);
}
@ -94,38 +95,7 @@ namespace Bind.Structures
#region public string TrimmedName
public string TrimmedName;
#endregion
#region public override string Name
/// <summary>
/// Gets or sets the name of the opengl function.
/// If no Tao compatibility is set, set TrimmedName to Name, after removing
/// [u][bsifd][v].
/// </summary>
public override string Name
{
get { return base.Name; }
set
{
base.Name = value;
if ((Settings.Compatibility & Settings.Legacy.NoTrimFunctionEnding) != Settings.Legacy.None)
{
// If we don't need compatibility with Tao,
// remove the Extension and the overload information from the name
// (Extension == "ARB", "EXT", etc, overload == [u][bsidf][v])
// TODO: Use some regex's here, to reduce clutter.
TrimmedName = value;
}
else
{
TrimmedName = FuncProcessor.TrimName(Name, false);
}
}
}
public string TrimmedName { get; set; }
#endregion

View file

@ -15,7 +15,7 @@ namespace Bind.Structures
/// <summary>
/// Represents a single parameter of an opengl function.
/// </summary>
public class Parameter : Type, IComparable<Parameter>
class Parameter : Type, IComparable<Parameter>
{
string cache;
bool rebuild;
@ -302,9 +302,9 @@ namespace Bind.Structures
#region Translate()
override public void Translate(XPathNavigator overrides, string category, EnumCollection enums)
override public void Translate(EnumProcessor enum_processor, XPathNavigator overrides, string category, EnumCollection enums)
{
base.Translate(overrides, category, enums);
base.Translate(enum_processor, overrides, category, enums);
if (Pointer >= 3)
{
@ -392,7 +392,7 @@ namespace Bind.Structures
/// <summary>
/// Holds the parameter list of an opengl function.
/// </summary>
public class ParameterCollection : List<Parameter>, IComparable<ParameterCollection>
class ParameterCollection : List<Parameter>, IComparable<ParameterCollection>
{
string cache = String.Empty;
string callStringCache = String.Empty;

View file

@ -11,7 +11,7 @@ using System.Xml.XPath;
namespace Bind.Structures
{
public class Type : IComparable<Type>
class Type : IComparable<Type>
{
internal static Dictionary<string, string> GLTypes;
internal static Dictionary<string, string> CSTypes;
@ -324,12 +324,12 @@ namespace Bind.Structures
#region public virtual void Translate(XPathNavigator overrides, string category)
public virtual void Translate(XPathNavigator overrides, string category, EnumCollection enums)
public virtual void Translate(EnumProcessor enum_processor, XPathNavigator overrides, string category, EnumCollection enums)
{
Enum @enum;
string s;
category = EnumProcessor.TranslateEnumName(category);
category = enum_processor.TranslateEnumName(category);
// Try to find out if it is an enum. If the type exists in the normal GLEnums list, use this.
// Otherwise, try to find it in the aux enums list. If it exists in neither, it is not an enum.
@ -368,7 +368,7 @@ namespace Bind.Structures
if (enums.ContainsKey(category))
{
QualifiedType = String.Format("{0}{1}{2}", Settings.EnumsOutput,
Settings.NamespaceSeparator, EnumProcessor.TranslateEnumName(category));
Settings.NamespaceSeparator, enum_processor.TranslateEnumName(category));
}
else
{