lib/tapioca/compilers/dynamic_mixin_compiler.rb in tapioca-0.6.1 vs lib/tapioca/compilers/dynamic_mixin_compiler.rb in tapioca-0.6.2
- old
+ new
@@ -172,27 +172,52 @@
tree << RBI::Include.new("GeneratedInstanceMethods")
end
sig { params(tree: RBI::Tree).returns([T::Array[Module], T::Array[Module]]) }
def compile_mixes_in_class_methods(tree)
- includes = dynamic_includes.select { |mod| (name = name_of(mod)) && !name.start_with?("T::") }
- includes.each do |mod|
+ includes = dynamic_includes.map do |mod|
qname = qualified_name_of(mod)
- tree << RBI::Include.new(T.must(qname))
- end
+ next if qname.nil? || qname.empty?
+ next if filtered_mixin?(qname)
+
+ tree << RBI::Include.new(qname)
+
+ mod
+ end.compact
+
# If we can generate multiple mixes_in_class_methods, then we want to use all dynamic extends that are not the
# constant itself
- mixed_in_class_methods = dynamic_extends.select { |mod| mod != @constant }
+ mixed_in_class_methods = dynamic_extends.select do |mod|
+ mod != @constant && !module_included_by_another_dynamic_extend?(mod, dynamic_extends)
+ end
+
return [[], []] if mixed_in_class_methods.empty?
mixed_in_class_methods.each do |mod|
qualified_name = qualified_name_of(mod)
+
next if qualified_name.nil? || qualified_name.empty?
+ next if filtered_mixin?(qualified_name)
+
tree << RBI::MixesInClassMethods.new(qualified_name)
end
[mixed_in_class_methods, includes]
rescue
[[], []] # silence errors
+ end
+
+ sig { params(mod: Module, dynamic_extends: T::Array[Module]).returns(T::Boolean) }
+ def module_included_by_another_dynamic_extend?(mod, dynamic_extends)
+ dynamic_extends.any? do |dynamic_extend|
+ mod != dynamic_extend && ancestors_of(dynamic_extend).include?(mod)
+ end
+ end
+
+ sig { params(qualified_mixin_name: String).returns(T::Boolean) }
+ def filtered_mixin?(qualified_mixin_name)
+ # filter T:: namespace mixins that aren't T::Props
+ # T::Props and subconstants have semantic value
+ qualified_mixin_name.start_with?("::T::") && !qualified_mixin_name.start_with?("::T::Props")
end
end