DecodeSourceDecodeRBSMethod

class Method

Represents a Ruby method definition wrapper for RBS generation.

Definitions

def initialize(definition)

Initialize a new method wrapper.

Signature

parameter definition Decode::Definition

The method definition to wrap.

Implementation

def initialize(definition)
	super
	@signatures = nil
end

def signatures

Extract method signatures from the method definition.

Signature

returns Array

The extracted signatures for this method.

Implementation

def signatures
	@signatures ||= extract_signatures
end

def to_rbs_ast(index = nil)

Convert the method definition to RBS AST

Implementation

def to_rbs_ast(index = nil)
	method_name = @definition.name
	comment = extract_comment(@definition)
	
	overloads = []
	if signatures.any?
		signatures.each do |signature_string|
			method_type = ::RBS::Parser.parse_method_type(signature_string)
			overloads << ::RBS::AST::Members::MethodDefinition::Overload.new(
				method_type: method_type,
				annotations: []
			)
		end
	else
		return_type = extract_return_type(@definition, index) || ::RBS::Parser.parse_type("untyped")
		parameters = extract_parameters(@definition, index)
		block_type = extract_block_type(@definition, index)
		
		method_type = ::RBS::MethodType.new(
			type_params: [],
			type: ::RBS::Types::Function.new(
				required_positionals: parameters,
				optional_positionals: [],
				rest_positionals: nil,
				trailing_positionals: [],
				required_keywords: {},
				optional_keywords: {},
				rest_keywords: nil,
				return_type: return_type
			),
			block: block_type,
			location: nil
		)
		
		overloads << ::RBS::AST::Members::MethodDefinition::Overload.new(
			method_type: method_type,
			annotations: []
		)
	end
	
	kind = @definition.receiver ? :singleton : :instance
	
	::RBS::AST::Members::MethodDefinition.new(
		name: method_name.to_sym,
		kind: kind,
		overloads: overloads,
		annotations: [],
		location: nil,
		comment: comment,
		overloading: false,
		visibility: :public
	)
end

def extract_return_type(definition, index)

Extract return type from method documentation

Implementation

def extract_return_type(definition, index)
	# Look for @returns tags in the method's documentation
	documentation = definition.documentation
	
	# Find @returns tag
	returns_tag = documentation&.filter(Decode::Comment::Returns)&.first
	
	if returns_tag
		# Parse the type from the tag
		type_string = returns_tag.type.strip
		parse_type_string(type_string)
	else
		# Infer return type based on method name patterns
		infer_return_type(definition)
	end
end

def extract_parameters(definition, index)

Extract parameter types from method documentation

Implementation

def extract_parameters(definition, index)
	documentation = definition.documentation
	return [] unless documentation
	
	# Find @parameter tags
	param_tags = documentation.filter(Decode::Comment::Parameter).to_a
	return [] if param_tags.empty?
	
	param_tags.map do |tag|
		name = tag.name
		type_string = tag.type.strip
		type = parse_type_string(type_string)
		
		::RBS::Types::Function::Param.new(
			type: type,
			name: name.to_sym
		)
	end
end

def extract_block_type(definition, index)

Extract block type from method documentation

Implementation

def extract_block_type(definition, index)
	documentation = definition.documentation
	return nil unless documentation
	
	# Find @yields tags
	yields_tag = documentation.filter(Decode::Comment::Yields).first
	return nil unless yields_tag
	
	# Extract block parameters from nested @parameter tags
	block_params = yields_tag.filter(Decode::Comment::Parameter).map do |param_tag|
		name = param_tag.name
		type_string = param_tag.type.strip
		type = parse_type_string(type_string)
		
		::RBS::Types::Function::Param.new(
			type: type,
			name: name.to_sym
		)
	end
	
	# Parse the block signature to determine if it's required
	# Check both the directive name and the block signature
	block_signature = yields_tag.block
	directive_name = yields_tag.directive
	required = !directive_name.include?("?") && !block_signature.include?("?") && !block_signature.include?("optional")
	
	# Determine block return type (default to void if not specified)
	block_return_type = ::RBS::Parser.parse_type("void")
	
	# Create the block function type
	block_function = ::RBS::Types::Function.new(
		required_positionals: block_params,
		optional_positionals: [],
		rest_positionals: nil,
		trailing_positionals: [],
		required_keywords: {},
		optional_keywords: {},
		rest_keywords: nil,
		return_type: block_return_type
	)
	
	# Create and return the block type
	::RBS::Types::Block.new(
		type: block_function,
		required: required,
		self_type: nil
	)
end

def infer_return_type(definition)

Infer return type based on method patterns and heuristics

Implementation

def infer_return_type(definition)
	method_name = definition.name
	method_name_str = method_name.to_s
	
	# Methods ending with ? are typically boolean
	if method_name_str.end_with?("?")
		return ::RBS::Parser.parse_type("bool")
	end
	
	# Methods named initialize return void
	if method_name == :initialize
		return ::RBS::Parser.parse_type("void")
	end
	
	# Methods with names that suggest they return self
	if method_name_str.match?(/^(add|append|prepend|push|<<|concat|merge!|sort!|reverse!|clear|delete|remove)/)
		return ::RBS::Parser.parse_type("self")
	end
	
	# Default to untyped
	::RBS::Parser.parse_type("untyped")
end

def parse_type_string(type_string)

Parse a type string and convert it to RBS type

Implementation

def parse_type_string(type_string)
	type = Types.parse(type_string)
	return ::RBS::Parser.parse_type(type.to_rbs)
rescue => error
	Console.warn(self, "Failed to parse type string: #{type_string}", error)
	return ::RBS::Parser.parse_type("untyped")
end