Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DefinitionBuilder #1268

Merged
merged 3 commits into from
Mar 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions lib/rbs/definition_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ def ensure_namespace!(namespace, location:)
end

def define_interface(definition, type_name, subst)
included_interfaces = ancestor_builder.one_interface_ancestors(type_name).included_interfaces or raise
interface_methods = interface_methods(included_interfaces)
included_interfaces = ancestor_builder.interface_ancestors(type_name).ancestors #: Array[Definition::Ancestor::Instance]
included_interfaces = included_interfaces.reject {|ancestor| ancestor.source == nil }

interface_methods = interface_methods(included_interfaces)
methods = method_builder.build_interface(type_name)

import_methods(definition, type_name, methods, interface_methods, subst)
Expand All @@ -55,7 +56,6 @@ def build_interface(type_name)
Definition.new(type_name: type_name, entry: entry, self_type: self_type, ancestors: ancestors).tap do |definition|
methods = method_builder.build_interface(type_name)
one_ancestors = ancestor_builder.one_interface_ancestors(type_name)

validate_type_params(definition, methods: methods, ancestors: one_ancestors)

define_interface(definition, type_name, subst)
Expand Down Expand Up @@ -94,7 +94,12 @@ def define_instance(definition, type_name, subst)
define_instance(definition, mod.name, subst + tapp_subst(mod.name, mod.args))
end

interface_methods = interface_methods(one_ancestors.each_included_interface.to_a)
all_interfaces = one_ancestors.each_included_interface.flat_map do |interface|
other_interfaces = ancestor_builder.interface_ancestors(interface.name).ancestors #: Array[Definition::Ancestor::Instance]
other_interfaces = other_interfaces.select {|ancestor| ancestor.source }
[interface, *other_interfaces]
end
interface_methods = interface_methods(all_interfaces)
import_methods(definition, type_name, methods, interface_methods, subst)

one_ancestors.each_prepended_module do |mod|
Expand Down Expand Up @@ -219,6 +224,7 @@ def build_singleton0(type_name)

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)
methods = method_builder.build_singleton(type_name)

if super_class = one_ancestors.super_class
case super_class
Expand All @@ -233,8 +239,13 @@ def build_singleton0(type_name)
definition.class_variables.merge!(defn.class_variables)
end

one_ancestors = ancestor_builder.one_singleton_ancestors(type_name)
methods = method_builder.build_singleton(type_name)
all_interfaces = one_ancestors.each_extended_interface.flat_map do |interface|
other_interfaces = ancestor_builder.interface_ancestors(interface.name).ancestors #: Array[Definition::Ancestor::Instance]
other_interfaces = other_interfaces.select {|ancestor| ancestor.source }
[interface, *other_interfaces]
end
interface_methods = interface_methods(all_interfaces)
import_methods(definition, type_name, methods, interface_methods, Substitution.new)

one_ancestors.each_extended_module do |mod|
mod.args.each do |arg|
Expand Down Expand Up @@ -279,7 +290,7 @@ def build_singleton0(type_name)

def build_singleton(type_name)
type_name = env.normalize_module_name(type_name)

try_cache type_name, cache: singleton_cache do
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)
Expand Down Expand Up @@ -683,8 +694,8 @@ def define_method(methods, definition, method, subst, defined_in:, implemented_i
Definition::Method::TypeDef.new(
type: method_type,
member: original,
defined_in: definition.type_name,
implemented_in: definition.type_name
defined_in: defined_in,
implemented_in: implemented_in
)
],
accessibility: method.accessibility,
Expand Down Expand Up @@ -713,7 +724,7 @@ def define_method(methods, definition, method, subst, defined_in:, implemented_i
method_definition = Definition::Method.new(
super_method: super_method,
defs: existing_method.defs.map do |defn|
defn.update(implemented_in: definition.type_name)
defn.update(implemented_in: implemented_in)
end,
accessibility: existing_method.accessibility,
alias_of: existing_method.alias_of
Expand All @@ -725,8 +736,8 @@ def define_method(methods, definition, method, subst, defined_in:, implemented_i
type_def = Definition::Method::TypeDef.new(
type: subst.empty? ? overload.method_type : overload.method_type.sub(subst),
member: overloading_def,
defined_in: definition.type_name,
implemented_in: definition.type_name
defined_in: defined_in,
implemented_in: implemented_in
)

method_definition.defs.unshift(type_def)
Expand Down
44 changes: 31 additions & 13 deletions lib/rbs/definition_builder/ancestor_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -432,8 +432,9 @@ def instance_ancestors(type_name, building_ancestors: [])
super_name = super_class.name
super_args = super_class.args

super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors).apply(super_args, location: entry.primary.decl.location)
super_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: super_name, source: :super) }
ancestors.unshift(*super_ancestors)
end
end

