rbplusplus 0.8 → 0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/Rakefile +13 -13
  2. data/TODO +9 -41
  3. data/lib/rbplusplus/builders/allocation_strategy.rb +57 -0
  4. data/lib/rbplusplus/builders/base.rb +115 -212
  5. data/lib/rbplusplus/builders/class.rb +129 -115
  6. data/lib/rbplusplus/builders/const.rb +30 -0
  7. data/lib/rbplusplus/builders/const_converter.rb +52 -0
  8. data/lib/rbplusplus/builders/constructor.rb +19 -0
  9. data/lib/rbplusplus/builders/director.rb +149 -0
  10. data/lib/rbplusplus/builders/director_method.rb +20 -0
  11. data/lib/rbplusplus/builders/enumeration.rb +19 -26
  12. data/lib/rbplusplus/builders/extension.rb +42 -54
  13. data/lib/rbplusplus/builders/global_function.rb +18 -0
  14. data/lib/rbplusplus/builders/helpers/class.rb +74 -0
  15. data/lib/rbplusplus/builders/helpers/enumeration.rb +28 -0
  16. data/lib/rbplusplus/builders/helpers/module.rb +22 -0
  17. data/lib/rbplusplus/builders/include.rb +32 -0
  18. data/lib/rbplusplus/builders/instance_variable.rb +36 -0
  19. data/lib/rbplusplus/builders/method.rb +14 -0
  20. data/lib/rbplusplus/builders/method_base.rb +136 -0
  21. data/lib/rbplusplus/builders/module.rb +37 -51
  22. data/lib/rbplusplus/builders/module_function.rb +16 -0
  23. data/lib/rbplusplus/builders/static_method.rb +14 -0
  24. data/lib/rbplusplus/extension.rb +140 -28
  25. data/lib/rbplusplus/logger.rb +45 -0
  26. data/lib/rbplusplus/module.rb +55 -1
  27. data/lib/rbplusplus/transformers/class.rb +116 -35
  28. data/lib/rbplusplus/transformers/function.rb +14 -16
  29. data/lib/rbplusplus/transformers/method.rb +26 -1
  30. data/lib/rbplusplus/transformers/namespace.rb +12 -0
  31. data/lib/rbplusplus/transformers/node.rb +47 -54
  32. data/lib/rbplusplus/transformers/node_cache.rb +5 -9
  33. data/lib/rbplusplus/writers/multiple_files_writer.rb +290 -88
  34. data/lib/rbplusplus/writers/single_file_writer.rb +36 -14
  35. data/lib/rbplusplus.rb +44 -18
  36. data/test/allocation_strategies_test.rb +33 -0
  37. data/test/class_methods_encapsulate_test.rb +59 -0
  38. data/test/class_methods_test.rb +2 -35
  39. data/test/classes_test.rb +72 -2
  40. data/test/compiling_test.rb +13 -0
  41. data/test/constructors_test.rb +9 -18
  42. data/test/custom_code_test.rb +53 -0
  43. data/test/default_arguments_test.rb +69 -0
  44. data/test/director_test.rb +173 -0
  45. data/test/enumerations_test.rb +29 -0
  46. data/test/extension_test.rb +7 -2
  47. data/test/file_writers_test.rb +11 -4
  48. data/test/function_pointer_test.rb +56 -0
  49. data/test/function_pointers_classes_test.rb +27 -0
  50. data/test/generated/extconf.rb +2 -2
  51. data/test/headers/Adder.cpp +8 -0
  52. data/test/headers/Adder.h +31 -1
  53. data/test/headers/alloc_strats.h +26 -0
  54. data/test/headers/class_methods.h +30 -0
  55. data/test/headers/code/custom_to_from_ruby.cpp +11 -0
  56. data/test/headers/code/custom_to_from_ruby.hpp +13 -0
  57. data/test/headers/constructors.h +8 -20
  58. data/test/headers/default_arguments.h +49 -0
  59. data/test/headers/director.h +148 -0
  60. data/test/headers/enums.h +33 -0
  61. data/test/headers/function_pointers.h +32 -0
  62. data/test/headers/function_pointers_class.h +26 -0
  63. data/test/headers/needs_code.h +10 -0
  64. data/test/headers/overload.h +0 -3
  65. data/test/headers/subclass.h +10 -0
  66. data/test/headers/to_from_ruby.h +6 -4
  67. data/test/headers/ugly_interface.h +4 -7
  68. data/test/modules_test.rb +11 -6
  69. data/test/overloading_test.rb +6 -2
  70. data/test/subclass_test.rb +20 -10
  71. data/test/test_helper.rb +6 -1
  72. data/test/to_from_ruby_test.rb +0 -2
  73. data/test/wrap_as_test.rb +28 -37
  74. metadata +89 -57
  75. data/lib/rbplusplus/builders/types_manager.rb +0 -93
  76. data/lib/rbplusplus/transformers/constructor.rb +0 -4
  77. data/lib/rbplusplus/transformers/module.rb +0 -71
  78. data/lib/rbplusplus/transformers/node_reference.rb +0 -30
  79. data/test/headers/ugly_helper.h +0 -18
  80. data/test/object_persistence_test.rb +0 -44
