CSClassWriter.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  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/IO/FileSystem.h>
  8. #include "../JSBind.h"
  9. #include "../JSBModule.h"
  10. #include "../JSBPackage.h"
  11. #include "../JSBEnum.h"
  12. #include "../JSBClass.h"
  13. #include "../JSBFunction.h"
  14. #include "CSTypeHelper.h"
  15. #include "CSClassWriter.h"
  16. #include "CSFunctionWriter.h"
  17. namespace ToolCore
  18. {
  19. CSClassWriter::CSClassWriter(JSBClass *klass) : JSBClassWriter(klass)
  20. {
  21. }
  22. void CSClassWriter::WriteNativeFunctions(String& source)
  23. {
  24. for (unsigned i = 0; i < klass_->functions_.Size(); i++)
  25. {
  26. JSBFunction* function = klass_->functions_.At(i);
  27. if (function->Skip())
  28. continue;
  29. if (function->IsDestructor())
  30. continue;
  31. if (CSTypeHelper::OmitFunction(function))
  32. continue;
  33. CSFunctionWriter writer(function);
  34. writer.GenerateNativeSource(source);
  35. }
  36. }
  37. void CSClassWriter::GenerateNativeSource(String& sourceOut)
  38. {
  39. String source = "";
  40. if (klass_->IsNumberArray())
  41. return;
  42. JSBPackage* package = klass_->GetPackage();
  43. source.AppendWithFormat("ATOMIC_EXPORT_API ClassID csb_%s_%s_GetClassIDStatic()\n{\n", package->GetName().CString(),klass_->GetName().CString());
  44. source.AppendWithFormat(" return %s::GetClassIDStatic();\n}\n\n", klass_->GetNativeName().CString());
  45. WriteNativeFunctions(source);
  46. sourceOut += source;
  47. }
  48. void CSClassWriter::WriteManagedProperties(String& sourceOut)
  49. {
  50. String source;
  51. if (klass_->HasProperties())
  52. {
  53. Vector<String> pnames;
  54. klass_->GetPropertyNames(pnames);
  55. for (unsigned j = 0; j < pnames.Size(); j++)
  56. {
  57. JSBProperty* prop = klass_->GetProperty(pnames[j]);
  58. JSBFunctionType* fType = NULL;
  59. JSBFunctionType* getType = NULL;
  60. JSBFunctionType* setType = NULL;
  61. if (CSTypeHelper::OmitFunction(prop->getter_) || CSTypeHelper::OmitFunction(prop->setter_))
  62. continue;
  63. if (prop->getter_ && !prop->getter_->Skip())
  64. {
  65. fType = getType = prop->getter_->GetReturnType();
  66. }
  67. if (prop->setter_ && !prop->setter_->Skip())
  68. {
  69. setType = prop->setter_->GetParameters()[0];
  70. if (!fType)
  71. fType = setType;
  72. else if (fType->type_->ToString() != setType->type_->ToString())
  73. continue;
  74. }
  75. if (!fType)
  76. continue;
  77. String line = "public ";
  78. JSBClass* baseClass = klass_->GetBaseClass();
  79. if (baseClass)
  80. {
  81. if (baseClass->MatchProperty(prop, true))
  82. {
  83. // always new so we don't have to deal with virtual/override on properties
  84. line += "new ";
  85. }
  86. }
  87. String type = CSTypeHelper::GetManagedTypeString(fType, false);
  88. line += ToString("%s %s\n", type.CString(), prop->name_.CString());
  89. source += IndentLine(line);
  90. source += IndentLine("{\n");
  91. Indent();
  92. if (prop->getter_)
  93. {
  94. source += IndentLine("get\n");
  95. source += IndentLine("{\n");
  96. Indent();
  97. source += IndentLine(ToString("return %s();\n", prop->getter_->GetName().CString()));
  98. Dedent();
  99. source += IndentLine("}\n");
  100. }
  101. if (prop->setter_)
  102. {
  103. source += IndentLine("set\n");
  104. source += IndentLine("{\n");
  105. Indent();
  106. source += IndentLine(ToString("%s(value);\n", prop->setter_->GetName().CString()));
  107. Dedent();
  108. source += IndentLine("}\n");
  109. }
  110. Dedent();
  111. source += IndentLine("}\n\n");
  112. }
  113. }
  114. sourceOut += source;
  115. }
  116. void CSClassWriter::GenerateManagedSource(String& sourceOut)
  117. {
  118. String source = "";
  119. if (klass_->IsNumberArray())
  120. return;
  121. Indent();
  122. source += "\n";
  123. String line;
  124. if (klass_->GetBaseClass())
  125. line = "public partial class " + klass_->GetName() + " : " + klass_->GetBaseClass()->GetName() + "\n";
  126. else
  127. line = "public partial class " + klass_->GetName() + "\n";
  128. source += IndentLine(line);
  129. source += IndentLine("{\n");
  130. Indent();
  131. WriteManagedProperties(source);
  132. Indent();
  133. JSBPackage* package = klass_->GetPackage();
  134. // CoreCLR has pinvoke security demand code commented out, so we do not (currently) need this optimization:
  135. // https://github.com/dotnet/coreclr/issues/1605
  136. // line = "[SuppressUnmanagedCodeSecurity]\n";
  137. // source += IndentLine(line);
  138. line = "[DllImport (Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]\n";
  139. source += IndentLine(line);
  140. line = ToString("public static extern IntPtr csb_%s_%s_GetClassIDStatic();\n", package->GetName().CString(),klass_->GetName().CString());
  141. source += IndentLine(line);
  142. source += "\n";
  143. Dedent();
  144. // managed functions
  145. bool wroteConstructor = false;
  146. for (unsigned i = 0; i < klass_->functions_.Size(); i++)
  147. {
  148. JSBFunction* function = klass_->functions_.At(i);
  149. if (function->Skip())
  150. continue;
  151. if (function->IsDestructor())
  152. continue;
  153. if (CSTypeHelper::OmitFunction(function))
  154. continue;
  155. if (function->IsConstructor())
  156. wroteConstructor = true;
  157. CSFunctionWriter fwriter(function);
  158. fwriter.GenerateManagedSource(source);
  159. }
  160. // There are some constructors being skipped (like HTTPRequest as it uses a vector of strings in args)
  161. // Make sure we have at least a IntPtr version
  162. if (!wroteConstructor)
  163. {
  164. LOGINFOF("WARNING: %s class didn't write a constructor, filling in generated native constructor", klass_->GetName().CString());
  165. line = ToString("public %s (IntPtr native) : base (native)\n", klass_->GetName().CString());
  166. source += IndentLine(line);
  167. source += IndentLine("{\n");
  168. source += IndentLine("}\n\n");
  169. }
  170. Dedent();
  171. source += IndentLine("}\n");
  172. Dedent();
  173. sourceOut += source;
  174. }
  175. void CSClassWriter::GenerateSource(String& sourceOut)
  176. {
  177. }
  178. }