rice 4.6.1 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/CMakeLists.txt +0 -4
  4. data/Rakefile +2 -8
  5. data/bin/rice-doc.rb +212 -0
  6. data/bin/rice-rbs.rb +93 -0
  7. data/include/rice/rice.hpp +4972 -4015
  8. data/include/rice/stl.hpp +822 -294
  9. data/lib/rice/doc/cpp_reference.rb +166 -0
  10. data/lib/rice/doc/doxygen.rb +294 -0
  11. data/lib/rice/doc/mkdocs.rb +298 -0
  12. data/lib/rice/doc/rice.rb +29 -0
  13. data/lib/rice/doc/ruby.rb +37 -0
  14. data/lib/rice/doc.rb +5 -0
  15. data/lib/{make_rice_headers.rb → rice/make_rice_headers.rb} +3 -0
  16. data/lib/rice/native.rb +18 -0
  17. data/lib/rice/native_registry.rb +21 -0
  18. data/lib/rice/parameter.rb +7 -0
  19. data/lib/rice/rbs.rb +104 -0
  20. data/lib/rice/version.rb +1 -1
  21. data/lib/rice.rb +4 -0
  22. data/lib/rubygems/cmake_builder.rb +24 -27
  23. data/rice/Arg.hpp +4 -4
  24. data/rice/Arg.ipp +4 -4
  25. data/rice/Buffer.hpp +32 -28
  26. data/rice/Buffer.ipp +306 -178
  27. data/rice/Data_Object.ipp +101 -82
  28. data/rice/Data_Type.hpp +5 -7
  29. data/rice/Data_Type.ipp +48 -29
  30. data/rice/Enum.ipp +15 -21
  31. data/rice/Function.hpp +17 -0
  32. data/rice/Function.ipp +13 -0
  33. data/rice/Pointer.hpp +15 -0
  34. data/rice/Pointer.ipp +49 -0
  35. data/rice/Return.hpp +1 -1
  36. data/rice/Return.ipp +2 -2
  37. data/rice/api.hpp +30 -0
  38. data/rice/cpp_api/Array.hpp +2 -2
  39. data/rice/cpp_api/Array.ipp +50 -5
  40. data/rice/cpp_api/Class.hpp +0 -5
  41. data/rice/cpp_api/Class.ipp +19 -0
  42. data/rice/cpp_api/Hash.ipp +20 -0
  43. data/rice/cpp_api/Module.hpp +6 -3
  44. data/rice/cpp_api/Module.ipp +49 -11
  45. data/rice/cpp_api/Object.ipp +31 -2
  46. data/rice/cpp_api/String.hpp +1 -2
  47. data/rice/cpp_api/String.ipp +21 -1
  48. data/rice/cpp_api/Struct.ipp +5 -0
  49. data/rice/cpp_api/Symbol.ipp +34 -0
  50. data/rice/cpp_api/shared_methods.hpp +12 -12
  51. data/rice/detail/MethodInfo.hpp +4 -2
  52. data/rice/detail/MethodInfo.ipp +19 -3
  53. data/rice/detail/ModuleRegistry.hpp +18 -0
  54. data/rice/detail/ModuleRegistry.ipp +25 -0
  55. data/rice/detail/Native.hpp +45 -2
  56. data/rice/detail/Native.ipp +196 -2
  57. data/rice/detail/NativeAttributeGet.hpp +9 -4
  58. data/rice/detail/NativeAttributeGet.ipp +65 -11
  59. data/rice/detail/NativeAttributeSet.hpp +4 -0
  60. data/rice/detail/NativeAttributeSet.ipp +30 -2
  61. data/rice/detail/NativeCallbackFFI.ipp +2 -2
  62. data/rice/detail/NativeCallbackSimple.ipp +1 -1
  63. data/rice/detail/NativeFunction.hpp +11 -49
  64. data/rice/detail/NativeFunction.ipp +82 -379
  65. data/rice/detail/NativeInvoker.hpp +74 -0
  66. data/rice/detail/NativeInvoker.ipp +197 -0
  67. data/rice/detail/NativeIterator.hpp +4 -0
  68. data/rice/detail/NativeIterator.ipp +19 -0
  69. data/rice/detail/NativeMethod.hpp +97 -0
  70. data/rice/detail/NativeMethod.ipp +332 -0
  71. data/rice/detail/NativeProc.hpp +51 -0
  72. data/rice/detail/NativeProc.ipp +133 -0
  73. data/rice/detail/NativeRegistry.hpp +8 -0
  74. data/rice/detail/NativeRegistry.ipp +27 -0
  75. data/rice/detail/Parameter.hpp +47 -0
  76. data/rice/detail/Parameter.ipp +105 -0
  77. data/rice/detail/Proc.ipp +14 -13
  78. data/rice/detail/Registries.hpp +1 -0
  79. data/rice/detail/RubyType.hpp +0 -2
  80. data/rice/detail/RubyType.ipp +15 -33
  81. data/rice/detail/Type.hpp +44 -8
  82. data/rice/detail/Type.ipp +151 -49
  83. data/rice/detail/TypeRegistry.hpp +3 -0
  84. data/rice/detail/TypeRegistry.ipp +17 -27
  85. data/rice/detail/Types.ipp +430 -0
  86. data/rice/detail/Wrapper.hpp +12 -0
  87. data/rice/detail/Wrapper.ipp +45 -2
  88. data/rice/detail/from_ruby.ipp +567 -1073
  89. data/rice/detail/ruby.hpp +1 -0
  90. data/rice/detail/to_ruby.ipp +4 -635
  91. data/rice/libc/file.ipp +3 -6
  92. data/rice/rice.hpp +22 -12
  93. data/rice/rice_api/Arg.hpp +7 -0
  94. data/rice/rice_api/Arg.ipp +9 -0
  95. data/rice/rice_api/ModuleRegistry.hpp +7 -0
  96. data/rice/rice_api/ModuleRegistry.ipp +10 -0
  97. data/rice/rice_api/Native.hpp +7 -0
  98. data/rice/rice_api/Native.ipp +52 -0
  99. data/rice/rice_api/NativeRegistry.hpp +7 -0
  100. data/rice/rice_api/NativeRegistry.ipp +21 -0
  101. data/rice/rice_api/Parameter.hpp +7 -0
  102. data/rice/rice_api/Parameter.ipp +11 -0
  103. data/rice/rice_api/Registries.hpp +6 -0
  104. data/rice/rice_api/Registries.ipp +12 -0
  105. data/rice/rice_api/TypeRegistry.hpp +7 -0
  106. data/rice/rice_api/TypeRegistry.ipp +10 -0
  107. data/rice/stl/complex.ipp +35 -0
  108. data/rice/stl/exception.ipp +20 -7
  109. data/rice/stl/filesystem.hpp +6 -0
  110. data/rice/stl/filesystem.ipp +34 -0
  111. data/rice/stl/map.ipp +13 -21
  112. data/rice/stl/monostate.ipp +37 -1
  113. data/rice/stl/multimap.ipp +17 -24
  114. data/rice/stl/optional.ipp +47 -2
  115. data/rice/stl/pair.ipp +23 -58
  116. data/rice/stl/reference_wrapper.ipp +22 -1
  117. data/rice/stl/set.ipp +17 -9
  118. data/rice/stl/shared_ptr.ipp +44 -17
  119. data/rice/stl/string.ipp +175 -7
  120. data/rice/stl/string_view.ipp +5 -0
  121. data/rice/stl/tuple.ipp +38 -9
  122. data/rice/stl/unique_ptr.ipp +46 -2
  123. data/rice/stl/unordered_map.ipp +13 -21
  124. data/rice/stl/variant.ipp +47 -11
  125. data/rice/stl/vector.ipp +183 -104
  126. data/rice/stl.hpp +1 -0
  127. data/rice/traits/function_traits.hpp +2 -2
  128. data/rice/traits/method_traits.hpp +5 -16
  129. data/rice/traits/rice_traits.hpp +24 -4
  130. data/rice.gemspec +11 -22
  131. data/test/embed_ruby.cpp +0 -3
  132. data/test/test_Array.cpp +38 -38
  133. data/test/test_Attribute.cpp +187 -2
  134. data/test/test_Buffer.cpp +302 -26
  135. data/test/test_Callback.cpp +2 -3
  136. data/test/test_Class.cpp +5 -5
  137. data/test/test_Data_Object.cpp +0 -55
  138. data/test/test_Data_Type.cpp +19 -30
  139. data/test/test_Enum.cpp +4 -46
  140. data/test/test_From_Ruby.cpp +88 -81
  141. data/test/test_GVL.cpp +109 -0
  142. data/test/test_Iterator.cpp +1 -1
  143. data/test/test_Keep_Alive_No_Wrapper.cpp +5 -3
  144. data/test/test_Module.cpp +8 -9
  145. data/test/test_Object.cpp +1 -1
  146. data/test/test_Overloads.cpp +3 -3
  147. data/test/test_Stl_Map.cpp +8 -8
  148. data/test/test_Stl_Multimap.cpp +4 -4
  149. data/test/test_Stl_Pair.cpp +5 -3
  150. data/test/test_Stl_SharedPtr.cpp +24 -12
  151. data/test/test_Stl_Tuple.cpp +1 -1
  152. data/test/test_Stl_UniquePtr.cpp +8 -0
  153. data/test/test_Stl_Unordered_Map.cpp +9 -9
  154. data/test/test_Stl_Variant.cpp +9 -3
  155. data/test/test_Stl_Vector.cpp +118 -13
  156. data/test/test_To_Ruby.cpp +35 -28
  157. data/test/test_Type.cpp +256 -53
  158. data/test/unittest.hpp +35 -0
  159. metadata +66 -34
  160. data/rice/Init.hpp +0 -8
  161. data/rice/Init.ipp +0 -8
  162. data/rice/detail/RubyFunction.hpp +0 -31
  163. data/rice/detail/RubyFunction.ipp +0 -77
  164. data/sample/callbacks/extconf.rb +0 -5
  165. data/sample/callbacks/sample_callbacks.cpp +0 -35
  166. data/sample/callbacks/test.rb +0 -28
  167. data/sample/enum/extconf.rb +0 -5
  168. data/sample/enum/sample_enum.cpp +0 -40
  169. data/sample/enum/test.rb +0 -8
  170. data/sample/inheritance/animals.cpp +0 -82
  171. data/sample/inheritance/extconf.rb +0 -5
  172. data/sample/inheritance/test.rb +0 -7
  173. data/sample/map/extconf.rb +0 -5
  174. data/sample/map/map.cpp +0 -73
  175. data/sample/map/test.rb +0 -7
  176. data/test/ext/t1/Foo.hpp +0 -10
  177. data/test/ext/t1/extconf.rb +0 -4
  178. data/test/ext/t1/t1.cpp +0 -13
  179. data/test/ext/t2/extconf.rb +0 -4
  180. data/test/ext/t2/t2.cpp +0 -11
  181. data/test/ruby/test_callbacks_sample.rb +0 -28
  182. data/test/ruby/test_multiple_extensions.rb +0 -18
  183. data/test/ruby/test_multiple_extensions_same_class.rb +0 -14
  184. data/test/ruby/test_multiple_extensions_with_inheritance.rb +0 -20
  185. /data/test/{test_Stl_Type.cpp → test_Stl_Type_Info.cpp} +0 -0
