easy-swig 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.
- 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
|