lib/rbs/definition.rb in rbs-0.4.0 vs lib/rbs/definition.rb in rbs-0.5.0
- old
+ new
@@ -8,33 +8,82 @@
def initialize(parent_variable:, type:, declared_in:)
@parent_variable = parent_variable
@type = type
@declared_in = declared_in
end
+
+ def sub(s)
+ self.class.new(
+ parent_variable: parent_variable,
+ type: type.sub(s),
+ declared_in: declared_in
+ )
+ end
end
class Method
+ class TypeDef
+ attr_reader :type
+ attr_reader :member
+ attr_reader :defined_in
+ attr_reader :implemented_in
+
+ def initialize(type:, member:, defined_in:, implemented_in:)
+ @type = type
+ @member = member
+ @defined_in = defined_in
+ @implemented_in = implemented_in
+ end
+
+ def comment
+ member.comment
+ end
+
+ def annotations
+ member.annotations
+ end
+
+ def update(type: self.type, member: self.member, defined_in: self.defined_in, implemented_in: self.implemented_in)
+ TypeDef.new(type: type, member: member, defined_in: defined_in, implemented_in: implemented_in)
+ end
+ end
+
attr_reader :super_method
- attr_reader :method_types
- attr_reader :defined_in
- attr_reader :implemented_in
+ attr_reader :defs
attr_reader :accessibility
- attr_reader :attributes
- attr_reader :annotations
- attr_reader :comment
- def initialize(super_method:, method_types:, defined_in:, implemented_in:, accessibility:, attributes:, annotations:, comment:)
+ def initialize(super_method:, defs:, accessibility:)
@super_method = super_method
- @method_types = method_types
- @defined_in = defined_in
- @implemented_in = implemented_in
+ @defs = defs
@accessibility = accessibility
- @attributes = attributes
- @annotations = annotations
- @comment = comment
end
+ def defined_in
+ @defined_in ||= defs.last.defined_in
+ end
+
+ def implemented_in
+ @implemented_in ||= defs.last.implemented_in
+ end
+
+ def method_types
+ @method_types ||= defs.map(&:type)
+ end
+
+ def comments
+ @comments ||= defs.map(&:comment).compact
+ end
+
+ def annotations
+ @annotations ||= defs.flat_map(&:annotations)
+ end
+
+ # @deprecated
+ def attributes
+ []
+ end
+
def public?
@accessibility == :public
end
def private?
@@ -42,124 +91,191 @@
end
def sub(s)
self.class.new(
super_method: super_method&.sub(s),
- method_types: method_types.map {|ty| ty.sub(s) },
- defined_in: defined_in,
- implemented_in: implemented_in,
- accessibility: @accessibility,
- attributes: attributes,
- annotations: annotations,
- comment: comment
+ defs: defs.map {|defn| defn.update(type: defn.type.sub(s)) },
+ accessibility: @accessibility
)
end
def map_type(&block)
self.class.new(
super_method: super_method&.map_type(&block),
- method_types: method_types.map do |ty|
- ty.map_type(&block)
- end,
- defined_in: defined_in,
- implemented_in: implemented_in,
- accessibility: @accessibility,
- attributes: attributes,
- annotations: annotations,
- comment: comment
+ defs: defs.map {|defn| defn.update(type: defn.type.map_type(&block)) },
+ accessibility: @accessibility
)
end
+
+ def map_method_type(&block)
+ self.class.new(
+ super_method: super_method,
+ defs: defs.map {|defn| defn.update(type: yield(defn.type)) },
+ accessibility: @accessibility
+ )
+ end
end
module Ancestor
Instance = Struct.new(:name, :args, keyword_init: true)
Singleton = Struct.new(:name, keyword_init: true)
- ExtensionInstance = Struct.new(:name, :extension_name, :args, keyword_init: true)
- ExtensionSingleton = Struct.new(:name, :extension_name, keyword_init: true)
end
- attr_reader :declaration
+ class InstanceAncestors
+ attr_reader :type_name
+ attr_reader :params
+ attr_reader :ancestors
+
+ def initialize(type_name:, params:, ancestors:)
+ @type_name = type_name
+ @params = params
+ @ancestors = ancestors
+ end
+
+ def apply(args, location:)
+ InvalidTypeApplicationError.check!(
+ type_name: type_name,
+ args: args,
+ params: params,
+ location: location
+ )
+
+ subst = Substitution.build(params, args)
+
+ ancestors.map do |ancestor|
+ case ancestor
+ when Ancestor::Instance
+ if ancestor.args.empty?
+ ancestor
+ else
+ Ancestor::Instance.new(
+ name: ancestor.name,
+ args: ancestor.args.map {|type| type.sub(subst) }
+ )
+ end
+ when Ancestor::Singleton
+ ancestor
+ end
+ end
+ end
+ end
+
+ class SingletonAncestors
+ attr_reader :type_name
+ attr_reader :ancestors
+
+ def initialize(type_name:, ancestors:)
+ @type_name = type_name
+ @ancestors = ancestors
+ end
+ end
+
+ attr_reader :type_name
+ attr_reader :entry
+ attr_reader :ancestors
attr_reader :self_type
attr_reader :methods
attr_reader :instance_variables
attr_reader :class_variables
- attr_reader :ancestors
- def initialize(declaration:, self_type:, ancestors:)
- unless declaration.is_a?(AST::Declarations::Class) ||
- declaration.is_a?(AST::Declarations::Module) ||
- declaration.is_a?(AST::Declarations::Interface) ||
- declaration.is_a?(AST::Declarations::Extension)
- raise "Declaration should be a class, module, or interface: #{declaration.name}"
+ def initialize(type_name:, entry:, self_type:, ancestors:)
+ case entry
+ when Environment::ClassEntry, Environment::ModuleEntry
+ # ok
+ else
+ unless entry.decl.is_a?(AST::Declarations::Interface)
+ raise "Declaration should be a class, module, or interface: #{type_name}"
+ end
end
- unless (self_type.is_a?(Types::ClassSingleton) || self_type.is_a?(Types::Interface) || self_type.is_a?(Types::ClassInstance)) && self_type.name == declaration.name.absolute!
+ unless self_type.is_a?(Types::ClassSingleton) || self_type.is_a?(Types::Interface) || self_type.is_a?(Types::ClassInstance)
raise "self_type should be the type of declaration: #{self_type}"
end
+ @type_name = type_name
@self_type = self_type
- @declaration = declaration
+ @entry = entry
@methods = {}
@instance_variables = {}
@class_variables = {}
@ancestors = ancestors
end
- def name
- declaration.name
- end
-
def class?
- declaration.is_a?(AST::Declarations::Class)
+ entry.is_a?(Environment::ClassEntry)
end
def module?
- declaration.is_a?(AST::Declarations::Module)
+ entry.is_a?(Environment::ModuleEntry)
end
+ def interface?
+ entry.is_a?(Environment::SingleEntry) && entry.decl.is_a?(AST::Declarations::Interface)
+ end
+
def class_type?
- @self_type.is_a?(Types::ClassSingleton)
+ self_type.is_a?(Types::ClassSingleton)
end
def instance_type?
- @self_type.is_a?(Types::ClassInstance)
+ self_type.is_a?(Types::ClassInstance)
end
def interface_type?
- @self_type.is_a?(Types::Interface)
+ self_type.is_a?(Types::Interface)
end
def type_params
- @self_type.args.map(&:name)
+ type_params_decl.each.map(&:name)
end
def type_params_decl
- case declaration
- when AST::Declarations::Extension
- nil
- else
- declaration.type_params
+ case entry
+ when Environment::ClassEntry, Environment::ModuleEntry
+ entry.type_params
+ when Environment::SingleEntry
+ entry.decl.type_params
end
end
+ def sub(s)
+ definition = self.class.new(type_name: type_name, self_type: self_type.sub(s), ancestors: ancestors, entry: entry)
+
+ definition.methods.merge!(methods.transform_values {|method| method.sub(s) })
+ definition.instance_variables.merge!(instance_variables.transform_values {|v| v.sub(s) })
+ definition.class_variables.merge!(class_variables.transform_values {|v| v.sub(s) })
+
+ definition
+ end
+
+ def map_method_type(&block)
+ definition = self.class.new(type_name: type_name, self_type: self_type, ancestors: ancestors, entry: entry)
+
+ definition.methods.merge!(methods.transform_values {|method| method.map_method_type(&block) })
+ definition.instance_variables.merge!(instance_variables)
+ definition.class_variables.merge!(class_variables)
+
+ definition
+ end
+
def each_type(&block)
if block_given?
methods.each_value do |method|
- if method.defined_in == self.declaration
+ if method.defined_in == type_name
method.method_types.each do |method_type|
method_type.each_type(&block)
end
end
end
instance_variables.each_value do |var|
- if var.declared_in == self.declaration
+ if var.declared_in == type_name
yield var.type
end
end
class_variables.each_value do |var|
- if var.declared_in == self.declaration
+ if var.declared_in == type_name
yield var.type
end
end
else
enum_for :each_type