@@ -0,0 +1,298 @@
1
+ require 'fileutils'
2
+
3
+ module Rice
4
+ module Doc
5
+ class Mkdocs
6
+ ESCAPE_METHODS = {'*' => '\*',
7
+ '+' => '\+',
8
+ '-' => '\-',
9
+ '.' => '\.',
10
+ '!' => '\!',
11
+ '|' => '\|',
12
+ '[]' => '\[\]',
13
+ '[]=' => '\[\]='}
14
+
15
+ attr_reader :klasses, :output
16
+
17
+ def initialize(klasses, doc_resolvers, output)
18
+ @klasses = klasses
19
+ @doc_resolvers = doc_resolvers
20
+ @output = output
21
+ end
22
+
23
+ def generate
24
+ FileUtils.mkdir_p(@output)
25
+
26
+ klasses.sort_by(&:name).each.with_index do |klass, i|
27
+ STDOUT << klass.name << " (" << i << "/" << klasses.count << ")" << "\n"
28
+ if klass.instance_of?(Module)
29
+ write_module(klass)
30
+ elsif klass.cpp_class.match(/^enum/i)
31
+ write_enum(klass)
32
+ elsif klass.cpp_class.match(/^union/i)
33
+ write_union(klass)
34
+ else
35
+ write_class(klass)
36
+ end
37
+ end
38
+ end
39
+
40
+ def output_path(klass)
41
+ parts = klass.name.split("::")
42
+ path = if klass.instance_of?(Module)
43
+ File.join(@output, *parts[0..-1], "index.md")
44
+ else
45
+ File.join(@output, *parts[0..-2], "#{parts.last}.md")
46
+ end
47
+
48
+ unless Dir.exist?(File.dirname(path))
49
+ FileUtils.mkdir_p((File.dirname(path)))
50
+ end
51
+ path
52
+ end
53
+
54
+ def resolver(klass)
55
+ parts = klass.name.split("::")
56
+ key = if parts.length == 1 && !klass.instance_of?(Module)
57
+ nil
58
+ else
59
+ parts.first
60
+ end
61
+
62
+ @doc_resolvers[key]
63
+ end
64
+
65
+ def class_sig(klass)
66
+ klass_name = klass.name.split("::").last
67
+
68
+ url = resolver(klass)&.class_url(klass)
69
+ if url
70
+ "#[#{klass_name}](#{url})"
71
+ else
72
+ "##{klass_name}"
73
+ end
74
+ end
75
+
76
+ def enum_sig(klass)
77
+ klass_name = klass.name.split("::").last
78
+ url = resolver(klass)&.enum_url(klass)
79
+ if url
80
+ "#[#{klass_name} Enum](#{url})"
81
+ else
82
+ "##{klass_name} Enum"
83
+ end
84
+ end
85
+
86
+ def enum_value_sig(klass, value)
87
+ url = resolver(klass)&.enum_value_url(klass, value)
88
+
89
+ if url
90
+ "[#{value}](#{url})"
91
+ else
92
+ "#{value}"
93
+ end
94
+ end
95
+
96
+ def union_sig(klass)
97
+ klass_name = klass.name.split("::").last
98
+ url = resolver(klass)&.union_url(klass)
99
+ if url
100
+ "#[#{klass_name} Union](#{url})"
101
+ else
102
+ "##{klass_name} Union"
103
+ end
104
+ end
105
+
106
+ def method_sigs(klass, native_methods, method_sig)
107
+ native_methods.map do |native_method|
108
+ method_sig(klass, native_method, method_sig)
109
+ end.join("\n\n")
110
+ end
111
+
112
+ def type_url(klass)
113
+ resolver = resolver(klass)
114
+
115
+ if klass.instance_of?(Module)
116
+ resolver&.module_url(klass)
117
+ elsif !klass.respond_to?(:cpp_class)
118
+ resolver&.class_url(klass)
119
+ elsif klass.cpp_class.match(/^enum/i)
120
+ resolver&.enum_url(klass)
121
+ elsif klass.cpp_class.match(/^union/i)
122
+ resolver&.union_url(klass)
123
+ else
124
+ resolver&.class_url(klass)
125
+ end
126
+ end
127
+
128
+ def parameters_sig(klass, native)
129
+ native.parameters.map do |parameter|
130
+ resolver = resolver(parameter.klass)
131
+ url = type_url(parameter.klass)
132
+ if url
133
+ "#{parameter.arg.name}: [#{parameter.klass}](#{url})"
134
+ else
135
+ "#{parameter.arg.name}: #{parameter.klass}"
136
+ end
137
+ end.join(", ")
138
+ end
139
+
140
+ def return_sig(klass, native)
141
+ resolver = resolver(native.return_klass)
142
+ url = type_url(native.return_klass)
143
+ if url
144
+ "[#{native.return_klass}](#{url})"
145
+ else
146
+ "#{native.return_klass}"
147
+ end
148
+ end
149
+
150
+ def constructor_sig(klass, native)
151
+ url = resolver(klass)&.method_url(klass, native)
152
+
153
+ if url
154
+ "[initialize](#{url})(#{parameters_sig(klass, native)})"
155
+ else
156
+ "initialize(#{parameters_sig(klass, native)})"
157
+ end
158
+ end
159
+
160
+ def method_sig(klass, native, singleton)
161
+ url = if singleton
162
+ resolver(klass)&.singleton_method_url(klass, native)
163
+ else
164
+ resolver(klass)&.method_url(klass, native)
165
+ end
166
+
167
+ name = ESCAPE_METHODS[native.name] || native.name
168
+
169
+ if url
170
+ "[#{name}](#{url})(#{parameters_sig(klass, native)}) -> #{return_sig(klass, native)}"
171
+ else
172
+ "#{name}(#{parameters_sig(klass, native)}) -> #{return_sig(klass, native)}"
173
+ end
174
+ end
175
+
176
+ def attribute_sig(klass, native_attributes)
177
+ attr_type = if native_attributes.size == 2
178
+ "read/write"
179
+ elsif native_attributes.first.kind == NativeKind::AttributeReader
180
+ "read"
181
+ else
182
+ "write"
183
+ end
184
+
185
+ native_attribute = native_attributes.first
186
+
187
+ attribute_resolver = resolver(klass)
188
+ attribute_url = attribute_resolver&.attribute_url(klass, native_attribute)
189
+
190
+ type_resolver = resolver(native_attribute.return_klass)
191
+ type_url = type_url(native_attribute.return_klass)
192
+
193
+ if attribute_url
194
+ "[#{native_attribute.name}](#{attribute_url}): [#{native_attribute.return_klass}](#{type_url}) (#{attr_type})"
195
+ else
196
+ "#{native_attribute.name}: [#{native_attribute.return_klass}](#{type_url}) (#{attr_type})"
197
+ end
198
+ end
199
+
200
+ def write_module(a_module)
201
+ native_singleton_functions = Registries.instance.natives.native_singleton_functions(a_module).sort.group_by(&:name)
202
+
203
+ path = output_path(a_module)
204
+ File.open(path, 'w') do |file|
205
+ file << "#" << a_module.name << "\n"
206
+ unless native_singleton_functions.empty?
207
+ file << "## Singleton Methods" << "\n"
208
+ native_singleton_functions.each do |name, natives|
209
+ file << method_sigs(a_module, natives, false) << "\n\n"
210
+ end
211
+ file << "\n"
212
+ end
213
+ end
214
+ end
215
+
216
+ def write_class(klass)
217
+ native_attributes = Registries.instance.natives.native_attributes(klass).sort.group_by(&:name)
218
+ native_singleton_functions = Registries.instance.natives.native_singleton_functions(klass).sort.group_by(&:name)
219
+ native_methods = Registries.instance.natives.native_methods(klass).sort.group_by(&:name)
220
+
221
+ path = output_path(klass)
222
+ File.open(path, 'w') do |file|
223
+ file << class_sig(klass) << "\n"
224
+
225
+ # Singleton methods
226
+ unless native_singleton_functions.empty?
227
+ file << "## Singleton Methods" << "\n"
228
+ native_singleton_functions.each do |name, natives|
229
+ file << method_sigs(klass, natives, true) << "\n\n"
230
+ end
231
+ file << "\n"
232
+ end
233
+
234
+ # Constructors
235
+ constructors = native_methods["initialize"]
236
+ if constructors
237
+ file << "## Constructors" << "\n"
238
+ constructors.each do |constructor|
239
+ file << constructor_sig(klass, constructor) << "\n\n"
240
+ end
241
+ file << "\n"
242
+ end
243
+
244
+ # Attributes
245
+ unless native_attributes.empty?
246
+ file << "## Attributes" << "\n"
247
+ native_attributes.each do |name, natives|
248
+ file << attribute_sig(klass, natives) << "\n\n"
249
+ end
250
+ file << "\n"
251
+ end
252
+
253
+ # Instance methods
254
+ unless native_methods.empty?
255
+ file << "## Methods" << "\n"
256
+ native_methods.each do |name, natives|
257
+ next if name == "initialize"
258
+ file << method_sigs(klass, natives, false) << "\n\n"
259
+ end
260
+ file << "\n"
261
+ end
262
+ end
263
+ end
264
+
265
+ def write_enum(klass)
266
+ klass_name = klass.name.split('::').last
267
+
268
+ path = output_path(klass)
269
+ File.open(path, 'w') do |file|
270
+ file << enum_sig(klass) << "\n"
271
+ file << "## Values" << "\n"
272
+ klass.values.each do |value|
273
+ file << "* " << enum_value_sig(klass, value) << "\n"
274
+ end
275
+ end
276
+ end
277
+
278
+ def write_union(klass)
279
+ klass_name = klass.name.split('::').last
280
+ native_attributes = Registries.instance.natives.native_attributes(klass).sort.group_by(&:name)
281
+
282
+ path = output_path(klass)
283
+ File.open(path, 'w') do |file|
284
+ file << union_sig(klass) << "\n"
285
+
286
+ # Attributes
287
+ unless native_attributes.empty?
288
+ file << "## Attributes" << "\n"
289
+ native_attributes.each do |name, natives|
290
+ file << attribute_sig(klass, natives) << "\n\n"
291
+ end
292
+ file << "\n"
293
+ end
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,29 @@
1
+ module Rice
2
+ module Doc
3
+ class Rice
4
+ def class_url(klass)
5
+ end
6
+
7
+ def module_url(klass)
8
+ end
9
+
10
+ def union_url(klass)
11
+ end
12
+
13
+ def enum_url(klass)
14
+ end
15
+
16
+ def enum_value_url(klass, enum_value)
17
+ end
18
+
19
+ def singleton_method_url(klass, native)
20
+ end
21
+
22
+ def method_url(klass, native)
23
+ end
24
+
25
+ def attribute_url(klass, native)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
1
+ module Rice
2
+ module Doc
3
+ class Ruby
4
+ ROOT = "https://docs.ruby-lang.org/en/master"
5
+
6
+ def initialize
7
+ end
8
+
9
+ def class_url(klass)
10
+ name = klass.name.split('::').last
11
+ name[0].upcase! # Can't use capitalize because it lowercases other letters which breaks links like NilClass
12
+ "#{ROOT}/#{name}.html"
13
+ end
14
+
15
+ def module_url(klass)
16
+ end
17
+
18
+ def union_url(klass)
19
+ end
20
+
21
+ def enum_url(klass)
22
+ end
23
+
24
+ def enum_value_url(klass, enum_value)
25
+ end
26
+
27
+ def singleton_method_url(klass, native)
28
+ end
29
+
30
+ def method_url(klass, native)
31
+ end
32
+
33
+ def attribute_url(klass, native)
34
+ end
35
+ end
36
+ end
37
+ end
data/lib/rice/doc.rb ADDED
@@ -0,0 +1,5 @@
1
+ require_relative 'doc/cpp_reference'
2
+ require_relative 'doc/doxygen'
3
+ require_relative 'doc/rice'
4
+ require_relative 'doc/ruby'
5
+ require_relative 'doc/mkdocs'
@@ -76,4 +76,7 @@ combine_headers('rice.hpp')
76
76
  puts "Building stl.hpp"
