Skip to content

Commit 21e5071

Browse files
committed
Fully qualify inserted extend T::Generic and T::Helpers
Previously, a TypeError could be raised when we tried to insert an `extend T::Generic` or `extend T::Helpers` into a class that had a generic type member called `T` This commit fully qualifies inserted extends to `::T::Generic` and `::T::Helpers` to prevent this
1 parent fdf2815 commit 21e5071

2 files changed

Lines changed: 52 additions & 23 deletions

File tree

lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,11 @@ def apply_class_annotations(node)
231231
node.expression.location.end_offset
232232
end
233233

234-
# Only translate (and `extend T::Helpers`) when there's at least one *known* class
234+
# Only translate (and `extend ::T::Helpers`) when there's at least one *known* class
235235
# annotation. A node with only unknown annotations (e.g. `@private`) is left untouched.
236236
if comments.class_annotations.any?
237237
unless already_extends?(node, /^(::)?T::Helpers$/)
238-
extend_with("T::Helpers", into: node, at: insert_pos)
238+
extend_with("::T::Helpers", into: node, at: insert_pos)
239239
end
240240

241241
comments.annotations.reverse_each do |annotation|
@@ -287,7 +287,7 @@ def apply_class_annotations(node)
287287
end
288288

289289
unless already_extends?(node, /^(::)?T::Generic$/)
290-
extend_with("T::Generic", into: node, at: insert_pos)
290+
extend_with("::T::Generic", into: node, at: insert_pos)
291291
end
292292

293293
type_params.each do |type_param|

test/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs_test.rb

Lines changed: 49 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def qux; end
167167

168168
to_pretty_format_for_humans: <<~RUBY,
169169
class Foo
170-
extend T::Helpers
170+
extend ::T::Helpers
171171
172172
abstract!
173173
@@ -177,7 +177,7 @@ def bar; end
177177
end
178178
179179
module Baz
180-
extend T::Helpers
180+
extend ::T::Helpers
181181
182182
abstract!
183183
@@ -189,14 +189,14 @@ def qux; end
189189

190190
to_line_matched_format_for_machines: <<~RUBY,
191191
# RBS_REWRITTEN_ANNOTATION: @abstract
192-
class Foo; extend T::Helpers; abstract!
192+
class Foo; extend ::T::Helpers; abstract!
193193
# @abstract
194194
#: -> String
195195
def bar; end
196196
end
197197
198198
# RBS_REWRITTEN_ANNOTATION: @abstract
199-
module Baz; extend T::Helpers; abstract!
199+
module Baz; extend ::T::Helpers; abstract!
200200
# @abstract
201201
#: -> String
202202
def qux; end
@@ -481,21 +481,21 @@ class << self
481481

482482
to_pretty_format_for_humans: <<~RUBY,
483483
class A
484-
extend T::Helpers
484+
extend ::T::Helpers
485485
486486
abstract!
487487
488488
requires_ancestor { ::T.class_of(Foo::Bar) }
489489
490490
module B
491-
extend T::Helpers
491+
extend ::T::Helpers
492492
493493
interface!
494494
495495
sealed!
496496
497497
class << self
498-
extend T::Helpers
498+
extend ::T::Helpers
499499
500500
final!
501501
end
@@ -506,12 +506,12 @@ class << self
506506
to_line_matched_format_for_machines: <<~RUBY,
507507
# RBS_REWRITTEN_ANNOTATION: @abstract
508508
# RBS_REWRITTEN_ANNOTATION: @requires_ancestor: singleton(Foo::Bar)
509-
class A; extend T::Helpers; abstract!; requires_ancestor { ::T.class_of(Foo::Bar) }
509+
class A; extend ::T::Helpers; abstract!; requires_ancestor { ::T.class_of(Foo::Bar) }
510510
# RBS_REWRITTEN_ANNOTATION: @interface
511511
# RBS_REWRITTEN_ANNOTATION: @sealed
512-
module B; extend T::Helpers; interface!; sealed!
512+
module B; extend ::T::Helpers; interface!; sealed!
513513
# RBS_REWRITTEN_ANNOTATION: @final
514-
class << self; extend T::Helpers; final!
514+
class << self; extend ::T::Helpers; final!
515515
end
516516
end
517517
end
@@ -549,7 +549,7 @@ def foo; end
549549
# @foo
550550
# @bar
551551
module Baz
552-
extend T::Helpers
552+
extend ::T::Helpers
553553
554554
requires_ancestor { Kernel }
555555
@@ -562,7 +562,7 @@ def foo; end
562562
# RBS_IGNORED_UNKNOWN_ANNOTATION: @foo
563563
# RBS_IGNORED_UNKNOWN_ANNOTATION: @bar
564564
# RBS_REWRITTEN_ANNOTATION: @requires_ancestor: Kernel
565-
module Baz; extend T::Helpers; requires_ancestor { Kernel }
565+
module Baz; extend ::T::Helpers; requires_ancestor { Kernel }
566566
sig { void }
567567
def foo; end
568568
end
@@ -586,21 +586,21 @@ class << self
586586

587587
to_pretty_format_for_humans: <<~RUBY,
588588
class A
589-
extend T::Generic
589+
extend ::T::Generic
590590
591591
A = type_member(:in)
592592
593593
B = type_member(:out)
594594
595595
module B
596-
extend T::Generic
596+
extend ::T::Generic
597597
598598
A = type_member
599599
600600
B = type_member {{ upper: C }}
601601
602602
class << self
603-
extend T::Generic
603+
extend ::T::Generic
604604
605605
A = type_member {{ fixed: ::T.class_of(Numeric) }}
606606
end
@@ -610,18 +610,47 @@ class << self
610610

611611
to_line_matched_format_for_machines: <<~RUBY,
612612
# RBS_WRITTEN_ANNOTATION: [in A, out B]
613-
class A; extend T::Generic; A = type_member(:in); B = type_member(:out)
613+
class A; extend ::T::Generic; A = type_member(:in); B = type_member(:out)
614614
# RBS_WRITTEN_ANNOTATION: [A, B < C]
615-
module B; extend T::Generic; A = type_member; B = type_member {{ upper: C }}
615+
module B; extend ::T::Generic; A = type_member; B = type_member {{ upper: C }}
616616
# RBS_WRITTEN_ANNOTATION: [A = singleton(Numeric)]
617-
class << self; extend T::Generic; A = type_member {{ fixed: ::T.class_of(Numeric) }}
617+
class << self; extend ::T::Generic; A = type_member {{ fixed: ::T.class_of(Numeric) }}
618618
end
619619
end
620620
end
621621
RUBY
622622
)
623623
end
624624

625+
def test_translate_to_rbi_fully_qualifies_extend_t_generic_and_helpers
626+
assert_rewrites_rbs(
627+
from: <<~RUBY,
628+
# @final
629+
#: [T]
630+
class Box
631+
end
632+
RUBY
633+
634+
to_pretty_format_for_humans: <<~RUBY,
635+
class Box
636+
extend ::T::Helpers
637+
638+
final!
639+
extend ::T::Generic
640+
641+
T = type_member
642+
end
643+
RUBY
644+
645+
to_line_matched_format_for_machines: <<~RUBY,
646+
# RBS_REWRITTEN_ANNOTATION: @final
647+
# RBS_WRITTEN_ANNOTATION: [T]
648+
class Box; extend ::T::Helpers; final!; extend ::T::Generic; T = type_member
649+
end
650+
RUBY
651+
)
652+
end
653+
625654
def test_translate_to_rbi_preserves_generic_types
626655
contents = <<~RB
627656
#: -> Array[Integer]
@@ -1379,7 +1408,7 @@ class Foo
13791408
RUBY
13801409
to_pretty_format_for_humans: <<~RUBY,
13811410
class Foo
1382-
extend T::Generic
1411+
extend ::T::Generic
13831412
13841413
A = type_member
13851414
B = type_member
@@ -1388,7 +1417,7 @@ class Foo
13881417
to_line_matched_format_for_machines: <<~RUBY,
13891418
# RBS_WRITTEN_ANNOTATION: [A,
13901419
# RBS_WRITTEN_ANNOTATION: B]
1391-
class Foo; extend T::Generic; A = type_member; B = type_member
1420+
class Foo; extend ::T::Generic; A = type_member; B = type_member
13921421
end
13931422
RUBY
13941423
)

0 commit comments

Comments
 (0)