lib/parlour/rbi_generator/class_namespace.rb in parlour-0.1.1 vs lib/parlour/rbi_generator/class_namespace.rb in parlour-0.2.0
- old
+ new
@@ -1,58 +1,82 @@
# typed: true
module Parlour
class RbiGenerator
+ # Represents a class definition.
class ClassNamespace < Namespace
extend T::Sig
sig do
params(
+ generator: RbiGenerator,
name: String,
superclass: T.nilable(String),
abstract: T::Boolean,
block: T.nilable(T.proc.params(x: ClassNamespace).void)
).void
end
- def initialize(name, superclass, abstract, &block)
- super(&block)
- @name = name
+ # Creates a new class definition.
+ # @note You should use {Namespace#create_class} rather than this directly.
+ #
+ # @param generator [RbiGenerator] The current RbiGenerator.
+ # @param name [String] The name of this class.
+ # @param superclass [String, nil] The superclass of this class, or nil if it doesn't
+ # have one.
+ # @param abstract [Boolean] A boolean indicating whether this class is abstract.
+ # @param block A block which the new instance yields itself to.
+ # @return [void]
+ def initialize(generator, name, superclass, abstract, &block)
+ super(generator, name, &block)
@superclass = superclass
@abstract = abstract
end
sig do
override.params(
indent_level: Integer,
options: Options
).returns(T::Array[String])
end
+ # Generates the RBI lines for this class.
+ #
+ # @param indent_level [Integer] The indentation level to generate the lines at.
+ # @param options [Options] The formatting options to use.
+ # @return [Array<String>] The RBI lines, formatted as specified.
def generate_rbi(indent_level, options)
class_definition = superclass.nil? \
? "class #{name}"
: "class #{name} < #{superclass}"
- lines = []
+ lines = generate_comments(indent_level, options)
lines << options.indented(indent_level, class_definition)
lines += [options.indented(indent_level + 1, "abstract!"), ""] if abstract
- lines += super(indent_level + 1, options)
+ lines += generate_body(indent_level + 1, options)
lines << options.indented(indent_level, "end")
end
- sig { returns(String) }
- attr_reader :name
-
sig { returns(T.nilable(String)) }
+ # The superclass of this class, or nil if it doesn't have one.
+ # @return [String, nil]
attr_reader :superclass
sig { returns(T::Boolean) }
+ # A boolean indicating whether this class is abstract or not.
+ # @return [Boolean]
attr_reader :abstract
sig do
override.params(
others: T::Array[RbiGenerator::RbiObject]
).returns(T::Boolean)
end
+ # Given an array of {ClassNamespace} instances, returns true if they may
+ # be merged into this instance using {merge_into_self}. For instances to
+ # be mergeable, they must either all be abstract or all not be abstract,
+ # and they must define the same superclass (or none at all).
+ #
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other {ClassNamespace} instances.
+ # @return [Boolean] Whether this instance may be merged with them.
def mergeable?(others)
others = T.cast(others, T::Array[ClassNamespace]) rescue (return false)
all = others + [self]
all.map(&:abstract).uniq.length == 1 &&
@@ -62,19 +86,31 @@
sig do
override.params(
others: T::Array[RbiGenerator::RbiObject]
).void
end
+ # Given an array of {ClassNamespace} instances, merges them into this one.
+ # You MUST ensure that {mergeable?} is true for those instances.
+ #
+ # @param others [Array<RbiGenerator::RbiObject>] An array of other {ClassNamespace} instances.
+ # @return [void]
def merge_into_self(others)
+ super
+
others.each do |other|
other = T.cast(other, ClassNamespace)
- other.children.each { |c| children << c }
- other.extends.each { |e| extends << e }
- other.includes.each { |i| includes << i }
-
@superclass = other.superclass unless superclass
end
end
+
+ sig { override.returns(String) }
+ # Returns a human-readable brief string description of this class.
+ # @return [String]
+ def describe
+ "Class #{name} - #{"superclass #{superclass}, " if superclass}" +
+ "#{"abstract, " if abstract}#{children.length} children, " +
+ "#{includes.length} includes, #{extends.length} extends"
+ end
end
end
-end
\ No newline at end of file
+end