lib/yard/handlers/c/handler_methods.rb in yard-0.8.7.6 vs lib/yard/handlers/c/handler_methods.rb in yard-0.9.0

- old
+ new

@@ -5,11 +5,11 @@ include Parser::C include CodeObjects def handle_class(var_name, class_name, parent, in_module = nil) parent = nil if parent == "0" - namespace = in_module ? namespace_for_variable(in_module) : Registry.root + namespace = in_module ? ensure_variable_defined!(in_module) : Registry.root if namespace.nil? raise Parser::UndocumentableError, "class #{class_name}. " + "Cannot find definition for parent namespace." end @@ -27,11 +27,11 @@ register_file_info(obj, statement.file, statement.line) end end def handle_module(var_name, module_name, in_module = nil) - namespace = in_module ? namespace_for_variable(in_module) : Registry.root + namespace = in_module ? ensure_variable_defined!(in_module) : Registry.root if namespace.nil? raise Parser::UndocumentableError, "module #{module_name}. " + "Cannot find definition for parent namespace." end @@ -49,10 +49,20 @@ when "private_method"; scope = :instance; visibility = :private else; scope = :instance end namespace = namespace_for_variable(var_name) + + # Is this method being defined on a core Ruby class or module? + if namespace.is_a?(Proxy) + if var_name =~ /^rb_c(\w+)/ && YARD::CodeObjects::BUILTIN_CLASSES.include?($1) + namespace = namespaces[var_name] = YARD::CodeObjects::ClassObject.new(:root, $1) + elsif var_name =~ /^rb_m(\w+)/ && YARD::CodeObjects::BUILTIN_MODULES.include?($1) + namespace = namespaces[var_name] = YARD::CodeObjects::ModuleObject.new(:root, $1) + end + end + return if namespace.nil? # XXX: raise UndocumentableError might be too noisy. register MethodObject.new(namespace, name, scope) do |obj| register_visibility(obj, visibility) find_method_body(obj, func_name) obj.explicit = true @@ -91,12 +101,16 @@ namespace.aliases[new_obj] = old_meth end def handle_constants(type, var_name, const_name, value) - return unless type == 'const' - namespace = namespace_for_variable(var_name) + return unless type =~ /^const$|^global_const$/ + if type == 'global_const' + namespace = :root + else + namespace = namespace_for_variable(var_name) + end register ConstantObject.new(namespace, const_name) do |obj| obj.source_type = :c obj.value = value register_file_info(obj, statement.file, statement.line) find_constant_docstring(obj) @@ -145,31 +159,51 @@ end if src_stmt = symbols[symbol] register_file_info(object, src_stmt.file, src_stmt.line, true) register_source(object, src_stmt) + record_parameters(object, symbol, src_stmt) unless src_stmt.comments.nil? || src_stmt.comments.source.empty? register_docstring(object, src_stmt.comments.source, src_stmt) return # found docstring end end # found source (possibly) but no docstring # so look in overrides override_comments.each do |name, override_comment| next unless override_comment.file == file - name = name.gsub(/::([^:]+?)\Z/, '.\1') - just_method_name = name.gsub(/\A.+(#|::|\.)/, '') - just_method_name = 'initialize' if just_method_name == 'new' - if object.path == name || object.name.to_s == just_method_name + name = name.gsub(/::([^:\.#]+?)\Z/, '.\1') + + path = if name =~ /\.|#/ # explicit namespace in override comment + object.path + else + object.name.to_s + end + + if path == name || path == name.sub(/new$/, 'initialize') || path == name.sub('.', '#') register_docstring(object, override_comment.source, override_comment) return end end # use any comments on this statement as a last resort if !in_file && statement.comments && statement.comments.source =~ /\S/ register_docstring(object, statement.comments.source, statement) + end + end + + def record_parameters(object, symbol, src) + # use regex to extract comma-delimited list of parameters from cfunc definition + if src.source =~ /VALUE\s+#{symbol}\(([^)]*)\)\s*\{/m + params = $~[1].split(/\s*,\s*/) + # cfunc for a "varargs" method has params "int argc, VALUE *argv" + if params[0] =~ /int\s+argc/ && params[1] =~ /VALUE\s*\*\s*argv/ + object.parameters = [['*args', nil]] + else + # the first cfunc argument is the 'self' argument, we don't need that + object.parameters = params.drop(1).map { |s| [s[/VALUE\s+(\S+)/, 1], nil] } + end end end end end end