easy-swig 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/MIT_LICENSE +19 -0
- data/README.md +86 -0
- data/lib/apinodes/api_attribute.rb +6 -0
- data/lib/apinodes/api_class.rb +207 -0
- data/lib/apinodes/api_enum.rb +10 -0
- data/lib/apinodes/api_function.rb +13 -0
- data/lib/apinodes/api_group.rb +13 -0
- data/lib/apinodes/api_method.rb +12 -0
- data/lib/apinodes/api_namespace.rb +104 -0
- data/lib/apinodes/api_node.rb +109 -0
- data/lib/apinodes/api_variable.rb +12 -0
- data/lib/apinodes/inc_file.rb +118 -0
- data/lib/config.rb +56 -0
- data/lib/csharp/csharp_features.rb +100 -0
- data/lib/csharp/generators/csharp_class_generator.rb +14 -0
- data/lib/csharp/generators/csharp_generator.rb +17 -0
- data/lib/csharp/generators/csharp_namespace_generator.rb +33 -0
- data/lib/easy-swig-cli.rb +143 -0
- data/lib/easy-swig.rb +71 -0
- data/lib/features.rb +39 -0
- data/lib/generators/class_generator.rb +209 -0
- data/lib/generators/generator.rb +124 -0
- data/lib/generators/generator_util.rb +135 -0
- data/lib/generators/hfile_generator.rb +56 -0
- data/lib/generators/namespace_generator.rb +58 -0
- data/lib/generators/properties.rb +13 -0
- data/lib/readers/csv_parser.rb +127 -0
- data/lib/tasks/doxygen_task.rb +28 -0
- data/lib/tasks/generate_task.rb +85 -0
- data/lib/tasks/hfiles_manager.rb +86 -0
- data/lib/tasks/swig_task.rb +69 -0
- data/lib/util/logger.rb +36 -0
- data/lib/util/print.rb +72 -0
- data/lib/util/query.rb +136 -0
- data/lib/util/utilities.rb +101 -0
- data/spec/accessors/accessors_spec.rb +45 -0
- data/spec/anonymousEnums/anonymous_enums_spec.rb +49 -0
- data/spec/friends/friends_spec.rb +45 -0
- data/spec/innerclasses/innerclasses_spec.rb +48 -0
- data/spec/namespacePrefixes/namespace_prefixes_spec.rb +39 -0
- data/spec/squish/squish_spec.rb +40 -0
- data/spec/subdirectories/subdirectories_spec.rb +41 -0
- data/spec/templates/templates_spec.rb +34 -0
- metadata +107 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MDNkNmY2ZmU4YTlkM2Y1YTFmYTA0ZWE2NTc3MmE3NWQ0ZjRhMmE5Yg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODE0YmIxYTM1MGU5NTU1YzQ5ZjcwMzliMDBkNjk5ZDY3ZjA5ZmQ5OQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
M2E2NDljMzMxZThlZWQ1YzdkYTE5OGJjZGExOTE0ODMxOTc0MjU3Mjc3NTdl
|
10
|
+
MGRmZDE2N2UyY2E5OTM5OWMxNzYwYzU3OWE5YmFkZTliYTE0ZTE4YzIyNmRi
|
11
|
+
N2QyMTQ2NGEwZDU1OGIxOWZlMTExMmJlMDFmZjA5YmVkYmRlMDM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OWQwZWQ2MTVmZTFhMWJhNDZmY2NiYzdlY2NhNDBhN2VkYzU0MzMzMWI1ZmJk
|
14
|
+
OGJiODFjMzIwOWI2NTE4YjZmMGY1NTliNWVlZTBkZDAyMTNlZDMzNWMzNjIy
|
15
|
+
MTQ1YjUzZDU2YWNjNzY0NDBmOGZhZTBmOTRhODA5MzUzOGE0MjE=
|
data/MIT_LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2013 David Fuenmayor
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
EasySwig
|
2
|
+
=========
|
3
|
+
|
4
|
+
Automatically generates wrappers for C/C++ code using SWIG.
|
5
|
+
|
6
|
+
This is both a Ruby Gem and a CLI Tool. Feed it with a directory containing the library's header files (the ones you want to wrap) and a CSV File with basic configuration (see usage). EasySwig will generate the corresponding SWIG interface files (.i) in an output directory. EasySwig also offers a facade allowing you to directly call SWIG in order to generate wrappers in the target language.
|
7
|
+
|
8
|
+
EasySwig supports currently only C#. There is ongoing work on other languages support.
|
9
|
+
|
10
|
+
|
11
|
+
Installation and Use
|
12
|
+
------------
|
13
|
+
|
14
|
+
EasySwig relies on the Doxyparser gem (https://github.com/davfuenmayor/ruby-doxygen-parser) which on his part depends on Nokogiri (http://nokogiri.org) and Doxygen (www.doxygen.org). Refer to Doxyparser for more information.
|
15
|
+
|
16
|
+
To actually generate wrappers you may also want to install SWIG (http://www.swig.org/). Currently only SWIG version 2.0.11 is supported. There is ongoing work on 3.0.0 version support.
|
17
|
+
|
18
|
+
|
19
|
+
For using EasySwig you need to create a folder with the following structure:
|
20
|
+
(it is recommended to use the subfolder 'spec/Example' as a template)
|
21
|
+
|
22
|
+
- A subfolder named 'include' with the header files you want to wrap.
|
23
|
+
- A CSV file named 'api.csv' with the name of the namespace you want to wrap and which classes to wrap/ignore.
|
24
|
+
- An optional file (optionally named custom_config.i) with %include statements for those header files found in subdirectories (otherwise SWIG won't find them)
|
25
|
+
|
26
|
+
There are three operations you can do with EasySwig: 'doxygen', 'generate' and 'swig'
|
27
|
+
1. doxygen: Generate Doxygen XML intermediate representation. Here you need the Doxyparser gem installed on your system.
|
28
|
+
2. generate: Generate SWIG Interface Files (.i) from the previously generated Doxygen XML intermediate representation
|
29
|
+
3. swig: Generate wrappers from your header files and the previously generated .i files. Here you need SWIG installed on your system.
|
30
|
+
|
31
|
+
|
32
|
+
As Ruby Gem
|
33
|
+
-----------
|
34
|
+
|
35
|
+
```shell
|
36
|
+
gem install doxyparser
|
37
|
+
```
|
38
|
+
or add the following line to your Gemfile:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
gem 'doxyparser'
|
42
|
+
```
|
43
|
+
and run `bundle install` from your shell.
|
44
|
+
|
45
|
+
Call EasySwig from your Ruby code using default values:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# Will use as target directory your current working directory (be careful!)
|
49
|
+
EasySwig::doxygen
|
50
|
+
EasySwig::generate
|
51
|
+
EasySwig::swig
|
52
|
+
```
|
53
|
+
Or with some configuration:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
config = EasySwig::Config.new('path/to/your/directory')
|
57
|
+
config.stl_support = nil # Inactivate default support for the STL Library
|
58
|
+
config.html = true # Generates HTML documentation for your header files
|
59
|
+
EasySwig::doxygen(config)
|
60
|
+
EasySwig::generate(config)
|
61
|
+
config.includes_dir = '/usr/lib/gcc/i686-linux-gnu/4.6.3/include' # Add other system include files you want SWIG to import during wrapper generation
|
62
|
+
EasySwig::swig(config)
|
63
|
+
```
|
64
|
+
|
65
|
+
You can consult the documentation (generated with YARD) in doc/ subfolder for more information about the EasySwig::Config class and its default values.
|
66
|
+
|
67
|
+
|
68
|
+
As CLI
|
69
|
+
----------
|
70
|
+
|
71
|
+
Download (or clone) this repository. An illustrative example of how to use EasySwig as CLI-Tool is found in subfolder spec/Example.
|
72
|
+
Open the corresponding README file and follow the instructions. This Example project can also be used as template for your own wrappers.
|
73
|
+
|
74
|
+
```shell
|
75
|
+
cd spec/Example
|
76
|
+
# Displays command help. Useful for parameter syntax, options and default values
|
77
|
+
sh ../../bin/easyswig.sh -h
|
78
|
+
# Generate Doxygen XML Intermediate representation. Found in generated subfolder: 'easy-swig/doxygen'
|
79
|
+
sh ../../bin/easyswig.sh doxygen
|
80
|
+
# Generate SWIG Interface Files (.i). Found in generated subfolder: 'easy-swig/generate'
|
81
|
+
sh ../../bin/easyswig.sh generate
|
82
|
+
# Generate Wrappers using your installed version of SWIG. Found in generated subfolder: 'easy-swig/swig'
|
83
|
+
sh ../../bin/easyswig.sh swig
|
84
|
+
```
|
85
|
+
|
86
|
+
|
@@ -0,0 +1,207 @@
|
|
1
|
+
module EasySwig
|
2
|
+
|
3
|
+
class ApiClass < ApiNode
|
4
|
+
|
5
|
+
attr_accessor :api_methods
|
6
|
+
attr_accessor :api_attributes
|
7
|
+
attr_accessor :api_innerclasses
|
8
|
+
attr_accessor :api_enums
|
9
|
+
attr_accessor :ignored_methods
|
10
|
+
attr_accessor :ignored_attributes
|
11
|
+
attr_accessor :ignored_innerclasses
|
12
|
+
attr_accessor :ignored_enums
|
13
|
+
attr_accessor :match_subclasses
|
14
|
+
attr_accessor :match_superclasses
|
15
|
+
attr_accessor :group
|
16
|
+
attr_accessor :wrap_innerclasses
|
17
|
+
attr_accessor :wrap_methods
|
18
|
+
attr_accessor :wrap_enums
|
19
|
+
attr_accessor :wrap_attributes
|
20
|
+
attr_accessor :nested_support
|
21
|
+
attr_accessor :friend_support
|
22
|
+
|
23
|
+
def initialize(hash)
|
24
|
+
super(hash)
|
25
|
+
@lookup_cache = {}
|
26
|
+
@api_methods=[]
|
27
|
+
@api_attributes=[]
|
28
|
+
@api_innerclasses=[]
|
29
|
+
@api_enums=[]
|
30
|
+
@ignored_methods=[]
|
31
|
+
@ignored_attributes=[]
|
32
|
+
@ignored_innerclasses=[]
|
33
|
+
@ignored_enums=[]
|
34
|
+
@director=false
|
35
|
+
end
|
36
|
+
|
37
|
+
def api_nodes
|
38
|
+
[self]
|
39
|
+
end
|
40
|
+
|
41
|
+
def file
|
42
|
+
return wrapped_node.file if node_type != 'innerclass'
|
43
|
+
return parent.file
|
44
|
+
end
|
45
|
+
|
46
|
+
def assoc_with_node(clazz)
|
47
|
+
super(clazz)
|
48
|
+
assoc_methods
|
49
|
+
assoc_attributes
|
50
|
+
assoc_innerclasses
|
51
|
+
assoc_enums
|
52
|
+
end
|
53
|
+
|
54
|
+
def assoc_methods
|
55
|
+
all_methods = @wrapped_node.methods + @wrapped_node.methods('public', 'static', nil)
|
56
|
+
all_methods.reject!{ |f| f.basename == f.basename.upcase }
|
57
|
+
ign_methods = @ignored_methods.map{|i| i.basename}
|
58
|
+
if @wrap_methods
|
59
|
+
all_methods.each { |m|
|
60
|
+
if not ign_methods.include?(m.basename)
|
61
|
+
hash = {'features' => @features, 'node_type' => 'method', 'parent' => self, 'basename' => m.basename }
|
62
|
+
@api_methods << ApiMethod.new(hash).assoc_with_node(m)
|
63
|
+
end
|
64
|
+
}
|
65
|
+
else
|
66
|
+
assoc_functions(all_methods, @api_methods, @ignored_methods)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def assoc_attributes
|
71
|
+
all_attributes = @wrapped_node.attributes + @wrapped_node.attributes('public', 'static')
|
72
|
+
ign_attributes = @ignored_attributes.map{|i| i.basename}
|
73
|
+
if @wrap_attributes
|
74
|
+
all_attributes.each { |a|
|
75
|
+
if not ign_attributes.include?(a.basename)
|
76
|
+
hash = {'features' => @features, 'node_type' => 'attribute', 'parent' => self, 'basename' => a.basename }
|
77
|
+
@api_attributes << ApiAttribute.new(hash).assoc_with_node(a)
|
78
|
+
end
|
79
|
+
}
|
80
|
+
else
|
81
|
+
assoc_members(all_attributes, @api_attributes, @ignored_attributes)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def assoc_innerclasses
|
86
|
+
all_innerclasses = @wrapped_node.innerclasses
|
87
|
+
ign_innerclasses = @ignored_innerclasses.map{|i| i.basename}
|
88
|
+
if @wrap_innerclasses
|
89
|
+
all_innerclasses.each { |c|
|
90
|
+
if !ign_innerclasses.include?(c.basename)
|
91
|
+
hash = {'wrap_methods' => 'x',
|
92
|
+
'wrap_attributes' => 'x',
|
93
|
+
'wrap_enums' => 'x',
|
94
|
+
'wrap_innerclasses' => 'x',
|
95
|
+
'node_type' => 'innerclass',
|
96
|
+
'nested_support' => @nested_support,
|
97
|
+
'features' => @features,
|
98
|
+
'parent' => self,
|
99
|
+
'basename' => c.basename }
|
100
|
+
@api_innerclasses << ApiClass.new(hash).assoc_with_node(c)
|
101
|
+
end
|
102
|
+
}
|
103
|
+
else
|
104
|
+
assoc_members(all_innerclasses, @api_innerclasses, @ignored_innerclasses)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def assoc_enums
|
109
|
+
all_enums = @wrapped_node.enums
|
110
|
+
ign_enums = @ignored_enums.map{ |i| i.basename }
|
111
|
+
if @wrap_enums
|
112
|
+
all_enums.each { |e|
|
113
|
+
if !ign_enums.include?(e.basename)
|
114
|
+
hash = {'features' => @features, 'node_type' => 'enum', 'parent' => self, 'basename' => e.basename }
|
115
|
+
@api_enums << ApiEnum.new(hash).assoc_with_node(e)
|
116
|
+
end
|
117
|
+
}
|
118
|
+
else
|
119
|
+
assoc_members(all_enums, @api_enums, @ignored_enums)
|
120
|
+
end
|
121
|
+
self
|
122
|
+
end
|
123
|
+
|
124
|
+
def lookup_node(type)
|
125
|
+
cached = @lookup_cache[type.escaped_name]
|
126
|
+
return cached if cached
|
127
|
+
looked_up = _lookup_node(type)
|
128
|
+
@lookup_cache[type.escaped_name] = looked_up
|
129
|
+
looked_up
|
130
|
+
end
|
131
|
+
|
132
|
+
def _lookup_node(type) # TODO use lookup methods of Doxyparser and avoid selects
|
133
|
+
return Doxyparser::Type.new({ name: type.basename, dir: ""}) if is_primitive?(type.basename)
|
134
|
+
return type if is_std?(type.basename)
|
135
|
+
return @wrapped_node if type.basename == @basename
|
136
|
+
expanded_type = expand_typedefs(type)
|
137
|
+
if expanded_type != type
|
138
|
+
looked_up_type = lookup_node(expanded_type)
|
139
|
+
return expanded_type if looked_up_type.nil? # TODO why?
|
140
|
+
looked_up = expanded_type.name.gsub(expanded_type.escaped_name, looked_up_type.escaped_name)
|
141
|
+
return Doxyparser::Type.new({ name: looked_up, dir: ""})
|
142
|
+
end
|
143
|
+
innerclass = innerclasses.select { |ic| ic.basename == type.basename }
|
144
|
+
unless innerclass.empty?
|
145
|
+
if type.template?
|
146
|
+
new_name = type.escaped_name.gsub(type.basename, innerclass[0].name)
|
147
|
+
return Doxyparser::Type.new({ name: new_name, dir: innerclass[0].dir})
|
148
|
+
end
|
149
|
+
return innerclass[0]
|
150
|
+
end
|
151
|
+
enum = enums.select { |ie| ie.basename == type.basename }
|
152
|
+
return enum[0] unless enum.empty?
|
153
|
+
if node_type == 'innerclass'
|
154
|
+
sibling = parent.innerclasses.select { |c| c.basename == type.basename }
|
155
|
+
else
|
156
|
+
siblings = parent.classes + parent.structs
|
157
|
+
sibling = siblings.select { |c| c.basename == type.basename }
|
158
|
+
end
|
159
|
+
unless sibling.empty?
|
160
|
+
if type.template?
|
161
|
+
new_name = type.escaped_name.gsub(type.basename, sibling[0].name)
|
162
|
+
return Doxyparser::Type.new({ name: new_name, dir: sibling[0].dir})
|
163
|
+
end
|
164
|
+
return sibling[0]
|
165
|
+
end
|
166
|
+
parent_enum = parent.enums.select { |e| e.basename == type.basename }
|
167
|
+
return parent_enum[0] unless parent_enum.empty?
|
168
|
+
if node_type == 'innerclass'
|
169
|
+
return parent.lookup_node(type)
|
170
|
+
else
|
171
|
+
puts "Type '" + type.basename+ "' not found in class '" + @wrapped_node.name + "'\n-> Function or variable will be ignored."
|
172
|
+
return nil
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def expand_typedefs(type)
|
177
|
+
typedef = visible_typedefs.select { |t| t.basename == type.basename } # TODO use Doxyparser, avoid selects
|
178
|
+
return type if typedef.empty?
|
179
|
+
new_type = typedef[0].type.dup
|
180
|
+
new_type.name = type.name.gsub(type.escaped_name, new_type.name)
|
181
|
+
expand_typedefs(new_type)
|
182
|
+
end
|
183
|
+
|
184
|
+
def visible_typedefs
|
185
|
+
if node_type == 'innerclass'
|
186
|
+
return typedefs(:all)
|
187
|
+
end
|
188
|
+
namespace = @parent
|
189
|
+
files_included = file.files_included
|
190
|
+
ns_typedefs = [] if namespace.nil?
|
191
|
+
ns_typedefs ||= namespace.typedefs.select { |typedef|
|
192
|
+
included_in_files(typedef, [file, *files_included])
|
193
|
+
}
|
194
|
+
typedefs(:all) + file.typedefs + ns_typedefs
|
195
|
+
end
|
196
|
+
|
197
|
+
def included_in_files(typedef, files) ## TODO Optimize this
|
198
|
+
files.any? { |file|
|
199
|
+
::File.basename(typedef.location) =~ %r{#{file.basename}:\d+$}
|
200
|
+
}
|
201
|
+
end
|
202
|
+
|
203
|
+
def is_enum_or_innerclass?(target_name)
|
204
|
+
(innerclasses + enums).any?{ |c| c.basename == target_name}
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module EasySwig
|
2
|
+
|
3
|
+
class ApiNamespace < ApiNode
|
4
|
+
|
5
|
+
attr_accessor :api_classes
|
6
|
+
attr_accessor :api_variables
|
7
|
+
attr_accessor :api_functions
|
8
|
+
attr_accessor :api_enums
|
9
|
+
attr_accessor :ignored_functions
|
10
|
+
attr_accessor :ignored_variables
|
11
|
+
attr_accessor :ignored_classes
|
12
|
+
attr_accessor :ignored_enums
|
13
|
+
attr_accessor :wrap_classes
|
14
|
+
attr_accessor :wrap_functions
|
15
|
+
attr_accessor :wrap_enums
|
16
|
+
attr_accessor :wrap_variables
|
17
|
+
attr_accessor :nested_support
|
18
|
+
attr_accessor :friend_support
|
19
|
+
|
20
|
+
def initialize(hash)
|
21
|
+
super(hash)
|
22
|
+
@api_classes=[]
|
23
|
+
@api_variables=[]
|
24
|
+
@api_functions=[]
|
25
|
+
@api_enums=[]
|
26
|
+
@ignored_functions=[]
|
27
|
+
@ignored_variables=[]
|
28
|
+
@ignored_classes=[]
|
29
|
+
@ignored_enums=[]
|
30
|
+
end
|
31
|
+
|
32
|
+
def api_nodes
|
33
|
+
return [self] if @api_classes.empty? # Only if there are no classes in this namespace
|
34
|
+
@api_classes
|
35
|
+
end
|
36
|
+
|
37
|
+
def assoc_with_node(ns)
|
38
|
+
super(ns)
|
39
|
+
all_functions = ns.functions
|
40
|
+
all_functions.reject!{ |f| f.basename == f.basename.upcase }
|
41
|
+
all_classes = ns.classes + ns.structs
|
42
|
+
all_enums = ns.enums
|
43
|
+
all_variables = ns.variables
|
44
|
+
ign_functions = @ignored_functions.map{|i| i.basename}
|
45
|
+
ign_classes = @ignored_classes.map{|i| i.basename}
|
46
|
+
ign_enums = @ignored_enums.map{|i| i.basename}
|
47
|
+
ign_variables = @ignored_variables.map{|i| i.basename}
|
48
|
+
|
49
|
+
if @wrap_functions
|
50
|
+
all_functions.each { |f|
|
51
|
+
if not ign_functions.include?(f.basename)
|
52
|
+
hash = {'features' => @features, 'node_type' => 'function', 'parent' => self, 'basename' => f.basename }
|
53
|
+
@api_functions << ApiFunction.new(hash).assoc_with_node(f)
|
54
|
+
end
|
55
|
+
}
|
56
|
+
else
|
57
|
+
assoc_functions(all_functions, @api_functions, @ignored_functions)
|
58
|
+
end
|
59
|
+
|
60
|
+
if @wrap_classes
|
61
|
+
all_classes.each { |c|
|
62
|
+
if not ign_classes.include?(c.basename)
|
63
|
+
hash = {'wrap_methods' => 'x',
|
64
|
+
'wrap_attributes' => 'x',
|
65
|
+
'wrap_enums' => 'x',
|
66
|
+
'wrap_innerclasses' => 'x',
|
67
|
+
'node_type' => 'class',
|
68
|
+
'nested_support' => @nested_support,
|
69
|
+
'friend_support' => @friend_support,
|
70
|
+
'features' => @features,
|
71
|
+
'parent' => self,
|
72
|
+
'basename' => c.basename }
|
73
|
+
@api_classes << ApiClass.new(hash).assoc_with_node(c)
|
74
|
+
end
|
75
|
+
}
|
76
|
+
else
|
77
|
+
assoc_members(all_classes, @api_classes, @ignored_classes)
|
78
|
+
end
|
79
|
+
|
80
|
+
if @wrap_variables
|
81
|
+
all_variables.each { |v|
|
82
|
+
if not ign_variables.include?(v.basename)
|
83
|
+
hash = {'features' => @features, 'node_type' => 'variable', 'parent' => self, 'basename' => v.basename}
|
84
|
+
@api_variables << ApiVariable.new(hash).assoc_with_node(v)
|
85
|
+
end
|
86
|
+
}
|
87
|
+
else
|
88
|
+
assoc_members(all_variables, @api_variables, @ignored_variables)
|
89
|
+
end
|
90
|
+
if @wrap_enums
|
91
|
+
all_enums.each { |e|
|
92
|
+
if not ign_enums.include?(e.basename)
|
93
|
+
hash = {'features' => @features, 'node_type' => 'enum', 'parent' => self, 'basename' => e.basename }
|
94
|
+
@api_enums << ApiEnum.new(hash).assoc_with_node(e)
|
95
|
+
end
|
96
|
+
}
|
97
|
+
else
|
98
|
+
assoc_members(all_enums, @api_enums, @ignored_enums)
|
99
|
+
end
|
100
|
+
self
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|