gir_ffi 0.13.0 → 0.13.1

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +10 -0
  3. data/lib/ffi-glib/array.rb +2 -2
  4. data/lib/ffi-glib/array_methods.rb +1 -0
  5. data/lib/ffi-glib/list_methods.rb +3 -2
  6. data/lib/ffi-glib/main_loop.rb +2 -0
  7. data/lib/ffi-glib/ptr_array.rb +2 -2
  8. data/lib/ffi-gobject.rb +3 -11
  9. data/lib/ffi-gobject/closure.rb +1 -0
  10. data/lib/ffi-gobject/object.rb +30 -16
  11. data/lib/ffi-gobject/object_class.rb +2 -2
  12. data/lib/ffi-gobject/ruby_closure.rb +2 -2
  13. data/lib/ffi-gobject/value.rb +2 -1
  14. data/lib/ffi-gobject_introspection/i_arg_info.rb +11 -11
  15. data/lib/ffi-gobject_introspection/i_base_info.rb +12 -10
  16. data/lib/ffi-gobject_introspection/i_callable_info.rb +8 -8
  17. data/lib/ffi-gobject_introspection/i_enum_info.rb +5 -5
  18. data/lib/ffi-gobject_introspection/i_field_info.rb +4 -4
  19. data/lib/ffi-gobject_introspection/i_function_info.rb +2 -2
  20. data/lib/ffi-gobject_introspection/i_interface_info.rb +15 -15
  21. data/lib/ffi-gobject_introspection/i_object_info.rb +22 -22
  22. data/lib/ffi-gobject_introspection/i_property_info.rb +2 -2
  23. data/lib/ffi-gobject_introspection/i_registered_type_info.rb +3 -3
  24. data/lib/ffi-gobject_introspection/i_repository.rb +16 -10
  25. data/lib/ffi-gobject_introspection/i_struct_info.rb +11 -7
  26. data/lib/ffi-gobject_introspection/i_type_info.rb +8 -8
  27. data/lib/ffi-gobject_introspection/i_union_info.rb +7 -7
  28. data/lib/ffi-gobject_introspection/i_value_info.rb +1 -1
  29. data/lib/ffi-gobject_introspection/strv.rb +1 -0
  30. data/lib/gir_ffi-base/gobject.rb +5 -0
  31. data/lib/gir_ffi-base/gobject/lib.rb +4 -0
  32. data/lib/gir_ffi/boolean.rb +2 -2
  33. data/lib/gir_ffi/builders/argument_builder.rb +41 -14
  34. data/lib/gir_ffi/builders/argument_builder_collection.rb +17 -4
  35. data/lib/gir_ffi/builders/base_argument_builder.rb +12 -16
  36. data/lib/gir_ffi/builders/callback_argument_builder.rb +1 -1
  37. data/lib/gir_ffi/builders/callback_builder.rb +1 -1
  38. data/lib/gir_ffi/builders/closure_to_pointer_convertor.rb +2 -9
  39. data/lib/gir_ffi/builders/field_builder.rb +11 -9
  40. data/lib/gir_ffi/builders/module_builder.rb +2 -1
  41. data/lib/gir_ffi/builders/object_builder.rb +21 -12
  42. data/lib/gir_ffi/builders/pointer_value_convertor.rb +8 -6
  43. data/lib/gir_ffi/builders/property_builder.rb +4 -2
  44. data/lib/gir_ffi/builders/registered_type_builder.rb +30 -19
  45. data/lib/gir_ffi/builders/return_value_builder.rb +2 -2
  46. data/lib/gir_ffi/builders/ruby_to_c_convertor.rb +2 -0
  47. data/lib/gir_ffi/builders/signal_closure_builder.rb +1 -1
  48. data/lib/gir_ffi/builders/struct_builder.rb +7 -8
  49. data/lib/gir_ffi/builders/unintrospectable_builder.rb +4 -1
  50. data/lib/gir_ffi/builders/user_defined_builder.rb +31 -95
  51. data/lib/gir_ffi/builders/vfunc_builder.rb +1 -1
  52. data/lib/gir_ffi/builders/with_layout.rb +3 -1
  53. data/lib/gir_ffi/callback_base.rb +3 -2
  54. data/lib/gir_ffi/class_base.rb +5 -0
  55. data/lib/gir_ffi/enum_like_base.rb +9 -5
  56. data/lib/gir_ffi/error_argument_info.rb +1 -1
  57. data/lib/gir_ffi/ffi_ext/pointer.rb +1 -4
  58. data/lib/gir_ffi/field_argument_info.rb +1 -1
  59. data/lib/gir_ffi/in_pointer.rb +36 -23
  60. data/lib/gir_ffi/info_ext/i_arg_info.rb +2 -0
  61. data/lib/gir_ffi/info_ext/i_callback_info.rb +4 -0
  62. data/lib/gir_ffi/info_ext/i_registered_type_info.rb +4 -0
  63. data/lib/gir_ffi/info_ext/i_type_info.rb +3 -27
  64. data/lib/gir_ffi/info_ext/safe_function_name.rb +1 -0
  65. data/lib/gir_ffi/interface_base.rb +5 -0
  66. data/lib/gir_ffi/module_base.rb +1 -0
  67. data/lib/gir_ffi/object_base.rb +10 -0
  68. data/lib/gir_ffi/object_store.rb +2 -0
  69. data/lib/gir_ffi/receiver_argument_info.rb +1 -1
  70. data/lib/gir_ffi/return_value_info.rb +1 -1
  71. data/lib/gir_ffi/sized_array.rb +7 -14
  72. data/lib/gir_ffi/struct_like_base.rb +3 -0
  73. data/lib/gir_ffi/type_map.rb +21 -0
  74. data/lib/gir_ffi/user_defined_object_info.rb +6 -2
  75. data/lib/gir_ffi/user_defined_property_info.rb +113 -71
  76. data/lib/gir_ffi/version.rb +1 -1
  77. data/lib/gir_ffi/zero_terminated.rb +26 -1
  78. data/tasks/test.rake +1 -0
  79. data/test/ffi-gobject_introspection/i_repository_test.rb +1 -2
  80. data/test/gir_ffi/builder_test.rb +13 -7
  81. data/test/gir_ffi/builders/argument_builder_test.rb +1 -5
  82. data/test/gir_ffi/builders/callback_return_value_builder_test.rb +1 -1
  83. data/test/gir_ffi/builders/field_builder_test.rb +20 -20
  84. data/test/gir_ffi/builders/return_value_builder_test.rb +1 -1
  85. data/test/gir_ffi/builders/signal_closure_builder_test.rb +1 -1
  86. data/test/gir_ffi/builders/unintrospectable_boxed_builder_test.rb +1 -1
  87. data/test/gir_ffi/builders/unintrospectable_builder_test.rb +2 -2
  88. data/test/gir_ffi/builders/vfunc_builder_test.rb +1 -1
  89. data/test/gir_ffi/enum_base_test.rb +43 -0
  90. data/test/gir_ffi/info_ext/i_type_info_test.rb +3 -9
  91. data/test/gir_ffi/object_base_test.rb +30 -0
  92. data/test/gir_ffi/sized_array_test.rb +0 -9
  93. data/test/gir_ffi/user_defined_object_info_test.rb +4 -6
  94. data/test/gir_ffi/user_defined_property_info_test.rb +6 -5
  95. data/test/gir_ffi/zero_terminated_test.rb +22 -0
  96. data/test/gir_ffi_test_helper.rb +2 -0
  97. data/test/integration/generated_gimarshallingtests_test.rb +1 -0
  98. data/test/integration/generated_gio_test.rb +5 -6
  99. data/test/integration/generated_gobject_test.rb +1 -1
  100. data/test/integration/generated_gtop_test.rb +3 -1
  101. data/test/integration/generated_regress_test.rb +3 -4
  102. metadata +3 -2
