JSBHeaderVisitor.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #pragma once
  2. #include <Atomic/IO/Log.h>
  3. #include <Atomic/Core/ProcessUtils.h>
  4. #include "JSBHeader.h"
  5. #include "JSBModule.h"
  6. #include "JSBindings.h"
  7. #include "JSBClass.h"
  8. #include "JSBFunction.h"
  9. #include "JSBNameVisitor.h"
  10. class JSBHeader;
  11. class JSBHeaderVisitor : public SymbolVisitor
  12. {
  13. JSBHeader* header_;
  14. JSBModule* module_;
  15. JSBindings* bindings_;
  16. Namespace* globalNamespace_;
  17. public:
  18. JSBHeaderVisitor(JSBHeader* header, TranslationUnit *unit, Namespace* globalNamespace) :
  19. header_(header),
  20. globalNamespace_(globalNamespace)
  21. {
  22. module_ = header_->module_;
  23. bindings_ = module_->bindings_;
  24. accept(globalNamespace_);
  25. }
  26. String getNameString(const Name* name)
  27. {
  28. JSBNameVisitor nvisitor;
  29. return nvisitor(name);
  30. }
  31. JSBType* processTypeConversion(Type* type)
  32. {
  33. JSBType* jtype = NULL;
  34. if (type->isIntegerType())
  35. {
  36. IntegerType* itype = type->asIntegerType();
  37. jtype = new JSBPrimitiveType(itype->kind());
  38. }
  39. if (type->isFloatType())
  40. {
  41. jtype = new JSBPrimitiveType(JSBPrimitiveType::Float);
  42. }
  43. else if (type->isNamedType())
  44. {
  45. NamedType* ntype = type->asNamedType();
  46. String classname = getNameString(ntype->name());
  47. if (classname == "String")
  48. {
  49. jtype = new JSBStringType();
  50. }
  51. else if (classname == "StringHash")
  52. {
  53. jtype = new JSBStringHashType();
  54. }
  55. else if (classname == "JS_HEAP_PTR")
  56. {
  57. jtype = new JSBHeapPtrType();
  58. }
  59. else
  60. {
  61. JSBClass* jclass = bindings_->GetClass(classname);
  62. if (jclass)
  63. jtype = new JSBClassType(jclass);
  64. else
  65. {
  66. // this might be an enum
  67. JSBEnum* jenum = bindings_->GetEnum(classname);
  68. if (jenum)
  69. jtype = new JSBEnumType(jenum);
  70. }
  71. }
  72. }
  73. else if (type->asUndefinedType())
  74. {
  75. UndefinedType* utype = type->asUndefinedType();
  76. //ErrorExit("Undefined type");
  77. }
  78. return jtype;
  79. }
  80. JSBFunctionType* processFunctionType(FullySpecifiedType fst)
  81. {
  82. JSBType* jtype = NULL;
  83. Type* type = fst.type();
  84. bool isPointer = false;
  85. bool isSharedPtr = false;
  86. bool isReference = false;
  87. if (type->isPointerType())
  88. {
  89. isPointer=true;
  90. FullySpecifiedType pfst = type->asPointerType()->elementType();
  91. type = pfst.type();
  92. }
  93. if (type->isReferenceType())
  94. {
  95. isReference=true;
  96. FullySpecifiedType pfst = type->asReferenceType()->elementType();
  97. type = pfst.type();
  98. }
  99. if (fst.isUnsigned())
  100. {
  101. if (type->isUndefinedType())
  102. {
  103. // this happens when just using "unsigned" in code
  104. jtype = new JSBPrimitiveType(JSBPrimitiveType::Int, true);
  105. }
  106. }
  107. if (!jtype)
  108. jtype = processTypeConversion(type);
  109. if (!jtype)
  110. return NULL;
  111. // no pointers to prim atm
  112. if ((isPointer || isReference) && jtype->asPrimitiveType())
  113. return NULL;
  114. JSBFunctionType* ftype = new JSBFunctionType(jtype);
  115. ftype->isPointer_ = isPointer;
  116. ftype->isSharedPtr_ = isSharedPtr;
  117. ftype->isReference_ = isReference;
  118. return ftype;
  119. }
  120. JSBFunctionType* processFunctionArgType(Argument* arg)
  121. {
  122. JSBFunctionType* jtype = processFunctionType(arg->type());
  123. if (!jtype)
  124. return NULL;
  125. jtype->name_ = getNameString(arg->name());
  126. return jtype;
  127. }
  128. JSBFunctionType* processFunctionReturnType(Function* function)
  129. {
  130. if (!function->hasReturnType())
  131. {
  132. return NULL;
  133. }
  134. JSBFunctionType* jtype = processFunctionType(function->returnType());
  135. if (!jtype)
  136. return NULL;
  137. return jtype;
  138. }
  139. JSBFunction* processFunction(JSBClass* klass, Function* function)
  140. {
  141. JSBFunction* jfunction = new JSBFunction(klass);
  142. // don't ... atm
  143. if (function->isVariadic())
  144. return NULL;
  145. jfunction->name_ = getNameString(function->name());
  146. // don't support operators atm
  147. if (jfunction->name_.StartsWith("operator "))
  148. return NULL;
  149. if (jfunction->name_ == klass->GetClassName())
  150. jfunction->isConstructor_ = true;
  151. if (jfunction->name_.StartsWith("~"))
  152. jfunction->isDestructor_ = true;
  153. // see if we support return type
  154. if (function->hasReturnType() && !function->returnType().type()->isVoidType())
  155. {
  156. jfunction->returnType_ = processFunctionReturnType(function);
  157. if (!jfunction->returnType_)
  158. return NULL;
  159. }
  160. if (function->hasArguments())
  161. {
  162. for (unsigned i = 0; i < function->argumentCount(); i++)
  163. {
  164. Symbol* symbol = function->argumentAt(i);
  165. if (symbol->isArgument())
  166. {
  167. Argument* arg = symbol->asArgument();
  168. JSBFunctionType* ftype = processFunctionArgType(arg);
  169. if (!ftype)
  170. return NULL;
  171. if (arg->hasInitializer())
  172. {
  173. ftype->initializer_ = arg->initializer()->chars();
  174. }
  175. jfunction->AddParameter(ftype);
  176. }
  177. else
  178. {
  179. return NULL;
  180. }
  181. }
  182. }
  183. return jfunction;
  184. }
  185. virtual bool visit(Namespace *nspace)
  186. {
  187. String name = getNameString(nspace->name());
  188. // LOGINFOF("Namespace: %s", name.CString());
  189. return true;
  190. }
  191. // reject template types
  192. virtual bool visit(Template *t)
  193. {
  194. return false;
  195. }
  196. // enums visited in preprocessor visitor
  197. virtual bool visit(Enum *penum)
  198. {
  199. return false;
  200. }
  201. // global var decl or function
  202. virtual bool visit(Declaration* decl)
  203. {
  204. FullySpecifiedType dtype = decl->type();
  205. Type* type = dtype.type();
  206. if (type->isPointerType() || type->isReferenceType())
  207. return true;
  208. if (type->asEnumType())
  209. return true;
  210. if (!type->asFloatType() && !type->asIntegerType())
  211. return true;
  212. module_->RegisterConstant(getNameString(decl->name()).CString());
  213. return true;
  214. }
  215. virtual bool visit(Class *klass)
  216. {
  217. String name = getNameString(klass->name());
  218. JSBClass* jclass = bindings_->GetClass(name);
  219. if (!jclass)
  220. {
  221. return false;
  222. }
  223. jclass->SetHeader(header_);
  224. //LOGINFOF("Adding Class: %s to Module: %s", name.CString(), module_->name_.CString());
  225. jclass->SetModule(module_);
  226. module_->AddClass(jclass);
  227. for (unsigned i = 0; i < klass->baseClassCount(); i++)
  228. {
  229. BaseClass* baseclass = klass->baseClassAt(i);
  230. String baseclassname = getNameString(baseclass->name());
  231. JSBClass* base = bindings_->GetClass(baseclassname);
  232. if (!base)
  233. {
  234. LOGINFOF("Warning: %s baseclass %s not in bindings", name.CString(), baseclassname.CString());
  235. }
  236. else
  237. {
  238. jclass->AddBaseClass(base);
  239. }
  240. }
  241. for (unsigned i = 0; i < klass->memberCount(); i++)
  242. {
  243. Symbol* symbol = klass->memberAt(i);
  244. Declaration* decl = symbol->asDeclaration();
  245. // if the function describes the body in the header
  246. Function* function = symbol->asFunction();
  247. // otherwise it could be a decl
  248. if (!function && decl)
  249. function = decl->type()->asFunctionType();
  250. if (function)
  251. {
  252. if (function->isPureVirtual())
  253. jclass->setAbstract(true);
  254. // only want public functions
  255. if (!symbol->isPublic())
  256. continue;
  257. JSBFunction* jfunction = processFunction(jclass, function);
  258. if (jfunction)
  259. jclass->AddFunction(jfunction);
  260. }
  261. }
  262. // return false so we don't traverse the class members
  263. return false;
  264. }
  265. };