Skip to content

Commit 6a36805

Browse files
committed
Merge pull request #756 from Shopify/uk-fix-nilable-untyped
Never generate `T.nilable(T.untyped)` in DSL generators
1 parent 042399f commit 6a36805

File tree

10 files changed

+42
-31
lines changed

10 files changed

+42
-31
lines changed

lib/tapioca/compilers/dsl/active_model_attributes.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def type_for(attribute_type_value)
109109
return "T.untyped"
110110
end
111111

112-
"T.nilable(#{type})"
112+
as_nilable_type(type)
113113
end
114114

115115
sig { params(klass: RBI::Scope, method: String, type: String).void }

lib/tapioca/compilers/dsl/active_record_associations.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ def populate_associations(mod, constant)
184184
end
185185
def populate_single_assoc_getter_setter(klass, constant, association_name, reflection)
186186
association_class = type_for(constant, reflection)
187-
association_type = "T.nilable(#{association_class})"
187+
association_type = as_nilable_type(association_class)
188188

189189
klass.create_method(
190190
association_name.to_s,

lib/tapioca/compilers/dsl/active_record_columns.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,6 @@ def add_methods_for_attribute(klass, constant, column_name, attribute_name = col
293293
return_type: "T::Boolean"
294294
)
295295
end
296-
297-
sig { params(type: String).returns(String) }
298-
def as_nilable_type(type)
299-
return type if type.start_with?("T.nilable(") || type == "T.untyped"
300-
"T.nilable(#{type})"
301-
end
302296
end
303297
end
304298
end

lib/tapioca/compilers/dsl/active_record_relations.rb

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,15 @@ def generate
250250
sig { returns(String) }
251251
attr_reader :constant_name
252252

253+
sig { params(type: String).returns(String) }
254+
def as_nilable_type(type)
255+
if type.start_with?("T.nilable(", "::T.nilable(") || type == "T.untyped" || type == "::T.untyped"
256+
type
257+
else
258+
"T.nilable(#{type})"
259+
end
260+
end
261+
253262
sig { void }
254263
def create_classes_and_includes
255264
model.create_extend(CommonRelationMethodsModuleName)
@@ -546,7 +555,7 @@ def create_common_methods
546555
parameters: [
547556
create_rest_param("args", type: "T.untyped"),
548557
],
549-
return_type: "T.nilable(#{constant_name})"
558+
return_type: as_nilable_type(constant_name)
550559
)
551560
when :find_by!
552561
create_common_method(
@@ -570,7 +579,7 @@ def create_common_methods
570579
return_type = if method_name.end_with?("!")
571580
constant_name
572581
else
573-
"T.nilable(#{constant_name})"
582+
as_nilable_type(constant_name)
574583
end
575584

576585
create_common_method(

lib/tapioca/compilers/dsl/active_record_typed_store.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def decorate(root, constant)
107107
store_data.accessors.each do |accessor|
108108
field = store_data.fields[accessor]
109109
type = type_for(field.type_sym)
110-
type = "T.nilable(#{type})" if field.null && type != "T.untyped"
110+
type = as_nilable_type(type) if field.null
111111

112112
store_accessors_module = model.create_module("StoreAccessors")
113113
generate_methods(store_accessors_module, field.name.to_s, type)

lib/tapioca/compilers/dsl/base.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,15 @@ def compile_method_return_type_to_rbi(method_def)
176176
return_type
177177
end
178178

179+
sig { params(type: String).returns(String) }
180+
def as_nilable_type(type)
181+
if type.start_with?("T.nilable(", "::T.nilable(") || type == "T.untyped" || type == "::T.untyped"
182+
type
183+
else
184+
"T.nilable(#{type})"
185+
end
186+
end
187+
179188
sig { params(name: String).returns(T::Boolean) }
180189
def valid_parameter_name?(name)
181190
name.match?(/^[[[:alnum:]]_]+$/)

lib/tapioca/compilers/dsl/identity_cache.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def type_for_field(field, returns_collection:)
116116
if returns_collection
117117
COLLECTION_TYPE.call(cache_type)
118118
else
119-
"T.nilable(::#{cache_type})"
119+
as_nilable_type(T.must(qualified_name_of(cache_type)))
120120
end
121121
rescue ArgumentError
122122
"T.untyped"
@@ -175,18 +175,20 @@ def create_index_fetch_by_methods(field, klass, constant)
175175
parameters << create_kw_opt_param("includes", default: "nil", type: "T.untyped")
176176

177177
if field.unique
178+
type = T.must(qualified_name_of(constant))
179+
178180
klass.create_method(
179181
"#{name}!",
180182
class_method: true,
181183
parameters: parameters,
182-
return_type: "::#{constant}"
184+
return_type: type
183185
)
184186

185187
klass.create_method(
186188
name,
187189
class_method: true,
188190
parameters: parameters,
189-
return_type: "T.nilable(::#{constant})"
191+
return_type: as_nilable_type(type)
190192
)
191193
else
192194
klass.create_method(

lib/tapioca/compilers/dsl/rails_generators.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def type_for(arg)
111111
if arg.required || arg.default
112112
type
113113
else
114-
"T.nilable(#{type})"
114+
as_nilable_type(type)
115115
end
116116
end
117117
end

lib/tapioca/compilers/dsl/smart_properties.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,8 @@ def type_for(property)
143143
"T.untyped"
144144
end
145145

146-
# Early return for "T.untyped", nothing more to do.
147-
return type if type == "T.untyped"
148-
149146
might_be_optional = Proc === required || !required
150-
type = "T.nilable(#{type})" if might_be_optional
147+
type = as_nilable_type(type) if might_be_optional
151148

152149
type
153150
end

spec/tapioca/compilers/dsl/active_record_associations_spec.rb

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,16 +184,16 @@ class Post
184184
include GeneratedAssociationMethods
185185
186186
module GeneratedAssociationMethods
187-
sig { returns(T.nilable(T.untyped)) }
187+
sig { returns(T.untyped) }
188188
def category; end
189189
190-
sig { params(value: T.nilable(T.untyped)).void }
190+
sig { params(value: T.untyped).void }
191191
def category=(value); end
192192
193193
sig { params(attributes: T.untyped).returns(T.untyped) }
194194
def category_attributes=(attributes); end
195195
196-
sig { returns(T.nilable(T.untyped)) }
196+
sig { returns(T.untyped) }
197197
def reload_category; end
198198
end
199199
end
@@ -872,16 +872,16 @@ class Post
872872
include GeneratedAssociationMethods
873873
874874
module GeneratedAssociationMethods
875-
sig { returns(T.nilable(T.untyped)) }
875+
sig { returns(T.untyped) }
876876
def category; end
877877
878-
sig { params(value: T.nilable(T.untyped)).void }
878+
sig { params(value: T.untyped).void }
879879
def category=(value); end
880880
881881
sig { params(attributes: T.untyped).returns(T.untyped) }
882882
def category_attributes=(attributes); end
883883
884-
sig { returns(T.nilable(T.untyped)) }
884+
sig { returns(T.untyped) }
885885
def reload_category; end
886886
end
887887
end
@@ -1500,22 +1500,22 @@ def create_photo_blob(*args, &blk); end
15001500
sig { params(args: T.untyped, blk: T.untyped).returns(T.untyped) }
15011501
def create_photo_blob!(*args, &blk); end
15021502
1503-
sig { returns(T.nilable(T.untyped)) }
1503+
sig { returns(T.untyped) }
15041504
def photo_attachment; end
15051505
1506-
sig { params(value: T.nilable(T.untyped)).void }
1506+
sig { params(value: T.untyped).void }
15071507
def photo_attachment=(value); end
15081508
1509-
sig { returns(T.nilable(T.untyped)) }
1509+
sig { returns(T.untyped) }
15101510
def photo_blob; end
15111511
1512-
sig { params(value: T.nilable(T.untyped)).void }
1512+
sig { params(value: T.untyped).void }
15131513
def photo_blob=(value); end
15141514
1515-
sig { returns(T.nilable(T.untyped)) }
1515+
sig { returns(T.untyped) }
15161516
def reload_photo_attachment; end
15171517
1518-
sig { returns(T.nilable(T.untyped)) }
1518+
sig { returns(T.untyped) }
15191519
def reload_photo_blob; end
15201520
end
15211521
end

0 commit comments

Comments
 (0)