JSBDoc.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. //
  2. // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
  3. // LICENSE: Atomic Game Engine Editor and Tools EULA
  4. // Please see LICENSE_ATOMIC_EDITOR_AND_TOOLS.md in repository root for
  5. // license information: https://github.com/AtomicGameEngine/AtomicGameEngine
  6. //
  7. #include <Atomic/Atomic.h>
  8. #include <Atomic/IO/Log.h>
  9. #include <Atomic/IO/FileSystem.h>
  10. #include <Atomic/Core/ProcessUtils.h>
  11. #include <Atomic/Resource/ResourceCache.h>
  12. #include "JSBind.h"
  13. #include "JSBPackage.h"
  14. #include "JSBModule.h"
  15. #include "JSBFunction.h"
  16. #include "JSBDoc.h"
  17. namespace ToolCore
  18. {
  19. static String GetScriptType(JSBFunctionType* ftype)
  20. {
  21. String scriptType = "number";
  22. if (ftype->type_->asPrimitiveType())
  23. {
  24. JSBPrimitiveType* ptype = ftype->type_->asPrimitiveType();
  25. if (ptype->kind_ == JSBPrimitiveType::Bool)
  26. scriptType = "boolean";
  27. }
  28. if (ftype->type_->asStringHashType() || ftype->type_->asStringType())
  29. scriptType = "string";
  30. if (ftype->type_->asEnumType())
  31. scriptType = "Atomic." + ftype->type_->asEnumType()->enum_->GetName();
  32. if (ftype->type_->asEnumType())
  33. scriptType = "Atomic." + ftype->type_->asEnumType()->enum_->GetName();
  34. if (ftype->type_->asClassType())
  35. scriptType = "Atomic." + ftype->type_->asClassType()->class_->GetName();
  36. return scriptType;
  37. }
  38. void JSBDoc::Begin()
  39. {
  40. source_ += "//////////////////////////////////////////////////////////\n";
  41. source_ += "// IMPORTANT: THIS FILE IS GENERATED, CHANGES WILL BE LOST\n";
  42. source_ += "//////////////////////////////////////////////////////////\n\n";
  43. source_ += "//Atomic JSDoc Definitions\n\n";
  44. source_ += "/**\n * Atomic Game Engine\n * @namespace\n*/\n var " + package_->GetName() + " = {}\n\n";
  45. }
  46. void JSBDoc::End()
  47. {
  48. }
  49. String JSBDoc::GenFunctionDoc(JSBFunction* function)
  50. {
  51. if (function->Skip())
  52. return "";
  53. String params;
  54. Vector<JSBFunctionType*>& parameters = function->GetParameters();
  55. for (unsigned i = 0; i < parameters.Size(); i++)
  56. {
  57. JSBFunctionType* ftype = parameters.At(i);
  58. String scriptType = GetScriptType(ftype);
  59. if (scriptType == "Atomic.Context")
  60. continue;
  61. // mark as optional
  62. if (ftype->initializer_.Length())
  63. scriptType += "=";
  64. params += " * @param {" + scriptType + "} " + ftype->name_ + "\n";
  65. }
  66. String returns;
  67. if (function->GetReturnType())
  68. returns = " * @returns { " + GetScriptType(function->GetReturnType()) + "}\n";
  69. String docString;
  70. if (function->IsConstructor())
  71. {
  72. docString.AppendWithFormat("%s", params.CString());
  73. }
  74. else
  75. {
  76. docString.AppendWithFormat(" * %s\n * @memberof Atomic.%s.prototype\n%s%s\n",
  77. function->GetDocString().CString(),
  78. function->GetClass()->GetName().CString(),
  79. params.CString(),
  80. returns.CString());
  81. }
  82. return docString;
  83. }
  84. void JSBDoc::ExportModuleClasses(JSBModule* module)
  85. {
  86. Vector<SharedPtr<JSBClass>> classes = module->GetClasses();
  87. if (!classes.Size())
  88. return;
  89. source_ += "\n";
  90. for (unsigned i = 0; i < classes.Size(); i++)
  91. {
  92. JSBClass* klass = classes.At(i);
  93. source_ += "/**\n * @class\n* @memberof Atomic\n";
  94. if (klass->GetBaseClass())
  95. source_ += " * @augments Atomic." + klass->GetBaseClass()->GetName()+ "\n";
  96. // PROPERTIES
  97. Vector<String> propertyNames;
  98. klass->GetPropertyNames(propertyNames);
  99. for (unsigned j = 0; j < propertyNames.Size(); j++)
  100. {
  101. JSBProperty* prop = klass->GetProperty(propertyNames[j]);
  102. JSBFunctionType* ftype = NULL;
  103. String desc;
  104. if (prop->getter_ && !prop->getter_->Skip())
  105. {
  106. desc = prop->getter_->GetDocString();
  107. ftype = prop->getter_->GetReturnType();
  108. }
  109. else if (prop->setter_ && !prop->setter_->Skip())
  110. {
  111. ftype = prop->setter_->GetParameters()[0];
  112. }
  113. if (prop->setter_ && prop->setter_->GetDocString().Length())
  114. {
  115. // overwrite getter docstring if it exsists
  116. desc = prop->setter_->GetDocString();
  117. }
  118. if (!ftype)
  119. continue;
  120. String scriptType = GetScriptType(ftype);
  121. String scriptName = prop->GetCasePropertyName();
  122. if (desc.Length())
  123. {
  124. source_ += " * @property {" + scriptType + "} " + scriptName + " - " + desc + "\n";
  125. }
  126. else
  127. {
  128. source_ += " * @property {" + scriptType + "} " + scriptName + "\n";
  129. }
  130. }
  131. JSBFunction* constructor = klass->GetConstructor();
  132. if (constructor)
  133. {
  134. String docs = GenFunctionDoc(constructor);
  135. source_ += docs;
  136. }
  137. source_ += "*/ \nfunction " + klass->GetName() + "() {};\n\n";
  138. // FUNCTIONS
  139. PODVector<JSBFunction*>& functions = klass->GetFunctions();
  140. for (unsigned j = 0; j < functions.Size(); j++)
  141. {
  142. JSBFunction* func = functions[j];
  143. if (func->IsConstructor() || func->IsDestructor() || func->Skip())
  144. continue;
  145. String docs = GenFunctionDoc(func);
  146. String scriptName = func->GetName();
  147. scriptName[0] = tolower(scriptName[0]);
  148. if (scriptName == "delete")
  149. scriptName = "__delete";
  150. String docString;
  151. docString.AppendWithFormat("/**\n %s */\n function %s() {};\n\n",
  152. docs.CString(),
  153. scriptName.CString());
  154. source_ += docString;
  155. }
  156. }
  157. }
  158. void JSBDoc::ExportModuleConstants(JSBModule* module)
  159. {
  160. const Vector<String>& constants = module->GetConstants().Keys();
  161. if (!constants.Size())
  162. return;
  163. source_ += "\n";
  164. for (unsigned i = 0; i < constants.Size(); i++)
  165. {
  166. const String& cname = constants.At(i);
  167. source_ += "/**\n * @memberof Atomic\n * @type {number}\n */\nvar " + cname + ";\n";
  168. }
  169. source_ += "\n";
  170. }
  171. void JSBDoc::ExportModuleEnums(JSBModule* module)
  172. {
  173. Vector<SharedPtr<JSBEnum>> enums = module->GetEnums();
  174. for (unsigned i = 0; i < enums.Size(); i++)
  175. {
  176. JSBEnum* _enum = enums.At(i);
  177. source_ += "/**\n * @memberof Atomic\n * @readonly\n * @enum {number}\n */\n";
  178. source_ += " var " + _enum->GetName() + " = {\n";
  179. HashMap<String, String>& values = _enum->GetValues();
  180. HashMap<String, String>::ConstIterator itr = values.Begin();
  181. while (itr != values.End())
  182. {
  183. String name = (*itr).first_;
  184. source_ += " " + name + " : undefined";
  185. itr++;
  186. if (itr != values.End())
  187. source_ += ",\n";
  188. }
  189. source_ += "\n\n};\n\n";
  190. }
  191. }
  192. void JSBDoc::WriteToFile(const String &path)
  193. {
  194. FileSystem* fs = package_->GetSubsystem<FileSystem>();
  195. String jsDocPath = GetPath(path);
  196. if (!fs->DirExists(jsDocPath))
  197. fs->CreateDir(jsDocPath);
  198. File file(package_->GetContext());
  199. file.Open(path, FILE_WRITE);
  200. file.Write(source_.CString(), source_.Length());
  201. file.Close();
  202. }
  203. void JSBDoc::Emit(JSBPackage* package, const String& path)
  204. {
  205. package_ = package;
  206. Vector<SharedPtr<JSBModule>>& modules = package->GetModules();
  207. Begin();
  208. for (unsigned i = 0; i < modules.Size(); i++)
  209. {
  210. ExportModuleEnums(modules[i]);
  211. }
  212. for (unsigned i = 0; i < modules.Size(); i++)
  213. {
  214. ExportModuleConstants(modules[i]);
  215. }
  216. for (unsigned i = 0; i < modules.Size(); i++)
  217. {
  218. source_ += "\n//----------------------------------------------------\n";
  219. source_ += "// MODULE: " + modules[i]->GetName() + "\n";
  220. source_ += "//----------------------------------------------------\n\n";
  221. ExportModuleClasses(modules[i]);
  222. }
  223. End();
  224. WriteToFile(path);
  225. }
  226. }