static class · System.Bindings

BindingRunner

public static class BindingRunner

Runs a profile for larva bind (larva calls it; a profile does not).

Tipo
static class
Espacio de nombres
System.Bindings
Ensamblado
System.Bindings
Acceso
public, static, abstract
Archivo fuente
Profile.ant

Herencia

Clases base
Any BindingRunner

Métodos

WriteSettings(BindingSettings s, str output)
#

static

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)
#

static

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
#

static

name in place when nothing else has it there, else the C name (and a warning).

Line(StringBuilder text, str key, str value)
#

static

Both(List<str> first, List<str> second) : List<str>
#

static

Retype(CType type, Dictionary<str, str> typedefs)
#

static

A number type written with typedefs' enum takes it (pointers keep their stars).

HeaderName(BindingSettings s, str header) : str
#

static

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
#

static

ClassOf(BindingModel model, str given, str ns, str header) : str
#

static

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
#

static

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
#

static

text with every name of names replaced (SDL_Rect* → Rect*).

Describe(BindingModel model, Dictionary<str, str> typeNames) : str
#

static

The binding as larva's description: the first library, then each declaration after where it goes.

Miembros heredados (5)

Código fuente

BindingRunner en Antril, descompilado a partir de su Larva HIR.

System.Bindings.BindingRunner.ant
// 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();
			}
	}
}
Esc