ASResult.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  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 functions because functions 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. ASGeneratedFile_Templates::ASGeneratedFile_Templates(const string& outputFilePath)
  114. {
  115. outputFilePath_ = outputFilePath;
  116. }
  117. void ASGeneratedFile_Templates::Save()
  118. {
  119. ofstream out(outputFilePath_);
  120. out <<
  121. "// DO NOT EDIT. This file is generated\n"
  122. "\n"
  123. "#pragma once\n"
  124. "\n"
  125. "#include \"../Precompiled.h\"\n"
  126. "#include \"../AngelScript/APITemplates.h\"\n"
  127. "\n"
  128. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  129. "\n"
  130. "#include \"../AngelScript/Manual.h\"\n"
  131. "\n"
  132. "namespace Urho3D\n"
  133. "{\n"
  134. "\n"
  135. "void FakeAddRef(void* ptr);\n"
  136. "void FakeReleaseRef(void* ptr);\n"
  137. "\n"
  138. << glue_.str()
  139. << reg_.str() <<
  140. "}\n";
  141. }
  142. bool ProcessedEnum::operator <(const ProcessedEnum& rhs) const
  143. {
  144. if (insideDefine_ != rhs.insideDefine_)
  145. return insideDefine_ < rhs.insideDefine_;
  146. return name_ < rhs.name_;
  147. }
  148. bool ProcessedGlobalFunction::operator <(const ProcessedGlobalFunction& rhs) const
  149. {
  150. if (insideDefine_ != rhs.insideDefine_)
  151. return insideDefine_ < rhs.insideDefine_;
  152. if (name_ != rhs.name_)
  153. return name_ < rhs.name_;
  154. // Overloads with the same name may exist
  155. if (comment_ != rhs.comment_)
  156. return comment_ < rhs.comment_;
  157. // Different specializations of the same template and aliases have the same comment
  158. return registration_ < rhs.registration_;
  159. }
  160. bool ProcessedGlobalVariable::operator <(const ProcessedGlobalVariable& rhs) const
  161. {
  162. if (insideDefine_ != rhs.insideDefine_)
  163. return insideDefine_ < rhs.insideDefine_;
  164. return name_ < rhs.name_;
  165. }
  166. namespace Result
  167. {
  168. vector<ProcessedEnum> enums_;
  169. // Write result to GeneratedEnums.cpp
  170. static void SaveEnums(const string& outputBasePath)
  171. {
  172. sort(enums_.begin(), enums_.end());
  173. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedEnums.cpp");
  174. ofs <<
  175. "// DO NOT EDIT. This file is generated\n"
  176. "\n"
  177. "// We need register all enums before registration of any functions because functions can use any enums\n"
  178. "\n"
  179. "#include \"../Precompiled.h\"\n"
  180. "#include \"../AngelScript/APITemplates.h\"\n"
  181. "\n"
  182. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  183. "\n"
  184. "namespace Urho3D\n"
  185. "{\n"
  186. "\n";
  187. for (const ProcessedEnum& processedEnum : enums_)
  188. {
  189. if (!processedEnum.glue_.size())
  190. continue;
  191. if (!processedEnum.insideDefine_.empty())
  192. ofs << "#ifdef " << processedEnum.insideDefine_ << "\n";
  193. ofs << "// " << processedEnum.comment_ << "\n";
  194. for (const string& glue : processedEnum.glue_)
  195. ofs << glue << "\n";
  196. if (!processedEnum.insideDefine_.empty())
  197. ofs << "#endif\n";
  198. ofs << "\n";
  199. }
  200. ofs <<
  201. "void ASRegisterGeneratedEnums(asIScriptEngine* engine)\n"
  202. "{\n";
  203. bool isFirst = true;
  204. string openedDefine;
  205. for (const ProcessedEnum& processedEnum : enums_)
  206. {
  207. if (processedEnum.insideDefine_ != openedDefine && !openedDefine.empty())
  208. {
  209. ofs << "#endif\n";
  210. openedDefine.clear();
  211. }
  212. if (!isFirst)
  213. ofs << "\n";
  214. if (processedEnum.insideDefine_ != openedDefine && !processedEnum.insideDefine_.empty())
  215. {
  216. ofs << "#ifdef " << processedEnum.insideDefine_ << "\n";
  217. openedDefine = processedEnum.insideDefine_;
  218. }
  219. ofs << " // " << processedEnum.comment_ << "\n";
  220. for (const string& registration : processedEnum.registration_)
  221. ofs << " " << registration << "\n";
  222. isFirst = false;
  223. }
  224. if (!openedDefine.empty())
  225. ofs << "#endif\n";
  226. ofs <<
  227. "}\n"
  228. "\n"
  229. "}\n";
  230. }
  231. // ============================================================================
  232. vector<ProcessedGlobalFunction> globalFunctions_;
  233. // Write result to GlobalFunctions.cpp
  234. static void SaveGlobalFunctions(const string& outputBasePath)
  235. {
  236. sort(globalFunctions_.begin(), globalFunctions_.end());
  237. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedGlobalFunctions.cpp");
  238. ofs <<
  239. "// DO NOT EDIT. This file is generated\n"
  240. "\n"
  241. "#include \"../Precompiled.h\"\n"
  242. "#include \"../AngelScript/APITemplates.h\"\n"
  243. "\n"
  244. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  245. "\n"
  246. "namespace Urho3D\n"
  247. "{\n"
  248. "\n";
  249. for (const ProcessedGlobalFunction& globalFunction : globalFunctions_)
  250. {
  251. if (globalFunction.glue_.empty())
  252. continue;
  253. if (!globalFunction.insideDefine_.empty())
  254. ofs << "#ifdef " << globalFunction.insideDefine_ << "\n";
  255. ofs << "// " << globalFunction.comment_ << "\n";
  256. ofs << globalFunction.glue_ << "\n";
  257. if (!globalFunction.insideDefine_.empty())
  258. ofs << "#endif\n";
  259. ofs << "\n";
  260. }
  261. ofs <<
  262. "void ASRegisterGeneratedGlobalFunctions(asIScriptEngine* engine)\n"
  263. "{\n";
  264. bool isFirst = true;
  265. string openedDefine;
  266. string lastComment;
  267. for (const ProcessedGlobalFunction& globalFunction : globalFunctions_)
  268. {
  269. if (globalFunction.insideDefine_ != openedDefine && !openedDefine.empty())
  270. {
  271. ofs << "#endif\n";
  272. openedDefine.clear();
  273. }
  274. if (!isFirst && lastComment != globalFunction.comment_)
  275. ofs << "\n";
  276. if (globalFunction.insideDefine_ != openedDefine && !globalFunction.insideDefine_.empty())
  277. {
  278. ofs << "#ifdef " << globalFunction.insideDefine_ << "\n";
  279. openedDefine = globalFunction.insideDefine_;
  280. }
  281. if (lastComment != globalFunction.comment_)
  282. ofs << " // " << globalFunction.comment_ << "\n";
  283. ofs << " " << globalFunction.registration_ << "\n";
  284. isFirst = false;
  285. lastComment = globalFunction.comment_;
  286. }
  287. if (!openedDefine.empty())
  288. ofs << "#endif\n";
  289. ofs <<
  290. "}\n"
  291. "\n"
  292. "}\n";
  293. }
  294. // ============================================================================
  295. vector<ProcessedGlobalVariable> globalVariables_;
  296. // Write result to GlobalVariables.cpp
  297. static void SaveGlobalVariables(const string& outputBasePath)
  298. {
  299. sort(globalVariables_.begin(), globalVariables_.end());
  300. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedGlobalVariables.cpp");
  301. ofs <<
  302. "// DO NOT EDIT. This file is generated\n"
  303. "\n"
  304. "#include \"../Precompiled.h\"\n"
  305. "#include \"../AngelScript/APITemplates.h\"\n"
  306. "\n"
  307. "#include \"../AngelScript/GeneratedIncludes.h\"\n"
  308. "\n"
  309. "// Some headers could re-define M_PI, ensure that it's undefined\n"
  310. "#undef M_PI\n"
  311. "\n"
  312. "namespace Urho3D\n"
  313. "{\n"
  314. "\n";
  315. ofs <<
  316. "void ASRegisterGeneratedGlobalVariables(asIScriptEngine* engine)\n"
  317. "{\n";
  318. bool isFirst = true;
  319. string openedDefine;
  320. string lastComment;
  321. for (const ProcessedGlobalVariable& globalVariable : globalVariables_)
  322. {
  323. if (globalVariable.insideDefine_ != openedDefine && !openedDefine.empty())
  324. {
  325. ofs << "#endif\n";
  326. openedDefine.clear();
  327. }
  328. if (!isFirst && lastComment != globalVariable.comment_)
  329. ofs << "\n";
  330. if (globalVariable.insideDefine_ != openedDefine && !globalVariable.insideDefine_.empty())
  331. {
  332. ofs << "#ifdef " << globalVariable.insideDefine_ << "\n";
  333. openedDefine = globalVariable.insideDefine_;
  334. }
  335. if (lastComment != globalVariable.comment_)
  336. ofs << " // " << globalVariable.comment_ << "\n";
  337. ofs << " " << globalVariable.registration_ << "\n";
  338. isFirst = false;
  339. lastComment = globalVariable.comment_;
  340. }
  341. if (!openedDefine.empty())
  342. ofs << "#endif\n";
  343. ofs <<
  344. "}\n"
  345. "\n"
  346. "}\n";
  347. }
  348. // ============================================================================
  349. // List of all required header files
  350. static vector<string> headers_;
  351. // Discarded header files for statistic
  352. static vector<string> ignoredHeaders_;
  353. // Add header to lists if not added yet
  354. void AddHeader(const string& headerFile)
  355. {
  356. if (IsIgnoredHeader(headerFile))
  357. {
  358. if (!CONTAINS(ignoredHeaders_, headerFile))
  359. ignoredHeaders_.push_back(headerFile);
  360. }
  361. else
  362. {
  363. if (!CONTAINS(headers_, headerFile))
  364. headers_.push_back(headerFile);
  365. }
  366. }
  367. // Write result to GeneratedIncludes.h
  368. static void SaveIncludes(const string& outputBasePath)
  369. {
  370. sort(headers_.begin(), headers_.end());
  371. sort(ignoredHeaders_.begin(), ignoredHeaders_.end());
  372. ofstream ofs(outputBasePath + "/Source/Urho3D/AngelScript/GeneratedIncludes.h");
  373. ofs <<
  374. "// DO NOT EDIT. This file is generated\n"
  375. "\n"
  376. "#pragma once\n"
  377. "\n";
  378. string openedDefine;
  379. bool isFirst = true;
  380. for (const string& header : headers_)
  381. {
  382. string insideDefine = InsideDefine(header);
  383. if (insideDefine != openedDefine)
  384. {
  385. if (!openedDefine.empty())
  386. {
  387. ofs << "#endif\n";
  388. openedDefine.clear();
  389. }
  390. if (!isFirst) // First include can be guarded. Avoid print \n before it
  391. ofs << "\n";
  392. if (!insideDefine.empty())
  393. {
  394. ofs << "#ifdef " << insideDefine << "\n";
  395. openedDefine = insideDefine;
  396. }
  397. }
  398. ofs << "#include \"" << header << "\"\n";
  399. isFirst = false;
  400. }
  401. if (!openedDefine.empty())
  402. {
  403. ofs << "#endif\n";
  404. openedDefine.clear();
  405. }
  406. if (headers_.size() > 0)
  407. ofs << "\n";
  408. if (ignoredHeaders_.size() > 0)
  409. ofs << "// Ignored headers\n\n";
  410. isFirst = true;
  411. for (const string& header : ignoredHeaders_)
  412. {
  413. string insideDefine = InsideDefine(header);
  414. if (insideDefine != openedDefine)
  415. {
  416. if (!openedDefine.empty())
  417. {
  418. ofs << "//#endif\n";
  419. openedDefine.clear();
  420. }
  421. if (!isFirst) // First include can be guarded. Avoid print \n before it
  422. ofs << "\n";
  423. if (!insideDefine.empty())
  424. {
  425. ofs << "//#ifdef " << insideDefine << "\n";
  426. openedDefine = insideDefine;
  427. }
  428. }
  429. ofs << "//#include \"" << header << "\"\n";
  430. isFirst = false;
  431. }
  432. if (!openedDefine.empty())
  433. ofs << "//#endif\n";
  434. }
  435. }
  436. void SaveResult(const string& outputBasePath)
  437. {
  438. Result::SaveEnums(outputBasePath);
  439. Result::SaveGlobalFunctions(outputBasePath);
  440. Result::SaveGlobalVariables(outputBasePath);
  441. Result::SaveIncludes(outputBasePath);
  442. }
  443. }