rbplusplus 0.9.1 → 1.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.
- data/Rakefile +4 -9
- data/lib/rbplusplus/builders/allocation_strategy.rb +0 -7
- data/lib/rbplusplus/builders/base.rb +11 -5
- data/lib/rbplusplus/builders/class.rb +5 -14
- data/lib/rbplusplus/builders/const.rb +1 -1
- data/lib/rbplusplus/builders/constructor.rb +1 -1
- data/lib/rbplusplus/builders/director.rb +13 -13
- data/lib/rbplusplus/builders/enumeration.rb +2 -2
- data/lib/rbplusplus/builders/helpers/class.rb +17 -2
- data/lib/rbplusplus/builders/helpers/implicit_caster.rb +0 -0
- data/lib/rbplusplus/builders/implicit_caster.rb +24 -0
- data/lib/rbplusplus/builders/instance_variable.rb +4 -4
- data/lib/rbplusplus/builders/method_base.rb +8 -7
- data/lib/rbplusplus/builders/module.rb +1 -1
- data/lib/rbplusplus/logger.rb +13 -4
- data/lib/rbplusplus/transformers/class.rb +43 -34
- data/lib/rbplusplus/transformers/constructor.rb +30 -0
- data/lib/rbplusplus/transformers/function.rb +3 -3
- data/lib/rbplusplus/transformers/method.rb +2 -2
- data/lib/rbplusplus/transformers/node.rb +10 -17
- data/lib/rbplusplus/writers/multiple_files_writer.rb +8 -6
- data/lib/rbplusplus.rb +2 -1
- data/test/allocation_strategies_test.rb +21 -14
- data/test/class_methods_encapsulate_test.rb +25 -25
- data/test/class_methods_test.rb +7 -12
- data/test/classes_test.rb +36 -40
- data/test/compiling_test.rb +23 -19
- data/test/constructors_test.rb +5 -5
- data/test/custom_code_test.rb +25 -32
- data/test/default_arguments_test.rb +38 -42
- data/test/director_test.rb +51 -53
- data/test/enumerations_test.rb +37 -41
- data/test/extension_test.rb +10 -10
- data/test/file_writers_test.rb +17 -21
- data/test/function_pointer_test.rb +9 -13
- data/test/function_pointers_classes_test.rb +7 -11
- data/test/functions_test.rb +4 -10
- data/test/generated/extconf.rb +2 -2
- data/test/headers/alloc_strats.h +3 -1
- data/test/headers/implicit_cast.h +107 -0
- data/test/headers/to_from_ruby.h +13 -6
- data/test/headers/to_from_ruby_source.cpp +2 -2
- data/test/implicit_cast_test.rb +67 -0
- data/test/modules_test.rb +39 -40
- data/test/nested_test.rb +14 -16
- data/test/overloading_test.rb +17 -20
- data/test/struct_test.rb +4 -6
- data/test/subclass_test.rb +10 -12
- data/test/test_helper.rb +21 -12
- data/test/to_from_ruby_test.rb +7 -1
- data/test/wrap_as_test.rb +32 -29
- metadata +170 -108
- data/lib/rbplusplus/transformers/node_cache.rb +0 -15
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ require 'rake/rdoctask'
|
|
3
3
|
require 'rake/contrib/sshpublisher'
|
4
4
|
|
5
5
|
PROJECT_NAME = "rb++"
|
6
|
-
RBPLUSPLUS_VERSION = "0
|
6
|
+
RBPLUSPLUS_VERSION = "1.0"
|
7
7
|
|
8
8
|
task :default => :test
|
9
9
|
|
@@ -70,14 +70,11 @@ spec = Gem::Specification.new do |s|
|
|
70
70
|
|
71
71
|
s.description = <<-END
|
72
72
|
Rb++ combines the powerful query interface of rbgccxml and the Rice library to
|
73
|
-
make Ruby wrapping extensions easier to write than ever.
|
73
|
+
make Ruby wrapping extensions of C++ libraries easier to write than ever.
|
74
74
|
END
|
75
75
|
|
76
|
-
s.add_dependency "rbgccxml", "~> 0
|
77
|
-
s.add_dependency "rice", "~> 1.
|
78
|
-
|
79
|
-
s.add_development_dependency "test-unit", "1.2.3"
|
80
|
-
s.add_development_dependency "mocha", "~> 0.9"
|
76
|
+
s.add_dependency "rbgccxml", "~> 1.0"
|
77
|
+
s.add_dependency "rice", "~> 1.4.0"
|
81
78
|
|
82
79
|
patterns = [
|
83
80
|
'TODO',
|
@@ -93,6 +90,4 @@ make Ruby wrapping extensions easier to write than ever.
|
|
93
90
|
end
|
94
91
|
|
95
92
|
Rake::GemPackageTask.new(spec) do |pkg|
|
96
|
-
pkg.need_zip = true
|
97
|
-
pkg.need_tar = true
|
98
93
|
end
|
@@ -27,7 +27,6 @@ module RbPlusPlus
|
|
27
27
|
namespace Rice {
|
28
28
|
template<>
|
29
29
|
struct Default_Allocation_Strategy< #{node_name} > {
|
30
|
-
static #{node_name} * allocate();
|
31
30
|
static void free(#{node_name} * obj);
|
32
31
|
};
|
33
32
|
}
|
@@ -37,12 +36,6 @@ namespace Rice {
|
|
37
36
|
|
38
37
|
pre = "Rice::Default_Allocation_Strategy< #{node_name} >::"
|
39
38
|
|
40
|
-
tmp = "#{node_name} * #{pre}allocate() { return "
|
41
|
-
tmp += @public_constructor ? "new #{node_name};" : "NULL;"
|
42
|
-
tmp += " }"
|
43
|
-
|
44
|
-
registrations << tmp
|
45
|
-
|
46
39
|
tmp = "void #{pre}free(#{node_name} * obj) { "
|
47
40
|
tmp += @public_destructor ? "delete obj;" : ""
|
48
41
|
tmp += " }"
|
@@ -64,8 +64,7 @@ module RbPlusPlus
|
|
64
64
|
raise "Nodes must implement #build"
|
65
65
|
end
|
66
66
|
|
67
|
-
# After #build has run, this then triggers the actual generation of the C++
|
68
|
-
# code and returns the final string.
|
67
|
+
# After #build has run, this then triggers the actual generation of the C++ code
|
69
68
|
# All nodes must implement this.
|
70
69
|
def write
|
71
70
|
raise "Nodes must implement #write"
|
@@ -84,7 +83,13 @@ module RbPlusPlus
|
|
84
83
|
# up sorted farther down the list
|
85
84
|
@nodes =
|
86
85
|
@nodes.sort_by do |a|
|
87
|
-
a.is_a?(ClassNode)
|
86
|
+
if a.is_a?(ClassNode)
|
87
|
+
superclass_count(a.code)
|
88
|
+
elsif a.is_a?(ImplicitCasterNode) # Hmm, hack
|
89
|
+
1_000_000
|
90
|
+
else
|
91
|
+
0
|
92
|
+
end
|
88
93
|
end
|
89
94
|
end
|
90
95
|
|
@@ -111,7 +116,8 @@ module RbPlusPlus
|
|
111
116
|
node.ignored? ||
|
112
117
|
(node.moved_to && node.moved_to != self.code) ||
|
113
118
|
!node.public? ||
|
114
|
-
(node.is_a?(RbGCCXML::Struct) && node.incomplete?)
|
119
|
+
(node.is_a?(RbGCCXML::Struct) && node.incomplete?) ||
|
120
|
+
node.is_a?(RbGCCXML::FundamentalType)
|
115
121
|
end
|
116
122
|
|
117
123
|
# Given a new node, build it and add it to our nodes list
|
@@ -142,7 +148,7 @@ module RbPlusPlus
|
|
142
148
|
if !node._disable_typedef_lookup?
|
143
149
|
while found
|
144
150
|
last_found = found
|
145
|
-
typedef = RbGCCXML::
|
151
|
+
typedef = RbGCCXML::NodeCache.all("Typedef").select {|t| t.attributes["type"] == found.attributes["id"]}.first
|
146
152
|
|
147
153
|
# Some typedefs have the access attribute, some don't. We want those without the attribute
|
148
154
|
# and those with the access="public". For this reason, we can't put :access => "public" in the
|
@@ -54,10 +54,6 @@ module RbPlusPlus
|
|
54
54
|
unless @director
|
55
55
|
check_allocation_strategies
|
56
56
|
end
|
57
|
-
|
58
|
-
# For now, build a const& type converter for all class types until Rice has
|
59
|
-
# better management of to_ruby of class types, if it ever happens
|
60
|
-
add_global_child ConstConverterNode.new(self.code, self)
|
61
57
|
end
|
62
58
|
|
63
59
|
def write
|
@@ -70,10 +66,10 @@ module RbPlusPlus
|
|
70
66
|
class_names = class_names.join(",")
|
71
67
|
|
72
68
|
if parent.rice_variable
|
73
|
-
registrations << "#{prefix} Rice::define_class_under< #{class_names} >" +
|
69
|
+
registrations << "\t#{prefix} Rice::define_class_under< #{class_names} >" +
|
74
70
|
"(#{parent.rice_variable}, \"#{ruby_name}\");"
|
75
71
|
else
|
76
|
-
registrations << "#{prefix} Rice::define_class< #{class_names} >(\"#{ruby_name}\");"
|
72
|
+
registrations << "\t#{prefix} Rice::define_class< #{class_names} >(\"#{ruby_name}\");"
|
77
73
|
end
|
78
74
|
|
79
75
|
handle_custom_code
|
@@ -83,7 +79,6 @@ module RbPlusPlus
|
|
83
79
|
|
84
80
|
# Here we take the code manually added to the extension via #add_custom_code
|
85
81
|
def handle_custom_code
|
86
|
-
|
87
82
|
# Any declaration code, usually wrapper function definitions
|
88
83
|
self.code._get_custom_declarations.flatten.each do |decl|
|
89
84
|
declarations << decl
|
@@ -91,7 +86,7 @@ module RbPlusPlus
|
|
91
86
|
|
92
87
|
# And the registration code to hook into Rice
|
93
88
|
self.code._get_custom_wrappings.flatten.each do |wrap|
|
94
|
-
registrations << "#{wrap.gsub(/<class>/, self.rice_variable)}"
|
89
|
+
registrations << "\t#{wrap.gsub(/<class>/, self.rice_variable)}"
|
95
90
|
end
|
96
91
|
end
|
97
92
|
|
@@ -105,16 +100,12 @@ module RbPlusPlus
|
|
105
100
|
# We check here if we're one of those classes and completely skip this step
|
106
101
|
return if [self.code.constructors].flatten.empty?
|
107
102
|
|
108
|
-
# Find a public default constructor
|
109
|
-
found = [self.code.constructors.find(:arguments => [], :access => "public")].flatten
|
110
|
-
has_public_constructor = !found.empty?
|
111
|
-
|
112
103
|
# See if the destructor is public
|
113
104
|
has_public_destructor = self.code.destructor && self.code.destructor.public?
|
114
105
|
|
115
|
-
if !
|
106
|
+
if !has_public_destructor
|
116
107
|
add_global_child AllocationStrategyNode.new(self,
|
117
|
-
self.code,
|
108
|
+
self.code, true, has_public_destructor)
|
118
109
|
end
|
119
110
|
end
|
120
111
|
|
@@ -20,7 +20,7 @@ module RbPlusPlus
|
|
20
20
|
end
|
21
21
|
|
22
22
|
prefix = parent.rice_variable ? "#{parent.rice_variable}." : "Rice::Module(rb_mKernel)."
|
23
|
-
registrations << "#{prefix}const_set(\"#{code.name}\", to_ruby(#{set_to}));"
|
23
|
+
registrations << "\t#{prefix}const_set(\"#{code.name}\", to_ruby(#{set_to}));"
|
24
24
|
end
|
25
25
|
|
26
26
|
end
|
@@ -10,7 +10,7 @@ module RbPlusPlus
|
|
10
10
|
|
11
11
|
def write
|
12
12
|
args = [code.parent.qualified_name, code.arguments.map {|a| a.cpp_type.to_cpp }].flatten.compact
|
13
|
-
registrations << "#{parent.rice_variable}.define_constructor(Rice::Constructor< #{args.join(",")} >());"
|
13
|
+
registrations << "\t#{parent.rice_variable}.define_constructor(Rice::Constructor< #{args.join(",")} >());"
|
14
14
|
end
|
15
15
|
|
16
16
|
end
|
@@ -27,7 +27,7 @@ module RbPlusPlus
|
|
27
27
|
def build
|
28
28
|
add_child IncludeNode.new(self, "rice/Director.hpp", :global)
|
29
29
|
add_child IncludeNode.new(self, "rice/Constructor.hpp", :global)
|
30
|
-
|
30
|
+
|
31
31
|
# To ensure proper compilation, this director class needs
|
32
32
|
# to implement all pure virtual methods found up the
|
33
33
|
# inheritance heirarchy of this class. So here, we traverse
|
@@ -68,15 +68,15 @@ module RbPlusPlus
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
declarations << "#{@name}(#{args.join(", ")}) : #{@class_qualified_name}(#{supercall_args.join(", ")}), Rice::Director(self) { }"
|
71
|
+
declarations << "\t\t#{@name}(#{args.join(", ")}) : #{@class_qualified_name}(#{supercall_args.join(", ")}), Rice::Director(self) { }"
|
72
72
|
|
73
|
-
registrations << "#{self.parent.rice_variable}.define_director< #{@name} >();"
|
74
|
-
registrations << "#{self.parent.rice_variable}.define_constructor(Rice::Constructor< #{types.join(", ")} >());"
|
73
|
+
registrations << "\t#{self.parent.rice_variable}.define_director< #{@name} >();"
|
74
|
+
registrations << "\t#{self.parent.rice_variable}.define_constructor(Rice::Constructor< #{types.join(", ")} >());"
|
75
75
|
end
|
76
76
|
|
77
77
|
def write
|
78
78
|
declarations << "class #{@name} : public #{@class_qualified_name}, public Rice::Director {"
|
79
|
-
declarations << "
|
79
|
+
declarations << "\tpublic:"
|
80
80
|
|
81
81
|
# Handle constructors
|
82
82
|
if @constructors.empty?
|
@@ -104,7 +104,7 @@ module RbPlusPlus
|
|
104
104
|
def_arguments = def_arguments.length == 0 ? "" : def_arguments.join(", ")
|
105
105
|
|
106
106
|
reverse = ""
|
107
|
-
up_or_raise =
|
107
|
+
up_or_raise =
|
108
108
|
if method.default_return_value
|
109
109
|
reverse = "!"
|
110
110
|
"return #{method.default_return_value}"
|
@@ -123,17 +123,17 @@ module RbPlusPlus
|
|
123
123
|
|
124
124
|
# Write out the virtual method that forwards calls into Ruby
|
125
125
|
declarations << ""
|
126
|
-
declarations << "
|
127
|
-
declarations << "#{call_down};"
|
128
|
-
declarations << "}"
|
126
|
+
declarations << "\t\tvirtual #{return_type} #{cpp_name}(#{def_arguments}) #{const} {"
|
127
|
+
declarations << "\t\t\t#{call_down};"
|
128
|
+
declarations << "\t\t}"
|
129
129
|
|
130
130
|
# Write out the wrapper method that gets exposed to Ruby that handles
|
131
131
|
# going up the inheritance chain
|
132
132
|
declarations << ""
|
133
|
-
declarations << "#{return_type} default_#{cpp_name}(#{def_arguments}) #{const} {"
|
134
|
-
declarations << "#{up_or_raise};"
|
135
|
-
declarations << "}"
|
136
|
-
|
133
|
+
declarations << "\t\t#{return_type} default_#{cpp_name}(#{def_arguments}) #{const} {"
|
134
|
+
declarations << "\t\t\t#{up_or_raise};"
|
135
|
+
declarations << "\t\t}"
|
136
|
+
|
137
137
|
end
|
138
138
|
|
139
139
|
declarations << "};"
|
@@ -20,11 +20,11 @@ module RbPlusPlus
|
|
20
20
|
def write
|
21
21
|
second = parent.rice_variable ? ", #{parent.rice_variable}" : ""
|
22
22
|
|
23
|
-
registrations << "#{rice_variable_type} #{rice_variable} = " \
|
23
|
+
registrations << "\t#{rice_variable_type} #{rice_variable} = " \
|
24
24
|
"Rice::define_enum<#{code.qualified_name}>(\"#{code.name}\"#{second});"
|
25
25
|
|
26
26
|
code.values.each do |v|
|
27
|
-
registrations << "#{rice_variable}.define_value(\"#{v.name}\", #{v.qualified_name});"
|
27
|
+
registrations << "\t#{rice_variable}.define_value(\"#{v.name}\", #{v.qualified_name});"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -35,8 +35,6 @@ module RbPlusPlus
|
|
35
35
|
"please use #use_contructor to select which one to use."
|
36
36
|
end
|
37
37
|
|
38
|
-
# First, lets see if we have any non-generated constructors
|
39
|
-
|
40
38
|
[to_use || real_constructors].flatten.each do |constructor|
|
41
39
|
next if do_not_wrap?(constructor)
|
42
40
|
|
@@ -44,6 +42,15 @@ module RbPlusPlus
|
|
44
42
|
next if ignore_artificial || constructor.arguments.length == 1
|
45
43
|
end
|
46
44
|
|
45
|
+
if implicit_converter?(constructor)
|
46
|
+
if constructor.implicit_casting?
|
47
|
+
parent.add_child ImplicitCasterNode.new(constructor, self)
|
48
|
+
end
|
49
|
+
|
50
|
+
# We don't want to expose these constructors to Rice
|
51
|
+
next
|
52
|
+
end
|
53
|
+
|
47
54
|
if @director
|
48
55
|
@director.wrap_constructor constructor
|
49
56
|
else
|
@@ -52,6 +59,14 @@ module RbPlusPlus
|
|
52
59
|
end
|
53
60
|
end
|
54
61
|
|
62
|
+
# Is this constructor a converter constructor?
|
63
|
+
def implicit_converter?(constructor)
|
64
|
+
# Single argument
|
65
|
+
constructor.arguments.length == 1 &&
|
66
|
+
# We are wrapping the type converting from
|
67
|
+
!do_not_wrap?(constructor.arguments[0].cpp_type.base_type)
|
68
|
+
end
|
69
|
+
|
55
70
|
# Wrap up any class constants
|
56
71
|
def with_constants
|
57
72
|
[self.code.constants].flatten.each do |const|
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RbPlusPlus
|
2
|
+
module Builders
|
3
|
+
|
4
|
+
class ImplicitCasterNode < Base
|
5
|
+
|
6
|
+
def initialize(constructor, parent)
|
7
|
+
super(constructor, parent)
|
8
|
+
|
9
|
+
@to = parent.code.qualified_name
|
10
|
+
@from = constructor.arguments[0].cpp_type.base_type.qualified_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def build
|
14
|
+
end
|
15
|
+
|
16
|
+
def write
|
17
|
+
if @from != @to
|
18
|
+
registrations << "\tRice::define_implicit_cast< #{@from}, #{@to} >();"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -15,19 +15,19 @@ module RbPlusPlus
|
|
15
15
|
if !code.cpp_type.const?
|
16
16
|
method_name = "wrap_#{parent_name}_#{code.name}_set"
|
17
17
|
declarations << "void #{method_name}(#{parent.code.qualified_name}* self, #{code.cpp_type.to_cpp} val) {"
|
18
|
-
declarations << "
|
18
|
+
declarations << "\tself->#{code.name} = val;"
|
19
19
|
declarations << "}"
|
20
20
|
|
21
|
-
registrations << "#{parent.rice_variable}.define_method(\"#{ruby_name}=\", &#{method_name});"
|
21
|
+
registrations << "\t#{parent.rice_variable}.define_method(\"#{ruby_name}=\", &#{method_name});"
|
22
22
|
end
|
23
23
|
|
24
24
|
# Getter
|
25
25
|
method_name = "wrap_#{parent_name}_#{code.name}_get"
|
26
26
|
declarations << "#{code.cpp_type.to_cpp} #{method_name}(#{parent.code.qualified_name}* self) {"
|
27
|
-
declarations << "
|
27
|
+
declarations << "\treturn self->#{code.name};"
|
28
28
|
declarations << "}"
|
29
29
|
|
30
|
-
registrations << "#{parent.rice_variable}.define_method(\"#{ruby_name}\", &#{method_name});"
|
30
|
+
registrations << "\t#{parent.rice_variable}.define_method(\"#{ruby_name}\", &#{method_name});"
|
31
31
|
end
|
32
32
|
|
33
33
|
end
|
@@ -72,9 +72,9 @@ module RbPlusPlus
|
|
72
72
|
|
73
73
|
funcall = "rb_funcall(#{block_var_name}, rb_intern(\"call\"), #{callback_values.join(", ")})"
|
74
74
|
if return_type == "void"
|
75
|
-
declarations << "#{funcall};"
|
75
|
+
declarations << "\t#{funcall};"
|
76
76
|
else
|
77
|
-
declarations << "
|
77
|
+
declarations << "\treturn from_ruby<#{return_type} >(#{funcall});"
|
78
78
|
end
|
79
79
|
|
80
80
|
declarations << "}"
|
@@ -96,7 +96,7 @@ module RbPlusPlus
|
|
96
96
|
declarations << "\treturn Qnil;"
|
97
97
|
declarations << "}"
|
98
98
|
|
99
|
-
registrations << "#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", &#{wrapper_func});"
|
99
|
+
registrations << "\t#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", &#{wrapper_func});"
|
100
100
|
end
|
101
101
|
|
102
102
|
def wrap_normal_method
|
@@ -137,13 +137,14 @@ module RbPlusPlus
|
|
137
137
|
|
138
138
|
const = self.code.const? ? " const" : ""
|
139
139
|
|
140
|
-
registrations << "
|
140
|
+
registrations << ""
|
141
|
+
registrations << "\t{"
|
141
142
|
|
142
|
-
registrations << "
|
143
|
-
registrations << "#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", " +
|
143
|
+
registrations << "\t\ttypedef #{return_type} ( #{method_ref} )( #{arguments.join(", ")} )#{const};"
|
144
|
+
registrations << "\t\t#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", " +
|
144
145
|
"#{usage_ref}( &#{code_path} )#{def_args});"
|
145
146
|
|
146
|
-
registrations << "}"
|
147
|
+
registrations << "\t}"
|
147
148
|
end
|
148
149
|
|
149
150
|
# See http://www.gccxml.org/Bug/view.php?id=9234
|
@@ -45,7 +45,7 @@ module RbPlusPlus
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def write
|
48
|
-
prefix = "#{rice_variable_type} #{rice_variable} = "
|
48
|
+
prefix = "\t#{rice_variable_type} #{rice_variable} = "
|
49
49
|
|
50
50
|
if parent.rice_variable
|
51
51
|
registrations << "#{prefix} Rice::define_module_under(#{parent.rice_variable}, \"#{@name}\");"
|
data/lib/rbplusplus/logger.rb
CHANGED
@@ -15,6 +15,10 @@ module RbPlusPlus
|
|
15
15
|
@@quiet = val
|
16
16
|
end
|
17
17
|
|
18
|
+
def silent!
|
19
|
+
@@silent = true
|
20
|
+
end
|
21
|
+
|
18
22
|
def verbose?
|
19
23
|
@@verbose = false unless defined?(@@verbose)
|
20
24
|
@@verbose
|
@@ -25,20 +29,25 @@ module RbPlusPlus
|
|
25
29
|
@@quiet
|
26
30
|
end
|
27
31
|
|
32
|
+
def silent?
|
33
|
+
@@silent = false unless defined?(@@silent)
|
34
|
+
@@silent
|
35
|
+
end
|
36
|
+
|
28
37
|
def info(msg)
|
29
|
-
$stdout.puts "(INFO) #{msg}"
|
38
|
+
$stdout.puts "(INFO) #{msg}" if !quiet? && !silent?
|
30
39
|
end
|
31
40
|
|
32
41
|
def warn(type, msg)
|
33
|
-
$stdout.puts "(WARNING) #{msg}"
|
42
|
+
$stdout.puts "(WARNING) #{msg}" if !silent?
|
34
43
|
end
|
35
44
|
|
36
45
|
def debug(msg)
|
37
|
-
$stdout.puts "(DEBUG) #{msg}" if verbose?
|
46
|
+
$stdout.puts "(DEBUG) #{msg}" if verbose? && !silent?
|
38
47
|
end
|
39
48
|
|
40
49
|
def error(msg)
|
41
|
-
$stderr.puts "(ERROR) #{msg}"
|
50
|
+
$stderr.puts "(ERROR) #{msg}" if !silent?
|
42
51
|
end
|
43
52
|
end
|
44
53
|
end
|
@@ -1,11 +1,22 @@
|
|
1
1
|
module RbGCCXML
|
2
2
|
class Class < Node
|
3
|
+
|
4
|
+
def initialize(*args)
|
5
|
+
super
|
6
|
+
|
7
|
+
@included_classes = []
|
8
|
+
@included_methods = []
|
9
|
+
|
10
|
+
@declarations = []
|
11
|
+
@wrappings = []
|
12
|
+
end
|
13
|
+
|
3
14
|
# Class can include nested classes and nested structs.
|
4
15
|
#
|
5
16
|
# Class can also include external methods/functions as class level methods
|
6
17
|
# also supports instance level methods
|
7
18
|
#
|
8
|
-
# ex.
|
19
|
+
# ex.
|
9
20
|
#
|
10
21
|
# math_class.includes node.namespaces("Math").functions("mod")
|
11
22
|
#
|
@@ -19,23 +30,21 @@ module RbGCCXML
|
|
19
30
|
#
|
20
31
|
def includes(val)
|
21
32
|
if (val.is_a?(RbGCCXML::Struct) || val.is_a?(RbGCCXML::Class))
|
22
|
-
|
23
|
-
cache[:classes] << val
|
33
|
+
@included_classes << val
|
24
34
|
else
|
25
|
-
|
26
|
-
cache[:methods] << val
|
35
|
+
@included_methods << val
|
27
36
|
end
|
28
37
|
val.moved_to = self
|
29
38
|
end
|
30
|
-
|
39
|
+
|
31
40
|
alias_method :node_classes, :classes
|
32
41
|
def classes(*args) #:nodoc:
|
33
|
-
|
42
|
+
find_with(node_classes(*args), @included_classes)
|
34
43
|
end
|
35
44
|
|
36
45
|
alias_method :node_methods, :methods
|
37
46
|
def methods(*args) #:nodoc:
|
38
|
-
|
47
|
+
find_with(node_methods(*args), @included_methods)
|
39
48
|
end
|
40
49
|
|
41
50
|
# Specify which superclass to use.
|
@@ -45,42 +54,42 @@ module RbGCCXML
|
|
45
54
|
# where this method hasn't been used yet.
|
46
55
|
#
|
47
56
|
# klass should be the node for the class you want to wrap
|
48
|
-
def use_superclass(
|
49
|
-
|
57
|
+
def use_superclass(klass)
|
58
|
+
@use_superclass = klass
|
50
59
|
end
|
51
60
|
|
52
61
|
def _get_superclass #:nodoc:
|
53
|
-
|
62
|
+
@use_superclass
|
54
63
|
end
|
55
64
|
|
56
|
-
# Like #use_superclass, this method allows the user to specify
|
57
|
-
# which constructor Rice should expose to Ruby.
|
58
|
-
# Rice currently, because of the lack of method overloading,
|
65
|
+
# Like #use_superclass, this method allows the user to specify
|
66
|
+
# which constructor Rice should expose to Ruby.
|
67
|
+
# Rice currently, because of the lack of method overloading,
|
59
68
|
# only supports one constructor definition. Having multiple
|
60
69
|
# in the code will work, but only the last defined will actually
|
61
|
-
# work.
|
70
|
+
# work.
|
62
71
|
def use_constructor(node)
|
63
|
-
|
72
|
+
@use_constructor = node
|
64
73
|
end
|
65
74
|
|
66
75
|
def _get_constructor #:nodoc:
|
67
|
-
|
76
|
+
@use_constructor
|
68
77
|
end
|
69
78
|
|
70
79
|
# Sometimes, type manipulation, moving nodes around, or flat
|
71
80
|
# ignoring nodes just doesn't do the trick and you need to write
|
72
81
|
# your own custom wrapper code. This method is for that. There are
|
73
|
-
# two parts to custom code: the declaration and the wrapping.
|
82
|
+
# two parts to custom code: the declaration and the wrapping.
|
74
83
|
#
|
75
84
|
# The Declaration:
|
76
85
|
# This is the actual custom code you write. It may need to take
|
77
86
|
# a pointer to the class type as the first parameter
|
78
|
-
# and follow with that any parameters you want.
|
87
|
+
# and follow with that any parameters you want.
|
79
88
|
#
|
80
89
|
# The Wrapping
|
81
90
|
# The wrapping is the custom (usually one-line) bit of Rice code that
|
82
91
|
# hooks up your declaration with the class in question. To ensure that
|
83
|
-
# you doesn't need to know the variable of the ruby class object,
|
92
|
+
# you doesn't need to know the variable of the ruby class object,
|
84
93
|
# use <class> and rb++ will replace it as needed.
|
85
94
|
#
|
86
95
|
# Example (taken from Ogre.rb's wrapping of Ogre)
|
@@ -100,45 +109,45 @@ module RbGCCXML
|
|
100
109
|
# of times for a class, it won't clobber any previous uses.
|
101
110
|
#
|
102
111
|
def add_custom_code(declaration, wrapping)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
cache[:wrappings] ||= []
|
107
|
-
cache[:wrappings] << wrapping
|
112
|
+
@declarations << declaration
|
113
|
+
@wrappings << wrapping
|
108
114
|
end
|
109
115
|
|
110
116
|
def _get_custom_declarations #:nodoc:
|
111
|
-
|
117
|
+
@declarations
|
112
118
|
end
|
113
119
|
|
114
120
|
def _get_custom_wrappings #:nodoc:
|
115
|
-
|
121
|
+
@wrappings
|
116
122
|
end
|
117
123
|
|
118
124
|
# Does this class have virtual methods (especially pure virtual?)
|
119
|
-
# If so, then rb++ will generate a proxy class to handle
|
125
|
+
# If so, then rb++ will generate a proxy class to handle
|
120
126
|
# the message routing as needed.
|
121
127
|
def needs_director? #:nodoc:
|
122
|
-
|
128
|
+
!!@build_director
|
123
129
|
end
|
124
130
|
|
125
131
|
# Until all the kinks of the director code generation can be
|
126
132
|
# worked out, rb++ must be told which classes to build
|
127
133
|
# directors for. Simply call this method on the class to do so
|
128
134
|
def director
|
129
|
-
|
135
|
+
@build_director = true
|
136
|
+
end
|
137
|
+
|
138
|
+
# See RbGCCXML::Constructor::implicit_casting
|
139
|
+
def implicit_casting(state)
|
140
|
+
self.constructors.each {|c| c.implicit_casting(state) }
|
130
141
|
end
|
131
142
|
|
132
143
|
private
|
133
144
|
|
134
145
|
# Take the cache key, and the normal results, adds to the results
|
135
146
|
# those that are in the cache and returns them properly.
|
136
|
-
def
|
137
|
-
in_cache = cache[type]
|
138
|
-
|
147
|
+
def find_with(results, with = nil)
|
139
148
|
ret = QueryResult.new
|
140
149
|
ret << results if results
|
141
|
-
ret <<
|
150
|
+
ret << with if with
|
142
151
|
ret.flatten!
|
143
152
|
|
144
153
|
ret.size == 1 ? ret[0] : ret
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RbGCCXML
|
2
|
+
class Constructor < Function
|
3
|
+
|
4
|
+
# See:
|
5
|
+
# http://msdn.microsoft.com/en-us/library/h1y7x448.aspx
|
6
|
+
# http://msdn.microsoft.com/en-us/library/s2ff0fz8(VS.100).aspx
|
7
|
+
#
|
8
|
+
# Single argument constructors of a class are called Conversion constructors.
|
9
|
+
# They manage the conversion of one type to another. Rice handles this functionality
|
10
|
+
# through a special method, define_implicit_cast<From, To>().
|
11
|
+
#
|
12
|
+
# Rb++ attempts to find all classes and constructors that fit this pattern
|
13
|
+
# and write out the casting declarations as needed. In the cases where this is
|
14
|
+
# functionality not wanted, use this method to turn off this casting check.
|
15
|
+
#
|
16
|
+
# This method can be called per Constructor or per Class.
|
17
|
+
def implicit_casting(state)
|
18
|
+
@implicit_casting = state
|
19
|
+
end
|
20
|
+
|
21
|
+
def implicit_casting? #:nodoc:
|
22
|
+
if @implicit_casting.nil?
|
23
|
+
@implicit_casting = true
|
24
|
+
end
|
25
|
+
|
26
|
+
@implicit_casting
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -2,19 +2,19 @@ module RbGCCXML
|
|
2
2
|
class Function < Node
|
3
3
|
# Always true for functions, false for methods
|
4
4
|
def static?
|
5
|
-
|
5
|
+
!@as_method
|
6
6
|
end
|
7
7
|
|
8
8
|
# Sets this function to be an instance method.
|
9
9
|
# Useful for custom function declaration.
|
10
10
|
def as_instance_method
|
11
|
-
|
11
|
+
@as_method = true
|
12
12
|
self
|
13
13
|
end
|
14
14
|
|
15
15
|
# Are we wrapping this function as an instance method?
|
16
16
|
def as_instance_method?
|
17
|
-
|
17
|
+
!!@as_method
|
18
18
|
end
|
19
19
|
|
20
20
|
# For Class#needs_director?
|