ToCppHook.lua 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. --
  2. -- Copyright (c) 2008-2017 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. local toWrite = {}
  23. local currentString = ''
  24. local out
  25. local WRITE, OUTPUT = write, output
  26. function output(s)
  27. out = _OUTPUT
  28. output = OUTPUT -- restore
  29. output(s)
  30. end
  31. function write(a)
  32. if out == _OUTPUT then
  33. currentString = currentString .. a
  34. if string.sub(currentString,-1) == '\n' then
  35. toWrite[#toWrite+1] = currentString
  36. currentString = ''
  37. end
  38. else
  39. WRITE(a)
  40. end
  41. end
  42. function post_output_hook(package)
  43. local result = table.concat(toWrite)
  44. local function replace(pattern, replacement)
  45. local k = 0
  46. local nxt, currentString = 1, ''
  47. repeat
  48. local s, e = string.find(result, pattern, nxt, true)
  49. if e then
  50. currentString = currentString .. string.sub(result, nxt, s-1) .. replacement
  51. nxt = e + 1
  52. k = k + 1
  53. end
  54. until not e
  55. result = currentString..string.sub(result, nxt)
  56. end
  57. replace("\t", " ")
  58. replace([[#ifndef __cplusplus
  59. #include "stdlib.h"
  60. #endif
  61. #include "string.h"
  62. #include "tolua++.h"]], [[//
  63. // Copyright (c) 2008-2017 the Urho3D project.
  64. //
  65. // Permission is hereby granted, free of charge, to any person obtaining a copy
  66. // of this software and associated documentation files (the "Software"), to deal
  67. // in the Software without restriction, including without limitation the rights
  68. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  69. // copies of the Software, and to permit persons to whom the Software is
  70. // furnished to do so, subject to the following conditions:
  71. //
  72. // The above copyright notice and this permission notice shall be included in
  73. // all copies or substantial portions of the Software.
  74. //
  75. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  76. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  77. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  78. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  79. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  80. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  81. // THE SOFTWARE.
  82. //
  83. #include "Precompiled.h"
  84. #include <toluapp/tolua++.h>
  85. #include "LuaScript/ToluaUtils.h"
  86. #if __clang__
  87. #pragma clang diagnostic push
  88. #pragma clang diagnostic ignored "-Wunused-function"
  89. #endif]])
  90. if not _extra_parameters["Urho3D"] then
  91. replace([[#include "LuaScript/ToluaUtils.h"]], [[#include <Urho3D/LuaScript/ToluaUtils.h>]])
  92. end
  93. -- Special handling for vector to table conversion which would simplify the implementation of the template functions
  94. result = string.gsub(result, "ToluaIs(P?O?D?)Vector([^\"]-)\"c?o?n?s?t? ?P?O?D?Vector<([^*>]-)%*?>\"", "ToluaIs%1Vector%2\"%3\"")
  95. result = string.gsub(result, "ToluaPush(P?O?D?)Vector([^\"]-)\"c?o?n?s?t? ?P?O?D?Vector<([^*>]-)%*?>\"", "ToluaPush%1Vector%2\"%3\"")
  96. result = string.gsub(result, "@1%(", "(\"\",") -- is_pointer overload uses const char* as signature
  97. result = string.gsub(result, "@2%(", "(0.f,") -- is_arithmetic overload uses double as signature
  98. WRITE(result)
  99. WRITE([[
  100. #if __clang__
  101. #pragma clang diagnostic pop
  102. #endif]])
  103. end
  104. _push_functions['Component'] = "ToluaPushObject"
  105. _push_functions['Resource'] = "ToluaPushObject"
  106. _push_functions['UIElement'] = "ToluaPushObject"
  107. -- Is Urho3D Vector type.
  108. function urho3d_is_vector(t)
  109. return t:find("Vector<") ~= nil
  110. end
  111. -- Is Urho3D PODVector type.
  112. function urho3d_is_podvector(t)
  113. return t:find("PODVector<") ~= nil
  114. end
  115. local old_get_push_function = get_push_function
  116. local old_get_to_function = get_to_function
  117. local old_get_is_function = get_is_function
  118. function is_pointer(t)
  119. return t:find("*>")
  120. end
  121. function is_arithmetic(t)
  122. for _, type in pairs({ "char", "short", "int", "unsigned", "long", "float", "double", "bool" }) do
  123. _, pos = t:find(type)
  124. if pos ~= nil and t:sub(pos + 1, pos + 1) ~= "*" then return true end
  125. end
  126. return false
  127. end
  128. function overload_if_necessary(t)
  129. return is_pointer(t) and "@1" or (is_arithmetic(t) and "@2" or "")
  130. end
  131. function get_push_function(t)
  132. if not urho3d_is_vector(t) then
  133. return old_get_push_function(t)
  134. end
  135. local T = t:match("<.*>")
  136. if not urho3d_is_podvector(t) then
  137. return "ToluaPushVector" .. T
  138. else
  139. return "ToluaPushPODVector" .. T .. overload_if_necessary(T)
  140. end
  141. end
  142. function get_to_function(t)
  143. if not urho3d_is_vector(t) then
  144. return old_get_to_function(t)
  145. end
  146. local T = t:match("<.*>")
  147. if not urho3d_is_podvector(t) then
  148. return "ToluaToVector" .. T
  149. else
  150. return "ToluaToPODVector" .. T .. overload_if_necessary(T)
  151. end
  152. end
  153. function get_is_function(t)
  154. if not urho3d_is_vector(t) then
  155. return old_get_is_function(t)
  156. end
  157. local T = t:match("<.*>")
  158. if not urho3d_is_podvector(t) then
  159. return "ToluaIsVector" .. T
  160. else
  161. return "ToluaIsPODVector" .. T .. overload_if_necessary(T)
  162. end
  163. end
  164. function get_property_methods_hook(ptype, name)
  165. if ptype == "get_set" then
  166. local Name = string.upper(string.sub(name, 1, 1))..string.sub(name, 2)
  167. return "Get"..Name, "Set"..Name
  168. end
  169. if ptype == "is_set" then
  170. local Name = string.upper(string.sub(name, 1, 1))..string.sub(name, 2)
  171. return "Is"..Name, "Set"..Name
  172. end
  173. if ptype == "has_set" then
  174. local Name = string.upper(string.sub(name, 1, 1))..string.sub(name, 2)
  175. return "Has"..Name, "Set"..Name
  176. end
  177. if ptype == "no_prefix" then
  178. local Name = string.upper(string.sub(name, 1, 1))..string.sub(name, 2)
  179. return Name, "Set"..Name
  180. end
  181. end
  182. -- Rudimentary checker to prevent function overloads being declared in a wrong order
  183. -- The checker assumes function overloads are declared in group one after another within a same pkg file
  184. -- The checker only checks for single argument function at the moment, but it can be extended to support more when it is necessary
  185. local overload_checker = {name="", has_number=false}
  186. function pre_call_hook(self)
  187. if table.getn(self.args) ~= 1 then return end
  188. if overload_checker.name ~= self.name then
  189. overload_checker.name = self.name
  190. overload_checker.has_number = false
  191. end
  192. local t = self.args[1].type
  193. if overload_checker.has_number then
  194. if t:find("String") or t:find("char*") then warning(self:inclass() .. ":" .. self.name .. " has potential binding problem: number overload becomes dead code if it is declared before string overload") end
  195. else
  196. overload_checker.has_number = t ~= "bool" and is_arithmetic(t)
  197. end
  198. end