@@ -1,73 +1,61 @@
1
1
  module RbPlusPlus
2
2
  module Builders
3
3
 
4
- # This class takes in all classes to be wrapped and builds
5
- # the top-level extension Init code
6
- class ExtensionBuilder < Base
7
-
8
- # Need to be given the list of modules as they are a special case
9
- attr_accessor :modules
4
+ # Extension node.
5
+ # There is only ever one of these in a project as this is
6
+ # the top level node for building a Ruby extension.
7
+ #
8
+ # Extensions are effectively Modules with some slightly different
9
+ # symantics, in that they expose to Kernel and have slightly
10
+ # different function handling and code generation.
11
+ class ExtensionNode < ModuleNode
10
12
 
11
- def build
12
- includes << "#include <rice/global_function.hpp>"
13
+ attr_reader :additional_includes
13
14
 
14
- add_additional_includes
15
+ def initialize(name, code, modules)
16
+ self.name = name
17
+ self.modules = modules
15
18
 
16
- body << "extern \"C\""
17
- body << "void Init_#{@name}() {"
19
+ @additional_includes = []
18
20
 
19
- # Explicitly ignore anything from the :: namespace
20
- if @node.name != "::"
21
-
22
- #Build a hash table to handle overloaded functions
23
- func_hash = {}
24
- @node.functions.each do |func|
25
- next if func.ignored? || func.moved?
26
-
27
- func_hash[func.name] ||= []
28
- func_hash[func.name] << func
29
- end
30
- #Iterate through the hash table to handle overloaded functions
31
- func_hash.each do |key, funcs|
32
- funcs.each_with_index do |func, i|
33
- add_includes_for func
34
-
35
- #append _#{i} to overloaded methods
36
- #this needs to be done in both the wrapper function and the ruby function
37
- func_append = ""
38
- func_append = "_#{i}" if funcs.size > 1
39
- wrapper_name = func.special_qualified_name || build_function_wrapper(func, func_append)
21
+ super(code, nil)
22
+ end
40
23
 
41
- if func.return_type.const? || func.const?
42
- TypesManager.build_const_converter(func.return_type)
43
- end
24
+ def qualified_name
25
+ name
26
+ end
44
27
 
45
- ruby_name = "#{Inflector.underscore(func.name)}#{func_append}"
46
- body << "\tdefine_global_function(\"#{ruby_name}\", &#{wrapper_name});"
47
- end
48
- end
49
-
50
- build_enumerations
51
- build_classes
28
+ def add_includes(includes)
29
+ @additional_includes << includes
30
+ includes.each do |inc|
31
+ add_child IncludeNode.new(self, inc)
52
32
  end
33
+ end
34
+
35
+ def build
36
+ super
37
+ self.rice_variable = nil
38
+ self.rice_variable_type = nil
39
+ end
53
40
 
54
- build_modules
41
+ def write
42
+ # Let nodes build their code, splitting up code blocks into
43
+ # includes, declarations, and registrations,
44
+ # then wrap it up in our own template
45
+ registrations << "extern \"C\""
46
+ registrations << "void Init_#{@name}() {"
55
47
  end
56
48
 
