Skip to content

Commit

Permalink
ActiveRecordRelations support for generic definitions in AR models
Browse files Browse the repository at this point in the history
  • Loading branch information
gustavompo committed Jul 31, 2024
1 parent 21a9a6d commit 5df059c
Show file tree
Hide file tree
Showing 3 changed files with 782 additions and 1 deletion.
11 changes: 10 additions & 1 deletion lib/tapioca/dsl/compilers/active_record_relations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,16 @@ def common_relation_methods_module

sig { returns(String) }
def constant_name
@constant_name ||= T.let(T.must(qualified_name_of(constant)), T.nilable(String))
@constant_name ||= T.let(constant_name_of(constant), T.nilable(String))
end

sig { params(constant: ConstantType).returns(String) }
def constant_name_of(constant)
if T::Generic === constant
generic_name_of(constant)
else
T.must(qualified_name_of(constant))
end
end

sig { params(method_name: Symbol).returns(T::Boolean) }
Expand Down
28 changes: 28 additions & 0 deletions lib/tapioca/helpers/rbi_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,33 @@ def valid_parameter_name?(name)
rescue SyntaxError
false
end

sig { params(constant: T.all(Module, T::Generic)).returns(String) }
def generic_name_of(constant)
type_name = T.must(qualified_name_of(constant))
return type_name if type_name =~ /\[.*\]$/

type_variables = Runtime::GenericTypeRegistry.lookup_type_variables(constant)
return type_name unless type_variables

type_variables = type_variables.reject(&:fixed?)
return type_name if type_variables.empty?

type_variable_names = type_variables.map { "T.untyped" }.join(", ")

"#{type_name}[#{type_variable_names}]"
end

sig { params(constant: Module).returns(T.nilable(String)) }
def qualified_name_of(constant)
name = name_of(constant)
return if name.nil?

if name.start_with?("::")
name
else
"::#{name}"
end
end
end
end
Loading

0 comments on commit 5df059c

Please sign in to comment.