dub 0.6.6 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/History.txt +26 -0
  2. data/README.rdoc +41 -1
  3. data/dub.gemspec +160 -166
  4. data/lib/dub/argument.rb +25 -13
  5. data/lib/dub/function.rb +14 -4
  6. data/lib/dub/group.rb +2 -6
  7. data/lib/dub/klass.rb +55 -19
  8. data/lib/dub/lua/class.cpp.erb +29 -2
  9. data/lib/dub/lua/class_gen.rb +33 -34
  10. data/lib/dub/lua/function.cpp.erb +9 -12
  11. data/lib/dub/lua/function_gen.rb +55 -19
  12. data/lib/dub/lua/lua_cpp_helper.cpp +252 -0
  13. data/lib/dub/lua/lua_cpp_helper.h +118 -40
  14. data/lib/dub/lua/namespace.cpp.erb +3 -1
  15. data/lib/dub/lua/namespace_gen.rb +14 -33
  16. data/lib/dub/member_extraction.rb +47 -11
  17. data/lib/dub/namespace.rb +14 -3
  18. data/lib/dub/opts_parser.rb +3 -3
  19. data/lib/dub/version.rb +2 -2
  20. data/test/argument_test.rb +46 -12
  21. data/test/fixtures/app/include/matrix.h +121 -0
  22. data/test/fixtures/app/vendor/lua/liblua.a +0 -0
  23. data/test/fixtures/app/xml/classdub_1_1_base.xml +85 -0
  24. data/test/fixtures/app/xml/classdub_1_1_custom_destructor.xml +67 -0
  25. data/test/fixtures/app/xml/classdub_1_1_deletable_out_of_lua.xml +43 -0
  26. data/test/fixtures/app/xml/classdub_1_1_matrix.xml +162 -21
  27. data/test/fixtures/app/xml/classdub_1_1_no_destructor.xml +49 -0
  28. data/test/fixtures/app/xml/classdub_1_1_priv_sub_base.xml +89 -0
  29. data/test/fixtures/app/xml/classdub_1_1_private_constr.xml +68 -0
  30. data/test/fixtures/app/xml/classdub_1_1_static_constr.xml +69 -0
  31. data/test/fixtures/app/xml/classdub_1_1_sub_base.xml +89 -0
  32. data/test/fixtures/app/xml/classdub_1_1_t_mat.xml +15 -15
  33. data/test/fixtures/app/xml/index.xml +43 -0
  34. data/test/fixtures/app/xml/matrix_8h.xml +263 -132
  35. data/test/fixtures/app/xml/namespacedub.xml +10 -3
  36. data/test/function_group_test.rb +20 -1
  37. data/test/function_test.rb +10 -0
  38. data/test/group_test.rb +95 -9
  39. data/test/klass_test.rb +134 -5
  40. data/test/lua_function_gen_test.rb +36 -9
  41. metadata +20 -23
  42. data/.gitignore +0 -8
@@ -49,39 +49,20 @@ module Dub
49
49
  res.join(",\n\n")
50
50
  end
51
51
 
52
- def members_list(all_members, ignore_list = [])
53
- list = (all_members || []).map do |member_or_group|
54
- if ignore_list.include?(member_or_group.name)
55
- nil
56
- elsif member_or_group.kind_of?(Array)
57
- members_list(member_or_group)
58
- elsif ignore_member?(member_or_group)
59
- nil
60
- else
61
- member_or_group
62
- end
63
- end
64
-
65
- list.compact!
66
- list == [] ? nil : list
67
- end
68
-
69
- def ignore_member?(member)
70
- if member.name =~ /^~/ || # do not build constructor
71
- member.name =~ /^operator/ || # no conversion operators
72
- member.original_signature =~ />/ || # no complex types in signature
73
- member.has_array_arguments? ||
74
- member.vararg? ||
75
- member.original_signature =~ /void\s+\*/ ||
76
- member.has_class_pointer_arguments?
77
-
78
- true # ignore
79
- elsif return_value = member.return_value
80
- return_value.type =~ />$/ || # no complex return types
81
- return_value.is_native? && member.return_value.is_pointer?
82
- else
83
- false # ok, do not ignore
84
- end
52
+ def members_list(all_members)
53
+ all_members
54
+ #list = (all_members || []).map do |member_or_group|
55
+ # if member_or_group.kind_of?(Array)
56
+ # members_list(member_or_group)
57
+ # elsif ignore_member?(member_or_group)
58
+ # nil
59
+ # else
60
+ # member_or_group
61
+ # end
62
+ #end
63
+ #
64
+ #list.compact!
65
+ #list == [] ? nil : list
85
66
  end
86
67
  end
87
68
  end