@@ -28,7 +28,7 @@ module GirFFI
28
28
  return false unless go
29
29
 
30
30
  Builder.attach_ffi_function lib, go
31
- modul.class_eval FunctionBuilder.new(go).method_definition
31
+ modul.class_eval FunctionBuilder.new(go).method_definition, __FILE__, __LINE__
32
32
 
33
33
  true
34
34
  end
@@ -108,6 +108,7 @@ module GirFFI
108
108
  def function_introspection_data(function)
109
109
  info = gir.find_by_name @namespace, function.to_s
110
110
  return unless info
111
+
111
112
  info.info_type == :function ? info : nil
112
113
  end
113
114
 
@@ -71,7 +71,7 @@ module GirFFI
71
71
  setup_property_accessors
72
72
  setup_vfunc_invokers
73
73
  setup_interfaces
74
- provide_initializer
74
+ setup_initializer
75
75
  end
76
76
 
77
77
  # FIXME: Private method only used in subclass
@@ -121,6 +121,7 @@ module GirFFI
121
121
 
122
122
  def define_vfunc_invoker(vfunc_name, invoker_name)
123
123
  return if vfunc_name == invoker_name
124
+
124
125
  klass.class_eval <<-DEF, __FILE__, __LINE__ + 1
125
126
  def #{vfunc_name} *args, &block
126
127
  #{invoker_name}(*args, &block)
@@ -128,24 +129,32 @@ module GirFFI
128
129
  DEF
129
130
  end
130
131
 
131
- def provide_initializer
132
+ def setup_initializer
132
133
  return if info.find_method 'new'
133
134
 
134
135
  if info.abstract?
135
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
136
- def initialize(*)
137
- raise NoMethodError
138
- end
139
- RUBY
136
+ define_abstract_initializer
140
137
  else
141
- klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
142
- def initialize(properties = {})
143
- base_initialize(properties)
144
- end
145
- RUBY
138
+ define_default_initializer
146
139
  end
147
140
  end
148
141
 
142
+ def define_abstract_initializer
143
+ klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
144
+ def initialize(*)
145
+ raise NoMethodError
146
+ end
147
+ RUBY
148
+ end
149
+
150
+ def define_default_initializer
151
+ klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1
152
+ def initialize(properties = {})
153
+ base_initialize(properties)
154
+ end
155
+ RUBY
156
+ end
157
+
149
158
  def setup_interfaces
150
159
  interfaces.each do |iface|
151
160
  klass.send :include, iface
@@ -9,21 +9,23 @@ module GirFFI
9
9
  @type_spec = type_spec
10
10
  end
11
11
 
12
- def pointer_to_value(ptr_exp)
12
+ def pointer_to_value(ptr_exp, offset = 0)
13
13
  case ffi_type_spec
14
14
  when Module
15
- "#{ffi_type_spec}.get_value_from_pointer(#{ptr_exp}, 0)"
15
+ "#{ffi_type_spec}.get_value_from_pointer(#{ptr_exp}, #{offset})"
16
16
  when Symbol
17
- "#{ptr_exp}.get_#{ffi_type_spec}(0)"
17
+ "#{ptr_exp}.get_#{ffi_type_spec}(#{offset})"
18
18
  end
19
19
  end
20
20
 
21
- def value_to_pointer(ptr_exp, value_exp)
21
+ def value_to_pointer(ptr_exp, value_exp, offset = 0)
22
22
  case ffi_type_spec
23
23
  when Module
24
- "#{ffi_type_spec}.copy_value_to_pointer(#{value_exp}, #{ptr_exp})"
24
+ args = [value_exp, ptr_exp]
25
+ args << offset unless offset == 0
26
+ "#{ffi_type_spec}.copy_value_to_pointer(#{args.join(', ')})"
25
27
  when Symbol
26
- "#{ptr_exp}.put_#{ffi_type_spec} 0, #{value_exp}"
28
+ "#{ptr_exp}.put_#{ffi_type_spec} #{offset}, #{value_exp}"
27
29
  end
28
30
  end
29
31
 
@@ -71,7 +71,9 @@ module GirFFI
71
71
  end
72
72
 
73
73
  def setup_getter
74
- container_class.class_eval getter_def unless container_defines_getter_method?
74
+ return if container_defines_getter_method?
75
+
76
+ container_class.class_eval getter_def, __FILE__, __LINE__
75
77
  end
76
78
 
77
79
  def container_defines_getter_method?
@@ -79,7 +81,7 @@ module GirFFI
79
81
  end
80
82
 
81
83
  def setup_setter
82
- container_class.class_eval setter_def
84
+ container_class.class_eval setter_def, __FILE__, __LINE__
83
85
  end
84
86
 
85
87
  def getter_def
@@ -15,13 +15,17 @@ module GirFFI
15
15
  def setup_method(method)
16
16
  method_info = info.find_method method
17
17
  return unless method_info
18
- attach_and_define_method method_info, meta_class
18
+
19
+ remove_old_method method_info, meta_class
20
+ attach_and_define_method method_info
19
21
  end
20
22
 
21
23
  def setup_instance_method(method)
22
24
  method_info = info.find_instance_method method
23
25
  return unless method_info
24
- attach_and_define_method method_info, build_class
26
+
27
+ remove_old_method method_info, build_class
28
+ attach_and_define_method method_info
25
29
  end
26
30
 
27
31
  def target_gtype
@@ -34,29 +38,36 @@ module GirFFI
34
38
  (class << build_class; self; end)
35
39
  end
36
40
 
37
- def attach_and_define_method(method_info, modul)
38
- method = method_info.safe_name
41
+ def attach_and_define_method(method_info)
39
42
  attach_method method_info
40
- remove_old_method method, modul
41
- define_method method_info
42
- method
43
+ if method_info.constructor?
44
+ define_construction_methods method_info
45
+ else
46
+ define_method method_info
47
+ end
48
+ method_info.safe_name
43
49
  end
44
50
 
45
51
  def define_method(method_info)
46
- if method_info.constructor?
47
- initializer_builder = InitializerBuilder.new(method_info)
48
- initializer_name = initializer_builder.method_name.to_sym
49
- unless build_class.private_instance_methods(false).include? initializer_name
50
- build_class.class_eval initializer_builder.method_definition
51
- end
52
- build_class.class_eval ConstructorBuilder.new(method_info).method_definition
53
- else
54
- build_class.class_eval FunctionBuilder.new(method_info).method_definition
52
+ method_definition = FunctionBuilder.new(method_info).method_definition
53
+ build_class.class_eval(method_definition, __FILE__, __LINE__)
54
+ end
55
+
56
+ def define_construction_methods(method_info)
57
+ initializer_builder = InitializerBuilder.new(method_info)
58
+ initializer_name = initializer_builder.method_name.to_sym
59
+ unless build_class.private_instance_methods(false).include? initializer_name
60
+ build_class.class_eval initializer_builder.method_definition, __FILE__, __LINE__
55
61
  end
62
+ constructor_definition = ConstructorBuilder.new(method_info).method_definition
63
+ build_class.class_eval(constructor_definition, __FILE__, __LINE__)
56
64
  end
57
65
 
58
- def remove_old_method(method, modul)
59
- modul.class_eval { remove_method method if method_defined? method }
66
+ def remove_old_method(method_info, modul)
67
+ method = method_info.safe_name
68
+ modul.class_eval do
69
+ remove_method method if method_defined? method
70
+ end
60
71
  end
61
72
 
62
73
  def attach_method(method_info)
@@ -65,7 +76,7 @@ module GirFFI
65
76
 
66
77
  def stub_methods
67
78
  info.get_methods.each do |minfo|
68
- klass.class_eval MethodStubber.new(minfo).method_stub
79
+ klass.class_eval MethodStubber.new(minfo).method_stub, __FILE__, __LINE__
69
80
  end
70
81
  end
71
82
 
@@ -17,7 +17,7 @@ module GirFFI
17
17
  end
18
18
 
19
19
  def has_post_conversion?
20
- closure? || needs_c_to_ruby_conversion?
20
+ user_data? || needs_c_to_ruby_conversion?
21
21
  end
22
22
 
