ASResult.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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 "ASResult.h"
  23. #include "Tuning.h"
  24. #include "Utils.h"
  25. #include <fstream>
  26. namespace ASBindingGenerator
  27. {
  28. ASGeneratedFile_WithRegistrationFunction::ASGeneratedFile_WithRegistrationFunction(const string& outputFilePath, const string& functionName)
  29. {
  30. outputFilePath_ = outputFilePath;
  31. functionName_ = functionName;
  32. }
  33. // ============================================================================
  34. void ASGeneratedFile_Classes::Save()
  35. {
  36. ofstream out(outputFilePath_);
  37. out <<
  38. "// DO NOT EDIT. This file is generated\n"
  39. "\n"
  40. "// We need register all types before registration of any members because members can use any types\n"
  41. "\n"
  42. "#include \"../Precompiled.h\"\n"
  43. "#include \"../AngelScript/APITemplates.h\"\n"
  44. "\n"
  45. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  46. "\n"
  47. "namespace Urho3D\n"
  48. "{\n"
  49. "\n"
  50. "void " << functionName_ << "(asIScriptEngine* engine)\n"
  51. "{\n"
  52. << reg_.str() <<
  53. "}\n"
  54. "\n"
  55. "}\n";
  56. }
  57. // ============================================================================
  58. void ASGeneratedFile_Members_HighPriority::Save()
  59. {
  60. ofstream out(outputFilePath_);
  61. out <<
  62. "// DO NOT EDIT. This file is generated\n"
  63. "\n"
  64. "// We need register default constructors before any members to allow using in Array<type>\n"
  65. "\n"
  66. "#include \"../Precompiled.h\"\n"
  67. "#include \"../AngelScript/APITemplates.h\"\n"
  68. "\n"
  69. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  70. "\n"
  71. "namespace Urho3D\n"
  72. "{\n"
  73. "\n"
  74. "void FakeAddRef(void* ptr);\n"
  75. "void FakeReleaseRef(void* ptr);\n"
  76. "\n"
  77. << glue_.str() <<
  78. "void " << functionName_ << "(asIScriptEngine* engine)\n"
  79. "{\n"
  80. << reg_.str() <<
  81. "}\n"
  82. "\n"
  83. "}\n";
  84. }
  85. // ============================================================================
  86. void ASGeneratedFile_Members::Save()
  87. {
  88. ofstream out(outputFilePath_);
  89. out <<
  90. "// DO NOT EDIT. This file is generated\n"
  91. "\n"
  92. "#include \"../Precompiled.h\"\n"
  93. "#include \"../AngelScript/APITemplates.h\"\n"
  94. "\n"
  95. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  96. "#include \"../AngelScript/Manual.h\"\n"
  97. "\n"
  98. "namespace Urho3D\n"
  99. "{\n"
  100. "\n"
  101. "void FakeAddRef(void* ptr);\n"
  102. "void FakeReleaseRef(void* ptr);\n"
  103. "\n"
  104. << glue_.str() <<
  105. "void " << functionName_ << "(asIScriptEngine* engine)\n"
  106. "{\n"
  107. << reg_.str() <<
  108. "}\n"
  109. "\n"
  110. "}\n";
  111. }
  112. // ============================================================================
  113. void ASGeneratedFile_GlobalVariables::Save()
  114. {
  115. ofstream out(outputFilePath_);
  116. out <<
  117. "// DO NOT EDIT. This file is generated\n"
  118. "\n"
  119. "#include \"../Precompiled.h\"\n"
  120. "#include \"../AngelScript/APITemplates.h\"\n"
  121. "\n"
  122. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  123. "\n"
  124. "// Some headers could re-define M_PI, ensure that it's undefined\n"
  125. "#undef M_PI\n"
  126. "\n"
  127. "namespace Urho3D\n"
  128. "{\n"
  129. "\n"
  130. << glue_.str() <<
  131. "void " << functionName_ << "(asIScriptEngine* engine)\n"
  132. "{\n"
  133. << reg_.str() <<
  134. "}\n"
  135. "\n"
  136. "}\n";
  137. }
  138. // ============================================================================
  139. ASGeneratedFile_Templates::ASGeneratedFile_Templates(const string& outputFilePath)
  140. {
  141. outputFilePath_ = outputFilePath;
  142. }
  143. void ASGeneratedFile_Templates::Save()
  144. {
  145. ofstream out(outputFilePath_);
  146. out <<
  147. "// DO NOT EDIT. This file is generated\n"
  148. "\n"
  149. "#pragma once\n"
  150. "\n"
  151. "#include \"../Precompiled.h\"\n"
  152. "#include \"../AngelScript/APITemplates.h\"\n"
  153. "\n"
  154. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  155. "\n"
  156. "#include \"../AngelScript/Manual.h\"\n"
  157. "\n"
  158. "namespace Urho3D\n"
  159. "{\n"
  160. "\n"
  161. "void FakeAddRef(void* ptr);\n"
  162. "void FakeReleaseRef(void* ptr);\n"
  163. "\n"
  164. << glue_.str()
  165. << reg_.str() <<
  166. "}\n";
  167. }
  168. bool ProcessedEnum::operator <(const ProcessedEnum& rhs) const
  169. {
  170. if (insideDefine_ != rhs.insideDefine_)
  171. return insideDefine_ < rhs.insideDefine_;
  172. return name_ < rhs.name_;
  173. }
  174. bool ProcessedGlobalFunction::operator <(const ProcessedGlobalFunction& rhs) const
  175. {
  176. if (insideDefine_ != rhs.insideDefine_)
  177. return insideDefine_ < rhs.insideDefine_;
  178. if (name_ != rhs.name_)
  179. return name_ < rhs.name_;
  180. // Overloads with the same name may exist
  181. if (comment_ != rhs.comment_)
  182. return comment_ < rhs.comment_;
  183. // Different specializations of the same template and aliases have the same comment
  184. return registration_ < rhs.registration_;
  185. }
  186. namespace Result
  187. {
  188. vector<ProcessedEnum> enums_;
  189. // Write result to GeneratedEnums.cpp
  190. static void SaveEnums(const string& outputBasePath)
  191. {
  192. sort(enums_.begin(), enums_.end());
  193. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedEnums.cpp");
  194. ofs <<
  195. "// DO NOT EDIT. This file is generated\n"
  196. "\n"
  197. "// We need register all enums before registration of any members because members can use any enums\n"
  198. "\n"
  199. "#include \"../Precompiled.h\"\n"
  200. "#include \"../AngelScript/APITemplates.h\"\n"
  201. "\n"
  202. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  203. "\n"
  204. "namespace Urho3D\n"
  205. "{\n"
  206. "\n";
  207. for (const ProcessedEnum& processedEnum : enums_)
  208. {
  209. if (!processedEnum.glue_.size())
  210. continue;
  211. if (!processedEnum.insideDefine_.empty())
  212. ofs << "#ifdef " << processedEnum.insideDefine_ << "\n";
  213. ofs << "// " << processedEnum.comment_ << "\n";
  214. for (const string& glue : processedEnum.glue_)
  215. ofs << glue << "\n";
  216. if (!processedEnum.insideDefine_.empty())
  217. ofs << "#endif\n";
  218. ofs << "\n";
  219. }
  220. ofs <<
  221. "void ASRegisterGeneratedEnums(asIScriptEngine* engine)\n"
  222. "{\n";
  223. bool isFirst = true;
  224. string openedDefine;
  225. for (const ProcessedEnum& processedEnum : enums_)
  226. {
  227. if (processedEnum.insideDefine_ != openedDefine && !openedDefine.empty())
  228. {
  229. ofs << "#endif\n";
  230. openedDefine.clear();
  231. }
  232. if (!isFirst)
  233. ofs << "\n";
  234. if (processedEnum.insideDefine_ != openedDefine && !processedEnum.insideDefine_.empty())
  235. {
  236. ofs << "#ifdef " << processedEnum.insideDefine_ << "\n";
  237. openedDefine = processedEnum.insideDefine_;
  238. }
  239. ofs << " // " << processedEnum.comment_ << "\n";
  240. for (const string& registration : processedEnum.registration_)
  241. ofs << " " << registration << "\n";
  242. isFirst = false;
  243. }
  244. if (!openedDefine.empty())
  245. ofs << "#endif\n";
  246. ofs <<
  247. "}\n"
  248. "\n"
  249. "}\n";
  250. }
  251. // ============================================================================
  252. vector<ProcessedGlobalFunction> globalFunctions_;
  253. // Write result to GlobalFunctions.cpp
  254. static void SaveGlobalFunctions(const string& outputBasePath)
  255. {
  256. sort(globalFunctions_.begin(), globalFunctions_.end());
  257. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedGlobalFunctions.cpp");
  258. ofs <<
  259. "// DO NOT EDIT. This file is generated\n"
  260. "\n"
  261. "#include \"../Precompiled.h\"\n"
  262. "#include \"../AngelScript/APITemplates.h\"\n"
  263. "\n"
  264. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  265. "\n"
  266. "namespace Urho3D\n"
  267. "{\n"
  268. "\n";
  269. for (const ProcessedGlobalFunction& globalFunction : globalFunctions_)
  270. {
  271. if (globalFunction.glue_.empty())
  272. continue;
  273. if (!globalFunction.insideDefine_.empty())
  274. ofs << "#ifdef " << globalFunction.insideDefine_ << "\n";
  275. ofs << "// " << globalFunction.comment_ << "\n";
  276. ofs << globalFunction.glue_ << "\n";
  277. if (!globalFunction.insideDefine_.empty())
  278. ofs << "#endif\n";
  279. ofs << "\n";
  280. }
  281. ofs <<
  282. "void ASRegisterGeneratedGlobalFunctions(asIScriptEngine* engine)\n"
  283. "{\n";
  284. bool isFirst = true;
  285. string openedDefine;
  286. string lastComment;
  287. for (const ProcessedGlobalFunction& globalFunction : globalFunctions_)
  288. {
  289. if (globalFunction.insideDefine_ != openedDefine && !openedDefine.empty())
  290. {
  291. ofs << "#endif\n";
  292. openedDefine.clear();
  293. }
  294. if (!isFirst && lastComment != globalFunction.comment_)
  295. ofs << "\n";
  296. if (globalFunction.insideDefine_ != openedDefine && !globalFunction.insideDefine_.empty())
  297. {
  298. ofs << "#ifdef " << globalFunction.insideDefine_ << "\n";
  299. openedDefine = globalFunction.insideDefine_;
  300. }
  301. if (lastComment != globalFunction.comment_)
  302. ofs << " // " << globalFunction.comment_ << "\n";
  303. ofs << " " << globalFunction.registration_ << "\n";
  304. isFirst = false;
  305. lastComment = globalFunction.comment_;
  306. }
  307. if (!openedDefine.empty())
  308. ofs << "#endif\n";
  309. ofs <<
  310. "}\n"
  311. "\n"
  312. "}\n";
  313. }
  314. // ============================================================================
  315. // List of all required header files
  316. static vector<string> headers_;
  317. // Discarded header files for statistic
  318. static vector<string> ignoredHeaders_;
  319. // Add header to lists if not added yet
  320. void AddHeader(const string& headerFile)
  321. {
  322. if (IsIgnoredHeader(headerFile))
  323. {
  324. if (!CONTAINS(ignoredHeaders_, headerFile))
  325. ignoredHeaders_.push_back(headerFile);
  326. }
  327. else
  328. {
  329. if (!CONTAINS(headers_, headerFile))
  330. headers_.push_back(headerFile);
  331. }
  332. }
  333. // Write result to GeneratedIncludes.h
  334. static void SaveIncludes(const string& outputBasePath)
  335. {
  336. sort(headers_.begin(), headers_.end());
  337. sort(ignoredHeaders_.begin(), ignoredHeaders_.end());
  338. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedIncludes.h");
  339. ofs <<
  340. "// DO NOT EDIT. This file is generated\n"
  341. "\n"
  342. "#pragma once\n"
  343. "\n";
  344. string openedDefine;
  345. bool isFirst = true;
  346. for (const string& header : headers_)
  347. {
  348. string insideDefine = InsideDefine(header);
  349. if (insideDefine != openedDefine)
  350. {
  351. if (!openedDefine.empty())
  352. {
  353. ofs << "#endif\n";
  354. openedDefine.clear();
  355. }
  356. if (!isFirst) // First include can be guarded. Avoid print \n before it
  357. ofs << "\n";
  358. if (!insideDefine.empty())
  359. {
  360. ofs << "#ifdef " << insideDefine << "\n";
  361. openedDefine = insideDefine;
  362. }
  363. }
  364. ofs << "#include \"" << header << "\"\n";
  365. isFirst = false;
  366. }
  367. if (!openedDefine.empty())
  368. {
  369. ofs << "#endif\n";
  370. openedDefine.clear();
  371. }
  372. if (headers_.size() > 0)
  373. ofs << "\n";
  374. if (ignoredHeaders_.size() > 0)
  375. ofs << "// Ignored headers\n\n";
  376. isFirst = true;
  377. for (const string& header : ignoredHeaders_)
  378. {
  379. string insideDefine = InsideDefine(header);
  380. if (insideDefine != openedDefine)
  381. {
  382. if (!openedDefine.empty())
  383. {
  384. ofs << "//#endif\n";
  385. openedDefine.clear();
  386. }
  387. if (!isFirst) // First include can be guarded. Avoid print \n before it
  388. ofs << "\n";
  389. if (!insideDefine.empty())
  390. {
  391. ofs << "//#ifdef " << insideDefine << "\n";
  392. openedDefine = insideDefine;
  393. }
  394. }
  395. ofs << "//#include \"" << header << "\"\n";
  396. isFirst = false;
  397. }
  398. if (!openedDefine.empty())
  399. ofs << "//#endif\n";
  400. }
  401. }
  402. void SaveResult(const string& outputBasePath)
  403. {
  404. Result::SaveEnums(outputBasePath);
  405. Result::SaveGlobalFunctions(outputBasePath);
  406. Result::SaveIncludes(outputBasePath);
  407. }
  408. }