77
77
  combine_headers('stl.hpp')
78
78
 
79
+ puts "Building api.hpp"
80
+ combine_headers('api.hpp')
81
+
79
82
  puts "Success"
@@ -0,0 +1,18 @@
1
+ module Rice
2
+ class Native
3
+ include Comparable
4
+
5
+ def <=>(other)
6
+ case
7
+ when self.name == other.name
8
+ self.parameters.size <=> other.parameters.size
9
+ when self.name == "initialize"
10
+ -1
11
+ when self.name == "initialize"
12
+ 1
13
+ else
14
+ self.name <=> other.name
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module Rice
2
+ class NativeRegistry
3
+ def native_attributes(klass)
4
+ self.native_by_kind(klass, [Rice::NativeKind::AttributeReader, Rice::NativeKind::AttributeWriter])
5
+ end
6
+
7
+ def native_methods(klass)
8
+ self.native_by_kind(klass, [Rice::NativeKind::Method])
9
+ end
10
+
11
+ def native_singleton_functions(klass)
12
+ self.native_by_kind(klass.singleton_class, [Rice::NativeKind::Function])
13
+ end
14
+
15
+ def native_by_kind(klass, kinds)
16
+ self.lookup(klass).find_all do |native|
17
+ kinds.include?(native.kind)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module Rice
2
+ class Parameter
3
+ def to_s
4
+ "Parameter<#{self.arg.name}: #{self.klass.name}>"
5
+ end
6
+ end
7
+ end
data/lib/rice/rbs.rb ADDED
@@ -0,0 +1,104 @@
1
+ require 'erb'
2
+ require 'fileutils'
3
+
4
+ module Rice
5
+ class Rbs
6
+ attr_reader :extension, :output
7
+
8
+ def initialize(extension, output)
9
+ @extension = extension
10
+ @output = output
11
+ end
12
+
13
+ def generate
14
+ STDOUT << "Writing rbs files to #{@output}" << "\n"
15
+ require self.extension
16
+ types = Registries.instance.types
17
+ types.klasses.each do |klass|
18
+ process_class(klass)
19
+ end
20
+ end
21
+
22
+ def process_class(klass)
23
+ if ['Rice', 'Std'].include?(klass.name.split('::').first)
24
+ return
25
+ end
26
+
27
+ STDOUT << " " << klass << "\n"
28
+
29
+ native_attributes = Registries.instance.natives.native_attributes(klass).sort.group_by(&:name)
30
+ native_functions = Registries.instance.natives.native_functions(klass).sort.group_by(&:name)
31
+ native_methods = Registries.instance.natives.native_methods(klass).sort.group_by(&:name)
32
+ content = render_template("class", :klass => klass,
33
+ :native_attributes => native_attributes,
34
+ :native_functions => native_functions,
35
+ :native_methods => native_methods)
36
+ write_file(klass, content)
37
+ end
38
+
39
+ def write_file(klass, content)
40
+ parts = klass.name.split("::")
41
+ file_name = "#{parts.pop}.rbs"
42
+ dir = File.join(self.output, *parts)
43
+ FileUtils.mkdir_p(dir)
44
+
45
+ path = File.join(dir, file_name)
46
+ File.write(path, content, mode: "wb")
47
+ end
48
+
49
+ def attribute_sig(native_attributes)
50
+ attr_type = if native_attributes.size == 2
51
+ "attr_accessor"
52
+ elsif native_attributes.first.kind == Rice::NativeKind::AttributeReader
53
+ "attr_reader"
54
+ else
55
+ "attr_writer"
56
+ end
57
+ "#{attr_type} #{native_attributes.first.name}: #{native_attributes.first.return_type}"
58
+ end
59
+
60
+ def method_sigs(native_methods, indent = 0)
61
+ join_string = "\n" + (" " * indent) + "| "
62
+ a = native_methods.map do |native_method|
63
+ method_sig(native_method)
64
+ end
65
+ a.join(join_string)
66
+ end
67
+
68
+ def method_sig(native)
69
+ params = native.parameters.map do |parameter|
70
+ "#{parameter.arg.name}: #{parameter.klass}"
71
+ end.join(", ")
72
+ "(#{params}) -> #{native.return_type}"
73
+ end
74
+
75
+ def render_template(template, local_variables = {})
76
+ template = ERB.new(self.template, :trim_mode => '-')
77
+ b = self.binding
78
+ local_variables.each do |key, value|
79
+ b.local_variable_set(key, value)
80
+ end
81
+ template.result(b)
82
+ end
83
+
84
+ def template
85
+ content = <<~EOS
86
+ module <%= klass.name.split("::")[0..-2].join("::") %>
87
+ class <%= klass.name.split("::").last %>
88
+ <%- native_functions.each do |name, functions| -%>
89
+ def self.<%= name %>: <%= method_sigs(functions, name.length + 5) %>
90
+ <%- end -%>
91
+ <%= native_functions.empty? ? "" : "\n" -%>
92
+ <%- native_attributes.each do |name, attributes| -%>
93
+ <%= attribute_sig(attributes) %>
94
+ <%- end -%>
95
+ <%= native_attributes.empty? ? "" : "\n" -%>
96
+ <%- native_methods.each do |name, methods| -%>
97
+ def <%= name %>: <%= method_sigs(methods, name.length + 5) %>
98
+ <%- end -%>
99
+ end
100
+ end
101
+ EOS
102
+ end
103
+ end
104
+ end
data/lib/rice/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rice
2
- VERSION = "4.6.1"
2
+ VERSION = "4.7.0"
3
3
  end