Expand All @@ -450,8 +451,9 @@ def instance_ancestors(type_name, building_ancestors: [])
included_modules.each do |mod|
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))
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors).apply(arg_types, location: entry.primary.decl.location)
mod_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: name, source: mod.source) }
ancestors.unshift(*mod_ancestors)
end
end

Expand All @@ -461,8 +463,9 @@ def instance_ancestors(type_name, building_ancestors: [])
prepended_modules.each do |mod|
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))
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors).apply(arg_types, location: entry.primary.decl.location)
mod_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: name, source: mod.source) }
ancestors.unshift(*mod_ancestors)
end
end

Expand Down Expand Up @@ -495,8 +498,9 @@ def singleton_ancestors(type_name, building_ancestors: [])
super_name = super_class.name
super_args = super_class.args

super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors).apply(super_args, location: entry.primary.decl.location)
super_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: super_name, source: :super) }
ancestors.unshift(*super_ancestors)

when Definition::Ancestor::Singleton
super_name = super_class.name
Expand All @@ -509,8 +513,9 @@ def singleton_ancestors(type_name, building_ancestors: [])
extended_modules.each do |mod|
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))
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors).apply(args, location: entry.primary.decl.location)
mod_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: name, source: mod.source) }
ancestors.unshift(*mod_ancestors)
end

ancestors.unshift(self_ancestor)
Expand Down Expand Up @@ -541,9 +546,9 @@ def interface_ancestors(type_name, building_ancestors: [])

included_interfaces = one_ancestors.included_interfaces or raise
included_interfaces.each do |a|
included_ancestors = interface_ancestors(a.name, building_ancestors: building_ancestors)

ancestors.unshift(*included_ancestors.apply(a.args, location: entry.decl.location))
included_ancestors = interface_ancestors(a.name, building_ancestors: building_ancestors).apply(a.args, location: entry.decl.location)
included_ancestors.map! {|ancestor| fill_ancestor_source(ancestor, name: a.name, source: a.source) }
ancestors.unshift(*included_ancestors)
end

ancestors.unshift(self_ancestor)
Expand All @@ -555,6 +560,19 @@ def interface_ancestors(type_name, building_ancestors: [])
ancestors: ancestors
)
end

def fill_ancestor_source(ancestor, name:, source:, &block)
case ancestor
when Definition::Ancestor::Instance
if ancestor.name == name && !ancestor.source
Definition::Ancestor::Instance.new(name: ancestor.name, args: ancestor.args, source: source)
else
ancestor
end
else
ancestor
end
end
end
end
end
4 changes: 4 additions & 0 deletions sig/ancestor_builder.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ module RBS
prepended_modules: Array[Definition::Ancestor::Instance]?,
extended_modules: Array[Definition::Ancestor::Instance]?,
extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void

# Fill `#source` of instance ancestor if `ancestor.name == name` and its `source` is `nil`
#
def fill_ancestor_source: (Definition::Ancestor::t, name: TypeName, source: Definition::Ancestor::Instance::source) -> Definition::Ancestor::t
end
end
end
5 changes: 3 additions & 2 deletions sig/definition.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ module RBS
type t = Instance | Singleton

class Instance
type source = :super | nil
| AST::Members::Include | AST::Members::Extend | AST::Members::Prepend
type source = :super # Inheritance
| nil # Itself
| AST::Members::Include | AST::Members::Extend | AST::Members::Prepend # AST
| AST::Declarations::Module::Self

attr_reader name: TypeName
Expand Down
4 changes: 4 additions & 0 deletions sig/definition_builder.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ module RBS
#
def define_instance: (Definition definition, TypeName type_name, Substitution subst) -> void

# Updates `definition` with methods defined in an interface `type_name`
#
# It processes includes recursively
#
def define_interface: (Definition definition, TypeName type_name, Substitution subst) -> void

# Returns a substitution that corresponds to type application
Expand Down
Loading