57
- def build_modules
58
- @modules.each do |mod|
59
- builder = ModuleBuilder.new(self, mod)
60
- builder.build
61
- builders << builder
49
+ private
50
+
51
+ def with_module_functions
52
+ @code.functions.each do |func|
53
+ next if do_not_wrap?(func)
54
+ add_child GlobalFunctionNode.new(func, self)
62
55
  end
63
56
  end
64
57
 
65
- # Finish up the required code before doing final output
66
- def to_s
67
- includes << "using namespace Rice;"
68
-
69
- super + "\n}"
70
- end
71
58
  end
59
+
72
60
  end
73
61
  end
@@ -0,0 +1,18 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Expose a global function
5
+ class GlobalFunctionNode < MethodBase
6
+
7
+ def build
8
+ add_child IncludeNode.new(self, "rice/global_function.hpp", :system)
9
+ add_child IncludeNode.new(self, code.file)
10
+
11
+ self.prefix = "Rice::"
12
+ self.rice_method = "define_global_function"
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,74 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+ module ClassHelpers
4
+
5
+ # Build up any classes or structs under this module
6
+ def with_classes
7
+ [
8
+ self.code.classes,
9
+ self.code.structs
10
+ ].flatten.each do |klass|
11
+ next if do_not_wrap?(klass)
12
+ add_child ClassNode.new(klass, self)
13
+ end
14
+ end
15
+
16
+ # Wrap any constructors for this class
17
+ def with_constructors
18
+ # Ignore constructors on classes that have pure virtual methods,
19
+ # as they aren't constructable
20
+ return if !@director && self.code.pure_virtual?
21
+
22
+ to_use = self.code._get_constructor
23
+
24
+ real_constructors = [self.code.constructors].flatten.select {|c| !c.attributes[:artificial]}
25
+
26
+ if real_constructors.empty?
27
+ real_constructors = self.code.constructors
28
+ else
29
+ ignore_artificial = true
30
+ end
31
+
32
+ if to_use.nil? && real_constructors.length > 1
33
+ Logger.warn :multiple_constructors, "#{self.code.qualified_name} has multiple constructors. " +
34
+ "While the extension will probably compile, Rice only supports one constructor, " +
35
+ "please use #use_contructor to select which one to use."
36
+ end
37
+
38
+ # First, lets see if we have any non-generated constructors
39
+
40
+ [to_use || real_constructors].flatten.each do |constructor|
41
+ next if do_not_wrap?(constructor)
42
+
43
+ if constructor.attributes[:artificial]
44
+ next if ignore_artificial || constructor.arguments.length == 1
45
+ end
46
+
47
+ if @director
48
+ @director.wrap_constructor constructor
49
+ else
50
+ add_child ConstructorNode.new(constructor, self)
51
+ end
52
+ end
53
+ end
54
+
55
+ # Wrap up any class constants
56
+ def with_constants
57
+ [self.code.constants].flatten.each do |const|
58
+ next if do_not_wrap?(const)
59
+ add_child ConstNode.new(const, self)
60
+ end
61
+ end
62
+
63
+ # Expose the public variables for this class
64
+ def with_variables
65
+ [self.code.variables].flatten.each do |var|
66
+ next if do_not_wrap?(var)
67
+
68
+ add_child InstanceVariableNode.new(var, self)
69
+ end
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,28 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+ module EnumerationHelpers
4
+
5
+ # Wrap up enumerations for this node.
6
+ # Anonymous enumerations are a special case. C++ doesn't
7
+ # see them as a seperate type and instead are just "scoped" constants,
8
+ # so we have to wrap them as such, constants.
9
+ def with_enumerations
10
+ [self.code.enumerations].flatten.each do |enum|
11
+ next if do_not_wrap?(enum)
12
+
13
+ if enum.anonymous?
14
+ # So for each value of this enumeration,
15
+ # expose it as a constant
16
+ enum.values.each do |value|
17
+ add_child ConstNode.new(value, self)
18
+ end
19
+ else
20
+ add_child EnumerationNode.new(enum, self)
21
+ end
22
+
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+ module ModuleHelpers
4
+
5
+ # Build up any user-defined modules for this node
6
+ def with_modules
7
+ self.modules.each do |mod|
8
+ add_child ModuleNode.new(mod, self)
9
+ end
10
+ end
11
+
12
+ # Expose a function in this module
13
+ def with_module_functions
14
+ [self.code.functions].flatten.each do |func|
15
+ next if do_not_wrap?(func)
16
+ add_child ModuleFunctionNode.new(func, self)
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,32 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Node for an #include line.
5
+ # Can be a :local (default) or :system
6
+ # include declaration.
7
+ #
8
+ # Includes have no children
9
+ class IncludeNode < Base
10
+
11
+ def initialize(parent, path, type = :local)
12
+ super(nil, parent)
13
+
14
+ @path = path
15
+ @type = type
16
+ end
17
+
18
+ def build
19
+ #nop
20
+ end
21
+
22
+ def write
23
+ if @path
24
+ includes << (@type == :local ? "#include \"#{@path}\"" : "#include <#{@path}>")
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
32
+
@@ -0,0 +1,36 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Wrap up a class instance variable
5
+ class InstanceVariableNode < Base
6
+
7
+ def build
8
+ end
9
+
10
+ def write
11
+ ruby_name = Inflector.underscore(code.name)
12
+ parent_name = parent.code.qualified_name.as_variable
13
+
14
+ # Setter, only if it isn't const
15
+ if !code.cpp_type.const?
16
+ method_name = "wrap_#{parent_name}_#{code.name}_set"
17
+ declarations << "void #{method_name}(#{parent.code.qualified_name}* self, #{code.cpp_type.base_type.qualified_name} val) {"
18
+ declarations << "self->#{code.name} = val;"
19
+ declarations << "}"
20
+
21
+ registrations << "#{parent.rice_variable}.define_method(\"#{ruby_name}=\", &#{method_name});"
22
+ end
23
+
24
+ # Getter
25
+ method_name = "wrap_#{parent_name}_#{code.name}_get"
26
+ declarations << "#{code.cpp_type.base_type.qualified_name} #{method_name}(#{parent.code.qualified_name}* self) {"
27
+ declarations << "return self->#{code.name};"
28
+ declarations << "}"
29
+
30
+ registrations << "#{parent.rice_variable}.define_method(\"#{ruby_name}\", &#{method_name});"
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Wrap up an indivitual method
5
+ class MethodNode < MethodBase
6
+
7
+ def build
8
+ self.rice_method = "define_method"
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,136 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Base class for any type of method or function handling
5
+ class MethodBase < Base
6
+
7
+ attr_accessor :prefix, :rice_method, :suffix
8
+
9
+ def initialize(code, parent = nil)
10
+ super
11
+
12
+ # Overload checks:
13
+ # - If we're the only one, no overload required
14
+ # - If we're one of many w/ the same name:
15
+ # - Find out which in the list we are
16
+ # - Add the number to ruby_name, unless user has renamed
17
+ # - Build typedef of the method and use it in the exposure
18
+ found = [code.parent.methods(code.name)].flatten
19
+ if found.length > 1 && !code.renamed?
20
+ num = found.index(code)
21
+ self.suffix = "_#{num}"
22
+ end
23
+ end
24
+
25
+ # Wrap up this method making sure that overloads
26
+ # are properly typedef'd to keep from compiler error from unresolvable types
27
+ #
28
+ # Thanks to Py++ for the appropriate C++ syntax for this.
29
+ def write
30
+ @ruby_name = Inflector.underscore(code.name)
31
+
32
+ self.prefix ||= "#{self.parent.rice_variable}."
33
+ self.suffix ||= ""
34
+
35
+ if self.code.arguments.size == 1 && (fp = self.code.arguments[0].cpp_type.base_type).is_a?(RbGCCXML::FunctionType)
36
+ wrap_with_function_pointer(fp)
37
+ else
38
+ wrap_normal_method
39
+ end
40
+ end
41
+
42
+ # This method should return the full C++ path to the method you're exposing
43
+ def code_path
44
+ self.code.qualified_name
45
+ end
46
+
47
+ protected
48
+
49
+ # Handling methods that take function pointers takes a lot of extra custom code.
50
+ # - Need a method that acts as the proxy between C and the Ruby proc
51
+ # - Need a method that gets wrapped into Ruby to handle type conversions
52
+ #
53
+ def wrap_with_function_pointer(func_pointer)
54
+ Logger.info "Building callback wrapper for #{self.code.qualified_name}"
55
+
56
+ base_name = self.code.qualified_name.as_variable
57
+ return_type = func_pointer.return_type.to_cpp
58
+ proxy_method_name = "do_yield_on_#{base_name}"
59
+
60
+ callback_arguments = []
61
+ callback_values = [func_pointer.arguments.length]
62
+
63
+ func_pointer.arguments.each_with_index do |arg, i|
64
+ callback_arguments << "#{arg.to_cpp} arg#{i}"
65
+ callback_values << "to_ruby(arg#{i}).value()"
66
+ end
67
+
68
+ # Build the method that acts as the Proc -> C func pointer proxy (the callback)
69
+ block_var_name = "_block_for_#{base_name}"
70
+ declarations << "VALUE #{block_var_name};"
71
+ declarations << "#{return_type} #{proxy_method_name}(#{callback_arguments.join(", ")}) {"
72
+
73
+ funcall = "rb_funcall(#{block_var_name}, rb_intern(\"call\"), #{callback_values.join(", ")})"
74
+ if return_type == "void"
75
+ declarations << "#{funcall};"
76
+ else
77
+ declarations << "return from_ruby<#{return_type} >(#{funcall});"
78
+ end
79
+
80
+ declarations << "}"
81
+
82
+ if self.parent.is_a?(ClassNode)
83
+ arg = "#{self.parent.qualified_name} *self"
84
+ callee = "self->#{self.code.qualified_name}"
85
+ else
86
+ arg = ""
87
+ callee = "#{self.code.qualified_name}"
88
+ end
89
+
90
+ wrapper_func = "wrap_for_callback_#{base_name}"
91
+
92
+ # Build the wrapper method that gets exposed to Ruby
93
+ declarations << "VALUE #{wrapper_func}(#{arg}) {"
94
+ declarations << "\t#{block_var_name} = rb_block_proc();"
95
+ declarations << "\t#{callee}(&#{proxy_method_name});"
96
+ declarations << "\treturn Qnil;"
97
+ declarations << "}"
98
+
99
+ registrations << "#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", &#{wrapper_func});"
100
+ end
101
+
102
+ def wrap_normal_method
103
+ parts = "#{self.qualified_name}".split("::")
104
+ usage_ref = "#{parts[-1]}_func_type"
105
+
106
+ if self.code.static? || self.code.as_instance_method?
107
+ method_ref = "*#{usage_ref}"
108
+ else
109
+ method_ref = [parts[0..-2], "*#{usage_ref}"].flatten.join("::")
110
+ end
111
+
112
+ default_arguments = []
113
+ arguments = []
114
+
115
+ self.code.arguments.each do |arg|
116
+ arguments << arg.to_cpp
117
+ default_arguments << "Rice::Arg(\"#{arg.name}\")#{arg.value ? " = (#{arg.cpp_type.to_cpp})#{arg.value}" : "" }"
118
+ end
119
+
120
+ return_type = find_typedef_for(self.code.return_type).to_cpp
121
+
122
+ def_args = default_arguments.any? ? ", (#{default_arguments.join(", ")})" : ""
123
+
124
+ registrations << "{"
125
+
126
+ registrations << "typedef #{return_type} ( #{method_ref} )( #{arguments.join(", ")} );"
127
+ registrations << "#{self.prefix}#{self.rice_method}(\"#{@ruby_name + self.suffix}\", " +
128
+ "#{usage_ref}( &#{code_path} )#{def_args});"
129
+
130
+ registrations << "}"
131
+ end
132
+
133
+ end
134
+
135
+ end
136
+ end
@@ -1,73 +1,59 @@
1
1
  module RbPlusPlus
2
2
  module Builders
3
3
 
4
- # This class handles generating source for a requested Module
5
- class ModuleBuilder < Base
4
+ # Handles code generation dealing with user-defined modules.
5
+ class ModuleNode < Base
6
+ include ModuleHelpers
7
+ include EnumerationHelpers
8
+ include ClassHelpers
6
9
 
7
- # Initializer takes the parent object and the RbModule construction
8
- def initialize(parent, mod)
9
- super(mod.name, mod.node)
10
- @module = mod
11
- self.parent = parent
12
- end
10
+ # Has a name
11
+ attr_accessor :name
13
12
 
14
- def build
15
- # Using qualified name with underscores here to allow for nested modules
16
- # of the same name
17
- self.rice_variable = "rb_m#{self.qualified_name.gsub(/::/, "_")}"
18
- self.rice_variable_type = "Rice::Module"
13
+ # And needs to specially handle any other nexted modules
14
+ attr_accessor :modules
19
15
 
20
- includes << "#include <rice/Module.hpp>"
21
-
22
- add_additional_includes
16
+ # Node is the RbModule object, it proxies any unknown calls
17
+ # off to it's internal Node object
18
+ def initialize(code, parent = nil)
19
+ super
23
20
 
24
- mod_defn = "\t#{rice_variable_type} #{rice_variable} = "
25
- if !parent.is_a?(ExtensionBuilder)
26
- mod_defn += "Rice::define_module_under(#{parent.rice_variable}, \"#{name}\");"
27
- else
28
- mod_defn += "Rice::define_module(\"#{name}\");"
29
- end
21
+ @name ||= code.name
22
+ @modules ||= code.modules
23
+ end
30
24
 
31
- body << mod_defn
25
+ def qualified_name
26
+ self.code.qualified_name
27
+ end
32
28
 
33
- # If a namespace has been given to this module, find and wrap the appropriate code
34
- if self.node
35
- build_enumerations
36
- end
29
+ def build
30
+ with_modules
37
31
 
38
- build_functions unless @module.functions.empty?
39
- build_classes(@module.classes) unless @module.classes.empty?
40
-
32
+ add_child IncludeNode.new(self, "rice/Module.hpp", :system)
41
33
 
42
- # Build each inner module
43
- @module.modules.each do |mod|
44
- builder = ModuleBuilder.new(self, mod)
45
- builder.build
46
- builders << builder
34
+ # Make sure we ignore anything from the :: namespace
35
+ if self.code && self.code.name != "::"
36
+ with_module_functions
37
+ with_enumerations
38
+ with_classes
47
39
  end
48
- end
49
40
 
50
- # Process functions to be added to this module
51
- def build_functions
52
- @module.functions.each do |func|
53
- next if func.ignored? || func.moved? # fine grained function filtering
54
- add_includes_for func
41
+ nodes.flatten!
55
42
 
56
- func_name = Inflector.underscore(func.name)
57
- wrapped_name = func.special_qualified_name || build_function_wrapper(func)
58
- body << "\t#{self.rice_variable}.define_module_function(\"#{func_name}\", &#{wrapped_name});"
59
- end
43
+ self.rice_variable_type = "Rice::Module"
44
+ self.rice_variable = "rb_m#{self.qualified_name.as_variable}"
60
45
  end
61
46
 
62
- # Special name handling. Qualified name is simply the name of this module
63
- def qualified_name
64
- if parent.is_a?(ModuleBuilder)
65
- "#{parent.qualified_name}::#{self.name}"
47
+ def write
48
+ prefix = "#{rice_variable_type} #{rice_variable} = "
49
+
50
+ if parent.rice_variable
51
+ registrations << "#{prefix} Rice::define_module_under(#{parent.rice_variable}, \"#{@name}\");"
66
52
  else
67
- self.name
53
+ registrations << "#{prefix} Rice::define_module(\"#{@name}\");"
68
54
  end
69
55
  end
70
-
71
56
  end
57
+
72
58
  end
73
59
  end
@@ -0,0 +1,16 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Wrap up a method on a Module as a module_function
5
+ class ModuleFunctionNode < MethodBase
6
+
7
+ def build
8
+ add_child IncludeNode.new(self, code.file)
9
+
10
+ self.rice_method = "define_module_function"
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module RbPlusPlus
2
+ module Builders
3
+
4
+ # Wrap up a static method on a class
5
+ class StaticMethodNode < MethodBase
6
+
7
+ def build
8
+ self.rice_method = "define_singleton_method"
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+ end