data/lib/rice.rb CHANGED
@@ -1 +1,5 @@
1
1
  require_relative "rice/version"
2
+ require_relative "rice/native"
3
+ require_relative "rice/native_registry"
4
+ require_relative "rice/parameter"
5
+ require_relative "rice/rbs"
@@ -25,36 +25,31 @@
25
25
  # -D<CMAKE_VARIABLE> to set a CMake variable (for example -DCMAKE_BUILD_TYPE=Release)
26
26
  # --preset <preset_name> to use a preset
27
27
  #
28
- # If the Gem author provides presets, via CMakePresets.json file, you will likely want to us use one of them.
29
- # If not, then you may wish to specify a generator (Ninja is recommended since it can build projects in parallel
30
- # versus a Make generator which build ins serial and thus is *much* slower).
31
-
32
- require "fileutils"
28
+ # If the Gem author provides presets, via CMakePresets.json file, you will likely want to use one of them.
29
+ # If not, you may wish to specify a generator. Ninja is recommended because it can build projects in parallel
30
+ # and thus much faster than building them serially like Make does.
33
31
 
34
32
  class Gem::Ext::CmakeBuilder
35
33
  attr_accessor :runner, :profile
36
-
37
34
  def initialize
38
35
  @runner = self.class.method(:run)
39
36
  @profile = :release
40
37
  end
41
38
 
42
- def build(extension, gem_dir, results, args = [], lib_dir = nil, cmake_dir = Dir.pwd, target_rbconfig = Gem.target_rbconfig)
39
+ def build(extension, dest_path, results, args = [], lib_dir = nil, cmake_dir = Dir.pwd,
40
+ target_rbconfig = Gem.target_rbconfig)
43
41
  if target_rbconfig.path
44
42
  warn "--target-rbconfig is not yet supported for CMake extensions. Ignoring"
45
43
  end
46
44
 
47
- # Make sure lib dir is set
48
- lib_dir ||= File.join(gem_dir, "lib")
49
-
50
45
  # Figure the build dir
51
46
  build_dir = File.join(cmake_dir, "build")
52
47
 
53
48
  # Check if the gem defined presets
54
- check_presets(cmake_dir, args)
49
+ check_presets(cmake_dir, args, results)
55
50
 
56
51
  # Configure
57
- configure(cmake_dir, build_dir, lib_dir, args, results)
52
+ configure(cmake_dir, build_dir, dest_path, args, results)
58
53
 
59
54
  # Compile
60
55
  compile(cmake_dir, build_dir, args, results)
@@ -62,16 +57,17 @@ class Gem::Ext::CmakeBuilder
62
57
  results
63
58
  end
64
59
 
65
- def configure(cmake_dir, build_dir, lib_dir, args, results)
60
+ def configure(cmake_dir, build_dir, install_dir, args, results)
66
61
  cmd = ["cmake",
67
62
  cmake_dir,
68
- "-B #{build_dir}",
69
- "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=#{lib_dir}", # Windows
70
- "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=#{lib_dir}", # Not Windows
63
+ "-B",
64
+ build_dir,
65
+ "-DCMAKE_RUNTIME_OUTPUT_DIRECTORY=#{install_dir}", # Windows
66
+ "-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=#{install_dir}", # Not Windows
71
67
  *Gem::Command.build_args,
72
68
  *args]
73
69
 
74
- runner.call(cmd, results, "cmake", cmake_dir)
70
+ runner.call(cmd, results, "cmake_configure", cmake_dir)
75
71
  end
76
72
 
77
73
  def compile(cmake_dir, build_dir, args, results)
@@ -80,32 +76,33 @@ class Gem::Ext::CmakeBuilder
80
76
  build_dir.to_s,
81
77
  "--config",
82
78
  @profile.to_s]
83
- runner.call(cmd, results, "cmake", cmake_dir)
79
+
80
+ runner.call(cmd, results, "cmake_compile", cmake_dir)
84
81
  end
