mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-01-11 08:35:39 +00:00
Simplifed Constant.Reference resolution
Instead of recursing, we use a simple do..while loop to resolve the transitive reference of a constant. If there is a loop at any point, we stop and use a brute force search over all tokens. If this still fails to resolve the reference, then we report this reference as unresolved.
This commit is contained in:
parent
e0664993bb
commit
1b937b48f8
|
@ -20,8 +20,6 @@ namespace Bind.Structures
|
||||||
public class Constant : IComparable<Constant>
|
public class Constant : IComparable<Constant>
|
||||||
{
|
{
|
||||||
static StringBuilder translator = new StringBuilder();
|
static StringBuilder translator = new StringBuilder();
|
||||||
static readonly int MaxReferenceDepth = 8;
|
|
||||||
static int CurrentReferenceDepth = 0;
|
|
||||||
|
|
||||||
#region PreviousName
|
#region PreviousName
|
||||||
|
|
||||||
|
@ -157,49 +155,42 @@ namespace Bind.Structures
|
||||||
if (enums == null)
|
if (enums == null)
|
||||||
throw new ArgumentNullException("enums");
|
throw new ArgumentNullException("enums");
|
||||||
|
|
||||||
if (++CurrentReferenceDepth >= MaxReferenceDepth)
|
|
||||||
throw new InvalidOperationException(String.Format(
|
|
||||||
"Enum specification contains cycle: {0}",
|
|
||||||
c.ToString()));
|
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(c.Reference))
|
if (!String.IsNullOrEmpty(c.Reference))
|
||||||
{
|
{
|
||||||
Constant referenced_constant;
|
// Resolve the referenced Constant. Be careful
|
||||||
|
// to avoid loops in the definitions.
|
||||||
|
Constant reference = c;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
reference =
|
||||||
|
enums.ContainsKey(reference.Reference) &&
|
||||||
|
enums[reference.Reference].ConstantCollection.ContainsKey(reference.Value) ?
|
||||||
|
enums[reference.Reference].ConstantCollection[reference.Value] : null;
|
||||||
|
} while (reference != null && reference.Reference != null && reference.Reference != c.Reference);
|
||||||
|
|
||||||
if (enums.ContainsKey(c.Reference) && enums[c.Reference].ConstantCollection.ContainsKey(c.Value))
|
// If we haven't managed to locate the reference, do
|
||||||
|
// a brute-force search through all enums.
|
||||||
|
if (reference == null || reference.Reference != null)
|
||||||
{
|
{
|
||||||
// Transitively translate the referenced token
|
reference = enums.Values.Select(e =>
|
||||||
// Todo: this may cause loops if two tokens reference each other.
|
e.ConstantCollection.Values.FirstOrDefault(t =>
|
||||||
// Add a max reference depth and bail out?
|
t.Reference == null && t.Name == c.Name))
|
||||||
TranslateConstantWithReference(enums[c.Reference].ConstantCollection[c.Value], enums);
|
.FirstOrDefault(t => t != null);
|
||||||
referenced_constant = (enums[c.Reference].ConstantCollection[c.Value]);
|
|
||||||
}
|
}
|
||||||
else if (enums.ContainsKey(Settings.CompleteEnumName) &&
|
|
||||||
enums[Settings.CompleteEnumName].ConstantCollection.ContainsKey(c.Value))
|
// Resolve the value for this Constant
|
||||||
|
if (reference != null)
|
||||||
{
|
{
|
||||||
// Try the All enum
|
c.Value = reference.Value;
|
||||||
var reference = enums[Settings.CompleteEnumName].ConstantCollection[c.Value];
|
c.Reference = null;
|
||||||
if (reference.Reference == null)
|
return true;
|
||||||
referenced_constant = (enums[Settings.CompleteEnumName].ConstantCollection[c.Value]);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
--CurrentReferenceDepth;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
--CurrentReferenceDepth;
|
Trace.WriteLine(String.Format("[Warning] Failed to resolve token: {0}", c));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//else throw new InvalidOperationException(String.Format("Unknown Enum \"{0}\" referenced by Constant \"{1}\"",
|
|
||||||
// c.Reference, c.ToString()));
|
|
||||||
|
|
||||||
c.Value = referenced_constant.Value;
|
|
||||||
c.Reference = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--CurrentReferenceDepth;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue