static class · System.Bindings
BindingRunner
public static class BindingRunner
Runs a profile for larva bind (larva calls it; a profile does not).
- Kind
- static class
- Namespace
- System.Bindings
- Assembly
- System.Bindings
- Access
- public, static, abstract
- Source file
Profile.ant
Inheritance
- Base classes
-
AnyBindingRunner
Methods
WriteSettings(BindingSettings s, str output)
#
The settings Configure gives, written to output for larva (one key=value a line; lists repeat the key).
Run(IBindingProfile profile, BindingModel model, str output)
#
The profile asked about every declaration of model, the names and places settled, and the binding written to
output as a description larva reads (library, namespace, class, file, enums, structs, constants, functions).
Unique(Dictionary<str, str> taken, str place, str name, str cName, str what) : str
#
name in place when nothing else has it there, else the C name (and a warning).
Line(StringBuilder text, str key, str value)
#
Retype(CType type, Dictionary<str, str> typedefs)
#
A number type written with typedefs' enum takes it (pointers keep their stars).
HeaderName(BindingSettings s, str header) : str
#
The name a header gives its namespace, class or file: its stem without the settings' prefixes, in Pascal case.
NamespaceOf(BindingSettings s, str given, str header) : str
#
ClassOf(BindingModel model, str given, str ns, str header) : str
#
The class of a function or constant; one with the name of a type of its namespace gets Functions after it.
FileOf(BindingSettings s, str given, str kind, str ns, str cls, str header) : str
#
The file a declaration goes to (its stem: larva adds the language's extension); "" is the class's file.
Renamed(str text, Dictionary<str, str> names) : str
#
text with every name of names replaced (SDL_Rect* → Rect*).
Describe(BindingModel model, Dictionary<str, str> typeNames) : str
#
The binding as larva's description: the first library, then each declaration after where it goes.
Inherited members (5)
GetTypemethod from AnyUndescribedmethod from AnyToStringmethod from AnyHashmethod from Anydestroymethod from Any
Source
BindingRunner as Antril, decompiled from its Larva HIR.
// System.Bindings.BindingRunner — System.Bindings (decompiled from Larva HIR)
import System;
import System.IO;
into namespace System.Bindings
{
/// Runs a profile for `larva bind` (larva calls it; a profile does not).
public static class BindingRunner
{
public:
/// The settings `Configure` gives, written to `output` for larva (one `key=value` a line; lists repeat the key).
WriteSettings(BindingSettings s, str output)
{
StringBuilder text = new StringBuilder();
{
ListIterator<str> _iterator1 = s.Libraries.Iterator();
loop (_iterator1.Next())
{
str library = _iterator1.Current;
Line(text, "library", library);
}
}
{
ListIterator<str> _iterator3 = s.Headers.Iterator();
loop (_iterator3.Next())
{
str header = _iterator3.Current;
Line(text, "header", header);
}
}
{
ListIterator<str> _iterator5 = s.Includes.Iterator();
loop (_iterator5.Next())
{
str include = _iterator5.Current;
Line(text, "include", include);
}
}
Line(text, "namespace", s.Namespace);
Line(text, "class", s.Class);
Line(text, "assembly", s.Assembly);
Line(text, "output", s.Output);
Line(text, "source", s.Source);
Line(text, "split", s.Split == SplitBy.Header ? "header" : s.Split == SplitBy.Namespace ? "namespace" : s.Split == SplitBy.Kind ? "kind" : "none");
Line(text, "exports", s.Exports == ExportCheck.Check ? "check" : "keep");
Line(text, "long", s.LongBits.ToString());
Line(text, "all", s.AllHeaders ? "true" : "false");
Line(text, "enums", s.EnumsFromC ? "true" : "false");
Line(text, "flags", s.AutoFlags ? "true" : "false");
File.WriteAllText(output, text.ToString());
}
/// The profile asked about every declaration of `model`, the names and places settled, and the binding written to
/// `output` as a description larva reads (`library`, `namespace`, `class`, `file`, enums, structs, constants, functions).
Run(IBindingProfile profile, BindingModel model, str output)
{
BindingSettings s = model.Settings;
profile.Start(model);
List<CEnum> enums = new List<CEnum>();
{
ListIterator<CEnum> _iterator2 = model.Enums.Iterator();
loop (_iterator2.Next())
{
CEnum e = _iterator2.Current;
{
if (profile.Enum(e))
enums.Add(e);
else
{
{
ListIterator<CEnumMember> _iterator4 = e.Members.Iterator();
loop (_iterator4.Next())
{
CEnumMember m = _iterator4.Current;
model.Constants.Add(new CConstant(m.CName, e.Header, m.Value));
}
}
}
}
}
}
model.Enums = enums;
model.Structs = model.Structs.Where(x => profile.Struct(x));
model.Constants = model.Constants.Where(c => profile.Constant(c));
model.Functions = model.Functions.Where(f => profile.Function(f));
Dictionary<str, str> typedefs = new Dictionary<str, str>();
{
ListIterator<CEnum> _iterator10 = model.Enums.Iterator();
loop (_iterator10.Next())
{
CEnum e = _iterator10.Current;
{
{
ListIterator<str> _iterator12 = e.Typedefs.Iterator();
loop (_iterator12.Next())
{
str typedef = _iterator12.Current;
typedefs.Set(typedef, e.CName);
}
}
}
}
}
{
ListIterator<CFunction> _iterator14 = model.Functions.Iterator();
loop (_iterator14.Next())
{
CFunction f = _iterator14.Current;
{
Retype(f.Result, typedefs);
{
ListIterator<CParameter> _iterator16 = f.Parameters.Iterator();
loop (_iterator16.Next())
{
CParameter p = _iterator16.Current;
Retype(p.Type, typedefs);
}
}
}
}
}
{
ListIterator<CStruct> _iterator18 = model.Structs.Iterator();
loop (_iterator18.Next())
{
CStruct x = _iterator18.Current;
{
{
ListIterator<CField> _iterator20 = x.Fields.Iterator();
loop (_iterator20.Next())
{
CField field = _iterator20.Current;
Retype(field.Type, typedefs);
}
}
}
}
}
Dictionary<str, str> typeNames = new Dictionary<str, str>();
List<str> typePrefixes = Both(s.StripTypes, s.Strip);
{
ListIterator<CEnum> _iterator24 = model.Enums.Iterator();
loop (_iterator24.Next())
{
CEnum e = _iterator24.Current;
{
if (e.Name == e.CName)
e.Name = Names.Writable(profile.Name(NameKind.Type, e.CName, Names.Shape(Names.Strip(e.CName, typePrefixes), s.TypeCase)));
typeNames.Set(e.CName, e.Name);
List<str> memberNames = new List<str>();
{
ListIterator<CEnumMember> _iterator27 = e.Members.Iterator();
loop (_iterator27.Next())
{
CEnumMember m = _iterator27.Current;
memberNames.Add(m.CName);
}
}
str prefix = e.MemberPrefix.Length > 0 ? e.MemberPrefix : s.StripMemberPrefix ? Names.CommonPrefix(memberNames) : "";
{
ListIterator<CEnumMember> _iterator30 = e.Members.Iterator();
loop (_iterator30.Next())
{
CEnumMember m = _iterator30.Current;
{
if (m.Name == m.CName)
m.Name = Names.Writable(profile.Name(NameKind.EnumMember, m.CName, Names.Shape(Names.Strip(m.CName, prefix), s.MemberCase)));
}
}
}
}
}
}
{
ListIterator<CStruct> _iterator32 = model.Structs.Iterator();
loop (_iterator32.Next())
{
CStruct x = _iterator32.Current;
{
if (x.Name == x.CName)
x.Name = Names.Writable(profile.Name(NameKind.Type, x.CName, Names.Shape(Names.Strip(x.CName, typePrefixes), s.TypeCase)));
typeNames.Set(x.CName, x.Name);
{
ListIterator<CField> _iterator34 = x.Fields.Iterator();
loop (_iterator34.Next())
{
CField field = _iterator34.Current;
{
if (field.Name == field.CName)
field.Name = Names.Writable(profile.Name(NameKind.Field, field.CName, Names.Shape(field.CName, s.FieldCase)));
}
}
}
}
}
}
List<str> constantPrefixes = Both(s.StripConstants, s.Strip);
{
ListIterator<CConstant> _iterator37 = model.Constants.Iterator();
loop (_iterator37.Next())
{
CConstant c = _iterator37.Current;
{
if (c.Name == c.CName)
c.Name = Names.Writable(profile.Name(NameKind.Constant, c.CName, Names.Shape(Names.Strip(c.CName, constantPrefixes), s.ConstantCase)));
}
}
}
List<str> functionPrefixes = Both(s.StripFunctions, s.Strip);
{
ListIterator<CFunction> _iterator40 = model.Functions.Iterator();
loop (_iterator40.Next())
{
CFunction f = _iterator40.Current;
{
if (f.Name == f.Entry)
f.Name = Names.Writable(profile.Name(NameKind.Function, f.Entry, Names.Shape(Names.Strip(f.Entry, functionPrefixes), s.FunctionCase)));
{
ListIterator<CParameter> _iterator42 = f.Parameters.Iterator();
loop (_iterator42.Next())
{
CParameter p = _iterator42.Current;
{
if (p.Name == p.CName)
p.Name = Names.Writable(profile.Name(NameKind.Parameter, p.CName, Names.Shape(p.CName, s.ParameterCase)));
}
}
}
}
}
}
{
ListIterator<CEnum> _iterator44 = model.Enums.Iterator();
loop (_iterator44.Next())
{
CEnum e = _iterator44.Current;
{
e.Namespace = NamespaceOf(s, e.Namespace, e.Header);
e.File = FileOf(s, e.File, "Enums", e.Namespace, "", e.Header);
}
}
}
{
ListIterator<CStruct> _iterator46 = model.Structs.Iterator();
loop (_iterator46.Next())
{
CStruct x = _iterator46.Current;
{
x.Namespace = NamespaceOf(s, x.Namespace, x.Header);
x.File = FileOf(s, x.File, "Structs", x.Namespace, "", x.Header);
}
}
}
{
ListIterator<CConstant> _iterator48 = model.Constants.Iterator();
loop (_iterator48.Next())
{
CConstant c = _iterator48.Current;
{
c.Namespace = NamespaceOf(s, c.Namespace, c.Header);
c.Class = ClassOf(model, c.Class, c.Namespace, c.Header);
c.File = FileOf(s, c.File, "", c.Namespace, c.Class, c.Header);
}
}
}
{
ListIterator<CFunction> _iterator50 = model.Functions.Iterator();
loop (_iterator50.Next())
{
CFunction f = _iterator50.Current;
{
f.Namespace = NamespaceOf(s, f.Namespace, f.Header);
f.Class = ClassOf(model, f.Class, f.Namespace, f.Header);
f.File = FileOf(s, f.File, "", f.Namespace, f.Class, f.Header);
}
}
}
profile.Finish(model);
Dictionary<str, str> taken = new Dictionary<str, str>();
{
ListIterator<CEnum> _iterator53 = model.Enums.Iterator();
loop (_iterator53.Next())
{
CEnum e = _iterator53.Current;
{
e.Name = Unique(taken, e.Namespace, e.Name, e.CName, "the enum");
typeNames.Set(e.CName, e.Name);
}
}
}
{
ListIterator<CStruct> _iterator55 = model.Structs.Iterator();
loop (_iterator55.Next())
{
CStruct x = _iterator55.Current;
{
x.Name = Unique(taken, x.Namespace, x.Name, x.CName, "the struct");
typeNames.Set(x.CName, x.Name);
}
}
}
{
ListIterator<CConstant> _iterator57 = model.Constants.Iterator();
loop (_iterator57.Next())
{
CConstant c = _iterator57.Current;
c.Name = Unique(taken, c.Namespace + "." + c.Class, c.Name, c.CName, "the constant");
}
}
{
ListIterator<CFunction> _iterator59 = model.Functions.Iterator();
loop (_iterator59.Next())
{
CFunction f = _iterator59.Current;
f.Name = Unique(taken, f.Namespace + "." + f.Class, f.Name, f.Entry, "the function");
}
}
File.WriteAllText(output, Describe(model, typeNames));
}
/// `name` in `place` when nothing else has it there, else the C name (and a warning).
Unique(Dictionary<str, str> taken, str place, str name, str cName, str what) : str
{
str key = place + "." + name;
if (taken.ContainsKey(key) && taken.Get(key) != cName)
{
Console.WriteLine("warning: " + what + " `" + cName + "` and `" + taken.Get(key) + "` would both be `" + key + "`: `" + cName + "` keeps its C name");
key = place + "." + cName;
name = cName;
}
taken.Set(key, cName);
return name;
}
Line(StringBuilder text, str key, str value)
{
text.Append(key).Append("=").Append(value).Append("\n");
}
Both(List<str> first, List<str> second) : List<str>
{
List<str> all = new List<str>();
all.AddRange(first);
all.AddRange(second);
return all;
}
/// A number type written with `typedefs`' enum takes it (pointers keep their stars).
Retype(CType type, Dictionary<str, str> typedefs)
{
if (type.Typedef.Length == 0 || !typedefs.ContainsKey(type.Typedef))
return;
i32 end = type.Text.Length;
loop (end > 0 && type.Text[end - 1] == 42)
end--;
CType plain = new CType(type.Text.Substring(0, end), "");
if (plain.IsNumber() && plain.Text[0] != 102)
type.Text = typedefs.Get(type.Typedef) + type.Text.Substring(end);
}
/// The name a header gives its namespace, class or file: its stem without the settings' prefixes, in Pascal case.
HeaderName(BindingSettings s, str header) : str
{
return header.Length == 0 ? s.Class : Names.Writable(Names.Pascal(Names.Strip(Names.Stem(header), s.HeaderStrip.Count > 0 ? s.HeaderStrip : s.Strip)));
}
NamespaceOf(BindingSettings s, str given, str header) : str
{
return given.Length > 0 ? given : s.NamespaceByHeader && header.Length > 0 ? s.Namespace + "." + HeaderName(s, header) : s.Namespace;
}
/// The class of a function or constant; one with the name of a type of its namespace gets `Functions` after it.
ClassOf(BindingModel model, str given, str ns, str header) : str
{
BindingSettings s = model.Settings;
str name = given.Length > 0 ? given : s.ClassByHeader && header.Length > 0 ? HeaderName(s, header) : s.Class;
if (model.Structs.Any(x => x.Namespace == ns && x.Name == name) || model.Enums.Any(e => e.Namespace == ns && e.Name == name))
return name + "Functions";
return name;
}
/// The file a declaration goes to (its stem: larva adds the language's extension); "" is the class's file.
FileOf(BindingSettings s, str given, str kind, str ns, str cls, str header) : str
{
if (given.Length > 0)
return given;
if (s.Split == SplitBy.Header)
return HeaderName(s, header);
if (s.Split == SplitBy.Namespace)
return ns;
if (s.Split == SplitBy.Kind)
return kind.Length > 0 ? kind : cls;
return "";
}
/// `text` with every name of `names` replaced (`SDL_Rect*` → `Rect*`).
Renamed(str text, Dictionary<str, str> names) : str
{
StringBuilder result = new StringBuilder();
i32 i = 0;
loop (i < text.Length)
{
u8 c = text[i];
if (c == 95 || c >= 65 && c <= 90 || c >= 97 && c <= 122)
{
i32 start = i;
loop (i < text.Length && (text[i] == 95 || text[i] >= 65 && text[i] <= 90 || text[i] >= 97 && text[i] <= 122 || text[i] >= 48 && text[i] <= 57))
i++;
str word = text.Substring(start, i - start);
result.Append(names.ContainsKey(word) ? names.Get(word) : word);
}
else
{
result.Append(text.Substring(i, 1));
i++;
}
}
return result.ToString();
}
/// The binding as larva's description: the first library, then each declaration after where it goes.
Describe(BindingModel model, Dictionary<str, str> typeNames) : str
{
BindingSettings s = model.Settings;
StringBuilder text = new StringBuilder();
str library = s.Libraries.Count > 0 ? s.Libraries[0] : "library";
i32 slash = library.LastIndexOf(47) > library.LastIndexOf(92) ? library.LastIndexOf(47) : library.LastIndexOf(92);
text.Append("library ").Append(library.Substring(slash + 1)).Append("\n");
if (s.Assembly.Length > 0)
text.Append("assembly ").Append(s.Assembly).Append("\n");
text.Append("namespace ").Append(s.Namespace).Append("\n");
text.Append("class ").Append(s.Class).Append("\n");
Place place = new Place(text, s.Namespace, s.Class);
{
ListIterator<CEnum> _iterator5 = model.Enums.Iterator();
loop (_iterator5.Next())
{
CEnum e = _iterator5.Current;
{
place.At(e.Namespace, s.Class, e.File);
text.Append("enum ").Append(e.Name).Append(" : ").Append(e.Underlying).Append(e.IsFlags ? " flags" : "").Append(" { ");
loop (i32 i = 0..e.Members.Count)
{
if (i > 0)
text.Append(", ");
text.Append(e.Members[i].Name).Append(" = ").Append(e.Members[i].Value);
}
text.Append(" }\n");
}
}
}
{
ListIterator<CStruct> _iterator8 = model.Structs.Iterator();
loop (_iterator8.Next())
{
CStruct x = _iterator8.Current;
{
place.At(x.Namespace, s.Class, x.File);
text.Append(x.IsUnion ? "union " : "struct ").Append(x.Name);
if (!x.IsUnion && x.Pack > 0)
text.Append(" pack ").Append(x.Pack.ToString());
text.Append(" { ");
loop (i32 i = 0..x.Fields.Count)
{
if (i > 0)
text.Append("; ");
text.Append(Renamed(x.Fields[i].Type.Text, typeNames)).Append(" ").Append(x.Fields[i].Name);
}
text.Append(" }\n");
}
}
}
{
ListIterator<CConstant> _iterator11 = model.Constants.Iterator();
loop (_iterator11.Next())
{
CConstant c = _iterator11.Current;
{
place.At(c.Namespace, c.Class, c.File);
text.Append("const ").Append(c.Name).Append(" = ").Append(c.Value).Append("\n");
}
}
}
{
ListIterator<CFunction> _iterator13 = model.Functions.Iterator();
loop (_iterator13.Next())
{
CFunction f = _iterator13.Current;
{
place.At(f.Namespace, f.Class, f.File);
text.Append(f.Entry);
if (f.Name != f.Entry)
text.Append(" as ").Append(f.Name);
text.Append("(");
loop (i32 i = 0..f.Parameters.Count)
{
if (i > 0)
text.Append(", ");
text.Append(Renamed(f.Parameters[i].Type.Text, typeNames)).Append(" ").Append(f.Parameters[i].Name);
}
text.Append(")");
if (f.Result.Text != "void")
text.Append(" : ").Append(Renamed(f.Result.Text, typeNames));
text.Append("\n");
}
}
}
return text.ToString();
}
}
}