85
82
 
86
83
  private
87
84
 
88
- def check_presets(cmake_dir, args)
85
+ def check_presets(cmake_dir, args, results)
89
86
  # Return if the user specified a preset
90
87
  return unless args.grep(/--preset/i).empty?
91
88
 
92
89
  cmd = ["cmake",
93
90
  "--list-presets"]
94
91
 
92
+ presets = Array.new
95
93
  begin
96
- require "open3"
97
- build_env = { "SOURCE_DATE_EPOCH" => Gem.source_date_epoch_string }
98
- stdout, _, _ = Open3.capture3(build_env, *cmd, chdir: cmake_dir)
99
- message = <<~EOS
94
+ runner.call(cmd, presets, "cmake_presets", cmake_dir)
95
+
96
+ # Remove the first two lines of the array which is the current_directory and the command
97
+ # that was run
98
+ presets = presets[2..].join
99
+ results << <<~EOS
100
100
  The gem author provided a list of presets that can be used to build the gem. To use a preset specify it on the command line:
101
101
 
102
102
  gem install <gem_name> -- --preset <preset_name>
103
103
 
104
- #{stdout}
104
+ #{presets}
105
105
  EOS
106
-
107
- STDOUT << message << "\n"
108
- STDOUT.flush
109
106
  rescue Gem::InstallError
110
107
  # Do nothing, CMakePresets.json was not included in the Gem
111
108
  end
data/rice/Arg.hpp CHANGED
@@ -81,9 +81,9 @@ namespace Rice
81
81
  virtual Arg& takeOwnership();
82
82
  bool isOwner();
83
83
 
84
- //! Is the parameter a C style array
85
- virtual Arg& setArray();
86
- bool isArray();
84
+ //! Is the parameter a buffer
85
+ virtual Arg& setBuffer();
86
+ bool isBuffer();
87
87
 
88
88
  public:
89
89
  std::string name;
@@ -96,7 +96,7 @@ namespace Rice
96
96
  bool isKeepAlive_ = false;
97
97
  bool isOwner_ = false;
98
98
  bool isOpaque_ = false;
99
- bool isArray_ = false;
99
+ bool isBuffer_ = false;
100
100
 
101
101
  };
102
102
  } // Rice