@@ -41,10 +41,11 @@ module Dub
41
41
  get_member(name.to_s, @members_hash)
42
42
  end
43
43
 
44
- def members
44
+ def members(ignore_list = [])
45
45
  @members ||= begin
46
46
  list = []
47
47
  @members_hash.each do |name, member|
48
+ next if ignore_list.include?(name)
48
49
  list << get_member(name)
49
50
  end
50
51
  list.compact!
@@ -61,12 +62,23 @@ module Dub
61
62
  if member_or_group = source[name]
62
63
  if member_or_group.kind_of?(Array)
63
64
  if member_or_group.first.kind_of?(Hpricot::Elem)
64
- list = Dub::FunctionGroup.new(self)
65
- member_or_group.each_with_index do |m,i|
66
- list << make_member(name, m, i + 1)
65
+ list = []
66
+ member_or_group.each do |m|
67
+ list << make_member(name, m)
68
+ end
69
+ list.compact!
70
+ if list == []
71
+ member_or_group = nil
72
+ elsif list.size == 1
73
+ member_or_group = list.first
74
+ else
75
+ member_or_group = Dub::FunctionGroup.new(self)
76
+ # set overloaded_index
77
+ list.each_with_index do |m, i|
78
+ m.overloaded_index = i + 1
79
+ member_or_group << m
80
+ end
67
81
  end
68
- member_or_group = list.compact
69
- member_or_group = nil if member_or_group == []
70
82
  end
71
83
  elsif member_or_group.kind_of?(Hpricot::Elem)
72
84
  source[name] = member_or_group = make_member(name, member_or_group)
@@ -75,17 +87,41 @@ module Dub
75
87
  member_or_group
76
88
  end
77
89
 
78
- def make_member(name, member, overloaded_index = nil)
79
- case member[:kind]
80
- when 'function'
90
+ def make_member(name, member)
91
+ member = case member[:kind]
92
+ when 'function', 'slot'
81
93
  Dub.logger.info "Building #{members_prefix}::#{name}"
82
- Function.new(self, name, member, members_prefix, overloaded_index)
94
+ Function.new(self, name, member, members_prefix)
83
95
  when 'class'
84
96
  Dub.logger.info "Building #{members_prefix}::#{name}"
85
97
  Klass.new(self, name, member, members_prefix)
86
98
  else
87
99
  # not supported: ignore
88
- nil
100
+ return nil
101
+ end
102
+
103
+ ignore_member?(member) ? nil : member
104
+ end
105
+
106
+ def ignore_member?(member)
107
+ return false if member.kind_of?(Klass)
108
+
109
+ if !member.public? ||
110
+ member.name =~ /^~/ || # do not build constructor
111
+ member.name =~ /^operator/ || # no conversion operators
112
+ member.has_complex_arguments? || # no complex arguments or return values
113
+ member.has_array_arguments? ||
114
+ member.vararg? ||
115
+ member.original_signature =~ /void\s+\*/ # used to detect return value and parameters
116
+ true # ignore
117
+ elsif return_value = member.return_value
118
+ if return_value.create_type == 'const char *'
119
+ return false # do not ignore
120
+ end
121
+ return_value.type =~ />$/ || # no complex return types
122
+ (return_value.is_native? && member.return_value.is_pointer?)
123
+ else
124
+ false # ok, do not ignore
89
125
  end
90
126
  end
91
127
  end
data/lib/dub/namespace.rb CHANGED
@@ -64,7 +64,12 @@ module Dub
64
64
  end
65
65
 
66
66
  def lib_name
67
- prefix ? "#{prefix}_#{name}" : name
67
+ @lib_name || (prefix ? "#{prefix}_#{name}" : name)
68
+ end
69
+
70
+ # FIXME: test
71
+ def lib_name=(name)
72
+ @lib_name = name
68
73
  end
69
74
 
70
75
  def id_name(name = self.name)
@@ -104,10 +109,11 @@ module Dub
104
109
  end
105
110
 
106
111
  def members
112
+ list = super(@ignores)
107
113
  if self.generator
108
- @gen_members ||= self.generator.members_list(super, @ignores)
114
+ @gen_members ||= self.generator.members_list(list)
109
115
  else
110
- super
116
+ list
111
117
  end
112
118
  end
113
119
 
@@ -115,6 +121,11 @@ module Dub
115
121
  has_enums? || has_defines?
116
122
  end
117
123
 
124
+ # FIXME: test
125
+ def has_functions?
126
+ members && members != []
127
+ end
128
+
118
129
  def has_enums?
119
130
  !@enums.empty?
120
131
  end
@@ -1,6 +1,6 @@
1
1
  module Dub
2
2
  module OptsParser
