DecodeSourceDecodeRBSClass

class Class

Represents a Ruby class definition wrapper for RBS generation.

Definitions

def initialize(definition)

Initialize a new class wrapper.

Signature

parameter definition Decode::Definition

The class definition to wrap.

Implementation

def initialize(definition)
	super
	@generics = nil
end

def generics

Extract generic type parameters from the class definition.

Signature

returns Array[Symbol]

The generic type parameters for this class.

Implementation

def generics
	@generics ||= extract_generics
end

def to_rbs_ast(method_definitions = [], constant_definitions = [], attribute_definitions = [], index = nil)

Convert the class definition to RBS AST

Implementation

def to_rbs_ast(method_definitions = [], constant_definitions = [], attribute_definitions = [], index = nil)
	name = simple_name_to_rbs(@definition.name)
	comment = self.comment
	
	# Extract generics from RBS tags
	type_params = generics.map do |generic|
		::RBS::AST::TypeParam.new(
			name: generic.to_sym,
			variance: nil,
			upper_bound: nil,
			location: nil
		)
	end
	
	# Build method definitions:
	methods = method_definitions.map{|method_def| Method.new(method_def).to_rbs_ast(index)}.compact
	
	# Build constant definitions:
	constants = constant_definitions.map{|const_def| build_constant_rbs(const_def)}.compact
	
	# Build attribute definitions and infer instance variable types:
	attributes, instance_variables = build_attributes_rbs(attribute_definitions)
	
	# Extract super class if present:
	super_class = if @definition.super_class
		::RBS::AST::Declarations::Class::Super.new(
					name: qualified_name_to_rbs(@definition.super_class),
					args: [],
					location: nil
				)
	end
	
	# Create the class declaration with generics:
	::RBS::AST::Declarations::Class.new(
		name: name,
		type_params: type_params,
		super_class: super_class,
		members: constants + attributes + instance_variables + methods,
		annotations: [],
		location: nil,
		comment: comment
	)
end

def build_constant_rbs(constant_definition)

Build a constant RBS declaration.

Implementation

def build_constant_rbs(constant_definition)
	# Look for @constant tags in the constant's documentation:
	documentation = constant_definition.documentation
	constant_tags = documentation&.filter(Decode::Comment::Constant)&.to_a
	
	if constant_tags&.any?
		type_string = constant_tags.first.type.strip
		type = ::Decode::RBS::Type.parse(type_string)
		
		::RBS::AST::Declarations::Constant.new(
			name: constant_definition.name.to_sym,
			type: type,
			location: nil,
			comment: nil
		)
	end
end

def simple_name_to_rbs(name)

Convert a simple name to RBS TypeName (not qualified).

Implementation

def simple_name_to_rbs(name)
	::RBS::TypeName.new(name: name.to_sym, namespace: ::RBS::Namespace.empty)
end

def build_attributes_rbs(attribute_definitions)

Build attribute RBS declarations and infer instance variable types.

Signature

parameter attribute_definitions Array

Array of Attribute definition objects

returns Array

A tuple of [attribute_declarations, instance_variable_declarations]

Implementation

def build_attributes_rbs(attribute_definitions)
	attributes = []
	instance_variables = []
	
	# Create a mapping from attribute names to their types:
	attribute_types = {}
	
	attribute_definitions.each do |attr_def|
		# Extract @attribute type annotation from documentation:
		documentation = attr_def.documentation
		attribute_tags = documentation&.filter(Decode::Comment::Attribute)&.to_a
		
		if attribute_tags&.any?
			type_string = attribute_tags.first.type.strip
			type = ::Decode::RBS::Type.parse(type_string)
			
			attribute_types[attr_def.name] = type
			
			# Generate attr_reader RBS declaration:
			attributes << ::RBS::AST::Members::AttrReader.new(
				name: attr_def.name.to_sym,
				type: type,
				ivar_name: :"@#{attr_def.name}",
				kind: :instance,
				annotations: [],
				location: nil,
				comment: nil
			)
			
			# Generate instance variable declaration:
			instance_variables << ::RBS::AST::Members::InstanceVariable.new(
				name: :"@#{attr_def.name}",
				type: type,
				location: nil,
				comment: nil
			)
		end
	end
	
	[attributes, instance_variables]
end

def qualified_name_to_rbs(qualified_name)

Convert a qualified name to RBS TypeName

Implementation

def qualified_name_to_rbs(qualified_name)
	parts = qualified_name.split("::")
	name = parts.pop
	
	# For simple names (no ::), create relative references within current namespace:
	if parts.empty?
		::RBS::TypeName.new(name: name.to_sym, namespace: ::RBS::Namespace.empty)
	else
		# For qualified names within the same root namespace, use relative references.
		# This handles cases like `Comment::Node`, `Language::Generic` within `Decode` module.
		namespace = ::RBS::Namespace.new(path: parts.map(&:to_sym), absolute: false)
		::RBS::TypeName.new(name: name.to_sym, namespace: namespace)
	end
end