lib/rbs/definition_builder.rb in rbs-0.20.1 vs lib/rbs/definition_builder.rb in rbs-1.0.0.pre
- old
+ new
@@ -1,446 +1,322 @@
module RBS
class DefinitionBuilder
attr_reader :env
attr_reader :type_name_resolver
+ attr_reader :ancestor_builder
+ attr_reader :method_builder
attr_reader :instance_cache
attr_reader :singleton_cache
+ attr_reader :singleton0_cache
attr_reader :interface_cache
- attr_reader :one_instance_cache
- attr_reader :one_singleton_cache
-
- attr_reader :instance_ancestors_cache
- attr_reader :singleton_ancestor_cache
-
- attr_reader :one_instance_ancestors_cache
- attr_reader :one_singleton_ancestors_cache
-
- class OneAncestors
- attr_reader :type_name
- attr_reader :params
- attr_reader :super_class
- attr_reader :self_types
- attr_reader :included_modules
- attr_reader :prepended_modules
- attr_reader :extended_modules
-
- def initialize(type_name:, params:, super_class:, self_types:, included_modules:, prepended_modules:, extended_modules:)
- @type_name = type_name
- @params = params
- @super_class = super_class
- @self_types = self_types
- @included_modules = included_modules
- @prepended_modules = prepended_modules
- @extended_modules = extended_modules
- end
-
- def each_ancestor(&block)
- if block
- if s = super_class
- yield s
- end
-
- self_types&.each(&block)
- included_modules&.each(&block)
- prepended_modules&.each(&block)
- extended_modules&.each(&block)
- else
- enum_for :each_ancestor
- end
- end
-
- def self.class_instance(type_name:, params:, super_class:)
- new(
- type_name: type_name,
- params: params,
- super_class: super_class,
- self_types: nil,
- included_modules: [],
- prepended_modules: [],
- extended_modules: nil
- )
- end
-
- def self.singleton(type_name:, super_class:)
- new(
- type_name: type_name,
- params: nil,
- super_class: super_class,
- self_types: nil,
- included_modules: nil,
- prepended_modules: nil,
- extended_modules: []
- )
- end
-
- def self.module_instance(type_name:, params:)
- new(
- type_name: type_name,
- params: params,
- self_types: [],
- included_modules: [],
- prepended_modules: [],
- super_class: nil,
- extended_modules: nil
- )
- end
- end
-
def initialize(env:)
@env = env
@type_name_resolver = TypeNameResolver.from_env(env)
+ @ancestor_builder = AncestorBuilder.new(env: env)
+ @method_builder = MethodBuilder.new(env: env)
@instance_cache = {}
@singleton_cache = {}
+ @singleton0_cache = {}
@interface_cache = {}
-
- @one_instance_cache = {}
- @one_singleton_cache = {}
-
- @instance_ancestors_cache = {}
- @singleton_ancestor_cache = {}
-
- @one_instance_ancestors_cache = {}
- @one_singleton_ancestors_cache = {}
end
- def validate_super_class!(type_name, entry)
- with_super_classes = entry.decls.select {|d| d.decl.super_class }
-
- return if with_super_classes.size <= 1
-
- super_types = with_super_classes.map do |d|
- super_class = d.decl.super_class or raise
- Types::ClassInstance.new(name: super_class.name, args: super_class.args, location: nil)
+ def ensure_namespace!(namespace, location:)
+ namespace.ascend do |ns|
+ unless ns.empty?
+ NoTypeFoundError.check!(ns.to_type_name, env: env, location: location)
+ end
end
-
- super_types.uniq!
-
- return if super_types.size == 1
-
- raise SuperclassMismatchError.new(name: type_name, super_classes: super_types, entry: entry)
end
- def one_instance_ancestors(type_name)
- as = one_instance_ancestors_cache[type_name] and return as
+ def build_interface(type_name)
+ try_cache(type_name, cache: interface_cache) do
+ entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
+ declaration = entry.decl
+ ensure_namespace!(type_name.namespace, location: declaration.location)
- entry = env.class_decls[type_name] or raise "Unknown name for one_instance_ancestors: #{type_name}"
- params = entry.type_params.each.map(&:name)
+ self_type = Types::Interface.new(
+ name: type_name,
+ args: Types::Variable.build(declaration.type_params.each.map(&:name)),
+ location: nil
+ )
- case entry
- when Environment::ClassEntry
- validate_super_class!(type_name, entry)
- primary = entry.primary
- super_class = primary.decl.super_class
+ ancestors = ancestor_builder.interface_ancestors(type_name)
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
+ ancestor_builder.one_interface_ancestors(type_name).included_interfaces.each do |mod|
+ defn = build_interface(mod.name)
+ subst = Substitution.build(defn.type_params, mod.args)
- if type_name != BuiltinNames::BasicObject.name
- if super_class
- super_name = super_class.name
- super_args = super_class.args
- else
- super_name = BuiltinNames::Object.name
- super_args = []
+ defn.methods.each do |name, method|
+ definition.methods[name] = method.sub(subst)
+ end
end
- NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
+ methods = method_builder.build_interface(type_name)
+ methods.each do |defn|
+ method = case defn.original
+ when AST::Members::MethodDefinition
+ defs = defn.original.types.map do |method_type|
+ Definition::Method::TypeDef.new(
+ type: method_type,
+ member: defn.original,
+ defined_in: type_name,
+ implemented_in: nil
+ )
+ end
- ancestors = OneAncestors.class_instance(
- type_name: type_name,
- params: params,
- super_class: Definition::Ancestor::Instance.new(name: super_name, args: super_args)
- )
- else
- ancestors = OneAncestors.class_instance(
- type_name: type_name,
- params: params,
- super_class: nil
- )
- end
- when Environment::ModuleEntry
- ancestors = OneAncestors.module_instance(type_name: type_name, params: params)
+ Definition::Method.new(
+ super_method: nil,
+ defs: defs,
+ accessibility: :public,
+ alias_of: nil
+ )
+ when AST::Members::Alias
+ unless definition.methods.key?(defn.original.old_name)
+ raise UnknownMethodAliasError.new(
+ original_name: defn.original.old_name,
+ aliased_name: defn.original.new_name,
+ location: defn.original.location
+ )
+ end
- entry.self_types.each do |module_self|
- NoSelfTypeFoundError.check!(module_self, env: env)
+ original_method = definition.methods[defn.original.old_name]
+ Definition::Method.new(
+ super_method: nil,
+ defs: original_method.defs.map do |defn|
+ defn.update(implemented_in: nil, defined_in: type_name)
+ end,
+ accessibility: :public,
+ alias_of: original_method
+ )
+ when nil
+ unless definition.methods.key?(defn.name)
+ raise InvalidOverloadMethodError.new(
+ type_name: type_name,
+ method_name: defn.name,
+ kind: :instance,
+ members: defn.overloads
+ )
+ end
- self_types = ancestors.self_types or raise
- self_types.push Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
- end
- end
+ definition.methods[defn.name]
+ end
- mixin_ancestors(entry,
- included_modules: ancestors.included_modules,
- prepended_modules: ancestors.prepended_modules,
- extended_modules: nil)
+ defn.overloads.each do |overload|
+ defs = overload.types.map do |method_type|
+ Definition::Method::TypeDef.new(
+ type: method_type,
+ member: overload,
+ defined_in: type_name,
+ implemented_in: nil
+ )
+ end
- one_instance_ancestors_cache[type_name] = ancestors
- end
+ method.defs.unshift(*defs)
+ end
- def one_singleton_ancestors(type_name)
- as = one_singleton_ancestors_cache[type_name] and return as
-
- entry = env.class_decls[type_name] or raise "Unknown name for one_singleton_ancestors: #{type_name}"
-
- case entry
- when Environment::ClassEntry
- validate_super_class!(type_name, entry)
- primary = entry.primary
- super_class = primary.decl.super_class
-
- if type_name != BuiltinNames::BasicObject.name
- if super_class
- super_name = super_class.name
- else
- super_name = BuiltinNames::Object.name
+ definition.methods[defn.name] = method
end
-
- NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
-
- ancestors = OneAncestors.singleton(
- type_name: type_name,
- super_class: Definition::Ancestor::Singleton.new(name: super_name)
- )
- else
- ancestors = OneAncestors.singleton(
- type_name: type_name,
- super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Class.name, args: [])
- )
end
- when Environment::ModuleEntry
- ancestors = OneAncestors.singleton(
- type_name: type_name,
- super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Module.name, args: [])
- )
end
-
- mixin_ancestors(entry,
- included_modules: nil,
- prepended_modules: nil,
- extended_modules: ancestors.extended_modules)
-
- one_singleton_ancestors_cache[type_name] = ancestors
end
- def mixin_ancestors(entry, included_modules:, extended_modules:, prepended_modules:)
- entry.decls.each do |d|
- decl = d.decl
+ def build_instance(type_name)
+ try_cache(type_name, cache: instance_cache) do
+ entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
+ ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
- align_params = Substitution.build(
- decl.type_params.each.map(&:name),
- Types::Variable.build(entry.type_params.each.map(&:name))
- )
+ case entry
+ when Environment::ClassEntry, Environment::ModuleEntry
+ ancestors = ancestor_builder.instance_ancestors(type_name)
+ self_type = Types::ClassInstance.new(name: type_name,
+ args: Types::Variable.build(entry.type_params.each.map(&:name)),
+ location: nil)
- decl.each_mixin do |member|
- case member
- when AST::Members::Include
- if included_modules
- NoMixinFoundError.check!(member.name, env: env, member: member)
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
+ one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
+ methods = method_builder.build_instance(type_name)
- module_name = member.name
- module_args = member.args.map {|type| type.sub(align_params) }
+ validate_type_params definition, methods: methods, ancestors: one_ancestors
- included_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
+ if super_class = one_ancestors.super_class
+ defn = build_instance(super_class.name)
+ merge_definition(src: defn,
+ dest: definition,
+ subst: Substitution.build(defn.type_params, super_class.args),
+ keep_super: true)
end
- when AST::Members::Prepend
- if prepended_modules
- NoMixinFoundError.check!(member.name, env: env, member: member)
+ if one_ancestors.self_types
+ one_ancestors.self_types.each do |ans|
+ defn = if ans.name.interface?
+ build_interface(ans.name)
+ else
+ build_instance(ans.name)
+ end
- module_name = member.name
- module_args = member.args.map {|type| type.sub(align_params) }
-
- prepended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
+ # Successor interface method overwrites.
+ merge_definition(src: defn,
+ dest: definition,
+ subst: Substitution.build(defn.type_params, ans.args),
+ keep_super: true)
+ end
end
- when AST::Members::Extend
- if extended_modules
- NoMixinFoundError.check!(member.name, env: env, member: member)
-
- module_name = member.name
- module_args = member.args
-
- extended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
+ one_ancestors.included_modules.each do |mod|
+ defn = build_instance(mod.name)
+ merge_definition(src: defn,
+ dest: definition,
+ subst: Substitution.build(defn.type_params, mod.args))
end
- end
- end
- end
- end
- def instance_ancestors(type_name, building_ancestors: [])
- as = instance_ancestors_cache[type_name] and return as
+ interface_methods = {}
- entry = env.class_decls[type_name] or raise "Unknown name for instance_ancestors: #{type_name}"
- params = entry.type_params.each.map(&:name)
- args = Types::Variable.build(params)
- self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args)
+ one_ancestors.included_interfaces.each do |mod|
+ defn = build_interface(mod.name)
+ subst = Substitution.build(defn.type_params, mod.args)
- RecursiveAncestorError.check!(self_ancestor,
- ancestors: building_ancestors,
- location: entry.primary.decl.location)
- building_ancestors.push self_ancestor
+ defn.methods.each do |name, method|
+ if interface_methods.key?(name)
+ raise DuplicatedInterfaceMethodDefinitionError.new(
+ type: self_type,
+ method_name: name,
+ member: mod.source
+ )
+ end
- one_ancestors = one_instance_ancestors(type_name)
+ merge_method(type_name, interface_methods, name, method, subst, implemented_in: type_name)
+ end
+ end
- ancestors = []
+ define_methods(definition,
+ interface_methods: interface_methods,
+ methods: methods,
+ super_interface_method: entry.is_a?(Environment::ModuleEntry))
- case entry
- when Environment::ClassEntry
- if super_class = one_ancestors.super_class
- # @type var super_class: Definition::Ancestor::Instance
- super_name = super_class.name
- super_args = super_class.args
+ entry.decls.each do |d|
+ d.decl.members.each do |member|
+ case member
+ when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
+ if member.kind == :instance
+ ivar_name = case member.ivar_name
+ when false
+ nil
+ else
+ member.ivar_name || :"@#{member.name}"
+ end
- super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
- ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
- end
- end
+ if ivar_name
+ insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
+ end
+ end
- if included_modules = one_ancestors.included_modules
- included_modules.each do |mod|
- if mod.name.class?
- name = mod.name
- arg_types = mod.args
- mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
- ancestors.unshift(*mod_ancestors.apply(arg_types, location: entry.primary.decl.location))
- end
- end
- end
+ when AST::Members::InstanceVariable
+ insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
- ancestors.unshift(self_ancestor)
+ when AST::Members::ClassVariable
+ insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
+ end
+ end
+ end
- if prepended_modules = one_ancestors.prepended_modules
- prepended_modules.each do |mod|
- if mod.name.class?
- name = mod.name
- arg_types = mod.args
- mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
- ancestors.unshift(*mod_ancestors.apply(arg_types, location: entry.primary.decl.location))
+ one_ancestors.prepended_modules.each do |mod|
+ defn = build_instance(mod.name)
+ merge_definition(src: defn,
+ dest: definition,
+ subst: Substitution.build(defn.type_params, mod.args))
+ end
end
end
end
-
- building_ancestors.pop
-
- instance_ancestors_cache[type_name] = Definition::InstanceAncestors.new(
- type_name: type_name,
- params: params,
- ancestors: ancestors
- )
end
- def singleton_ancestors(type_name, building_ancestors: [])
- as = singleton_ancestor_cache[type_name] and return as
+ # Builds a definition for singleton without .new method.
+ #
+ def build_singleton0(type_name)
+ try_cache type_name, cache: singleton0_cache do
+ entry = env.class_decls[type_name] or raise "Unknown name for build_singleton0: #{type_name}"
+ ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
- entry = env.class_decls[type_name] or raise "Unknown name for singleton_ancestors: #{type_name}"
- self_ancestor = Definition::Ancestor::Singleton.new(name: type_name)
+ case entry
+ when Environment::ClassEntry, Environment::ModuleEntry
+ ancestors = ancestor_builder.singleton_ancestors(type_name)
+ self_type = Types::ClassSingleton.new(name: type_name, location: nil)
- RecursiveAncestorError.check!(self_ancestor,
- ancestors: building_ancestors,
- location: entry.primary.decl.location)
- building_ancestors.push self_ancestor
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
+ one_ancestors = ancestor_builder.one_singleton_ancestors(type_name)
- one_ancestors = one_singleton_ancestors(type_name)
+ if super_class = one_ancestors.super_class
+ case super_class
+ when Definition::Ancestor::Instance
+ defn = build_instance(super_class.name)
+ merge_definition(src: defn,
+ dest: definition,
+ subst: Substitution.build(defn.type_params, super_class.args),
+ keep_super: true)
+ when Definition::Ancestor::Singleton
+ defn = build_singleton0(super_class.name)
+ merge_definition(src: defn, dest: definition, subst: Substitution.new, keep_super: true)
+ end
+ end
- ancestors = []
+ one_ancestors.extended_modules.each do |mod|
+ defn = build_instance(mod.name)
+ merge_definition(src: defn,
+ dest: definition,
+ subst: Substitution.build(defn.type_params, mod.args))
+ end
- case super_class = one_ancestors.super_class
- when Definition::Ancestor::Instance
- super_name = super_class.name
- super_args = super_class.args
+ interface_methods = {}
+ one_ancestors.extended_interfaces.each do |mod|
+ defn = build_interface(mod.name)
+ subst = Substitution.build(defn.type_params, mod.args)
- super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
- ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
+ defn.methods.each do |name, method|
+ if interface_methods.key?(name)
+ raise DuplicatedInterfaceMethodDefinitionError.new(
+ type: self_type,
+ method_name: name,
+ member: mod.source
+ )
+ end
- when Definition::Ancestor::Singleton
- super_name = super_class.name
+ merge_method(type_name, interface_methods, name, method, subst, implemented_in: type_name)
+ end
+ end
- super_ancestors = singleton_ancestors(super_name, building_ancestors: [])
- ancestors.unshift(*super_ancestors.ancestors)
- end
+ methods = method_builder.build_singleton(type_name)
+ define_methods(definition, interface_methods: interface_methods, methods: methods, super_interface_method: false)
- extended_modules = one_ancestors.extended_modules or raise
- extended_modules.each do |mod|
- if mod.name.class?
- name = mod.name
- args = mod.args
- mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
- ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
- end
- end
+ entry.decls.each do |d|
+ d.decl.members.each do |member|
+ case member
+ when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
+ if member.kind == :singleton
+ ivar_name = case member.ivar_name
+ when false
+ nil
+ else
+ member.ivar_name || :"@#{member.name}"
+ end
- ancestors.unshift(self_ancestor)
+ if ivar_name
+ insert_variable(type_name, definition.instance_variables, name: ivar_name, type: member.type)
+ end
+ end
- building_ancestors.pop
+ when AST::Members::ClassInstanceVariable
+ insert_variable(type_name, definition.instance_variables, name: member.name, type: member.type)
- singleton_ancestor_cache[type_name] = Definition::SingletonAncestors.new(
- type_name: type_name,
- ancestors: ancestors
- )
- end
-
- def each_member_with_accessibility(members, accessibility: :public)
- members.each do |member|
- case member
- when AST::Members::Public
- accessibility = :public
- when AST::Members::Private
- accessibility = :private
- else
- yield member, accessibility
- end
- end
- end
-
- def ensure_namespace!(namespace, location:)
- namespace.ascend do |ns|
- unless ns.empty?
- NoTypeFoundError.check!(ns.to_type_name, env: env, location: location)
- end
- end
- end
-
- def build_instance(type_name)
- try_cache type_name, cache: instance_cache do
- entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
- ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
-
- case entry
- when Environment::ClassEntry, Environment::ModuleEntry
- ancestors = instance_ancestors(type_name)
- self_type = Types::ClassInstance.new(name: type_name,
- args: Types::Variable.build(entry.type_params.each.map(&:name)),
- location: nil)
-
- definition_pairs = ancestors.ancestors.map do |ancestor|
- # @type block: [Definition::Ancestor::t, Definition]
- case ancestor
- when Definition::Ancestor::Instance
- [ancestor, build_one_instance(ancestor.name)]
- when Definition::Ancestor::Singleton
- [ancestor, build_one_singleton(ancestor.name)]
+ when AST::Members::ClassVariable
+ insert_variable(type_name, definition.class_variables, name: member.name, type: member.type)
+ end
+ end
end
end
-
- case entry
- when Environment::ModuleEntry
- entry.self_types.each do |module_self|
- ancestor = Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
- definition_pairs.push(
- [
- ancestor,
- if module_self.name.interface?
- build_interface(module_self.name)
- else
- build_instance(module_self.name)
- end
- ]
- )
- end
- end
-
- merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
end
end
end
def build_singleton(type_name)
@@ -448,284 +324,88 @@
entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
case entry
when Environment::ClassEntry, Environment::ModuleEntry
- ancestors = singleton_ancestors(type_name)
+ ancestors = ancestor_builder.singleton_ancestors(type_name)
self_type = Types::ClassSingleton.new(name: type_name, location: nil)
instance_type = Types::ClassInstance.new(
name: type_name,
- args: Types::Variable.build(entry.type_params.each.map(&:name)),
+ args: entry.type_params.each.map { Types::Bases::Any.new(location: nil) },
location: nil
)
- definition_pairs = ancestors.ancestors.map do |ancestor|
- # @type block: [Definition::Ancestor::t, Definition]
- case ancestor
- when Definition::Ancestor::Instance
- [ancestor, build_one_instance(ancestor.name)]
- when Definition::Ancestor::Singleton
- definition = build_one_singleton(ancestor.name)
- definition = definition.sub(Substitution.build([], [], instance_type: instance_type))
- definition = definition.map_method_type do |method_type|
- s = Substitution.build(
- method_type.free_variables.to_a,
- method_type.free_variables.map { Types::Bases::Any.new(location: nil) }
- )
- method_type.sub(s)
- end
+ Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
+ def0 = build_singleton0(type_name)
+ subst = Substitution.build([], [], instance_type: instance_type)
- [
- ancestor,
- definition
- ]
- end
- end
+ merge_definition(src: def0, dest: definition, subst: subst, keep_super: true)
- merge_definitions(type_name, definition_pairs, entry: entry, self_type: self_type, ancestors: ancestors)
- end
- end
- end
+ if entry.is_a?(Environment::ClassEntry)
+ new_method = definition.methods[:new]
+ if new_method.defs.all? {|d| d.defined_in == BuiltinNames::Class.name }
+ # The method is _untyped new_.
- def method_definition_members(type_name, entry, kind:)
- # @type var interface_methods: Hash[Symbol, [Definition::Method, AST::Members::t]]
- interface_methods = {}
- # @type var methods: Hash[Symbol, Array[[AST::Members::MethodDefinition, Definition::accessibility]]]
- methods = {}
+ instance = build_instance(type_name)
+ initialize = instance.methods[:initialize]
- entry.decls.each do |d|
- each_member_with_accessibility(d.decl.members) do |member, accessibility|
- case member
- when AST::Members::MethodDefinition
- case kind
- when :singleton
- next unless member.singleton?
- when :instance
- next unless member.instance?
- end
+ if initialize
+ class_params = entry.type_params.each.map(&:name)
- methods[member.name] ||= []
- methods[member.name] << [
- member.update(types: member.types),
- accessibility
- ]
- when AST::Members::Include, AST::Members::Extend
- if member.name.interface?
- if (kind == :instance && member.is_a?(AST::Members::Include)) || (kind == :singleton && member.is_a?(AST::Members::Extend))
- NoMixinFoundError.check!(member.name, env: env, member: member)
+ # Inject a virtual _typed new_.
+ initialize_defs = initialize.defs
+ definition.methods[:new] = Definition::Method.new(
+ super_method: new_method,
+ defs: initialize_defs.map do |initialize_def|
+ method_type = initialize_def.type
- interface_name = member.name
- interface_args = member.args
+ class_type_param_vars = Set.new(class_params)
+ method_type_param_vars = Set.new(method_type.type_params)
- interface_definition = build_interface(interface_name)
+ if class_type_param_vars.intersect?(method_type_param_vars)
+ renamed_method_params = method_type.type_params.map do |name|
+ if class_type_param_vars.include?(name)
+ Types::Variable.fresh(name).name
+ else
+ name
+ end
+ end
+ method_params = class_params + renamed_method_params
- InvalidTypeApplicationError.check!(
- type_name: interface_name,
- args: interface_args,
- params: interface_definition.type_params_decl,
- location: member.location
- )
+ sub = Substitution.build(method_type.type_params, Types::Variable.build(renamed_method_params))
+ else
+ method_params = class_params + method_type.type_params
+ sub = Substitution.build([], [])
+ end
- sub = Substitution.build(interface_definition.type_params, interface_args)
+ method_type = method_type.map_type {|ty| ty.sub(sub) }
+ method_type = method_type.update(
+ type_params: method_params,
+ type: method_type.type.with_return_type(
+ Types::ClassInstance.new(
+ name: type_name,
+ args: Types::Variable.build(entry.type_params.each.map(&:name)),
+ location: nil
+ )
+ )
+ )
- interface_definition.methods.each do |name, method|
- interface_methods[name] = [method.sub(sub), member]
- end
- end
- end
- end
- end
- end
-
- # @type var result: Hash[Symbol, member_detail]
- result = {}
-
- interface_methods.each do |name, pair|
- method_definition, _ = pair
- # @type var detail: member_detail
- detail = [:public, method_definition, nil, []]
- result[name] = detail
- end
-
- methods.each do |method_name, array|
- if result[method_name]
- unless array.all? {|pair| pair[0].overload? }
- raise MethodDefinitionConflictWithInterfaceMixinError.new(
- type_name: type_name,
- method_name: method_name,
- kind: :instance,
- mixin_member: interface_methods[method_name][1],
- entries: array.map(&:first)
- )
- end
-
- unless array.all? {|pair| pair[1] == :public }
- raise InconsistentMethodVisibilityError.new(
- type_name: type_name,
- method_name: method_name,
- kind: :instance,
- member_pairs: array
- )
- end
-
- result[method_name][3].push(*array.map(&:first))
- else
- case
- when array.size == 1 && !array[0][0].overload?
- member, visibility = array[0]
- result[method_name] = [visibility, nil, member, []]
-
- else
- visibilities = array.group_by {|pair| pair[1] }
-
- if visibilities.size > 1
- raise InconsistentMethodVisibilityError.new(
- type_name: type_name,
- method_name: method_name,
- kind: :instance,
- member_pairs: array
- )
- end
-
- overloads, primary = array.map(&:first).partition(&:overload?)
- result[method_name] = [array[0][1], nil, primary[0], overloads]
- end
- end
- end
-
- result
- end
-
- def build_one_instance(type_name)
- try_cache(type_name, cache: one_instance_cache) do
- entry = env.class_decls[type_name]
-
- param_names = entry.type_params.each.map(&:name)
- self_type = Types::ClassInstance.new(name: type_name,
- args: Types::Variable.build(param_names),
- location: nil)
- ancestors = Definition::InstanceAncestors.new(
- type_name: type_name,
- params: param_names,
- ancestors: [Definition::Ancestor::Instance.new(name: type_name, args: self_type.args)]
- )
-
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
- method_definition_members(type_name, entry, kind: :instance).each do |method_name, array|
- visibility, method_def, primary_member, overload_members = array
-
- members = if primary_member
- [primary_member, *overload_members]
- else
- overload_members
- end
-
- m = if method_def
- Definition::Method.new(
- super_method: nil,
- accessibility: visibility,
- defs: method_def.defs.map {|defn| defn.update(implemented_in: type_name) },
+ Definition::Method::TypeDef.new(
+ type: method_type,
+ member: initialize_def.member,
+ defined_in: initialize_def.defined_in,
+ implemented_in: initialize_def.implemented_in
+ )
+ end,
+ accessibility: :public,
+ annotations: [],
alias_of: nil
)
- else
- Definition::Method.new(
- super_method: nil,
- accessibility: visibility,
- defs: [],
- alias_of: nil
- )
end
-
- definition.methods[method_name] = members.inject(m) do |original, member|
- defs = member.types.map do |method_type|
- Definition::Method::TypeDef.new(
- type: method_type,
- member: member,
- implemented_in: type_name,
- defined_in: type_name
- )
end
-
- Definition::Method.new(
- super_method: nil,
- defs: defs + original.defs,
- accessibility: original.accessibility,
- alias_of: nil
- )
end
end
-
- entry.decls.each do |d|
- each_member_with_accessibility(d.decl.members) do |member, accessibility|
- case member
- when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
- if member.kind == :instance
- build_attribute(
- type_name: type_name,
- definition: definition,
- member: member,
- accessibility: accessibility
- )
- end
-
- when AST::Members::InstanceVariable
- definition.instance_variables[member.name] = Definition::Variable.new(
- parent_variable: nil,
- type: member.type,
- declared_in: type_name
- )
-
- when AST::Members::ClassVariable
- definition.class_variables[member.name] = Definition::Variable.new(
- parent_variable: nil,
- type: member.type,
- declared_in: type_name
- )
-
- end
- end
- end
-
- entry.decls.each do |d|
- d.decl.members.each do |member|
- case member
- when AST::Members::Alias
- if member.instance?
- UnknownMethodAliasError.check!(
- methods: definition.methods,
- original_name: member.old_name,
- aliased_name: member.new_name,
- location: member.location
- )
-
- DuplicatedMethodDefinitionError.check!(
- decl: d.decl,
- methods: definition.methods,
- name: member.new_name,
- location: member.location
- )
-
- original_method = definition.methods[member.old_name]
-
- definition.methods[member.new_name] = Definition::Method.new(
- super_method: original_method.super_method,
- defs: original_method.defs,
- accessibility: original_method.accessibility,
- alias_of: original_method,
- annotations: original_method.annotations
- )
- end
- end
- end
- end
-
- entry.decls.each do |d|
- validate_parameter_variance(
- decl: d.decl,
- methods: definition.methods
- )
- end
end
end
end
def validate_params_with(type_params, result:)
@@ -736,353 +416,306 @@
end
end
end
end
- def validate_parameter_variance(decl:, methods:)
- type_params = decl.type_params
+ def validate_type_params(definition, ancestors:, methods:)
+ type_params = definition.type_params_decl
calculator = VarianceCalculator.new(builder: self)
param_names = type_params.each.map(&:name)
- errors = []
+ ancestors.each_ancestor do |ancestor|
+ case ancestor
+ when Definition::Ancestor::Instance
+ result = calculator.in_inherit(name: ancestor.name, args: ancestor.args, variables: param_names)
+ validate_params_with(type_params, result: result) do |param|
+ location = case source = ancestor.source
+ when nil
+ definition.entry.primary.decl.location
+ when :super
+ definition.entry.primary.decl.super_class.location
+ else
+ source.location
+ end
- case decl
- when AST::Declarations::Class
- if super_class = decl.super_class
- result = calculator.in_inherit(name: super_class.name, args: super_class.args, variables: param_names)
-
- validate_params_with type_params, result: result do |param|
- errors.push InvalidVarianceAnnotationError::InheritanceError.new(
- param: param
+ raise InvalidVarianceAnnotationError.new(
+ type_name: definition.type_name,
+ param: param,
+ location: location
)
end
end
end
- # @type var result: VarianceCalculator::Result
+ methods.each do |defn|
+ next if defn.name == :initialize
- decl.members.each do |member|
- case member
- when AST::Members::Include
- if member.name.class?
- result = calculator.in_inherit(name: member.name, args: member.args, variables: param_names)
+ method_types = case original = defn.original
+ when AST::Members::MethodDefinition
+ original.types
+ when AST::Members::AttrWriter, AST::Members::AttrReader, AST::Members::AttrAccessor
+ if defn.name.to_s.end_with?("=")
+ [
+ MethodType.new(
+ type_params: [],
+ type: Types::Function.empty(original.type).update(
+ required_positionals: [
+ Types::Function::Param.new(type: original.type, name: original.name)
+ ]
+ ),
+ block: nil,
+ location: original.location
+ )
+ ]
+ else
+ [
+ MethodType.new(
+ type_params: [],
+ type: Types::Function.empty(original.type),
+ block: nil,
+ location: original.location
+ )
+ ]
+ end
+ when AST::Members::Alias
+ nil
+ when nil
+ nil
+ else
+ raise
+ end
- validate_params_with type_params, result: result do |param|
- errors.push InvalidVarianceAnnotationError::MixinError.new(
- include_member: member,
- param: param
- )
- end
- end
- end
- end
-
- methods.each do |name, method|
- method.method_types.each do |method_type|
- unless name == :initialize
+ if method_types
+ method_types.each do |method_type|
result = calculator.in_method_type(method_type: method_type, variables: param_names)
-
- validate_params_with type_params, result: result do |param|
- errors.push InvalidVarianceAnnotationError::MethodTypeError.new(
- method_name: name,
- method_type: method_type,
- param: param
+ validate_params_with(type_params, result: result) do |param|
+ raise InvalidVarianceAnnotationError.new(
+ type_name: definition.type_name,
+ param: param,
+ location: method_type.location
)
end
end
end
end
+ end
- unless errors.empty?
- raise InvalidVarianceAnnotationError.new(decl: decl, errors: errors)
- end
+ def insert_variable(type_name, variables, name:, type:)
+ variables[name] = Definition::Variable.new(
+ parent_variable: variables[name],
+ type: type,
+ declared_in: type_name
+ )
end
- def build_one_singleton(type_name)
- try_cache(type_name, cache: one_singleton_cache) do
- entry = env.class_decls[type_name]
+ def define_methods(definition, interface_methods:, methods:, super_interface_method:)
+ methods.each do |method_def|
+ method_name = method_def.name
+ original = method_def.original
- self_type = Types::ClassSingleton.new(name: type_name, location: nil)
- ancestors = Definition::SingletonAncestors.new(
- type_name: type_name,
- ancestors: [Definition::Ancestor::Singleton.new(name: type_name)]
- )
+ if original.is_a?(AST::Members::Alias)
+ existing_method = interface_methods[method_name] || definition.methods[method_name]
+ original_method = interface_methods[original.old_name] || definition.methods[original.old_name]
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
- method_definition_members(type_name, entry, kind: :singleton).each do |method_name, array|
- visibility, method_def, primary_member, overload_members = array
+ unless original_method
+ raise UnknownMethodAliasError.new(
+ original_name: original.old_name,
+ aliased_name: original.new_name,
+ location: original.location
+ )
+ end
- members = if primary_member
- [primary_member, *overload_members]
- else
- overload_members
- end
+ method = Definition::Method.new(
+ super_method: existing_method,
+ defs: original_method.defs.map do |defn|
+ defn.update(defined_in: definition.type_name, implemented_in: definition.type_name)
+ end,
+ accessibility: method_def.accessibility,
+ alias_of: original_method
+ )
+ else
+ if interface_methods.key?(method_name)
+ interface_method = interface_methods[method_name]
- m = Definition::Method.new(
- super_method: nil,
- defs: method_def&.yield_self do |method_def|
- method_def.defs.map {|defn| defn.update(implemented_in: type_name) }
- end || [],
- accessibility: visibility,
- alias_of: nil
- )
- definition.methods[method_name] = members.inject(m) do |original, new|
- defs = new.types.map do |type|
- Definition::Method::TypeDef.new(
- type: type,
- member: new,
- defined_in: type_name,
- implemented_in: type_name
- )
- end
- Definition::Method.new(
- super_method: nil,
- defs: defs + original.defs,
- accessibility: original.accessibility,
- alias_of: nil
+ if method_def.original
+ raise DuplicatedMethodDefinitionError.new(
+ type: definition.self_type,
+ method_name: method_name,
+ members: [method_def.original]
)
end
+
+ definition.methods[method_name] = interface_method
end
- entry.decls.each do |d|
- d.decl.members.each do |member|
- case member
- when AST::Members::Alias
- if member.singleton?
- UnknownMethodAliasError.check!(
- methods: definition.methods,
- original_name: member.old_name,
- aliased_name: member.new_name,
- location: member.location
- )
+ existing_method = definition.methods[method_name]
- DuplicatedMethodDefinitionError.check!(
- decl: d.decl,
- methods: definition.methods,
- name: member.new_name,
- location: member.location
- )
-
- original_method = definition.methods[member.old_name]
- definition.methods[member.new_name] = Definition::Method.new(
- super_method: original_method.super_method,
- defs: original_method.defs,
- accessibility: original_method.accessibility,
- alias_of: original_method,
- annotations: original_method.annotations
- )
- end
- end
+ case original
+ when AST::Members::MethodDefinition
+ defs = original.types.map do |method_type|
+ Definition::Method::TypeDef.new(
+ type: method_type,
+ member: original,
+ defined_in: definition.type_name,
+ implemented_in: definition.type_name
+ )
end
- end
- unless definition.methods.key?(:new)
- instance = build_instance(type_name)
- initialize = instance.methods[:initialize]
+ accessibility = if method_name == :initialize
+ :private
+ else
+ method_def.accessibility
+ end
- if initialize
- class_params = entry.type_params.each.map(&:name)
+ method = Definition::Method.new(
+ super_method: existing_method,
+ defs: defs,
+ accessibility: accessibility,
+ alias_of: nil
+ )
- initialize_defs = initialize.defs
- definition.methods[:new] = Definition::Method.new(
- super_method: nil,
- defs: initialize_defs.map do |initialize_def|
- method_type = initialize_def.type
+ when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
+ method_type = if method_name.to_s.end_with?("=")
+ # setter
+ MethodType.new(
+ type_params: [],
+ type: Types::Function.empty(original.type).update(
+ required_positionals: [
+ Types::Function::Param.new(type: original.type, name: original.name)
+ ]
+ ),
+ block: nil,
+ location: nil
+ )
+ else
+ # getter
+ MethodType.new(
+ type_params: [],
+ type: Types::Function.empty(original.type),
+ block: nil,
+ location: nil
+ )
+ end
+ defs = [
+ Definition::Method::TypeDef.new(
+ type: method_type,
+ member: original,
+ defined_in: definition.type_name,
+ implemented_in: definition.type_name
+ )
+ ]
- class_type_param_vars = Set.new(class_params)
- method_type_param_vars = Set.new(method_type.type_params)
+ method = Definition::Method.new(
+ super_method: existing_method,
+ defs: defs,
+ accessibility: method_def.accessibility,
+ alias_of: nil
+ )
- if class_type_param_vars.intersect?(method_type_param_vars)
- renamed_method_params = method_type.type_params.map do |name|
- if class_type_param_vars.include?(name)
- Types::Variable.fresh(name).name
- else
- name
- end
- end
- method_params = class_params + renamed_method_params
-
- sub = Substitution.build(method_type.type_params, Types::Variable.build(renamed_method_params))
- else
- method_params = class_params + method_type.type_params
- sub = Substitution.build([], [])
- end
-
- method_type = method_type.map_type {|ty| ty.sub(sub) }
- method_type = method_type.update(
- type_params: method_params,
- type: method_type.type.with_return_type(Types::Bases::Instance.new(location: nil))
- )
-
- Definition::Method::TypeDef.new(
- type: method_type,
- member: initialize_def.member,
- defined_in: initialize_def.defined_in,
- implemented_in: initialize_def.implemented_in
- )
- end,
- accessibility: :public,
- annotations: [AST::Annotation.new(location: nil, string: "rbs:test:target")],
- alias_of: nil
+ when nil
+ unless definition.methods.key?(method_name)
+ raise InvalidOverloadMethodError.new(
+ type_name: definition.type_name,
+ method_name: method_name,
+ kind: :instance,
+ members: method_def.overloads
)
end
- end
- entry.decls.each do |d|
- each_member_with_accessibility(d.decl.members) do |member, accessibility|
- case member
- when AST::Members::AttrReader, AST::Members::AttrAccessor, AST::Members::AttrWriter
- if member.kind == :singleton
- build_attribute(type_name: type_name,
- definition: definition,
- member: member,
- accessibility: accessibility)
- end
-
- when AST::Members::ClassInstanceVariable
- definition.instance_variables[member.name] = Definition::Variable.new(
- parent_variable: nil,
- type: member.type,
- declared_in: type_name
- )
-
- when AST::Members::ClassVariable
- definition.class_variables[member.name] = Definition::Variable.new(
- parent_variable: nil,
- type: member.type,
- declared_in: type_name
- )
- end
+ if !super_interface_method && existing_method.defs.any? {|defn| defn.defined_in.interface? }
+ super_method = existing_method.super_method
+ else
+ super_method = existing_method
end
+
+ method = Definition::Method.new(
+ super_method: super_method,
+ defs: existing_method.defs.map do |defn|
+ defn.update(implemented_in: definition.type_name)
+ end,
+ accessibility: existing_method.accessibility,
+ alias_of: existing_method.alias_of
+ )
end
end
- end
- end
- def build_attribute(type_name:, definition:, member:, accessibility:)
- name = member.name
- type = member.type
-
- ivar_name = case member.ivar_name
- when false
- nil
- else
- member.ivar_name || :"@#{member.name}"
- end
-
- if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
- definition.methods[name] = Definition::Method.new(
- super_method: nil,
- defs: [
+ method_def.overloads.each do |overload|
+ defs = overload.types.map do |method_type|
Definition::Method::TypeDef.new(
- type: MethodType.new(
- type_params: [],
- type: Types::Function.empty(type),
- block: nil,
- location: nil
- ),
- member: member,
- defined_in: type_name,
- implemented_in: type_name
+ type: method_type,
+ member: overload,
+ defined_in: definition.type_name,
+ implemented_in: definition.type_name
)
- ],
- accessibility: accessibility,
- alias_of: nil
- )
- end
+ end
- if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
- definition.methods[:"#{name}="] = Definition::Method.new(
- super_method: nil,
- defs: [
- Definition::Method::TypeDef.new(
- type: MethodType.new(
- type_params: [],
- type: Types::Function.empty(type).update(
- required_positionals: [Types::Function::Param.new(name: name, type: type)]
- ),
- block: nil,
- location: nil
- ),
- member: member,
- defined_in: type_name,
- implemented_in: type_name
- ),
- ],
- accessibility: accessibility,
- alias_of: nil
- )
+ method.defs.unshift(*defs)
+ end
+
+ definition.methods[method_name] = method
end
- if ivar_name
- definition.instance_variables[ivar_name] = Definition::Variable.new(
- parent_variable: nil,
- type: type,
- declared_in: type_name
- )
+ interface_methods.each do |name, method|
+ unless methods.methods.key?(name)
+ merge_method(definition.type_name, definition.methods, name, method, Substitution.new)
+ end
end
end
- def merge_definitions(type_name, pairs, entry:, self_type:, ancestors:)
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
- pairs.reverse_each do |ancestor, current_definition|
- sub = case ancestor
- when Definition::Ancestor::Instance
- Substitution.build(current_definition.type_params, ancestor.args)
- when Definition::Ancestor::Singleton
- Substitution.build([], [])
- end
+ def merge_definition(src:, dest:, subst:, implemented_in: :keep, keep_super: false)
+ src.methods.each do |name, method|
+ merge_method(dest.type_name, dest.methods, name, method, subst, implemented_in: implemented_in, keep_super: keep_super)
+ end
- # @type var kind: method_kind
- kind = case ancestor
- when Definition::Ancestor::Instance
- :instance
- when Definition::Ancestor::Singleton
- :singleton
- end
+ src.instance_variables.each do |name, variable|
+ merge_variable(dest.instance_variables, name, variable, subst, keep_super: keep_super)
+ end
- current_definition.methods.each do |name, method|
- merge_method type_name, definition.methods, name, method, sub, kind: kind
- end
-
- current_definition.instance_variables.each do |name, variable|
- merge_variable definition.instance_variables, name, variable
- end
-
- current_definition.class_variables.each do |name, variable|
- merge_variable definition.class_variables, name, variable
- end
- end
+ src.class_variables.each do |name, variable|
+ merge_variable(dest.class_variables, name, variable, subst, keep_super: keep_super)
end
end
- def merge_variable(variables, name, variable)
+ def merge_variable(variables, name, variable, sub, keep_super: false)
super_variable = variables[name]
variables[name] = Definition::Variable.new(
- parent_variable: super_variable,
- type: variable.type,
+ parent_variable: keep_super ? variable.parent_variable : super_variable,
+ type: sub.empty? ? variable.type : variable.type.sub(sub),
declared_in: variable.declared_in
)
end
- def merge_method(type_name, methods, name, method, sub, kind:)
+ def merge_method(type_name, methods, name, method, sub, implemented_in: :keep, keep_super: false)
+ defs = method.defs.yield_self do |defs|
+ if sub.empty? && implemented_in == :keep
+ defs
+ else
+ defs.map do |defn|
+ defn.update(
+ type: sub.empty? ? defn.type : defn.type.sub(sub),
+ implemented_in: case implemented_in
+ when :keep
+ defn.implemented_in
+ when nil
+ nil
+ else
+ implemented_in
+ end
+ )
+ end
+ end
+ end
+
super_method = methods[name]
- defs = if method.defs.all? {|d| d.overload? }
- raise InvalidOverloadMethodError.new(type_name: type_name, method_name: name, kind: kind, members: method.members) unless super_method
- method.defs + super_method.defs
- else
- method.defs
- end
-
methods[name] = Definition::Method.new(
- super_method: super_method,
+ super_method: keep_super ? method.super_method : super_method,
accessibility: method.accessibility,
- defs: sub.mapping.empty? ? defs : defs.map {|defn| defn.update(type: defn.type.sub(sub)) },
- alias_of: nil
+ defs: defs,
+ alias_of: method.alias_of
)
end
def try_cache(type_name, cache:)
cached = _ = cache[type_name]
@@ -1100,106 +733,9 @@
cache.delete(type_name)
raise ex
end
else
raise
- end
- end
-
- def build_interface(type_name)
- try_cache(type_name, cache: interface_cache) do
- entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
- declaration = entry.decl
- ensure_namespace!(type_name.namespace, location: declaration.location)
-
- self_type = Types::Interface.new(
- name: type_name,
- args: Types::Variable.build(declaration.type_params.each.map(&:name)),
- location: nil
- )
-
- Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: nil).tap do |definition|
- include_members = []
- def_members = []
- alias_members = []
-
- declaration.members.each do |member|
- case member
- when AST::Members::Include
- include_members << member
- when AST::Members::MethodDefinition
- def_members << member
- when AST::Members::Alias
- alias_members << member
- end
- end
-
- include_members.each do |member|
- NoMixinFoundError.check!(member.name, env: env, member: member)
-
- mixin = build_interface(member.name)
-
- args = member.args
- # @type var interface_entry: Environment::SingleEntry[TypeName, AST::Declarations::Interface]
- interface_entry = _ = mixin.entry
- type_params = interface_entry.decl.type_params
-
- InvalidTypeApplicationError.check!(
- type_name: type_name,
- args: args,
- params: type_params.each.map(&:name),
- location: member.location
- )
-
- sub = Substitution.build(type_params.each.map(&:name), args)
- mixin.methods.each do |name, method|
- definition.methods[name] = method.sub(sub)
- end
- end
-
- def_members.each do |member|
- DuplicatedMethodDefinitionError.check!(
- decl: declaration,
- methods: definition.methods,
- name: member.name,
- location: member.location
- )
-
- method = Definition::Method.new(
- super_method: nil,
- defs: member.types.map do |method_type|
- Definition::Method::TypeDef.new(
- type: method_type,
- member: member,
- defined_in: type_name,
- implemented_in: nil
- )
- end,
- accessibility: :public,
- alias_of: nil
- )
- definition.methods[member.name] = method
- end
-
- alias_members.each do |member|
- UnknownMethodAliasError.check!(
- methods: definition.methods,
- original_name: member.old_name,
- aliased_name: member.new_name,
- location: member.location
- )
-
- DuplicatedMethodDefinitionError.check!(
- decl: declaration,
- methods: definition.methods,
- name: member.new_name,
- location: member.location
- )
-
- # FIXME: may cause a problem if #old_name has super type
- definition.methods[member.new_name] = definition.methods[member.old_name]
- end
- end
end
end
def expand_alias(type_name)
entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"