3
-
3
+ ENTRY_REGEXP = %r{^\s*([^:]+):\s*('[^']*'|"[^"]*")\s*,?\s*}m
4
4
  def self.extract_hash(xml)
5
5
  (xml/'simplesect').each do |x|
6
6
  if (x/'title').inner_html == 'Bindings info:'
@@ -17,8 +17,8 @@ module Dub
17
17
 
18
18
  def self.parse(src)
19
19
  res = {}
20
- while !src.empty?
21
- src = src.sub(/^\s*([^:]+):\s*('[^']+'|"[^"]+")\s*,?\s*/m) do
20
+ while !src.empty? && src =~ ENTRY_REGEXP
21
+ src = src.sub(ENTRY_REGEXP) do
22
22
  res[$1.to_sym] = $2[1..-2]
23
23
  ''
24
24
  end
data/lib/dub/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Dub
2
- VERSION = '0.6.6'
3
- end
2
+ VERSION = '0.7.0'
3
+ end
@@ -160,45 +160,49 @@ class ArgumentTest < Test::Unit::TestCase
160
160
  end
161
161
 
162
162
  context 'A bool argument' do
163
- setup do
163
+ subject do
164
164
  # namespacecv_xml = Dub.parse(fixture('namespacecv.xml'))
165
- @argument = namespacedub_xml[:dub][:Matrix][:do_something].arguments[1]
165
+ namespacedub_xml[:dub][:Matrix][:do_something].arguments[1]
166
+ end
167
+
168
+ should 'belong to the :boolean group' do
169
+ assert_equal :boolean, Dub::Argument.type_group(MockArgument.new('bool'))
166
170
  end
167
171
 
168
172
  should 'return type with type' do
169
- assert_equal 'bool', @argument.type
173
+ assert_equal 'bool', subject.type
170
174
  end
171
175
 
172
176
  should 'return name with name' do
173
- assert_equal 'fast', @argument.name
177
+ assert_equal 'fast', subject.name
174
178
  end
175
179
 
176
180
  should 'know if argument is const' do
177
- assert !@argument.is_const?
181
+ assert !subject.is_const?
178
182
  end
179
183
 
180
184
  should 'know if argument is passed by ref' do
181
- assert !@argument.is_ref?
185
+ assert !subject.is_ref?
182
186
  end
183
187
 
184
188
  should 'know that it is a pointer' do
185
- assert !@argument.is_pointer?
189
+ assert !subject.is_pointer?
186
190
  end
187
191
 
188
192
  should 'know if argument type is a native type' do
189
- assert @argument.is_native?
193
+ assert subject.is_native?
190
194
  end
191
195
 
192
196
  should 'return bool on create_type' do
193
- assert_equal 'bool ', @argument.create_type
197
+ assert_equal 'bool ', subject.create_type
194
198
  end
195
199
 
196
200
  should 'return signature' do
197
- assert_equal 'bool', @argument.signature
201
+ assert_equal 'bool', subject.signature
198
202
  end
199
203
 
200
204
  should 'return default value if it has one' do
201
- assert_equal 'false', @argument.default
205
+ assert_equal 'false', subject.default
202
206
  end
203
207
  end
204
208
 
@@ -229,7 +233,7 @@ class ArgumentTest < Test::Unit::TestCase
229
233
  end
230
234
 
231
235
  should 'not nest own namespace in type' do
232
- assert_match %r{luaL_checkudata\(L,\s*1,\s*\"std\.string\"}, @function.to_s
236
+ assert_match %r{luaL_checkudata\(L,\s*\d,\s*\"std\.string\"}, @function.to_s
233
237
  end
234
238
  end
235
239
  end
@@ -489,6 +493,36 @@ class ArgumentTest < Test::Unit::TestCase
489
493
  end
490
494
  end
491
495
 
496
+ context 'A pointer to a const char' do
497
+ setup do
498
+ @argument = namespacedub_xml[:dub][:Matrix][:name].return_value
499
+ end
500
+
501
+ should 'belong to the string group' do
502
+ assert_equal :string, Dub::Argument.type_group(MockArgument.new('char', 'char', true))
503
+ end
504
+
505
+ should 'know if argument is const' do
506
+ assert @argument.is_const?
507
+ end
508
+
509
+ should 'know if argument is passed by ref' do
510
+ assert !@argument.is_ref?
511
+ end
512
+
513
+ should 'know that it is a pointer' do
514
+ assert @argument.is_pointer?
515
+ end
516
+
517
+ should 'return the type without star' do
518
+ assert_equal 'char', @argument.type
519
+ end
520
+
521
+ should 'create a native type' do
522
+ assert_equal 'const char *', @argument.create_type
523
+ end
524
+ end
525
+
492
526
  context 'In a class defined from a template' do
493
527
  setup do
494
528
  @class = namespacecv_xml[:cv][:Scalar]
@@ -6,6 +6,7 @@
6
6
 
7
7
 
8
8
  /** @file */
9
+ typedef int LuaStackSize;
9
10
 
10
11
  namespace dub {
11
12
 
@@ -13,8 +14,12 @@ namespace dub {
13
14
  *
14
15
  * @dub var_from_dub:'dummy value'
15
16
  * other_from_dub: "some other value"
17
+ * ignore: 'bad_method'
16
18
  */
17
19
  class Matrix {
20
+
21
+ Q_PROPERTY(size_t foo_prop READ size)
22
+ Q_PROPERTY(size_t size READ size WRITE setSize)
18
23
  public:
19
24
  Matrix() : data_(NULL), rows_(0), cols_(0) {}
20
25
 
@@ -58,6 +63,14 @@ public:
58
63
 
59
64
  }
60
65
 
66
+ void do_something(int i, const char *baz) {
67
+ // overloaded member method
68
+ }
69
+
70
+ void bad_method(int i) {
71
+ // method should not exist in bindings
72
+ }
73
+
61
74
  void use_other_lib(const std::string &name) {
62
75
  // dummy
63
76
  }
@@ -66,10 +79,24 @@ public:
66
79
  // dummy
67
80
  }
68
81
 
82
+ bool true() {
83
+ // dummy
84
+ return true;
85
+ }
86
+
87
+ const char *name() {
88
+ // should make method return string
89
+ }
90
+
69
91
  int *lua_thing(int a, lua_State *L, int b) {
70
92
  // dummy
71
93
  }
72
94
 
95
+ LuaStackSize work_with_lua(int a, int b) {
96
+ // method that directly pushes lua values on the stack
97
+ return 2;
98
+ }
99
+
73
100
  /** Named constructor.
74
101
  */
75
102
  static Matrix *MakeMatrix(int rows, int cols) {
@@ -77,6 +104,9 @@ public:
77
104
  }
78
105
 
79
106
  private:
107
+ Matrix(int x) {
108
+ // private constructor
109
+ }
80
110
 
81
111
  int private_method() {
82
112
  // should not be implemented
@@ -96,6 +126,97 @@ protected:
96
126
  };
97
127
 
98
128
 
129
+ /** Test that private constructors are not used.
130
+ */
131
+ class PrivateConstr {
132
+ public:
133
+
134
+ PrivateConstr(int x) {}
135
+
136
+ ~PrivateConstr() {}
137
+
138
+ private:
139
+ // should not be used to build a FunctionGroup
140
+ PrivateConstr(const char *name) {}
141
+ };
142
+
143
+ /** Test that custom destructors are used.
144
+ * @dub destructor: 'dub_destroy'
145
+ */
146
+ class CustomDestructor : public DeletableOutOfLua
147
+ {
148
+ public:
149
+
150
+ CustomDestructor(int x) {}
151
+
152
+ ~CustomDestructor() {}
153
+
154
+ void do_this(int x) {
155
+
156
+ }
157
+ };
158
+
159
+ /** Test that no destructor option is used.
160
+ *
161
+ * @dub destructor: ''
162
+ */
163
+ class NoDestructor {
164
+ public:
165
+
166
+ NoDestructor(int x) {}
167
+
168
+ ~NoDestructor() {}
169
+ };
170
+
171
+ /** Test that we can use a static constructor.
172
+ * @dub constructor: 'MakeStaticConstr'
173
+ */
174
+ class StaticConstr {
175
+ public:
176
+
177
+ StaticConstr(int x) {}
178
+
179
+ ~StaticConstr() {}
180
+
181
+ // We usually want to push the userdata ourself in
182
+ // such cases.
183
+ static LuaStackSize MakeStaticConstr(lua_State *L) {
184
+ return 0; // fake error (nil return)
185
+ }
186
+ };
187
+
188
+ // class inheritence tests
189
+ class Base {
190
+ public:
191
+ Base() {}
192
+ ~Base() {}
193
+
194
+ const char *method_in_base(int x, float y) {
195
+ return "nothing";
196
+ }
197
+ };
198
+
199
+ // class inheritence tests
200
+ class SubBase : public Base {
201
+ public:
202
+ SubBase() {}
203
+ ~SubBase() {}
204
+
205
+ void method_in_sub(float y) {
206
+ return "nothing";
207
+ }
208
+ };
209
+
210
+ // class inheritence tests
211
+ class PrivSubBase : private Base {
212
+ public:
213
+ SubBase() {}
214
+ ~SubBase() {}
215
+
216
+ void method_in_sub(float y) {
217
+ return "nothing";
218
+ }
219
+ };
99
220
  template<class T>
100
221
  class TMat {
101
222
  public: