ASUtils.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  1. // Copyright (c) 2008-2022 the Urho3D project
  2. // License: MIT
  3. #include "ASUtils.h"
  4. #include "Tuning.h"
  5. #include "Utils.h"
  6. #include "XmlAnalyzer.h"
  7. #include "XmlSourceData.h"
  8. #include <cassert>
  9. #include <regex>
  10. using namespace std;
  11. using namespace pugi;
  12. namespace ASBindingGenerator
  13. {
  14. // https://www.angelcode.com/angelscript/sdk/docs/manual/doc_datatypes_primitives.html
  15. // https://en.cppreference.com/w/cpp/language/types
  16. string CppPrimitiveTypeToAS(const string& cppType)
  17. {
  18. if (cppType == "bool")
  19. return "bool";
  20. if (cppType == "char" || cppType == "signed char" || cppType == "i8")
  21. return "int8";
  22. if (cppType == "unsigned char" || cppType == "u8")
  23. return "uint8";
  24. if (cppType == "short" || cppType == "i16")
  25. return "int16";
  26. if (cppType == "unsigned short" || cppType == "u16")
  27. return "uint16";
  28. if (cppType == "int" || cppType == "i32")
  29. return "int";
  30. if (cppType == "unsigned" || cppType == "unsigned int" || cppType == "u32")
  31. return "uint";
  32. if (cppType == "long long" || cppType == "i64")
  33. return "int64";
  34. if (cppType == "unsigned long long" || cppType == "u64")
  35. return "uint64";
  36. if (cppType == "float")
  37. return "float";
  38. if (cppType == "double")
  39. return "double";
  40. // Types below are registered in Manual.cpp
  41. if (cppType == "long") // Size is compiler-dependent
  42. return "long";
  43. if (cppType == "unsigned long") // Size is compiler-dependent
  44. return "ulong";
  45. if (cppType == "size_t")
  46. return "size_t";
  47. if (cppType == "SDL_JoystickID")
  48. return "SDL_JoystickID";
  49. if (cppType == "c32")
  50. return "c32";
  51. throw Exception(cppType + " not a primitive type");
  52. }
  53. static bool IsKnownPrimitiveCppType(const string& cppType)
  54. {
  55. try
  56. {
  57. CppPrimitiveTypeToAS(cppType);
  58. }
  59. catch (...)
  60. {
  61. return false;
  62. }
  63. return true;
  64. }
  65. string JoinASDeclarations(const vector<ConvertedVariable>& vars)
  66. {
  67. string result;
  68. for (const ConvertedVariable& var : vars)
  69. {
  70. if (!var.asDeclaration_.empty())
  71. {
  72. if (!result.empty())
  73. result += ", ";
  74. result += var.asDeclaration_;
  75. }
  76. }
  77. return result;
  78. }
  79. string JoinCppDeclarations(const string& firstCppDeclaration, const vector<ConvertedVariable>& vars)
  80. {
  81. string result = firstCppDeclaration;
  82. for (const ConvertedVariable& var : vars)
  83. {
  84. if (!var.cppDeclaration_.empty())
  85. {
  86. if (!result.empty())
  87. result += ", ";
  88. result += var.cppDeclaration_;
  89. }
  90. }
  91. return result;
  92. }
  93. string JoinCppDeclarations(const vector<ConvertedVariable>& vars)
  94. {
  95. return JoinCppDeclarations("", vars);
  96. }
  97. shared_ptr<EnumAnalyzer> FindEnum(const string& name)
  98. {
  99. NamespaceAnalyzer namespaceAnalyzer(SourceData::namespaceUrho3D_);
  100. vector<EnumAnalyzer> enumAnalyzers = namespaceAnalyzer.GetEnums();
  101. for (const EnumAnalyzer& enumAnalyzer : enumAnalyzers)
  102. {
  103. if (enumAnalyzer.GetTypeName() == name)
  104. return make_shared<EnumAnalyzer>(enumAnalyzer);
  105. }
  106. return shared_ptr<EnumAnalyzer>();
  107. }
  108. static bool IsUsing(const string& identifier)
  109. {
  110. for (xml_node memberdef : SourceData::usings_)
  111. {
  112. UsingAnalyzer usingAnalyzer(memberdef);
  113. if (usingAnalyzer.GetName() == identifier)
  114. return true;
  115. }
  116. return false;
  117. }
  118. bool IsKnownCppType(const string& name)
  119. {
  120. static vector<string> _knownTypes = {
  121. "void",
  122. // TODO: Remove
  123. "VariantMap",
  124. };
  125. if (CONTAINS(_knownTypes, name))
  126. return true;
  127. if (IsKnownPrimitiveCppType(name))
  128. return true;
  129. if (SourceData::classesByName_.find(name) != SourceData::classesByName_.end())
  130. return true;
  131. if (SourceData::enums_.find(name) != SourceData::enums_.end())
  132. return true;
  133. if (EndsWith(name, "Flags"))
  134. return true;
  135. return false;
  136. }
  137. shared_ptr<ClassAnalyzer> FindClassByName(const string& name)
  138. {
  139. auto it = SourceData::classesByName_.find(name);
  140. if (it != SourceData::classesByName_.end())
  141. {
  142. xml_node compounddef = it->second;
  143. return make_shared<ClassAnalyzer>(compounddef);
  144. }
  145. // using VariantVector = Vector<Variant>
  146. return shared_ptr<ClassAnalyzer>();
  147. }
  148. shared_ptr<ClassAnalyzer> FindClassByID(const string& id)
  149. {
  150. auto it = SourceData::classesByID_.find(id);
  151. if (it != SourceData::classesByID_.end())
  152. {
  153. xml_node compounddef = it->second;
  154. return make_shared<ClassAnalyzer>(compounddef);
  155. }
  156. // using VariantVector = Vector<Variant>
  157. return shared_ptr<ClassAnalyzer>();
  158. }
  159. // Variable name can be empty for function return type
  160. ConvertedVariable CppVariableToAS(const TypeAnalyzer& type, VariableUsage usage, const string& name, const string& defaultValue)
  161. {
  162. ConvertedVariable result;
  163. if (usage == VariableUsage::PostfixIncDecParameter)
  164. {
  165. result.glue_ = " " + type.ToString() + " " + name + "{};\n";
  166. return result;
  167. }
  168. if (type.IsRvalueReference() || type.IsDoublePointer() || type.IsRefToPointer())
  169. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  170. string cppTypeName = type.GetNameWithTemplateParams();
  171. if (cppTypeName == "void")
  172. {
  173. if (usage == VariableUsage::FunctionReturn && !type.IsPointer())
  174. {
  175. result.asDeclaration_ = "void";
  176. result.cppDeclaration_ = "void";
  177. return result;
  178. }
  179. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  180. }
  181. if (cppTypeName == "Context")
  182. {
  183. if (usage == VariableUsage::FunctionParameter && type.IsPointer())
  184. {
  185. result.glue_ = " " + type.ToString() + " " + name + " = GetScriptContext();\n";
  186. return result;
  187. }
  188. throw Exception("Error: type \"" + type.ToString() + "\" can used only as function parameter");
  189. }
  190. // Works with both Vector<String> and Vector<String>&
  191. if (cppTypeName == "Vector<String>" || cppTypeName == "StringVector")
  192. {
  193. // Works with both Vector<String> and Vector<String>&
  194. if (usage == VariableUsage::FunctionReturn && !type.IsPointer())
  195. {
  196. result.asDeclaration_ = "Array<String>@";
  197. result.cppDeclaration_ = "CScriptArray*";
  198. result.glue_ = "return VectorToArray<String>(result, \"Array<String>\");\n";
  199. return result;
  200. }
  201. if (usage == VariableUsage::FunctionParameter && type.IsConst() && type.IsReference())
  202. {
  203. string newCppVarName = name + "_conv";
  204. //result->asDecl_ = "String[]&";
  205. result.asDeclaration_ = "Array<String>@+";
  206. result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
  207. result.glue_ = " " + cppTypeName + " " + name + " = ArrayToVector<String>(" + newCppVarName + ");\n";
  208. if (!defaultValue.empty())
  209. {
  210. assert(defaultValue == "Vector< String >()");
  211. //result->asDecl_ += " = Array<String>()";
  212. result.asDeclaration_ += " = null";
  213. }
  214. return result;
  215. }
  216. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  217. }
  218. smatch match;
  219. regex_match(cppTypeName, match, regex("SharedPtr<(\\w+)>"));
  220. if (!match.empty())
  221. {
  222. string cppSubtypeName = match[1].str();
  223. string asSubtypeName;
  224. try
  225. {
  226. asSubtypeName = CppPrimitiveTypeToAS(cppSubtypeName);
  227. }
  228. catch (...)
  229. {
  230. asSubtypeName = cppSubtypeName;
  231. }
  232. if (cppSubtypeName == "WorkItem") // TODO autodetect
  233. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  234. if (usage == VariableUsage::FunctionReturn)
  235. {
  236. result.asDeclaration_ = asSubtypeName + "@+";
  237. result.cppDeclaration_ = cppSubtypeName + "*";
  238. result.glue_ = "return result.Detach();\n";
  239. return result;
  240. }
  241. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  242. }
  243. regex_match(cppTypeName, match, regex("Vector<SharedPtr<(\\w+)>>"));
  244. if (!match.empty())
  245. {
  246. string cppSubtypeName = match[1].str();
  247. string asSubtypeName;
  248. try
  249. {
  250. asSubtypeName = CppPrimitiveTypeToAS(cppSubtypeName);
  251. }
  252. catch (...)
  253. {
  254. asSubtypeName = cppSubtypeName;
  255. }
  256. if (cppSubtypeName == "WorkItem") // TODO autodetect
  257. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  258. if (usage == VariableUsage::FunctionReturn)
  259. {
  260. result.asDeclaration_ = "Array<" + asSubtypeName + "@>@";
  261. result.cppDeclaration_ = "CScriptArray*";
  262. // Which variant is correct/better?
  263. #if 0
  264. result->glueResult_ = "return VectorToArray<SharedPtr<" + cppTypeName + ">>(result, \"Array<" + asTypeName + "@>@\");\n";
  265. #else
  266. result.glue_ = "return VectorToHandleArray(result, \"Array<" + asSubtypeName + "@>\");\n";
  267. #endif
  268. return result;
  269. }
  270. if (usage == VariableUsage::FunctionParameter && type.IsConst() && type.IsReference())
  271. {
  272. string newCppVarName = name + "_conv";
  273. result.asDeclaration_ = "Array<" + asSubtypeName + "@>@+";
  274. result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
  275. result.glue_ = " " + cppTypeName + " " + name + " = HandleArrayToVector<" + cppSubtypeName + ">(" + newCppVarName + ");\n";
  276. assert(defaultValue.empty()); // TODO: make
  277. return result;
  278. }
  279. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  280. }
  281. regex_match(cppTypeName, match, regex("PODVector<(\\w+)\\*>"));
  282. if (!match.empty())
  283. {
  284. string cppSubtypeName = match[1].str();
  285. string asSubtypeName;
  286. try
  287. {
  288. asSubtypeName = CppPrimitiveTypeToAS(cppSubtypeName);
  289. }
  290. catch (...)
  291. {
  292. asSubtypeName = cppSubtypeName;
  293. }
  294. if (usage == VariableUsage::FunctionReturn)
  295. {
  296. result.asDeclaration_ = "Array<" + asSubtypeName + "@>@";
  297. result.cppDeclaration_ = "CScriptArray*";
  298. result.glue_ = "return VectorToHandleArray(result, \"Array<" + asSubtypeName + "@>\");\n";
  299. return result;
  300. }
  301. if (usage == VariableUsage::FunctionParameter && type.IsConst() && type.IsReference())
  302. {
  303. string newCppVarName = name + "_conv";
  304. result.asDeclaration_ = "Array<" + asSubtypeName + "@>@";
  305. result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
  306. result.glue_ = " " + cppTypeName + " " + name + " = ArrayToVector<" + cppSubtypeName + "*>(" + newCppVarName + ");\n";
  307. assert(defaultValue.empty()); // TODO: make
  308. return result;
  309. }
  310. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  311. }
  312. regex_match(cppTypeName, match, regex("PODVector<(\\w+)>"));
  313. if (!match.empty())
  314. {
  315. string cppSubtypeName = match[1].str();
  316. string asSubtypeName;
  317. try
  318. {
  319. asSubtypeName = CppPrimitiveTypeToAS(cppSubtypeName);
  320. }
  321. catch (...)
  322. {
  323. asSubtypeName = cppSubtypeName;
  324. }
  325. if (usage == VariableUsage::FunctionReturn && type.IsConst() == type.IsReference())
  326. {
  327. result.asDeclaration_ = "Array<" + asSubtypeName + ">@";
  328. result.cppDeclaration_ = "CScriptArray*";
  329. result.glue_ = "return VectorToArray(result, \"Array<" + asSubtypeName + ">\");\n";
  330. return result;
  331. }
  332. if (usage == VariableUsage::FunctionParameter && type.IsConst() && type.IsReference())
  333. {
  334. string newCppVarName = name + "_conv";
  335. result.asDeclaration_ = "Array<" + asSubtypeName + ">@+";
  336. result.cppDeclaration_ = "CScriptArray* " + newCppVarName;
  337. result.glue_ = " " + cppTypeName + " " + name + " = ArrayToVector<" + cppSubtypeName + ">(" + newCppVarName + ");\n";
  338. assert(defaultValue.empty()); // TODO: make
  339. return result;
  340. }
  341. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  342. }
  343. if (!IsKnownCppType(cppTypeName))
  344. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  345. shared_ptr<ClassAnalyzer> analyzer = FindClassByName(cppTypeName);
  346. if (analyzer && analyzer->IsInternal())
  347. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind bacause internal");
  348. if (analyzer && Contains(analyzer->GetComment(), "NO_BIND"))
  349. throw Exception("Error: type \"" + cppTypeName + "\" can not automatically bind bacause have @nobind mark");
  350. if (analyzer && analyzer->IsAbstract() && !(analyzer->IsRefCounted() || analyzer->IsNoCount()))
  351. throw Exception("Error: type \"" + cppTypeName + "\" can not bind bacause abstract value");
  352. // analyzer can be null for simple types (int, float) or if type "using VariantVector = Vector<Variant>"
  353. // TODO add to type info "IsUsing"
  354. // TODO add description to TypeAnalyzer::GetClass()
  355. if (IsUsing(cppTypeName) && cppTypeName != "VariantMap")
  356. throw Exception("Using \"" + cppTypeName + "\" can not automatically bind");
  357. string asTypeName;
  358. try
  359. {
  360. asTypeName = CppPrimitiveTypeToAS(cppTypeName);
  361. }
  362. catch (...)
  363. {
  364. asTypeName = cppTypeName;
  365. }
  366. if (Contains(asTypeName, '<'))
  367. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  368. if (Contains(type.ToString(), "::"))
  369. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind bacause internal");
  370. if (usage == VariableUsage::FunctionParameter && type.IsConst() && type.IsReference())
  371. {
  372. result.asDeclaration_ = "const " + asTypeName + "&in";
  373. result.cppDeclaration_ = type.ToString();
  374. if (!name.empty())
  375. result.cppDeclaration_ += " " + name;
  376. if (!defaultValue.empty())
  377. {
  378. string asDefaultValue = CppValueToAS(defaultValue);
  379. asDefaultValue = ReplaceAll(asDefaultValue, "\"", "\\\"");
  380. result.asDeclaration_ += " = " + asDefaultValue;
  381. }
  382. return result;
  383. }
  384. result.asDeclaration_ = asTypeName;
  385. if (type.IsReference())
  386. {
  387. result.asDeclaration_ += "&";
  388. }
  389. else if (type.IsPointer())
  390. {
  391. shared_ptr<ClassAnalyzer> analyzer = FindClassByName(cppTypeName);
  392. if (analyzer && (analyzer->IsRefCounted() || analyzer->IsNoCount()))
  393. result.asDeclaration_ = result.asDeclaration_ + "@" + (analyzer->IsNoCount() ? "" : "+");
  394. else
  395. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  396. }
  397. result.cppDeclaration_ = type.ToString();
  398. if (!name.empty())
  399. result.cppDeclaration_ += " " + name;
  400. if (usage == VariableUsage::FunctionReturn && type.IsConst() && !type.IsPointer())
  401. result.asDeclaration_ = "const " + result.asDeclaration_;
  402. if (!defaultValue.empty())
  403. {
  404. string asDefaultValue = CppValueToAS(defaultValue);
  405. asDefaultValue = ReplaceAll(asDefaultValue, "\"", "\\\"");
  406. result.asDeclaration_ += " = " + asDefaultValue;
  407. }
  408. return result;
  409. }
  410. string HideUnnamedType(const string& name)
  411. {
  412. regex rgx("@\\d+");
  413. return regex_replace(name, rgx, "@?");
  414. }
  415. string CppTypeToAS(const TypeAnalyzer& type, TypeUsage typeUsage)
  416. {
  417. if (Contains(type.GetName(), "@")) // Unnamed union inside class
  418. throw Exception("Error: type \"" + HideUnnamedType(type.ToString()) + "\" can not automatically bind");
  419. if (type.IsRvalueReference() || type.IsDoublePointer() || type.IsRefToPointer())
  420. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  421. string cppTypeName = type.GetNameWithTemplateParams();
  422. if (cppTypeName == "Context" && typeUsage == TypeUsage::FunctionReturn)
  423. throw Exception("Error: type \"" + type.ToString() + "\" can not be returned");
  424. if (!IsKnownCppType(type.GetNameWithTemplateParams()))
  425. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  426. shared_ptr<ClassAnalyzer> analyzer = FindClassByName(type.GetNameWithTemplateParams());
  427. if (analyzer && analyzer->IsInternal())
  428. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind bacause internal");
  429. if (analyzer && Contains(analyzer->GetComment(), "NO_BIND"))
  430. throw Exception("Error: type \"" + cppTypeName + "\" can not automatically bind bacause have @nobind mark");
  431. // analyzer can be null for simple types (int, float) or if type "using VariantVector = Vector<Variant>"
  432. // TODO add to type info "IsUsing"
  433. // TODO add description to TypeAnalyzer::GetClass()
  434. if (IsUsing(cppTypeName) && cppTypeName != "VariantMap")
  435. throw Exception("Using \"" + cppTypeName + "\" can not automatically bind");
  436. string asTypeName;
  437. try
  438. {
  439. asTypeName = CppPrimitiveTypeToAS(cppTypeName);
  440. }
  441. catch (...)
  442. {
  443. asTypeName = cppTypeName;
  444. }
  445. if (asTypeName == "void" && type.IsPointer())
  446. throw Exception("Error: type \"void*\" can not automatically bind");
  447. if (Contains(asTypeName, '<'))
  448. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  449. if (Contains(type.ToString(), "::"))
  450. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind bacause internal");
  451. if (type.IsConst() && type.IsReference() && typeUsage == TypeUsage::FunctionParameter)
  452. return "const " + asTypeName + "&in";
  453. string result = asTypeName;
  454. if (type.IsReference())
  455. {
  456. result += "&";
  457. }
  458. else if (type.IsPointer())
  459. {
  460. shared_ptr<ClassAnalyzer> analyzer = FindClassByName(type.GetNameWithTemplateParams());
  461. if (analyzer && (analyzer->IsRefCounted() || analyzer->IsNoCount()))
  462. result = result + "@" + (analyzer->IsNoCount() ? "" : "+");
  463. else
  464. throw Exception("Error: type \"" + type.ToString() + "\" can not automatically bind");
  465. }
  466. if (typeUsage == TypeUsage::FunctionReturn && type.IsConst() && !type.IsPointer())
  467. result = "const " + result;
  468. return result;
  469. }
  470. string CppValueToAS(const string& cppValue)
  471. {
  472. if (cppValue == "nullptr")
  473. return "null";
  474. if (cppValue == "Variant::emptyVariantMap")
  475. return "VariantMap()";
  476. if (cppValue == "NPOS")
  477. return "String::NPOS";
  478. return cppValue;
  479. }
  480. // =================================================================================
  481. static string GenerateFunctionWrapperName(xml_node memberdef)
  482. {
  483. TypeAnalyzer returnType = ExtractType(memberdef);
  484. string result = ExtractType(memberdef).ToString() + "_" + ExtractName(memberdef);
  485. vector<ParamAnalyzer> params = ExtractParams(memberdef);
  486. if (params.size() == 0)
  487. {
  488. result += "_void";
  489. }
  490. else
  491. {
  492. for (ParamAnalyzer param : params)
  493. {
  494. result += "_" + param.GetType().ToString();
  495. }
  496. }
  497. result = ReplaceAll(result, "=", "eq");
  498. result = ReplaceAll(result, "<", "les");
  499. result = ReplaceAll(result, ">", "gre");
  500. result = ReplaceAll(result, "*", "star");
  501. result = ReplaceAll(result, "/", "div");
  502. result = ReplaceAll(result, "+", "plus");
  503. result = ReplaceAll(result, "-", "min");
  504. result = ReplaceAll(result, "[", "lbr");
  505. result = ReplaceAll(result, "]", "rbr");
  506. result = ReplaceAll(result, ":", "col");
  507. result = ReplaceAll(result, " ", "sp");
  508. result = ReplaceAll(result, "&", "amp");
  509. return result;
  510. }
  511. string GenerateWrapperName(const GlobalFunctionAnalyzer& functionAnalyzer)
  512. {
  513. return GenerateFunctionWrapperName(functionAnalyzer.GetMemberdef());
  514. }
  515. string GenerateWrapperName(const ClassStaticFunctionAnalyzer& functionAnalyzer)
  516. {
  517. return functionAnalyzer.GetClassName() + "_" + GenerateFunctionWrapperName(functionAnalyzer.GetMemberdef());
  518. }
  519. string GenerateWrapperName(const MethodAnalyzer& methodAnalyzer, bool templateVersion)
  520. {
  521. if (templateVersion)
  522. return methodAnalyzer.GetClassName() + "_" + GenerateFunctionWrapperName(methodAnalyzer.GetMemberdef()) + "_template";
  523. else
  524. return methodAnalyzer.GetClassName() + "_" + GenerateFunctionWrapperName(methodAnalyzer.GetMemberdef());
  525. }
  526. // =================================================================================
  527. string GenerateWrapper(const GlobalFunctionAnalyzer& functionAnalyzer, const vector<ConvertedVariable>& convertedParams, const ConvertedVariable& convertedReturn)
  528. {
  529. string result;
  530. string glueReturnType = convertedReturn.cppDeclaration_;
  531. result =
  532. "static " + glueReturnType + " " + GenerateWrapperName(functionAnalyzer) + "(" + JoinCppDeclarations(convertedParams) + ")\n"
  533. "{\n";
  534. for (size_t i = 0; i < convertedParams.size(); i++)
  535. result += convertedParams[i].glue_;
  536. if (glueReturnType != "void")
  537. result += " " + functionAnalyzer.GetReturnType().ToString() + " result = ";
  538. else
  539. result += " ";
  540. result += functionAnalyzer.GetName() + "(" + functionAnalyzer.JoinParamsNames() + ");\n";
  541. if (!convertedReturn.glue_.empty())
  542. result += " " + convertedReturn.glue_;
  543. else if (glueReturnType != "void")
  544. result += " return result;\n";
  545. result += "}";
  546. return result;
  547. }
  548. string GenerateWrapper(const ClassStaticFunctionAnalyzer& functionAnalyzer, bool templateVersion, const vector<ConvertedVariable>& convertedParams, const ConvertedVariable& convertedReturn)
  549. {
  550. string result = templateVersion ? "template <class T> " : "static ";
  551. string className = templateVersion ? "T" : functionAnalyzer.GetClassName();
  552. string glueReturnType = convertedReturn.cppDeclaration_;
  553. result +=
  554. glueReturnType + " " + GenerateWrapperName(functionAnalyzer) + "(" + JoinCppDeclarations(convertedParams) + ")\n"
  555. "{\n";
  556. for (size_t i = 0; i < convertedParams.size(); i++)
  557. result += convertedParams[i].glue_;
  558. if (glueReturnType != "void")
  559. result += " " + functionAnalyzer.GetReturnType().ToString() + " result = ";
  560. else
  561. result += " ";
  562. result += className + "::" + functionAnalyzer.GetName() + "(" + functionAnalyzer.JoinParamsNames() + ");\n";
  563. if (!convertedReturn.glue_.empty())
  564. result += " " + convertedReturn.glue_;
  565. else if (glueReturnType != "void")
  566. result += " return result;\n";
  567. result += "}\n";
  568. return result;
  569. }
  570. string GenerateWrapper(const MethodAnalyzer& methodAnalyzer, bool templateVersion, const vector<ConvertedVariable>& convertedParams, const ConvertedVariable& convertedReturn)
  571. {
  572. string result = templateVersion ? "template <class T> " : "static ";
  573. string className = templateVersion ? "T" : methodAnalyzer.GetClassName();
  574. string glueReturnType = convertedReturn.cppDeclaration_;
  575. result +=
  576. glueReturnType + " " + GenerateWrapperName(methodAnalyzer, templateVersion) + "(" + JoinCppDeclarations(className + "* _ptr", convertedParams) + ")\n"
  577. "{\n";
  578. for (size_t i = 0; i < convertedParams.size(); i++)
  579. result += convertedParams[i].glue_;
  580. if (glueReturnType != "void")
  581. result += " " + methodAnalyzer.GetReturnType().ToString() + " result = ";
  582. else
  583. result += " ";
  584. result += "_ptr->" + methodAnalyzer.GetName() + "(" + methodAnalyzer.JoinParamsNames() + ");\n";
  585. if (!convertedReturn.glue_.empty())
  586. result += " " + convertedReturn.glue_;
  587. else if (glueReturnType != "void")
  588. result += " return result;\n";
  589. result += "}\n";
  590. return result;
  591. }
  592. string GenerateConstructorWrapper(const MethodAnalyzer& methodAnalyzer, const vector<ConvertedVariable>& convertedParams)
  593. {
  594. string className = methodAnalyzer.GetClassName();
  595. string result =
  596. "static void " + GenerateWrapperName(methodAnalyzer) + "(" + JoinCppDeclarations(className + "* _ptr", convertedParams) + ")\n"
  597. "{\n";
  598. for (size_t i = 0; i < convertedParams.size(); i++)
  599. result += convertedParams[i].glue_;
  600. result +=
  601. " new(_ptr) " + className + "(" + methodAnalyzer.JoinParamsNames() + ");\n"
  602. "}\n";
  603. return result;
  604. }
  605. string GenerateFactoryWrapper(const MethodAnalyzer& methodAnalyzer, const vector<ConvertedVariable>& convertedParams)
  606. {
  607. string className = methodAnalyzer.GetClassName();
  608. string result =
  609. "static " + className + "* " + GenerateWrapperName(methodAnalyzer) + "(" + JoinCppDeclarations(convertedParams) + ")\n"
  610. "{\n";
  611. for (size_t i = 0; i < convertedParams.size(); i++)
  612. result += convertedParams[i].glue_;
  613. result +=
  614. " return new " + className + "(" + methodAnalyzer.JoinParamsNames() + ");\n"
  615. "}\n";
  616. return result;
  617. }
  618. // =================================================================================
  619. string Generate_asFUNCTIONPR(const GlobalFunctionAnalyzer& functionAnalyzer)
  620. {
  621. string functionName = functionAnalyzer.GetName();
  622. string cppParams = "(" + JoinParamsTypes(functionAnalyzer.GetMemberdef(), functionAnalyzer.GetSpecialization()) + ")";
  623. string returnType = functionAnalyzer.GetReturnType().ToString();
  624. return "AS_FUNCTIONPR(" + functionName + ", " + cppParams + ", " + returnType + ")";
  625. }
  626. string Generate_asFUNCTIONPR(const ClassStaticFunctionAnalyzer& functionAnalyzer, bool templateVersion)
  627. {
  628. string className = functionAnalyzer.GetClassName();
  629. string functionName = functionAnalyzer.GetName();
  630. string cppParams = "(" + JoinParamsTypes(functionAnalyzer.GetMemberdef(), functionAnalyzer.GetSpecialization()) + ")";
  631. string returnType = functionAnalyzer.GetReturnType().ToString();
  632. if (templateVersion)
  633. return "AS_FUNCTIONPR(T::" + functionName + ", " + cppParams + ", " + returnType + ")";
  634. else
  635. return "AS_FUNCTIONPR(" + className + "::" + functionName + ", " + cppParams + ", " + returnType + ")";
  636. }
  637. string Generate_asMETHODPR(const MethodAnalyzer& methodAnalyzer, bool templateVersion)
  638. {
  639. string className = methodAnalyzer.GetClassName();
  640. string functionName = methodAnalyzer.GetName();
  641. string cppParams = "(" + JoinParamsTypes(methodAnalyzer.GetMemberdef(), methodAnalyzer.GetSpecialization()) + ")";
  642. if (methodAnalyzer.IsConst())
  643. cppParams += " const";
  644. string returnType = methodAnalyzer.GetReturnType().ToString();
  645. if (templateVersion)
  646. return "AS_METHODPR(T, " + functionName + ", " + cppParams + ", " + returnType + ")";
  647. else
  648. return "AS_METHODPR(" + className + ", " + functionName + ", " + cppParams + ", " + returnType + ")";
  649. }
  650. } // namespace ASBindingGenerator