23
23
  def needs_c_to_ruby_conversion?
@@ -28,7 +28,7 @@ module GirFFI
28
28
 
29
29
  def post_convertor
30
30
  @post_convertor ||=
31
- if closure?
31
+ if user_data?
32
32
  ClosureConvertor.new(capture_variable_name)
33
33
  else
34
34
  FullCToRubyConvertor.new(type_info,
@@ -33,6 +33,8 @@ module GirFFI
33
33
  else
34
34
  'from'
35
35
  end
36
+ when :enum
37
+ 'to_int'
36
38
  else
37
39
  'from'
38
40
  end
@@ -10,7 +10,7 @@ module GirFFI
10
10
  class SignalClosureBuilder < BaseTypeBuilder
11
11
  def setup_class
12
12
  setup_constants
13
- klass.class_eval marshaller_definition
13
+ klass.class_eval marshaller_definition, __FILE__, __LINE__
14
14
  end
15
15
 
16
16
  def setup_method(_method)
@@ -15,18 +15,17 @@ module GirFFI
15
15
  end
16
16
 
17
17
  def superclass
18
- if info.gtype_struct?
19
- # HACK: Inheritance chain is not expressed in GObject's code correctly.
20
- type_name = info.full_type_name
21
- return GObject::ObjectClass if type_name == 'GObject::InitiallyUnownedClass'
22
- type = fields.first.field_type
23
- return type.tag_or_class if type.tag == :interface
24
- end
25
-
18
+ # HACK: Inheritance chain is not expressed in GObject's code correctly.
19
+ return GObject::ObjectClass if info.full_type_name == 'GObject::InitiallyUnownedClass'
20
+ return parent_field_type.tag_or_class if info.gtype_struct?
26
21
  return BoxedBase if GObject.type_fundamental(info.gtype) == GObject::TYPE_BOXED
27
22
 
28
23
  StructBase
29
24
  end
25
+
26
+ def parent_field_type
27
+ fields.first.field_type
28
+ end
30
29
  end
31
30
  end
32
31
  end
@@ -26,8 +26,11 @@ module GirFFI
26
26
  def find_signal(signal_name)
27
27
  info = super
28
28
  return info if info
29
+
29
30
  signal_id = GObject.signal_lookup signal_name, target_gtype
30
- return UnintrospectableSignalInfo.new(signal_id) unless signal_id.zero?
31
+ return if signal_id == 0
32
+
33
+ UnintrospectableSignalInfo.new(signal_id)
31
34
  end
32
35
  end
33
36
  end
@@ -16,7 +16,7 @@ module GirFFI
16
16
  register_type
17
17
  setup_constants
18
18
  setup_property_accessors
19
- setup_constructor
19
+ setup_initializer
20
20
  TypeBuilder::CACHE[@gtype] = klass
21
21
  end
22
22
 
@@ -49,7 +49,7 @@ module GirFFI
49
49
  end
50
50
 
51
51
  def included_interfaces
52
- klass.included_modules - Object.included_modules
52
+ klass.included_interfaces
53
53
  end
54
54
 
55
55
  def klass
@@ -86,11 +86,13 @@ module GirFFI
86
86
  end
87
87
 
88
88
  def instance_size
89
- size = parent_gtype.instance_size
90
- alignment = struct_class.alignment
91
- properties.each do |prop|
92
- type_size = FFI.type_size(prop.ffi_type)
93
- size += [type_size, alignment].max
89
+ if property_fields.any?
90
+ last_property = property_fields.last
91
+ size = last_property.offset
92
+ type_size = FFI.type_size(last_property.ffi_type)
93
+ size += [type_size, field_alignment].max
94
+ else
95
+ size = parent_gtype.instance_size
94
96
  end
95
97
  size
96
98
  end
@@ -105,7 +107,7 @@ module GirFFI
105
107
  object_class.get_property = property_getter
106
108
  object_class.set_property = property_setter
107
109
 
108
- properties.each_with_index do |property, index|
110
+ property_fields.each_with_index do |property, index|
109
111
  object_class.install_property index + 1, property.param_spec
110
112
  end
111
113
  end
@@ -156,110 +158,44 @@ module GirFFI
156
158
  end
157
159
 
158
160
  def properties
159
- info.properties
161
+ @properties ||= info.properties
160
162
  end
161
163
 
162
164
  def layout_specification
163
165
  parent_spec = [:parent, superclass::Struct]
164
- offset = parent_gtype.instance_size
165
-
166
- alignment = superclass::Struct.alignment
167
- fields_spec = properties.flat_map do |param_info|
168
- field_name = param_info.accessor_name.to_sym
169
- ffi_type = param_info.ffi_type
170
- type_size = FFI.type_size(ffi_type)
171
- spec = [field_name, ffi_type, offset]
172
- offset += [type_size, alignment].max
173
- spec
174
- end
175
- parent_spec + fields_spec
176
- end
177
-
178
- # TODO: Move this to its own file.
179
- # TODO: See if this or FieldTypeInfo can be merged with with
180
- # UserDefinedPropertyInfo.
181
- class UserDefinedPropertyFieldInfo
182
- # Field info for user-defined property
183
- class FieldTypeInfo
184
- include InfoExt::ITypeInfo
185
-
186
- def initialize(property_info)
187
- @property_info = property_info
188
- end
189
-
190
- def tag
191
- @property_info.type_tag
192
- end
193
-
194
- def pointer?
195
- @property_info.pointer_type?
196
- end
197
-
198
- def interface_type
199
- @property_info.interface_type_tag if tag == :interface
200
- end
201
-
202
- def hidden_struct_type?
203
- false
204
- end
205
-
206
- def interface_class
207
- Builder.build_by_gtype @property_info.value_type if tag == :interface
208
- end
209
-
210
- def interface_class_name
211
- interface_class.name if tag == :interface
212
- end
213
- end
214
-
215
- def initialize(property_info, container, offset)
216
- @property_info = property_info
217
- @container = container
218
- @offset = offset
219
- end
220
-
221
- attr_reader :container, :offset
222
166
 
223
- def name
224
- @property_info.accessor_name
167
+ fields_spec = property_fields.flat_map do |property_info|
168
+ [property_info.field_symbol, property_info.ffi_type, property_info.offset]
225
169
  end
226
170
 
227
- def field_type
228
- @field_type ||= FieldTypeInfo.new @property_info
229
- end
230
-
231
- def related_array_length_field
232
- nil
233
- end
171
+ parent_spec + fields_spec
172
+ end
234
173
 
235
- def writable?
236
- @property_info.writable?
237
- end
174
+ def field_alignment
175
+ @field_alignment ||= superclass::Struct.alignment
238
176
  end
239
177
 
240
178
  def setup_property_accessors
241
- offset = parent_gtype.instance_size
242
- alignment = struct_class.alignment
243
- properties.each do |param_info|
244
- field_info = UserDefinedPropertyFieldInfo.new(param_info, info, offset)
245
- type_size = FFI.type_size(param_info.ffi_type)
246
- offset += [type_size, alignment].max
179
+ property_fields.each do |field_info|
247
180
  FieldBuilder.new(field_info, klass).build
248
181
  end
249
182
  end
250
183
 
251
- def method_introspection_data(_method)
252
- nil
184
+ def property_fields
185
+ @property_fields ||=
186
+ begin
187
+ offset = parent_gtype.instance_size
188
+ properties.map do |param_spec|
189
+ field_info = UserDefinedPropertyInfo.new(param_spec, info, offset)
190
+ type_size = FFI.type_size(field_info.ffi_type)
191
+ offset += [type_size, field_alignment].max
192
+ field_info
193
+ end
194
+ end
253
195
  end
254
196
 
255
- def setup_constructor
256
- code = <<-CODE
257
- def initialize
258
- ptr = GObject::Lib.g_object_new #{@gtype}, nil
259
- store_pointer(ptr)
260
- end
261
- CODE
262
- klass.class_eval code
197
+ def method_introspection_data(_method)
198
+ nil
263
199
  end
264
200
  end
265
201
  end