rbplusplus 0.8 → 0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +13 -13
- data/TODO +9 -41
- data/lib/rbplusplus/builders/allocation_strategy.rb +57 -0
- data/lib/rbplusplus/builders/base.rb +115 -212
- data/lib/rbplusplus/builders/class.rb +129 -115
- data/lib/rbplusplus/builders/const.rb +30 -0
- data/lib/rbplusplus/builders/const_converter.rb +52 -0
- data/lib/rbplusplus/builders/constructor.rb +19 -0
- data/lib/rbplusplus/builders/director.rb +149 -0
- data/lib/rbplusplus/builders/director_method.rb +20 -0
- data/lib/rbplusplus/builders/enumeration.rb +19 -26
- data/lib/rbplusplus/builders/extension.rb +42 -54
- data/lib/rbplusplus/builders/global_function.rb +18 -0
- data/lib/rbplusplus/builders/helpers/class.rb +74 -0
- data/lib/rbplusplus/builders/helpers/enumeration.rb +28 -0
- data/lib/rbplusplus/builders/helpers/module.rb +22 -0
- data/lib/rbplusplus/builders/include.rb +32 -0
- data/lib/rbplusplus/builders/instance_variable.rb +36 -0
- data/lib/rbplusplus/builders/method.rb +14 -0
- data/lib/rbplusplus/builders/method_base.rb +136 -0
- data/lib/rbplusplus/builders/module.rb +37 -51
- data/lib/rbplusplus/builders/module_function.rb +16 -0
- data/lib/rbplusplus/builders/static_method.rb +14 -0
- data/lib/rbplusplus/extension.rb +140 -28
- data/lib/rbplusplus/logger.rb +45 -0
- data/lib/rbplusplus/module.rb +55 -1
- data/lib/rbplusplus/transformers/class.rb +116 -35
- data/lib/rbplusplus/transformers/function.rb +14 -16
- data/lib/rbplusplus/transformers/method.rb +26 -1
- data/lib/rbplusplus/transformers/namespace.rb +12 -0
- data/lib/rbplusplus/transformers/node.rb +47 -54
- data/lib/rbplusplus/transformers/node_cache.rb +5 -9
- data/lib/rbplusplus/writers/multiple_files_writer.rb +290 -88
- data/lib/rbplusplus/writers/single_file_writer.rb +36 -14
- data/lib/rbplusplus.rb +44 -18
- data/test/allocation_strategies_test.rb +33 -0
- data/test/class_methods_encapsulate_test.rb +59 -0
- data/test/class_methods_test.rb +2 -35
- data/test/classes_test.rb +72 -2
- data/test/compiling_test.rb +13 -0
- data/test/constructors_test.rb +9 -18
- data/test/custom_code_test.rb +53 -0
- data/test/default_arguments_test.rb +69 -0
- data/test/director_test.rb +173 -0
- data/test/enumerations_test.rb +29 -0
- data/test/extension_test.rb +7 -2
- data/test/file_writers_test.rb +11 -4
- data/test/function_pointer_test.rb +56 -0
- data/test/function_pointers_classes_test.rb +27 -0
- data/test/generated/extconf.rb +2 -2
- data/test/headers/Adder.cpp +8 -0
- data/test/headers/Adder.h +31 -1
- data/test/headers/alloc_strats.h +26 -0
- data/test/headers/class_methods.h +30 -0
- data/test/headers/code/custom_to_from_ruby.cpp +11 -0
- data/test/headers/code/custom_to_from_ruby.hpp +13 -0
- data/test/headers/constructors.h +8 -20
- data/test/headers/default_arguments.h +49 -0
- data/test/headers/director.h +148 -0
- data/test/headers/enums.h +33 -0
- data/test/headers/function_pointers.h +32 -0
- data/test/headers/function_pointers_class.h +26 -0
- data/test/headers/needs_code.h +10 -0
- data/test/headers/overload.h +0 -3
- data/test/headers/subclass.h +10 -0
- data/test/headers/to_from_ruby.h +6 -4
- data/test/headers/ugly_interface.h +4 -7
- data/test/modules_test.rb +11 -6
- data/test/overloading_test.rb +6 -2
- data/test/subclass_test.rb +20 -10
- data/test/test_helper.rb +6 -1
- data/test/to_from_ruby_test.rb +0 -2
- data/test/wrap_as_test.rb +28 -37
- metadata +89 -57
- data/lib/rbplusplus/builders/types_manager.rb +0 -93
- data/lib/rbplusplus/transformers/constructor.rb +0 -4
- data/lib/rbplusplus/transformers/module.rb +0 -71
- data/lib/rbplusplus/transformers/node_reference.rb +0 -30
- data/test/headers/ugly_helper.h +0 -18
- data/test/object_persistence_test.rb +0 -44
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 = "0.9"
|
7
7
|
|
8
8
|
task :default => :test
|
9
9
|
|
@@ -16,10 +16,13 @@ task :default => :test
|
|
16
16
|
# tests individually
|
17
17
|
desc "Run the tests"
|
18
18
|
task :test do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
require 'rbconfig'
|
20
|
+
FileList["test/*_test.rb"].each do |file|
|
21
|
+
# To allow multiple ruby installs (like a multiruby test suite), I need to get
|
22
|
+
# the exact ruby binary that's linked to the ruby running the Rakefile. Just saying
|
23
|
+
# "ruby" will find the system's installed ruby and be worthless
|
24
|
+
ruby = File.join(Config::CONFIG["bindir"], Config::CONFIG["RUBY_INSTALL_NAME"])
|
25
|
+
sh "#{ruby} #{file}"
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
@@ -37,14 +40,11 @@ PROJECT_WEB_PATH = "/var/www/gforge-projects/rbplusplus"
|
|
37
40
|
namespace :web do
|
38
41
|
desc "Build website"
|
39
42
|
task :build => :rdoc do |t|
|
40
|
-
cd "website" do
|
41
|
-
sh "webgen"
|
42
|
-
end
|
43
|
-
|
44
43
|
unless File.directory?("publish")
|
45
44
|
mkdir "publish"
|
46
45
|
end
|
47
|
-
|
46
|
+
|
47
|
+
sh "jekyll --pygment website publish/"
|
48
48
|
sh "cp -r html/* publish/rbplusplus/"
|
49
49
|
end
|
50
50
|
|
@@ -63,7 +63,7 @@ spec = Gem::Specification.new do |s|
|
|
63
63
|
s.name = "rbplusplus"
|
64
64
|
s.version = RBPLUSPLUS_VERSION
|
65
65
|
s.summary = 'Ruby library to generate Rice wrapper code'
|
66
|
-
s.homepage = 'http://rbplusplus.rubyforge.org
|
66
|
+
s.homepage = 'http://rbplusplus.rubyforge.org'
|
67
67
|
s.rubyforge_project = "rbplusplus"
|
68
68
|
s.author = 'Jason Roelofs'
|
69
69
|
s.email = 'jameskilton@gmail.com'
|
@@ -73,8 +73,8 @@ Rb++ combines the powerful query interface of rbgccxml and the Rice library to
|
|
73
73
|
make Ruby wrapping extensions easier to write than ever.
|
74
74
|
END
|
75
75
|
|
76
|
-
s.add_dependency "rbgccxml", "0.
|
77
|
-
s.add_dependency "rice", "
|
76
|
+
s.add_dependency "rbgccxml", "~> 0.9"
|
77
|
+
s.add_dependency "rice", "~> 1.2.0"
|
78
78
|
|
79
79
|
patterns = [
|
80
80
|
'TODO',
|
data/TODO
CHANGED
@@ -1,45 +1,13 @@
|
|
1
|
-
|
2
|
-
* Figure out how to fix the error when running rake test
|
3
|
-
* Allowing use of "have_library"
|
4
|
-
* Other mkmf functions?
|
1
|
+
Parts to move into rbgccxml:
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
- Class purely_virtual? (check the abstract attribute)
|
4
|
+
- Namespace#methods ?
|
8
5
|
|
9
|
-
|
10
|
-
- ArrayType
|
11
|
-
- Converter
|
12
|
-
- Destructor
|
13
|
-
- Field
|
14
|
-
- FunctionType
|
15
|
-
- OperatorFunction
|
16
|
-
- OperatorMethod
|
17
|
-
- OffsetType
|
18
|
-
- Union
|
19
|
-
- Variable
|
6
|
+
Move documentation to YARD?
|
20
7
|
|
21
|
-
|
22
|
-
* Adding constructor
|
23
|
-
- Test constructor arguments
|
24
|
-
|
25
|
-
DONE
|
26
|
-
* Adding -I entries
|
27
|
-
* Adding -L and -l entries
|
28
|
-
* Adding classes to global (define_class)
|
29
|
-
* Adding modules
|
30
|
-
* Adding methods to modules (define_module_function)
|
31
|
-
* Adding classes to modules / other classes (define_class_under)
|
32
|
-
* Adding methods to classes (.define_method)
|
33
|
-
* Adding classes to classes (ad infinitum)
|
34
|
-
* Look into file naming when dealing with Modules
|
35
|
-
* Nested Modules
|
36
|
-
* Recognizing and building to_ruby / from_ruby methods for const type references
|
37
|
-
* Moving the to_ruby / from_ruby definitions to a place that all will know about them
|
38
|
-
* Enumerations
|
39
|
-
* Proper TypesManager dealings with single_file writer mode
|
40
|
-
* Working with the defined C++ heirarchy chain
|
41
|
-
|
42
|
-
No longer waiting on rice - just building a wrapper myself now.
|
43
|
-
* Adding global methods (Kernel-level methods)
|
44
|
-
* Adding class-level methods (define_singleton_method)
|
8
|
+
Use sdoc?
|
45
9
|
|
10
|
+
Logging:
|
11
|
+
- Method overloads, wrap what a method is getting named as
|
12
|
+
- More detail into the writing, multiple and single file writers
|
13
|
+
- More debug messages in the building process
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module RbPlusPlus
|
2
|
+
module Builders
|
3
|
+
|
4
|
+
# Handles code generation for telling Rice how to allocate / deallocate
|
5
|
+
# classes. See ClassNode#check_allocation_strategies.
|
6
|
+
class AllocationStrategyNode < Base
|
7
|
+
|
8
|
+
def initialize(parent, code, has_public_constructor, has_public_destructor)
|
9
|
+
super(code, parent)
|
10
|
+
@public_constructor = has_public_constructor
|
11
|
+
@public_destructor = has_public_destructor
|
12
|
+
end
|
13
|
+
|
14
|
+
# Used by MultipleFileWriter to only wrap a given type once.
|
15
|
+
def qualified_name
|
16
|
+
"#{self.code.qualified_name}_AllocStrat"
|
17
|
+
end
|
18
|
+
|
19
|
+
def build
|
20
|
+
end
|
21
|
+
|
22
|
+
def write
|
23
|
+
includes << "#include <rice/Allocation_Strategies.hpp>"
|
24
|
+
|
25
|
+
node_name = self.code.qualified_name
|
26
|
+
code = <<-END
|
27
|
+
namespace Rice {
|
28
|
+
template<>
|
29
|
+
struct Default_Allocation_Strategy< #{node_name} > {
|
30
|
+
static #{node_name} * allocate();
|
31
|
+
static void free(#{node_name} * obj);
|
32
|
+
};
|
33
|
+
}
|
34
|
+
END
|
35
|
+
|
36
|
+
declarations << code
|
37
|
+
|
38
|
+
pre = "Rice::Default_Allocation_Strategy< #{node_name} >::"
|
39
|
+
|
40
|
+
tmp = "#{node_name} * #{pre}allocate() { return "
|
41
|
+
tmp += @public_constructor ? "new #{node_name};" : "NULL;"
|
42
|
+
tmp += " }"
|
43
|
+
|
44
|
+
registrations << tmp
|
45
|
+
|
46
|
+
tmp = "void #{pre}free(#{node_name} * obj) { "
|
47
|
+
tmp += @public_destructor ? "delete obj;" : ""
|
48
|
+
tmp += " }"
|
49
|
+
|
50
|
+
registrations << tmp
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -1,256 +1,159 @@
|
|
1
1
|
module RbPlusPlus
|
2
2
|
module Builders
|
3
3
|
|
4
|
-
#
|
5
|
-
# code "parts" to fill up for the source writer:
|
4
|
+
# Base class for all code generation nodes
|
6
5
|
#
|
7
|
-
#
|
8
|
-
# declarations
|
9
|
-
# body
|
6
|
+
# A Node is simply a handler for one complete statement or block of C++ code.
|
10
7
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# Any extra required functions or class declarations that will be defined
|
16
|
-
# outside of the main body of the code
|
17
|
-
#
|
18
|
-
# body:
|
19
|
-
# The body is the code that will go in the main control function
|
20
|
-
# of the file. For extensions, it's Init_extension_name() { [body] }.
|
21
|
-
# For classes it's usually a register_ClassName() { [body] }, and so on.
|
22
|
-
#
|
23
|
-
# All builders can access their parent and add pieces of code to any of these
|
24
|
-
# three parts
|
8
|
+
# The code generation system for Rb++ is a two step process.
|
9
|
+
# We first, starting with an ExtensionNode, build up an internal representation
|
10
|
+
# of the resulting code, setting up all the code nodes required for proper
|
11
|
+
# wrapping of the library.
|
25
12
|
#
|
13
|
+
# Once that's in place, then we run through the tree, actually generating
|
14
|
+
# the C++ wrapper code.
|
26
15
|
class Base
|
27
16
|
|
28
|
-
|
29
|
-
|
30
|
-
# Any given builder has a list of sub-builders of any type
|
31
|
-
attr_accessor :builders
|
32
|
-
|
33
|
-
# Builders need to constcuct the following code parts
|
34
|
-
#
|
35
|
-
# The list of includes this builder needs
|
17
|
+
# List of includes for this node
|
36
18
|
attr_accessor :includes
|
37
|
-
|
19
|
+
|
20
|
+
# List of declaration nodes for this node
|
38
21
|
attr_accessor :declarations
|
39
|
-
# The body code
|
40
|
-
attr_accessor :body
|
41
22
|
|
42
|
-
#
|
23
|
+
# List of registeration nodes for this node
|
24
|
+
attr_accessor :registrations
|
25
|
+
|
26
|
+
# Link to the parent node of this node
|
43
27
|
attr_accessor :parent
|
44
28
|
|
45
|
-
#
|
29
|
+
# Link to the underlying rbgccxml node this node is writing code for
|
30
|
+
attr_accessor :code
|
31
|
+
|
32
|
+
# List of children nodes
|
33
|
+
attr_accessor :nodes
|
34
|
+
|
35
|
+
# List of children nodes that generate code that the entire extension
|
36
|
+
# needs to be able to read. Code that fits here includes any auto-generated
|
37
|
+
# to_/from_ruby and any Allocation Strategies
|
38
|
+
attr_accessor :global_nodes
|
39
|
+
|
40
|
+
# The Rice variable name for this node
|
46
41
|
attr_accessor :rice_variable
|
42
|
+
|
43
|
+
# The type of the rice_variable
|
47
44
|
attr_accessor :rice_variable_type
|
48
45
|
|
49
|
-
|
50
|
-
|
51
|
-
@
|
52
|
-
@node = parser
|
53
|
-
@builders = []
|
46
|
+
def initialize(code, parent = nil)
|
47
|
+
@code = code
|
48
|
+
@parent = parent
|
54
49
|
@includes = []
|
55
50
|
@declarations = []
|
56
|
-
@
|
57
|
-
@
|
51
|
+
@registrations = []
|
52
|
+
@nodes = []
|
53
|
+
@global_nodes = []
|
58
54
|
end
|
59
|
-
|
60
|
-
#
|
61
|
-
def
|
62
|
-
@
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def nested_level(node, level=0)
|
68
|
-
return level if node.is_a?(RbGCCXML::Namespace) || node.is_a?(RbGCCXML::Enumeration)
|
69
|
-
return level if node.super_classes.length == 0
|
70
|
-
node.super_classes.each do |sup|
|
71
|
-
level = nested_level(sup, level+1)
|
72
|
-
end
|
73
|
-
return level
|
55
|
+
|
56
|
+
# Does this builder node have child nodes?
|
57
|
+
def has_children?
|
58
|
+
@nodes && !@nodes.empty?
|
74
59
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
60
|
+
|
61
|
+
# Trigger the construction of the internal representation of a given node.
|
62
|
+
# All nodes must implement this.
|
63
|
+
def build
|
64
|
+
raise "Nodes must implement #build"
|
65
|
+
end
|
66
|
+
|
67
|
+
# After #build has run, this then triggers the actual generation of the C++
|
68
|
+
# code and returns the final string.
|
69
|
+
# All nodes must implement this.
|
70
|
+
def write
|
71
|
+
raise "Nodes must implement #write"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Once building is done, the resulting node tree needs to be sorted according
|
75
|
+
# to subclass / superclass definitions. Like anything with C++, Rice needs to
|
76
|
+
# know about base classes before it can build sub classes. We go through
|
77
|
+
# each node's children, sorting them according to this.
|
78
|
+
def sort
|
79
|
+
@nodes.each { |n| n.sort }
|
80
|
+
|
81
|
+
# sort_by lets us build an array of numbers that Ruby then uses
|
82
|
+
# to sort the list. Our method here is to simply specify the
|
83
|
+
# depth a given class is in a heirarchy, as bigger numbers end
|
84
|
+
# up sorted farther down the list
|
85
|
+
@nodes =
|
86
|
+
@nodes.sort_by do |a|
|
87
|
+
a.is_a?(ClassNode) ? superclass_count(a.code) : 0
|
89
88
|
end
|
90
|
-
end
|
91
|
-
|
92
|
-
#collect the sorted members
|
93
|
-
nodes.collect do |node, func|
|
94
|
-
func
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
# The name of the header file to include
|
99
|
-
# This is the file default, so long as it matches one of the export files
|
100
|
-
# If not this returns all exported files.
|
101
|
-
#
|
102
|
-
# This was added to workaround badly declared namespaces
|
103
|
-
def header_files(node)
|
104
|
-
file = node.file_name(false)
|
105
|
-
return [file] if self.class.sources.include?(file)
|
106
|
-
self.class.sources
|
107
|
-
end
|
108
|
-
|
109
|
-
# Adds the necessary includes in order to compile the specified node
|
110
|
-
def add_includes_for(node)
|
111
|
-
header_files(node).each do |header|
|
112
|
-
includes << "#include \"#{header}\""
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
# Include any user specified include files
|
117
|
-
def add_additional_includes
|
118
|
-
self.class.additional_includes.each do |inc|
|
119
|
-
includes << "#include \"#{inc}\""
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
# Set a list of user specified include files
|
124
|
-
def self.additional_includes=(addl)
|
125
|
-
@@additional_includes = addl
|
126
|
-
end
|
127
|
-
|
128
|
-
# Get an array of user specified include files
|
129
|
-
def self.additional_includes
|
130
|
-
@@additional_includes || []
|
131
|
-
end
|
132
|
-
|
133
|
-
# A list of all the source files. This is used in order to prevent files
|
134
|
-
# that are not in the list from being included and mucking things up
|
135
|
-
def self.sources=(sources)
|
136
|
-
@@sources = sources
|
137
|
-
end
|
138
|
-
|
139
|
-
# Retrieves a list of user specified source files
|
140
|
-
def self.sources
|
141
|
-
@@sources || []
|
142
89
|
end
|
143
90
|
|
144
|
-
#
|
145
|
-
def
|
146
|
-
|
91
|
+
# Proxy method for writers
|
92
|
+
def qualified_name
|
93
|
+
self.code.qualified_name
|
147
94
|
end
|
148
95
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
96
|
+
protected
|
97
|
+
|
98
|
+
# Count the heirarchy depth of a given class node
|
99
|
+
def superclass_count(node)
|
100
|
+
count = 0
|
101
|
+
n = node
|
102
|
+
while n = n.superclass
|
103
|
+
count += 1
|
156
104
|
end
|
157
|
-
|
158
|
-
return [
|
159
|
-
self.includes.flatten.uniq,
|
160
|
-
"",
|
161
|
-
self.declarations,
|
162
|
-
"",
|
163
|
-
self.body,
|
164
|
-
"",
|
165
|
-
self.registered_nodes,
|
166
|
-
extras
|
167
|
-
].flatten.join("\n")
|
105
|
+
count
|
168
106
|
end
|
169
107
|
|
170
|
-
#
|
171
|
-
|
172
|
-
|
108
|
+
# Should this node be wrapped as it is or has the user
|
109
|
+
# specified something else for this node?
|
110
|
+
def do_not_wrap?(node)
|
111
|
+
node.ignored? || (node.moved_to && node.moved_to != self.code) || !node.public?
|
173
112
|
end
|
174
113
|
|
175
|
-
#
|
176
|
-
def
|
177
|
-
|
178
|
-
|
179
|
-
next if klass.ignored? || klass.moved?
|
180
|
-
next unless klass.public?
|
181
|
-
builder = ClassBuilder.new(self, klass)
|
182
|
-
builder.build
|
183
|
-
builders << builder
|
184
|
-
end
|
114
|
+
# Given a new node, build it and add it to our nodes list
|
115
|
+
def add_child(node)
|
116
|
+
node.build
|
117
|
+
nodes << node
|
185
118
|
end
|
186
119
|
|
187
|
-
#
|
188
|
-
def
|
189
|
-
|
190
|
-
|
191
|
-
builder.build
|
192
|
-
builders << builder
|
193
|
-
end
|
120
|
+
# Add a node to the "globals" list. See the declaration of global_nodes
|
121
|
+
def add_global_child(node)
|
122
|
+
node.build
|
123
|
+
global_nodes << node
|
194
124
|
end
|
195
125
|
|
196
|
-
#
|
197
|
-
#
|
126
|
+
# Any node can also have a typedef. There are cases where it's
|
127
|
+
# much better to use a typedef instead of the original fully qualified
|
128
|
+
# name, for example deep template definitions (say, any STL structures).
|
129
|
+
# This method will look for the best Typedef to use for this node.
|
130
|
+
# This lookup can be disabled on a per-node basis by calling node.disable_typedef_lookup,
|
131
|
+
# as there are cases where the typedef search works against the parsed code.
|
198
132
|
#
|
199
|
-
#
|
200
|
-
def
|
201
|
-
return if
|
202
|
-
wrapper_func = "wrap_#{function.qualified_name.gsub(/::/, "_")}#{append}"
|
133
|
+
# @returns the typedef node found or the node passed in (self.code by default)
|
134
|
+
def find_typedef(node = self.code)
|
135
|
+
return node if node.is_a?(RbGCCXML::FundamentalType)
|
203
136
|
|
204
|
-
|
205
|
-
call_string = []
|
206
|
-
function.arguments.map{|arg| [arg.cpp_type.to_s(true), arg.name]}.each do |parts|
|
207
|
-
type = parts[0]
|
208
|
-
name = parts[1]
|
209
|
-
proto_string << "#{type} #{name}"
|
210
|
-
call_string << "#{name}"
|
211
|
-
end
|
137
|
+
found = last_found = node
|
212
138
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
returns ||= "return"
|
139
|
+
if !node._disable_typedef_lookup?
|
140
|
+
while found
|
141
|
+
last_found = found
|
142
|
+
typedef = RbGCCXML::XMLParsing.find(:node_type => "Typedef", :type => found.attributes["id"])
|
218
143
|
|
219
|
-
|
220
|
-
|
221
|
-
|
144
|
+
# Some typedefs have the access attribute, some don't. We want those without the attribute
|
145
|
+
# and those with the access="public". For this reason, we can't put :access => "public" in the
|
146
|
+
# query above.
|
147
|
+
found = (typedef && typedef.public?) ? typedef : nil
|
148
|
+
end
|
149
|
+
end
|
222
150
|
|
223
|
-
|
151
|
+
last_found
|
224
152
|
end
|
225
153
|
|
226
|
-
|
227
|
-
|
228
|
-
#
|
229
|
-
# Returns: the name of the wrapper function
|
230
|
-
def build_method_wrapper(cls, method, i)
|
231
|
-
return if method.ignored? || method.moved?
|
232
|
-
wrapper_func = "wrap_#{method.qualified_name.functionize}_#{i}"
|
233
|
-
proto_string = ["#{cls.qualified_name} *self"]
|
234
|
-
call_string = []
|
235
|
-
method.arguments.map{|arg| [arg.cpp_type.to_s(true), arg.name]}.each do |parts|
|
236
|
-
type = parts[0]
|
237
|
-
name = parts[1]
|
238
|
-
proto_string << "#{type} #{name}"
|
239
|
-
call_string << "#{name}"
|
240
|
-
end
|
241
|
-
|
242
|
-
proto_string = proto_string.join(",")
|
243
|
-
call_string = call_string.join(",")
|
244
|
-
return_type = method.return_type.to_s(true)
|
245
|
-
returns = "" if return_type == "void"
|
246
|
-
returns ||= "return"
|
247
|
-
|
248
|
-
declarations << "#{return_type} #{wrapper_func}(#{proto_string}) {"
|
249
|
-
declarations << "\t#{returns} self->#{method.qualified_name}(#{call_string});"
|
250
|
-
declarations << "}"
|
251
|
-
|
252
|
-
wrapper_func
|
253
|
-
end
|
154
|
+
alias find_typedef_for find_typedef
|
155
|
+
|
254
156
|
end
|
157
|
+
|
255
158
|
end
|
256
159
|
end
|