Skip to content

Commit

Permalink
Allow alias to module-self-type from module
Browse files Browse the repository at this point in the history
  • Loading branch information
soutaro committed Aug 2, 2024
1 parent 99bb5e2 commit 3fe6743
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
27 changes: 21 additions & 6 deletions lib/rbs/definition_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def define_interface(definition, type_name, subst)
interface_methods = interface_methods(included_interfaces)
methods = method_builder.build_interface(type_name)

import_methods(definition, type_name, methods, interface_methods, subst)
import_methods(definition, type_name, methods, interface_methods, subst, nil)
end

def build_interface(type_name)
Expand Down Expand Up @@ -86,6 +86,19 @@ def define_instance(definition, type_name, subst)
one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
methods = method_builder.build_instance(type_name)

self_type_methods = one_ancestors.each_self_type.with_object({}) do |self_type, hash| #$ Hash[Symbol, Definition::Method]
self_type.args.each do |arg|
validate_type_presence(arg)
end

self_type_defn = self_type.name.interface? ? build_interface(self_type.name) : build_instance(self_type.name)

s = subst + tapp_subst(self_type.name, self_type.args)
self_type_defn.methods.each do |method_name, method_def|
hash[method_name] = method_def.sub(s)
end
end

one_ancestors.each_included_module do |mod|
mod.args.each do |arg|
validate_type_presence(arg)
Expand All @@ -100,7 +113,7 @@ def define_instance(definition, type_name, subst)
[interface, *other_interfaces]
end
interface_methods = interface_methods(all_interfaces)
import_methods(definition, type_name, methods, interface_methods, subst)
import_methods(definition, type_name, methods, interface_methods, subst, self_type_methods)

one_ancestors.each_prepended_module do |mod|
mod.args.each do |arg|
Expand Down Expand Up @@ -254,7 +267,7 @@ def build_singleton0(type_name)
[interface, *other_interfaces]
end
interface_methods = interface_methods(all_interfaces)
import_methods(definition, type_name, methods, interface_methods, Substitution.new)
import_methods(definition, type_name, methods, interface_methods, Substitution.new, nil)

entry.decls.each do |d|
d.decl.members.each do |member|
Expand Down Expand Up @@ -529,7 +542,7 @@ def insert_variable(type_name, variables, name:, type:)
)
end

def import_methods(definition, module_name, module_methods, interfaces_methods, subst)
def import_methods(definition, module_name, module_methods, interfaces_methods, subst, self_type_methods)
new_methods = {} #: Hash[Symbol, Definition::Method]
interface_method_duplicates = Set[] #: Set[Symbol]

Expand Down Expand Up @@ -567,6 +580,7 @@ def import_methods(definition, module_name, module_methods, interfaces_methods,
definition,
method,
subst_,
nil,
defined_in: interface.name,
implemented_in: module_name
)
Expand All @@ -579,6 +593,7 @@ def import_methods(definition, module_name, module_methods, interfaces_methods,
definition,
method,
subst,
self_type_methods,
defined_in: module_name,
implemented_in: module_name.interface? ? nil : module_name
)
Expand All @@ -587,12 +602,12 @@ def import_methods(definition, module_name, module_methods, interfaces_methods,
definition.methods.merge!(new_methods)
end

def define_method(methods, definition, method, subst, defined_in:, implemented_in: defined_in)
def define_method(methods, definition, method, subst, self_type_methods, defined_in:, implemented_in: defined_in)
existing_method = methods[method.name] || definition.methods[method.name]

case original = method.original
when AST::Members::Alias
original_method = methods[original.old_name] || definition.methods[original.old_name]
original_method = methods[original.old_name] || definition.methods[original.old_name] || self_type_methods&.fetch(original.old_name, nil)

unless original_method
raise UnknownMethodAliasError.new(
Expand Down
4 changes: 3 additions & 1 deletion sig/definition_builder.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ module RBS
Definition class_definition,
MethodBuilder::Methods::Definition method_definition,
Substitution subst,
Hash[Symbol, Definition::Method]? self_type_methods,
defined_in: TypeName,
?implemented_in: TypeName?
) -> void
Expand All @@ -137,7 +138,8 @@ module RBS
TypeName module_name,
MethodBuilder::Methods module_methods,
interface_methods interface_methods,
Substitution subst
Substitution subst,
Hash[Symbol, Definition::Method]? self_type_methods,
) -> void

# Updates `definition` with methods and variables of `type_name` that can be a module or a class
Expand Down
19 changes: 19 additions & 0 deletions test/rbs/definition_builder_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2686,4 +2686,23 @@ module Bar : Foo
end
end
end

def test_alias__to_module_self_indierect_method
SignatureManager.new(system_builtin: false) do |manager|
manager.add_file("foo.rbs", <<-EOF)
module Kernel
alias foo __id__
end
module Foo
end
EOF

manager.build do |env|
builder = DefinitionBuilder.new(env: env)

builder.build_instance(type_name("::Foo"))
end
end
end
end

0 comments on commit 3fe6743

Please sign in to comment.