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
@@ -0,0 +1,28 @@
|
|
1
|
+
module EasySwig
|
2
|
+
|
3
|
+
class DoxygenTask
|
4
|
+
include EasySwig
|
5
|
+
|
6
|
+
def initialize config
|
7
|
+
@config = config
|
8
|
+
if Dir.exists?(@config.doxy_dir)
|
9
|
+
FileUtils.rm_r @config.doxy_dir
|
10
|
+
end
|
11
|
+
FileUtils.mkdir_p @config.doxy_dir
|
12
|
+
|
13
|
+
@log = EasySwig::Logger.doxy_log(@config.doxy_dir)
|
14
|
+
@log.info { "Created Doxygen directory in #{@config.doxy_dir}" }
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
@log.info { "Creating Doxygen documentation in directory: #{@config.doxy_dir} ..." }
|
19
|
+
headers_dirs = [@config.headers_dir]
|
20
|
+
output = Doxyparser::gen_xml_docs(headers_dirs, @config.doxy_dir, true, @config.includes_dir, @config.html, @config.stl_support)
|
21
|
+
@log.info { 'Doxygen documentation created at: '+ @config.doxy_dir}
|
22
|
+
end
|
23
|
+
|
24
|
+
def dispose
|
25
|
+
@log.close
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module EasySwig
|
2
|
+
|
3
|
+
class GenerateTask
|
4
|
+
include Util
|
5
|
+
include Print
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
@gen_dir = @config.generate_dir+'/'+@config.lang
|
10
|
+
@generators = {}
|
11
|
+
|
12
|
+
FileUtils.rm_r @gen_dir if Dir.exists?(@gen_dir)
|
13
|
+
FileUtils.mkdir_p @gen_dir
|
14
|
+
FileUtils.cp "#{home_dir}/resources/#{@config.lang}/standard_header.i", "#{@gen_dir}/standard_header.i"
|
15
|
+
FileUtils.cp @config.custom_file, "#{@gen_dir}/custom_config.i" if @config.custom_file
|
16
|
+
FileUtils.cp "#{home_dir}/resources/swig-patches/attribute.i", "#{@gen_dir}/attribute.i"
|
17
|
+
|
18
|
+
@log=EasySwig::Logger.gen_log(@gen_dir)
|
19
|
+
@log.info { "Created Generator directory for #{@native_name} in #{@node_gen_dir}" }
|
20
|
+
end
|
21
|
+
|
22
|
+
def generate
|
23
|
+
module_file = <<-IFILE.escape_heredoc
|
24
|
+
%module #{@config.module_name}
|
25
|
+
|
26
|
+
%include "standard_header.i"
|
27
|
+
%include "#{@config.custom_file}"
|
28
|
+
%include "attribute.i"
|
29
|
+
|
30
|
+
IFILE
|
31
|
+
|
32
|
+
@log.info { "Parsing CSV file #{@csv_file} ..." }
|
33
|
+
csv_parser = EasySwig::Readers::CsvParser.new(@config.csv_file, @config.lang)
|
34
|
+
|
35
|
+
@log.info { "Parsed CSV file. Number of entries: #{csv_parser.table.size}" }
|
36
|
+
|
37
|
+
@log.info { "Generating Namespaces from CSV file #{@csv_file}..." }
|
38
|
+
api_namespaces = csv_parser.namespaces_from_csv
|
39
|
+
@log.info { "Namespaces generated in memory: \n\t\tNamespaces: " + (api_namespaces.map{|n| n.basename}.join(', ')) }
|
40
|
+
@log.debug { "Namespace contents:\n\t\t\t\t" + print_api_namespaces(api_namespaces) }
|
41
|
+
|
42
|
+
api_namespaces.each do |api_namespace|
|
43
|
+
|
44
|
+
@log.info { "Parsing namespace from C++ files..." }
|
45
|
+
namespace = Doxyparser::parse_namespace(api_namespace.basename, @config.doxy_dir+'/xml')
|
46
|
+
@log.info { "C++ Namespace parsed" }
|
47
|
+
|
48
|
+
@log.info { "Associating namespace tree (classes, structs, enums...) with the corresponding Doxygen tree..." }
|
49
|
+
api_namespace.assoc_with_node(namespace)
|
50
|
+
@log.info { "Namespace Tree associated" }
|
51
|
+
@log.debug { print_api_namespace(api_namespace) }
|
52
|
+
|
53
|
+
# If there are no classes in this namespace things get a bit tricky
|
54
|
+
conf_doxy_dir = @config.doxy_dir
|
55
|
+
if api_namespace.api_classes.empty?
|
56
|
+
api_namespace.define_singleton_method(:file) {
|
57
|
+
Doxyparser::parse_file(api_namespace.basename + '.h', conf_doxy_dir+"/xml")
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
@log.info { "Associating and sorting header files for all sub-nodes of: #{api_namespace.node_type} #{api_namespace.name}..." }
|
62
|
+
hfiles = EasySwig::HFilesManager.assoc_headers(api_namespace)
|
63
|
+
@log.info { "Header files associated" }
|
64
|
+
hfiles = EasySwig::HFilesManager.sort_headers(hfiles)
|
65
|
+
@log.info { "Header files sorted" }
|
66
|
+
@log.debug { print_incl_files(hfiles) }
|
67
|
+
|
68
|
+
native_name = api_namespace.basename # Name of module (C++ namespace)
|
69
|
+
target_name = api_namespace.target_name # Name of target namespace
|
70
|
+
|
71
|
+
@generators[api_namespace] = Generator.create_instance(hfiles, api_namespace, @config, @log)
|
72
|
+
|
73
|
+
@log.info { "Generating SWIG configuration files..." }
|
74
|
+
gen_node_name = @generators[api_namespace].generate
|
75
|
+
@log.info { "SWIG configuration files generated" }
|
76
|
+
module_file << %Q{%include "#{gen_node_name}.i"\n}
|
77
|
+
end
|
78
|
+
write_file(%Q{#{@gen_dir}/#{@config.module_name}.i}, module_file)
|
79
|
+
end
|
80
|
+
|
81
|
+
def dispose
|
82
|
+
@log.close
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module EasySwig
|
2
|
+
module HFilesManager
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def assoc_headers(api_node)
|
7
|
+
|
8
|
+
api_nodes = api_node.api_nodes
|
9
|
+
hfile_hash = Hash.new
|
10
|
+
|
11
|
+
api_nodes.each { |api_n|
|
12
|
+
hfile = api_n.file
|
13
|
+
|
14
|
+
next if hfile.nil?
|
15
|
+
|
16
|
+
filename = hfile.name
|
17
|
+
|
18
|
+
if hfile_hash[filename] == nil
|
19
|
+
params = {'node_type' => 'file', 'features' => api_n.features }
|
20
|
+
hfile_hash[filename] = IncFile.new(params).assoc_with_node(hfile)
|
21
|
+
hfile_hash[filename].assoc_inner_node(api_node)
|
22
|
+
end
|
23
|
+
api_n.header_file = hfile_hash[filename]
|
24
|
+
hfile_hash[filename].assoc_inner_node(api_n)
|
25
|
+
}
|
26
|
+
hfile_hash.each_value { |f|
|
27
|
+
f.ignore_inner_nodes
|
28
|
+
puts f.name
|
29
|
+
}
|
30
|
+
hfiles = hfile_hash.values
|
31
|
+
hfiles
|
32
|
+
end
|
33
|
+
|
34
|
+
def sort_headers(files)
|
35
|
+
sorted = []
|
36
|
+
includes = {}
|
37
|
+
while true
|
38
|
+
|
39
|
+
break if files.empty?
|
40
|
+
|
41
|
+
files_aux = files.map { |f| f.name }
|
42
|
+
files = files.sort { |fx,fy| compare(fx, fy, files_aux) }
|
43
|
+
includes = {}
|
44
|
+
while true
|
45
|
+
f = files.shift
|
46
|
+
break if f.nil?
|
47
|
+
|
48
|
+
incs = f.files_included.map { |x| x.name }
|
49
|
+
t1 = files.select { |h| incs.include?(h.name) }
|
50
|
+
t2 = sorted.select { |h| incs.include?(h.name) }
|
51
|
+
t2.select! { |h| compare(h, f, files_aux) > 0}
|
52
|
+
includes[f] = t1
|
53
|
+
includes[f] << t2.flatten
|
54
|
+
t1.each { |v| files.delete(v) }
|
55
|
+
t2.each { |v| sorted.delete(v) }
|
56
|
+
files -= includes[f]
|
57
|
+
end
|
58
|
+
sorted.push(*includes.keys)
|
59
|
+
files = includes.values.flatten
|
60
|
+
end
|
61
|
+
sorted.reverse
|
62
|
+
end
|
63
|
+
|
64
|
+
def compare(fx, fy, files_set)
|
65
|
+
num_incl_by_fx = num_included_by(fx, files_set)
|
66
|
+
num_incl_by_fy = num_included_by(fy, files_set)
|
67
|
+
num_incl_fx = num_includes(fx, files_set)
|
68
|
+
num_incl_fy = num_includes(fy, files_set)
|
69
|
+
if num_incl_by_fx == 0 && num_incl_by_fy == 0
|
70
|
+
return num_incl_fy <=> num_incl_fx
|
71
|
+
end
|
72
|
+
return -1 if num_incl_by_fx == 0
|
73
|
+
return 1 if num_incl_by_fy == 0
|
74
|
+
return (num_incl_fy - num_incl_by_fy) <=> (num_incl_fx - num_incl_by_fx)
|
75
|
+
end
|
76
|
+
|
77
|
+
def num_includes(file, files_set)
|
78
|
+
file.files_included.map { |f| f.name }.select { |f| files_set.include?(f) }.size
|
79
|
+
end
|
80
|
+
|
81
|
+
def num_included_by(file, files_set)
|
82
|
+
file.files_including.map { |f| f.name }.select{ |f| files_set.include?(f) }.size
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module EasySwig
|
2
|
+
class SwigTask
|
3
|
+
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
@target = @config.target_file
|
7
|
+
@header_dir = @config.headers_dir
|
8
|
+
@out_dir = @config.output_dir
|
9
|
+
@lang = @config.lang
|
10
|
+
@inc_dirs = @config.includes_dir
|
11
|
+
|
12
|
+
if Dir.exists? @out_dir
|
13
|
+
FileUtils.rm_r @out_dir
|
14
|
+
end
|
15
|
+
FileUtils.mkdir_p(@out_dir)
|
16
|
+
|
17
|
+
@log=EasySwig::Logger.swig_log @out_dir
|
18
|
+
@log.info { "Created SWIG output directory in #{@out_dir}" }
|
19
|
+
end
|
20
|
+
|
21
|
+
def run_swig
|
22
|
+
|
23
|
+
swig_opts=%Q{-c++ -#{@lang} -v -Wall -debug-classes} #
|
24
|
+
saved_dir = Dir.pwd
|
25
|
+
output_dir = @out_dir.clone
|
26
|
+
ifiles = []
|
27
|
+
current_dir = nil
|
28
|
+
if File.directory? @target
|
29
|
+
ifiles = Dir.entries(@target).select { |entry| File.extname(entry)=='.i' }
|
30
|
+
output_dir << "/#{File.basename(@target)}"
|
31
|
+
current_dir = @target
|
32
|
+
else
|
33
|
+
ifiles << File.basename(@target)
|
34
|
+
current_dir = ::File.dirname(@target)
|
35
|
+
end
|
36
|
+
|
37
|
+
ifiles.each { |f|
|
38
|
+
@log.info "\nExecuting SWIG command for file: " + f
|
39
|
+
target_name = File.basename(f, '.i')
|
40
|
+
odir = output_dir + "/#{target_name}"
|
41
|
+
FileUtils.mkdir_p(odir)
|
42
|
+
Dir.chdir current_dir
|
43
|
+
incs = ""
|
44
|
+
Dir.foreach(@header_dir) { |e|
|
45
|
+
subdir = File.absolute_path(e, @header_dir)
|
46
|
+
if File.directory?(subdir)
|
47
|
+
incs << "-I#{subdir} "
|
48
|
+
end
|
49
|
+
}
|
50
|
+
@inc_dirs.each { |idir|
|
51
|
+
incs << "-I#{idir} "
|
52
|
+
}
|
53
|
+
command=%Q{swig #{swig_opts} -namespace #{target_name} -outdir #{odir} #{incs} #{f} > swig_output 2>&1}
|
54
|
+
@log.info command
|
55
|
+
output=IO.popen(command)
|
56
|
+
@log.debug { 'SWIG output:' }
|
57
|
+
@log.debug { output.readlines.join }
|
58
|
+
output.close
|
59
|
+
FileUtils.mv("#{File.basename(f, '.i')}_wrap.cxx", output_dir)
|
60
|
+
}
|
61
|
+
Dir.chdir saved_dir
|
62
|
+
end
|
63
|
+
|
64
|
+
def dispose
|
65
|
+
@log.close
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
data/lib/util/logger.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module EasySwig
|
2
|
+
|
3
|
+
class Logger
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def doxy_log dir
|
7
|
+
file = File.open("#{dir}/doxygen.log", File::WRONLY | File::APPEND | File::CREAT)
|
8
|
+
@doxy_log ||= ::Logger.new(file)
|
9
|
+
end
|
10
|
+
|
11
|
+
def log msg
|
12
|
+
@gen_log.info msg
|
13
|
+
end
|
14
|
+
|
15
|
+
def gen_log dir=nil
|
16
|
+
@gen_log ||= ::Logger.new(File.open("#{dir}/generate.log", File::WRONLY | File::APPEND | File::CREAT))
|
17
|
+
end
|
18
|
+
|
19
|
+
def node_log dir=nil
|
20
|
+
@gen_log
|
21
|
+
end
|
22
|
+
|
23
|
+
def csv_log dir
|
24
|
+
@csv_log ||= ::Logger.new(File.open("#{dir}/generate.log", File::WRONLY | File::APPEND | File::CREAT))
|
25
|
+
end
|
26
|
+
|
27
|
+
def swig_log dir
|
28
|
+
@swig_log ||= ::Logger.new(File.open("#{dir}/swig.log", File::WRONLY | File::APPEND | File::CREAT))
|
29
|
+
end
|
30
|
+
|
31
|
+
def close_logs
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
data/lib/util/print.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module EasySwig
|
2
|
+
module Print
|
3
|
+
|
4
|
+
def print_incl_files incl_files
|
5
|
+
ret = ''
|
6
|
+
ret << "\nGenerated Include Files: "
|
7
|
+
incl_files.each { |f|
|
8
|
+
ret << "\nincl_file:" + f.basename
|
9
|
+
f.api_classes.each { |c|
|
10
|
+
ret << "\t"+"Api Class:" + c.basename
|
11
|
+
c.api_methods.each { |m|
|
12
|
+
ret << "\t"+"\t"+"Api Method:" + m.basename
|
13
|
+
}
|
14
|
+
c.ignored_methods.each { |m|
|
15
|
+
ret << "\t"+"\t"+"Ignored Method:" + m.basename
|
16
|
+
}
|
17
|
+
}
|
18
|
+
f.ignored_classes.each { |c|
|
19
|
+
ret << "\t"+"Ignored Class:" + c.basename
|
20
|
+
# c.methods.each { |m|
|
21
|
+
# log "\t"+"\t"+"Ignored Method:" + m.name
|
22
|
+
#}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
ret
|
26
|
+
end
|
27
|
+
|
28
|
+
def print_api_namespaces api_namespaces
|
29
|
+
ret = ''
|
30
|
+
api_namespaces.each { |api_ns|
|
31
|
+
ret << print_api_namespace(api_ns)
|
32
|
+
}
|
33
|
+
ret
|
34
|
+
end
|
35
|
+
|
36
|
+
def print_api_namespace api_ns
|
37
|
+
ret = '\n'
|
38
|
+
ret << "\tNamespace: "+ api_ns+"\n"
|
39
|
+
api_ns.api_functions.each { |f|
|
40
|
+
ret << "\t\tFunction: "+f.basename+" Assoc: "+f.wrapped_node.to_s + '\n'
|
41
|
+
}
|
42
|
+
api_ns.api_variables.each { |f|
|
43
|
+
ret << "\t\tVariable: "+f.basename+" Assoc: "+f.wrapped_node.to_s + '\n'
|
44
|
+
}
|
45
|
+
api_ns.api_enums.each { |f|
|
46
|
+
ret << "\t\tEnum: "+f.basename+" Assoc: "+f.wrapped_node.to_s + '\n'
|
47
|
+
}
|
48
|
+
api_ns.api_classes.each { |c|
|
49
|
+
ret << print_api_class(c)
|
50
|
+
}
|
51
|
+
ret
|
52
|
+
end
|
53
|
+
|
54
|
+
def print_api_class c
|
55
|
+
ret = ''
|
56
|
+
ret << "\t\tClass: " + c + "\n"
|
57
|
+
c.api_methods.each { |m|
|
58
|
+
ret << "\t\t\tMethod: "+m.basename+" Assoc: "+m.wrapped_node.to_s + '\n'
|
59
|
+
}
|
60
|
+
c.api_attributes.each { |m|
|
61
|
+
ret << "\t\t\tAttribute : "+m.basename+" Assoc: "+m.wrapped_node.to_s + '\n'
|
62
|
+
}
|
63
|
+
c.api_enums.each { |m|
|
64
|
+
ret << "\t\t\tEnum: "+m.basename+" Assoc: "+m.wrapped_node.to_s + '\n'
|
65
|
+
}
|
66
|
+
c.api_innerclasses.each { |m|
|
67
|
+
ret << "\t\t\tInnerClass: "+m.basename+" Assoc: "+m.wrapped_node.to_s + '\n'
|
68
|
+
}
|
69
|
+
ret
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/util/query.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
module EasySwig
|
2
|
+
module Query
|
3
|
+
|
4
|
+
def get_reference_type(type, klass)
|
5
|
+
if is_primitive?(type.name)
|
6
|
+
return :ptr
|
7
|
+
elsif type.name.end_with?('&')
|
8
|
+
return :ref
|
9
|
+
elsif type.name == 'std::string'
|
10
|
+
return :str
|
11
|
+
else
|
12
|
+
looked_up = klass.lookup_node(type)
|
13
|
+
return nil if looked_up.nil?
|
14
|
+
if type.name.end_with?('*')
|
15
|
+
if is_primitive?(looked_up.name)
|
16
|
+
return :prim_ptr
|
17
|
+
end
|
18
|
+
return :ptr
|
19
|
+
end
|
20
|
+
if looked_up.class == Doxyparser::Enum
|
21
|
+
return :ptr
|
22
|
+
else
|
23
|
+
return :val
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def lookup_typename(type, klass) # Type should not have * & const
|
29
|
+
escaped_typename = escape_template(type.escaped_name)
|
30
|
+
return type.escaped_name if escaped_typename.include?('::') || is_primitive?(escaped_typename)
|
31
|
+
return type.escaped_name.gsub(escaped_typename, 'std::' + escaped_typename) if is_std?(escaped_typename)
|
32
|
+
lookedup = klass.lookup_node(type)
|
33
|
+
return nil if lookedup.nil?
|
34
|
+
lookedup.name
|
35
|
+
end
|
36
|
+
|
37
|
+
def nested_typenames_for(typename)
|
38
|
+
Doxyparser::Type.nested_typenames(typename)
|
39
|
+
end
|
40
|
+
|
41
|
+
def no_public_constructors?(klass)
|
42
|
+
klass.constructors(:public).empty? && !klass.constructors(:all).empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
def no_public_destructors?(klass)
|
46
|
+
klass.destructors(:public).empty? && !klass.destructors(:all).empty?
|
47
|
+
end
|
48
|
+
|
49
|
+
def name_for_template(template_name)
|
50
|
+
nested_typenames_for(template_name).map{ |typename|
|
51
|
+
del_prefix_class(typename.split(' ').join('')).capitalize
|
52
|
+
}.join('')
|
53
|
+
end
|
54
|
+
|
55
|
+
def name_for_operator(typename, num_args)
|
56
|
+
ret = case typename
|
57
|
+
when 'operator+'
|
58
|
+
return num_args == 2 ? '__add__' : '__pos__'
|
59
|
+
when 'operator-'
|
60
|
+
return num_args == 2 ? '__sub__' : '__neg__'
|
61
|
+
when 'operator*'
|
62
|
+
return '__mul__'
|
63
|
+
when 'operator/'
|
64
|
+
return '__div__'
|
65
|
+
when 'operator%'
|
66
|
+
return '__mod__'
|
67
|
+
when 'operator<<'
|
68
|
+
return '__lshift__'
|
69
|
+
when 'operator>>'
|
70
|
+
return '__rshift__'
|
71
|
+
when 'operator&'
|
72
|
+
return '__and__'
|
73
|
+
when 'operator||'
|
74
|
+
return '__or__'
|
75
|
+
when 'operator^'
|
76
|
+
return '__xor__'
|
77
|
+
when 'operator~'
|
78
|
+
return '__invert__'
|
79
|
+
when 'operator<'
|
80
|
+
return '__lt__'
|
81
|
+
when 'operator<='
|
82
|
+
return '__le__'
|
83
|
+
when 'operator>'
|
84
|
+
return '__gt__'
|
85
|
+
when 'operator>='
|
86
|
+
return '__ge__'
|
87
|
+
when 'operator=='
|
88
|
+
return '__eq__'
|
89
|
+
when 'operator()'
|
90
|
+
return '__call__'
|
91
|
+
else
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def name_for_friend(typename, num_args = 0)
|
97
|
+
return '_friend_' + typename if num_args == 0
|
98
|
+
result = name_for_operator(typename, num_args)
|
99
|
+
return result.nil? ? '_friend_' + typename : result
|
100
|
+
end
|
101
|
+
|
102
|
+
def is_template_param?(typename, klass)
|
103
|
+
class_template_params = klass.template_params.map{|tp| tp.declname}
|
104
|
+
return if nested_typenames_for(typename).any?{ |t|
|
105
|
+
class_template_params.include?(t)
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
def is_template?(typename)
|
110
|
+
Doxyparser::Type.template?(typename)
|
111
|
+
end
|
112
|
+
|
113
|
+
def is_operator?(name)
|
114
|
+
name =~ /operator\W+/
|
115
|
+
end
|
116
|
+
|
117
|
+
def method_has_blacklisted_types?(method)
|
118
|
+
return true if type_is_blacklisted?(method)
|
119
|
+
return true if method.params.any?{ |p| type_is_blacklisted?(p) }
|
120
|
+
return false
|
121
|
+
end
|
122
|
+
|
123
|
+
def type_is_blacklisted?(p)
|
124
|
+
return p.type.nested_typenames.any?{ |t| typename_is_blacklisted?(t)}
|
125
|
+
end
|
126
|
+
|
127
|
+
def typename_is_blacklisted?(typename)
|
128
|
+
return typename == 'multimap' || typename == 'std::multimap'
|
129
|
+
end
|
130
|
+
|
131
|
+
def anonymous_enum?(enum)
|
132
|
+
enum.basename =~ /_Enum\d*$/
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|