2
0

ASUtils.cpp 27 KB

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