Last active
July 22, 2018 07:27
-
-
Save aliyome/e17e707c5c82f24329b2a99ead86fe00 to your computer and use it in GitHub Desktop.
黒魔術系
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
import std.traits; | |
import std.range; | |
import std.array; | |
import std.algorithm; | |
import core.sync.mutex; | |
class A { | |
private int private_field; | |
public string public_field; | |
private int private_method() { return 10; } | |
public int public_method(ref int a, in int b, out int c) { return 20; } | |
static public void static_method() {} | |
public this() { | |
} | |
} | |
//template GenerateCInterface(T) if (is(T == class)) { | |
// // T* T_storage; | |
// mixin(T.stringof ~ "* " ~ T.stringof ~ "_storage;"); | |
// //pragma(msg, allMembers!T); | |
//} | |
//string[] allMembers(T)() if (is(T == class)) { | |
// return [__traits(allMembers, T)]; | |
//} | |
////string[] privateFields(T)() { | |
//void privateFields(T)() { | |
// foreach (member_name; [__traits(allMembers, T)]) { | |
// mixin("alias member = " ~ T.stringof ~ "." ~ member_name ~ ";"); | |
// //pragma(msg, __traits(getProtection, __traits(getMember, T.stringof ~ "." ~ member_name))); | |
// } | |
//} | |
enum BuiltInFunctions = ["toString", "toHash", "opCmp", "opEquals", "factory"]; | |
struct MethodInfo { | |
string name; | |
ArgInfo[] args; | |
string return_type; | |
string protection; | |
bool is_static; | |
} | |
struct ArgInfo { | |
string name; | |
uint storage_class; // ParameterStorageClassTuple.ref_とか | |
string type; | |
} | |
private template GetAllMethodsTrait(T) if (is(T == class)) { | |
private MethodInfo[] _getMethods() { | |
MethodInfo[] result; | |
foreach (member_string; __traits(allMembers, T)) { | |
mixin("alias member = " ~ T.stringof ~ "." ~ member_string ~ ";"); | |
static if (is(typeof(member) == function)) { | |
MethodInfo m = MethodInfo(); | |
m.name = __traits(identifier, member); | |
m.return_type = ReturnType!member.stringof; | |
m.protection = __traits(getProtection, member); | |
m.is_static = __traits(isStaticFunction, member); | |
foreach (i, n; ParameterIdentifierTuple!member) { | |
ArgInfo a = ArgInfo(); | |
a.name = n; | |
m.args ~= a; | |
} | |
foreach (i, n; ParameterStorageClassTuple!member) { | |
m.args[i].storage_class = n; | |
} | |
foreach (i, n; Parameters!member) { | |
m.args[i].type = n.stringof; | |
} | |
result ~= m; | |
} | |
} | |
return result; | |
} | |
enum GetAllMethodsTrait = _getMethods(); | |
} | |
uint GetGuid() { | |
static guid = 0; | |
static Mutex mutex; | |
if (mutex is null) mutex = new Mutex; | |
synchronized (mutex) { | |
++guid; | |
} | |
return guid; | |
} | |
string buildBindingMixinString(T)() { | |
string result; | |
result ~= T.stringof ~ "[] _" ~ T.stringof ~ ";\n"; | |
foreach (m; GetAllMethodsTrait!T.filter!(x => x.protection == "public")) { | |
bool is_new = false; | |
if (m.name == "__ctor") { | |
result ~= "uint " ~ T.stringof ~ "_new("; | |
is_new = true; | |
} | |
else { | |
result ~= m.return_type ~ " " ~ T.stringof ~ "_" ~ m.name ~ "("; | |
if (!m.is_static) { | |
result ~= "uint guid"; | |
} | |
} | |
foreach (i, a; m.args) { | |
if (!m.is_static && !is_new) result ~= ", "; | |
if (a.storage_class & ParameterStorageClass.scope_) result ~= "scope "; | |
if (a.storage_class & ParameterStorageClass.out_) result ~= "out "; | |
if (a.storage_class & ParameterStorageClass.ref_) result ~= "ref "; | |
if (a.storage_class & ParameterStorageClass.lazy_) result ~= "lazy "; | |
if (a.storage_class & ParameterStorageClass.return_) result ~= "return "; | |
result ~= a.type ~ " " ~ a.name; | |
} | |
result ~= ")"; | |
if (is_new) { | |
result ~= "{ _" ~ T.stringof ~ " ~= new " ~ T.stringof ~ "("; | |
} | |
else { | |
result ~= "{ "; | |
if (m.return_type != "void") { | |
result ~= "return "; | |
} | |
if (m.is_static) { | |
result ~= T.stringof ~ "." ~ m.name ~ "("; | |
} | |
else { | |
result ~= "_" ~ T.stringof ~ "[guid]." ~ m.name ~ "("; | |
} | |
} | |
foreach (i, a; m.args) { | |
if (i != 0) result ~= ", "; | |
result ~= a.name; | |
} | |
result ~= ");"; | |
if (is_new) { | |
result ~= " return GetGuid();"; | |
} | |
result ~= "}"; | |
result ~= "\n"; | |
} | |
return result; | |
} | |
//private template AllMethods(T) if (is(T == class)) { | |
// private string[] getMethods() { | |
// string[] result; | |
// foreach (member_string; __traits(allMembers, T)) { | |
// mixin("alias member = " ~ T.stringof ~ "." ~ member_string ~ ";"); | |
// static if (is(typeof(member) == function)) { | |
// result ~= __traits(identifier, member); | |
// } | |
// } | |
// return result; | |
// } | |
// enum AllMethods = getMethods().join("\n"); | |
//} | |
//private template PrivateMethods(T) if (is(T == class)) { | |
// private string[] getPrivateMethods() { | |
// string[] result; | |
// foreach (member_string; __traits(allMembers, T)) { | |
// mixin("alias member = " ~ T.stringof ~ "." ~ member_string ~ ";"); | |
// static if (is(typeof(member) == function)) { | |
// static if (__traits(getProtection, member) == "private") { | |
// result ~= __traits(identifier, member); | |
// } | |
// } | |
// } | |
// return result; | |
// } | |
// enum PrivateMethods = getPrivateMethods().join("\n"); | |
//} | |
//private template PublicMethods(T) if (is(T == class)) { | |
// private string[] getPublicMethods() { | |
// string[] result; | |
// foreach (member_string; __traits(allMembers, T)) { | |
// mixin("alias member = " ~ T.stringof ~ "." ~ member_string ~ ";"); | |
// static if (is(typeof(member) == function)) { | |
// static if (__traits(getProtection, member) == "public") { | |
// result ~= __traits(identifier, member); | |
// } | |
// } | |
// } | |
// return result; | |
// } | |
// enum PublicMethods = getPublicMethods(); | |
//} | |
//auto publicMethodInterface(T)() { | |
// foreach (m; PublicMethods!T) { | |
// static if (true) { | |
// __traits(getMember, T, m); | |
// } | |
// } | |
//} | |
mixin(buildBindingMixinString!A()); | |
version(unittest) void main() {} | |
unittest { | |
//pragma(msg, AllMethods!A); | |
//pragma(msg, PrivateMethods!A); | |
//pragma(msg, PublicMethods!A); | |
//pragma(msg, GetAllMethodsTrait!A); | |
pragma(msg, buildBindingMixinString!A()); | |
uint id = A_new(); | |
int a, c; | |
writeln(id, ",", _A[a].public_method(a, 2, c)); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment