require 'dub/argument'
require 'dub/entities_unescape'
module Dub
class Function
include Dub::EntitiesUnescape
attr_reader :arguments, :prefix, :overloaded_index, :return_value, :xml, :parent
attr_accessor :gen, :name, :is_constructor
def initialize(parent, name, xml, prefix = '', overloaded_index = nil)
@parent, @name = parent, name
@xml, @prefix, @overloaded_index = xml, prefix, overloaded_index
parse_xml
parse_template_params
end
def set_as_constructor
@return_value = Argument.new(self, (Hpricot::XML("#{name} *")/''))
@is_constructor = true
end
def bind(generator)
@gen = generator.function_generator
end
def to_s
generator.function(self)
end
def generator
@gen || (@parent && @parent.function_generator)
end
def klass
@parent.kind_of?(Klass) ? @parent : nil
end
def member_method?
!klass.nil?
end
def constructor?
@is_constructor
end
def static?
@is_static
end
alias gen generator
def name=(n)
@name = n
if constructor?
@return_value.type = n
end
end
def call_name
if klass
static? ? "#{klass.name}::#{name}" : name
else
name
end
end
def source
loc = (@xml/'location').first.attributes
"#{loc['file'].split('/')[-3..-1].join('/')}:#{loc['line']}"
end
def original_signature
unescape "#{(@xml/'definition').innerHTML}#{(@xml/'argsstring').innerHTML}"
end
def has_default_arguments?
return @has_defaults if defined?(@has_defaults)
@has_defaults = !@arguments.detect {|a| a.has_default? }.nil?
end
def has_array_arguments?
return @has_array_arguments if defined?(@has_array_arguments)
@has_array_arguments = !@arguments.detect {|a| a.array_suffix }.nil?
end
def has_class_pointer_arguments?
return @has_class_pointer_arguments if defined?(@has_class_pointer_arguments)
@has_class_pointer_arguments = !@arguments.detect {|a| !a.is_native? && a.is_pointer? }.nil?
end
def has_complex_arguments?
return @has_complex_arguments if defined?(@has_complex_arguments)
@has_complex_arguments = !(@arguments + [@return_value]).compact.detect {|a| a.complex? }.nil?
end
def vararg?
@arguments.last && @arguments.last.vararg?
end
def arg_is_list(list_position, count_position)
@arguments[list_position ].is_list = true
@arguments[count_position].is_list_count = true
end
def template?
!@template_params.nil?
end
def template_params
@template_params
end
def inspect
"#"
end
def <=>(other)
name <=> other.name
end
# ====== these methods are alias to
# generator methods on this object
def method_name(overloaded_index = nil)
gen.method_name(self, overloaded_index)
end
# =================================
private
def parse_xml
@arguments = []
(@xml/'param').each_with_index do |arg, i|
@arguments << Argument.new(self, arg, i + 1)
end
raw_type = (@xml/'/type').innerHTML
if raw_type.strip == ''
# no return type
else
arg = Argument.new(self, (@xml/'/type'))
@return_value = arg unless arg.create_type =~ /void\s*$/
end
@is_static = @xml[:static] == 'yes'
end
def parse_template_params
template_params = (@xml/'/templateparamlist/param')
if !template_params.empty?
@template_params = template_params.map do |param|
(param/'/type').innerHTML.gsub(/^\s*(typename|class)\s+/,'')
end
end
end
end
end # Namespace