rubocop-sorbet 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +1 -1
  3. data/.rubocop.yml +12 -1
  4. data/.yardopts +1 -0
  5. data/Gemfile +1 -0
  6. data/Gemfile.lock +23 -17
  7. data/README.md +1 -1
  8. data/Rakefile +1 -1
  9. data/bin/rspec +4 -2
  10. data/bin/rubocop +4 -2
  11. data/config/default.yml +23 -2
  12. data/lib/rubocop/cop/sorbet/binding_constant_without_type_alias.rb +105 -0
  13. data/lib/rubocop/cop/sorbet/callback_conditionals_binding.rb +39 -11
  14. data/lib/rubocop/cop/sorbet/constants_from_strings.rb +5 -3
  15. data/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb +27 -23
  16. data/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb +26 -27
  17. data/lib/rubocop/cop/sorbet/forbid_t_unsafe.rb +7 -3
  18. data/lib/rubocop/cop/sorbet/forbid_t_untyped.rb +7 -3
  19. data/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb +13 -11
  20. data/lib/rubocop/cop/sorbet/implicit_conversion_method.rb +56 -0
  21. data/lib/rubocop/cop/sorbet/mixin/target_sorbet_version.rb +49 -0
  22. data/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb +8 -5
  23. data/lib/rubocop/cop/sorbet/obsolete_strict_memoization.rb +92 -0
  24. data/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb +8 -3
  25. data/lib/rubocop/cop/sorbet/rbi/forbid_extend_t_sig_helpers_in_shims.rb +12 -18
  26. data/lib/rubocop/cop/sorbet/rbi/forbid_rbi_outside_of_allowed_paths.rb +8 -7
  27. data/lib/rubocop/cop/sorbet/rbi/single_line_rbi_class_module_definitions.rb +12 -18
  28. data/lib/rubocop/cop/sorbet/redundant_extend_t_sig.rb +5 -6
  29. data/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb +3 -2
  30. data/lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb +6 -5
  31. data/lib/rubocop/cop/sorbet/sigils/false_sigil.rb +1 -1
  32. data/lib/rubocop/cop/sorbet/sigils/has_sigil.rb +1 -1
  33. data/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb +1 -1
  34. data/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb +1 -1
  35. data/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb +1 -1
  36. data/lib/rubocop/cop/sorbet/sigils/true_sigil.rb +1 -1
  37. data/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb +50 -25
  38. data/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb +19 -30
  39. data/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb +3 -2
  40. data/lib/rubocop/cop/sorbet/signatures/empty_line_after_sig.rb +3 -3
  41. data/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb +8 -4
  42. data/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb +5 -4
  43. data/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb +8 -3
  44. data/lib/rubocop/cop/sorbet/signatures/signature_cop.rb +6 -1
  45. data/lib/rubocop/cop/sorbet/type_alias_name.rb +10 -17
  46. data/lib/rubocop/cop/sorbet_cops.rb +6 -1
  47. data/lib/rubocop/sorbet/inject.rb +9 -7
  48. data/lib/rubocop/sorbet/version.rb +2 -1
  49. data/lib/rubocop/sorbet.rb +1 -0
  50. data/manual/cops.md +2 -0
  51. data/manual/cops_sorbet.md +137 -31
  52. data/rubocop-sorbet.gemspec +1 -0
  53. data/tasks/cops_documentation.rake +16 -5
  54. metadata +8 -4
  55. data/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb +0 -127
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87c7e5f3cd38dc5528234c83895115c4f0fe10010c041c0c914f73cf92f289f4
4
- data.tar.gz: f991837c8cce7938ae4f0043b2c10a98b9130bd01f0d2b95f62a967e03337fab
3
+ metadata.gz: c0d4456bcb92b2f40f1208842fce6a102f6ce2ba88ff491840d77a3001784677
4
+ data.tar.gz: 5e389a2c6c772f68aaf95555da670732ac70a9c5262be18c0418e0d787feb5de
5
5
  SHA512:
6
- metadata.gz: 71581073a6caba33b050d643815d98fdeae36d17eedbbcab985b9b467c9ccde100f153c58970ac3fb06f03c7834170fab65276f499bcf5e398b8dfdcde0ae5f7
7
- data.tar.gz: 66ab517902652d5921967544c7c81d89b758886d9c893b2ed60d0e32a4826fc8391c6e91c6c0701e17c916a0a6535390fead92f740cc367e34530865cc4e4122
6
+ metadata.gz: c2cb4129f91d6c52aa3affe2728a9c049635ce9ccefdcaa86520bbf0a1d25b7160a3d253597329008661f4207bf953ec36058c3908874b6f9077da0742a9f15f
7
+ data.tar.gz: c4736a927b8f377f81bf7982e9a6d6fa4669b6ebc7dea5c60bba7a8e54adc843f096c8bfe6a0eea7fc47e34cc4374c4675495936d5c9b1289a17b2d226c44375
@@ -11,7 +11,7 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- ruby: [ '2.5', '2.6', '2.7', '3.0', '3.1', '3.2' ]
14
+ ruby: [ '2.7', '3.0', '3.1', '3.2' ]
15
15
  name: Test Ruby ${{ matrix.ruby }}
16
16
  steps:
17
17
  - uses: actions/checkout@v2
data/.rubocop.yml CHANGED
@@ -3,11 +3,22 @@
3
3
  inherit_gem:
4
4
  rubocop-shopify: rubocop.yml
5
5
 
6
+ require:
7
+ - rubocop/cop/internal_affairs
8
+
6
9
  AllCops:
7
- TargetRubyVersion: 2.5
10
+ TargetRubyVersion: 2.7
8
11
  Exclude:
9
12
  - vendor/**/*
13
+ NewCops: disable
14
+ SuggestExtensions: false
15
+
16
+ InternalAffairs:
17
+ Enabled: true
10
18
 
11
19
  Naming/FileName:
12
20
  Exclude:
13
21
  - lib/rubocop-sorbet.rb
22
+
23
+ Layout/LineLength:
24
+ IgnoreCopDirectives: true
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --tag safety:"Cop Safety Information"
data/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  source "https://rubygems.org"
3
4
 
4
5
  # Specify your gem's dependencies in rubocop-sorbet.gemspec
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubocop-sorbet (0.7.0)
4
+ rubocop-sorbet (0.7.1)
5
5
  rubocop (>= 0.90.0)
6
6
 
7
7
  GEM
@@ -10,13 +10,17 @@ GEM
10
10
  ast (2.4.2)
11
11
  byebug (11.1.3)
12
12
  diff-lcs (1.3)
13
- parallel (1.21.0)
14
- parser (3.0.1.1)
13
+ json (2.6.3)
14
+ language_server-protocol (3.17.0.3)
15
+ parallel (1.23.0)
16
+ parser (3.2.2.3)
15
17
  ast (~> 2.4.1)
18
+ racc
19
+ racc (1.7.1)
16
20
  rainbow (3.1.1)
17
21
  rake (13.0.1)
18
- regexp_parser (2.2.0)
19
- rexml (3.2.5)
22
+ regexp_parser (2.8.1)
23
+ rexml (3.2.6)
20
24
  rspec (3.8.0)
21
25
  rspec-core (~> 3.8.0)
22
26
  rspec-expectations (~> 3.8.0)
@@ -30,21 +34,23 @@ GEM
30
34
  diff-lcs (>= 1.2.0, < 2.0)
31
35
  rspec-support (~> 3.8.0)
32
36
  rspec-support (3.8.2)
33
- rubocop (1.24.1)
37
+ rubocop (1.55.1)
38
+ json (~> 2.3)
39
+ language_server-protocol (>= 3.17.0)
34
40
  parallel (~> 1.10)
35
- parser (>= 3.0.0.0)
41
+ parser (>= 3.2.2.3)
36
42
  rainbow (>= 2.2.2, < 4.0)
37
43
  regexp_parser (>= 1.8, < 3.0)
38
- rexml
39
- rubocop-ast (>= 1.15.1, < 2.0)
44
+ rexml (>= 3.2.5, < 4.0)
45
+ rubocop-ast (>= 1.28.1, < 2.0)
40
46
  ruby-progressbar (~> 1.7)
41
- unicode-display_width (>= 1.4.0, < 3.0)
42
- rubocop-ast (1.15.1)
43
- parser (>= 3.0.1.1)
44
- rubocop-shopify (2.1.0)
45
- rubocop (~> 1.13)
46
- ruby-progressbar (1.11.0)
47
- unicode-display_width (2.1.0)
47
+ unicode-display_width (>= 2.4.0, < 3.0)
48
+ rubocop-ast (1.29.0)
49
+ parser (>= 3.2.1.0)
50
+ rubocop-shopify (2.14.0)
51
+ rubocop (~> 1.51)
52
+ ruby-progressbar (1.13.0)
53
+ unicode-display_width (2.4.2)
48
54
  unparser (0.6.0)
49
55
  diff-lcs (~> 1.3)
50
56
  parser (>= 3.0.0)
@@ -63,4 +69,4 @@ DEPENDENCIES
63
69
  yard (~> 0.9)
64
70
 
65
71
  BUNDLED WITH
66
- 2.2.16
72
+ 2.4.18
data/README.md CHANGED
@@ -98,7 +98,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/Shopif
98
98
  To contribute a new cop, please use the supplied generator like this:
99
99
 
100
100
  ```sh
101
- bundle exec rake new_cop[Sorbet/NewCopName]
101
+ bundle exec rake "new_cop[Sorbet/NewCopName]"
102
102
  ```
103
103
 
104
104
  which will create a skeleton cop, a skeleton spec, an entry in the default config file and will require the new cop so that it is properly exported from the gem.
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ task :new_cop, [:cop] do |_task, args|
18
18
  require "rubocop"
19
19
 
20
20
  cop_name = args.fetch(:cop) do
21
- warn("usage: bundle exec rake new_cop[Department/Name]")
21
+ warn('usage: bundle exec rake "new_cop[Department/Name]"')
22
22
  exit!
23
23
  end
24
24
 
data/bin/rspec CHANGED
@@ -9,8 +9,10 @@
9
9
  #
10
10
 
11
11
  require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
13
+ "../../Gemfile",
14
+ Pathname.new(__FILE__).realpath,
15
+ )
14
16
 
15
17
  bundle_binstub = File.expand_path("../bundle", __FILE__)
16
18
 
data/bin/rubocop CHANGED
@@ -9,8 +9,10 @@
9
9
  #
10
10
 
11
11
  require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
13
+ "../../Gemfile",
14
+ Pathname.new(__FILE__).realpath,
15
+ )
14
16
 
15
17
  bundle_binstub = File.expand_path("../bundle", __FILE__)
16
18
 
data/config/default.yml CHANGED
@@ -120,7 +120,8 @@ Sorbet/HasSigil:
120
120
  Description: 'Makes the Sorbet typed sigil mandatory in all files.'
121
121
  Enabled: false
122
122
  SuggestedStrictness: "false"
123
- MinimumStrictness: "false"
123
+ MinimumStrictness: nil
124
+ ExactStrictness: nil
124
125
  VersionAdded: 0.3.3
125
126
  Include:
126
127
  - "**/*.{rb,rbi,rake,ru}"
@@ -141,6 +142,13 @@ Sorbet/IgnoreSigil:
141
142
  - db/**/*.rb
142
143
  - script/**/*
143
144
 
145
+ Sorbet/ImplicitConversionMethod:
146
+ Description: >-
147
+ This cop disallows declaring implicit conversion methods, as sorbet does
148
+ not support implicit conversion.
149
+ Enabled: false
150
+ VersionAdded: '<<next>>'
151
+
144
152
  Sorbet/KeywordArgumentOrdering:
145
153
  Description: >-
146
154
  Enforces a compatible keyword arguments with Sorbet.
@@ -151,6 +159,18 @@ Sorbet/KeywordArgumentOrdering:
151
159
  Enabled: true
152
160
  VersionAdded: 0.2.0
153
161
 
162
+ Sorbet/ObsoleteStrictMemoization:
163
+ Description: >-
164
+ This cop checks for the obsolete pattern for initializing instance variables that was required for older Sorbet
165
+ versions in `#typed: strict` files.
166
+
167
+ It's no longer required, as of Sorbet 0.5.10210
168
+ See https://sorbet.org/docs/type-assertions#put-type-assertions-behind-memoization
169
+ Enabled: true
170
+ VersionAdded: '0.7.1'
171
+ Safe: true
172
+ SafeAutoCorrect: true
173
+
154
174
  Sorbet/OneAncestorPerLine:
155
175
  Description: 'Enforces one ancestor per call to requires_ancestor'
156
176
  Enabled: false
@@ -235,7 +255,8 @@ Sorbet/ValidSigil:
235
255
  Enabled: true
236
256
  RequireSigilOnAllFiles: false
237
257
  SuggestedStrictness: "false"
238
- MinimumStrictness: "false"
258
+ MinimumStrictness: nil
259
+ ExactStrictness: nil
239
260
  VersionAdded: 0.3.3
240
261
  Include:
241
262
  - "**/*.{rb,rbi,rake,ru}"
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubocop"
4
+
5
+ module RuboCop
6
+ module Cop
7
+ module Sorbet
8
+ # Disallows binding the return value of `T.any`, `T.all`, `T.enum`
9
+ # to a constant directly. To bind the value, one must use `T.type_alias`.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ # FooOrBar = T.any(Foo, Bar)
15
+ #
16
+ # # good
17
+ # FooOrBar = T.type_alias { T.any(Foo, Bar) }
18
+ class BindingConstantWithoutTypeAlias < RuboCop::Cop::Base
19
+ extend AutoCorrector
20
+
21
+ MSG = "It looks like you're trying to bind a type to a constant. " \
22
+ "To do this, you must alias the type using `T.type_alias`."
23
+ WITHOUT_BLOCK_MSG = "It looks like you're using the old `T.type_alias` syntax. " \
24
+ "`T.type_alias` now expects a block." \
25
+ 'Run Sorbet with the options "--autocorrect --error-white-list=5043" ' \
26
+ "to automatically upgrade to the new syntax."
27
+
28
+ # @!method type_alias_without_block(node)
29
+ def_node_matcher :type_alias_without_block, <<~PATTERN
30
+ (send
31
+ (const {nil? cbase} :T)
32
+ :type_alias
33
+ $_
34
+ )
35
+ PATTERN
36
+
37
+ # @!method type_alias_with_block?(node)
38
+ def_node_matcher :type_alias_with_block?, <<~PATTERN
39
+ (block
40
+ (send
41
+ (const {nil? cbase} :T)
42
+ :type_alias)
43
+ ...
44
+ )
45
+ PATTERN
46
+
47
+ # @!method requires_type_alias?(node)
48
+ def_node_matcher :requires_type_alias?, <<~PATTERN
49
+ (send
50
+ (const {nil? cbase} :T)
51
+ {
52
+ :all
53
+ :any
54
+ :class_of
55
+ :nilable
56
+ :noreturn
57
+ :proc
58
+ :self_type
59
+ :untyped
60
+ }
61
+ ...
62
+ )
63
+ PATTERN
64
+
65
+ def on_casgn(node)
66
+ expression = node.expression
67
+ return if expression.nil? # multiple assignment
68
+
69
+ type_alias_without_block(expression) do |type|
70
+ return add_offense(expression, message: WITHOUT_BLOCK_MSG) do |corrector|
71
+ corrector.replace(expression, "T.type_alias { #{type.source} }")
72
+ end
73
+ end
74
+
75
+ return if type_alias_with_block?(expression)
76
+
77
+ requires_type_alias?(send_leaf(expression)) do
78
+ return add_offense(expression) do |corrector|
79
+ corrector.replace(expression, "T.type_alias { #{expression.source} }")
80
+ end
81
+ end
82
+ end
83
+
84
+ private
85
+
86
+ # Given nested send nodes, returns the leaf with explicit receiver.
87
+ #
88
+ # i.e. in Ruby
89
+ #
90
+ # a.b.c.d.e.f
91
+ # ^^^
92
+ #
93
+ # i.e. in AST
94
+ #
95
+ # (send (send (send (send (send (send nil :a) :b) :c) :d) :e) :f)
96
+ # ^^^^^^^^^^^^^^^^^^^^^^^
97
+ #
98
+ def send_leaf(node)
99
+ node = node.receiver while node&.receiver&.send_type?
100
+ node
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Sorbet
6
- # This cop ensures that callback conditionals are bound to the right type
6
+ # Ensures that callback conditionals are bound to the right type
7
7
  # so that they are type checked properly.
8
8
  #
9
9
  # Auto-correction is unsafe because other libraries define similar style callbacks as Rails, but don't always need
@@ -32,16 +32,44 @@ module RuboCop
32
32
  # true
33
33
  # end
34
34
  # end
35
- class CallbackConditionalsBinding < RuboCop::Cop::Cop
35
+ class CallbackConditionalsBinding < RuboCop::Cop::Cop # rubocop:todo InternalAffairs/InheritDeprecatedCopClass
36
36
  CALLBACKS = [
37
- :validate, :validates, :validates_with, :before_validation, :around_validation, :before_create,
38
- :before_save, :before_destroy, :before_update, :after_create, :after_save, :after_destroy,
39
- :after_update, :after_touch, :after_initialize, :after_find, :around_create, :around_save,
40
- :around_destroy, :around_update, :before_commit, :after_commit, :after_create_commit,
41
- :after_destroy_commit, :after_rollback, :after_save_commit, :after_update_commit,
42
- :before_action, :prepend_before_action, :append_before_action, :around_action,
43
- :prepend_around_action, :append_around_action, :after_action, :prepend_after_action,
44
- :append_after_action
37
+ :validate,
38
+ :validates,
39
+ :validates_with,
40
+ :before_validation,
41
+ :around_validation,
42
+ :before_create,
43
+ :before_save,
44
+ :before_destroy,
45
+ :before_update,
46
+ :after_create,
47
+ :after_save,
48
+ :after_destroy,
49
+ :after_update,
50
+ :after_touch,
51
+ :after_initialize,
52
+ :after_find,
53
+ :around_create,
54
+ :around_save,
55
+ :around_destroy,
56
+ :around_update,
57
+ :before_commit,
58
+ :after_commit,
59
+ :after_create_commit,
60
+ :after_destroy_commit,
61
+ :after_rollback,
62
+ :after_save_commit,
63
+ :after_update_commit,
64
+ :before_action,
65
+ :prepend_before_action,
66
+ :append_before_action,
67
+ :around_action,
68
+ :prepend_around_action,
69
+ :append_around_action,
70
+ :after_action,
71
+ :prepend_after_action,
72
+ :append_after_action,
45
73
  ].freeze
46
74
 
47
75
  def autocorrect(node)
@@ -132,7 +160,7 @@ module RuboCop
132
160
  unless block.source.include?("T.bind(self")
133
161
  add_offense(
134
162
  node,
135
- message: "Callback conditionals should be bound to the right type. Use T.bind(self, #{expected_class})"
163
+ message: "Callback conditionals should be bound to the right type. Use T.bind(self, #{expected_class})",
136
164
  )
137
165
  end
138
166
  end
@@ -5,7 +5,7 @@ require "rubocop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop disallows the calls that are used to get constants fom Strings
8
+ # Disallows the calls that are used to get constants fom Strings
9
9
  # such as +constantize+, +const_get+, and +constants+.
10
10
  #
11
11
  # The goal of this cop is to make the code easier to statically analyze,
@@ -33,18 +33,20 @@ module RuboCop
33
33
  #
34
34
  # # good
35
35
  # { "User" => User }.fetch(class_name)
36
- class ConstantsFromStrings < ::RuboCop::Cop::Cop
36
+ class ConstantsFromStrings < ::RuboCop::Cop::Cop # rubocop:todo InternalAffairs/InheritDeprecatedCopClass
37
+ # @!method constant_from_string?(node)
37
38
  def_node_matcher(:constant_from_string?, <<-PATTERN)
38
39
  (send _ {:constantize :constants :const_get} ...)
39
40
  PATTERN
40
41
 
41
42
  def on_send(node)
42
43
  return unless constant_from_string?(node)
44
+
43
45
  add_offense(
44
46
  node,
45
47
  location: :selector,
46
48
  message: "Don't use `#{node.method_name}`, it makes the code harder to understand, less editor-friendly, " \
47
- "and impossible to analyze. Replace `#{node.method_name}` with a case/when or a hash."
49
+ "and impossible to analyze. Replace `#{node.method_name}` with a case/when or a hash.",
48
50
  )
49
51
  end
50
52
  end
@@ -3,34 +3,35 @@
3
3
 
4
4
  require "rubocop"
5
5
 
6
- # Correct `send` expressions in include statements by constant literals.
7
- #
8
- # Sorbet, the static checker, is not (yet) able to support constructs on the
9
- # following form:
10
- #
11
- # ```ruby
12
- # class MyClass
13
- # include send_expr
14
- # end
15
- # ```
16
- #
17
- # Multiple occurences of this can be found in Shopify's code base like:
18
- #
19
- # ```ruby
20
- # include Rails.application.routes.url_helpers
21
- # ```
22
- # or
23
- # ```ruby
24
- # include Polaris::Engine.helpers
25
- # ```
26
6
  module RuboCop
27
7
  module Cop
28
8
  module Sorbet
29
- class ForbidIncludeConstLiteral < RuboCop::Cop::Cop
9
+ # Correct `send` expressions in include statements by constant literals.
10
+ #
11
+ # Sorbet, the static checker, is not (yet) able to support constructs on the
12
+ # following form:
13
+ #
14
+ # ```ruby
15
+ # class MyClass
16
+ # include send_expr
17
+ # end
18
+ # ```
19
+ #
20
+ # Multiple occurences of this can be found in Shopify's code base like:
21
+ #
22
+ # ```ruby
23
+ # include Rails.application.routes.url_helpers
24
+ # ```
25
+ # or
26
+ # ```ruby
27
+ # include Polaris::Engine.helpers
28
+ # ```
29
+ class ForbidIncludeConstLiteral < RuboCop::Cop::Cop # rubocop:todo InternalAffairs/InheritDeprecatedCopClass
30
30
  MSG = "Includes must only contain constant literals"
31
31
 
32
32
  attr_accessor :used_names
33
33
 
34
+ # @!method not_lit_const_include?(node)
34
35
  def_node_matcher :not_lit_const_include?, <<-PATTERN
35
36
  (send nil? {:include :extend :prepend}
36
37
  $_
@@ -46,18 +47,21 @@ module RuboCop
46
47
  return unless not_lit_const_include?(node) do |send_argument|
47
48
  ![:const, :self].include?(send_argument.type)
48
49
  end
50
+
49
51
  parent = node.parent
50
52
  return unless parent
53
+
51
54
  parent = parent.parent if [:begin, :block].include?(parent.type)
52
55
  return unless [:module, :class, :sclass].include?(parent.type)
56
+
53
57
  add_offense(node)
54
58
  end
55
59
 
56
60
  def autocorrect(node)
57
61
  lambda do |corrector|
58
62
  corrector.replace(
59
- node.source_range,
60
- "T.unsafe(self).#{node.source}"
63
+ node,
64
+ "T.unsafe(self).#{node.source}",
61
65
  )
62
66
  end
63
67
  end
@@ -3,41 +3,40 @@
3
3
 
4
4
  require "rubocop"
5
5
 
6
- # Correct superclass `send` expressions by constant literals.
7
- #
8
- # Sorbet, the static checker, is not (yet) able to support constructs on the
9
- # following form:
10
- #
11
- # ```ruby
12
- # class Foo < send_expr; end
13
- # ```
14
- #
15
- # Multiple occurences of this can be found in Shopify's code base like:
16
- #
17
- # ```ruby
18
- # class ShopScope < Component::TrustedIdScope[ShopIdentity::ShopId]
19
- # ```
20
- # or
21
- # ```ruby
22
- # class ApiClientEligibility < Struct.new(:api_client, :match_results, :shop)
23
- # ```
24
6
  module RuboCop
25
7
  module Cop
26
8
  module Sorbet
27
- class ForbidSuperclassConstLiteral < RuboCop::Cop::Cop
9
+ # Correct superclass `send` expressions by constant literals.
10
+ #
11
+ # Sorbet, the static checker, is not (yet) able to support constructs on the
12
+ # following form:
13
+ #
14
+ # ```ruby
15
+ # class Foo < send_expr; end
16
+ # ```
17
+ #
18
+ # Multiple occurences of this can be found in Shopify's code base like:
19
+ #
20
+ # ```ruby
21
+ # class ShopScope < Component::TrustedIdScope[ShopIdentity::ShopId]
22
+ # ```
23
+ # or
24
+ # ```ruby
25
+ # class ApiClientEligibility < Struct.new(:api_client, :match_results, :shop)
26
+ # ```
27
+
28
+ class ForbidSuperclassConstLiteral < RuboCop::Cop::Base
28
29
  MSG = "Superclasses must only contain constant literals"
29
30
 
30
- def_node_matcher :not_lit_const_superclass?, <<-PATTERN
31
- (class
32
- (const ...)
33
- (send ...)
34
- ...
35
- )
31
+ # @!method dynamic_superclass?(node)
32
+ def_node_matcher :dynamic_superclass?, <<-PATTERN
33
+ (class (const ...) $(send ...) ...)
36
34
  PATTERN
37
35
 
38
36
  def on_class(node)
39
- return unless not_lit_const_superclass?(node)
40
- add_offense(node.child_nodes[1])
37
+ dynamic_superclass?(node) do |superclass|
38
+ add_offense(superclass)
39
+ end
41
40
  end
42
41
  end
43
42
  end
@@ -5,7 +5,7 @@ require "rubocop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop disallows using `T.unsafe` anywhere.
8
+ # Disallows using `T.unsafe` anywhere.
9
9
  #
10
10
  # @example
11
11
  #
@@ -14,11 +14,15 @@ module RuboCop
14
14
  #
15
15
  # # good
16
16
  # foo
17
- class ForbidTUnsafe < RuboCop::Cop::Cop
17
+ class ForbidTUnsafe < RuboCop::Cop::Base
18
+ MSG = "Do not use `T.unsafe`."
19
+ RESTRICT_ON_SEND = [:unsafe].freeze
20
+
21
+ # @!method t_unsafe?(node)
18
22
  def_node_matcher(:t_unsafe?, "(send (const nil? :T) :unsafe _)")
19
23
 
20
24
  def on_send(node)
21
- add_offense(node, message: "Do not use `T.unsafe`.") if t_unsafe?(node)
25
+ add_offense(node) if t_unsafe?(node)
22
26
  end
23
27
  end
24
28
  end
@@ -5,7 +5,7 @@ require "rubocop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop disallows using `T.untyped` anywhere.
8
+ # Disallows using `T.untyped` anywhere.
9
9
  #
10
10
  # @example
11
11
  #
@@ -17,11 +17,15 @@ module RuboCop
17
17
  # sig { params(my_argument: String).void }
18
18
  # def foo(my_argument); end
19
19
  #
20
- class ForbidTUntyped < RuboCop::Cop::Cop
20
+ class ForbidTUntyped < RuboCop::Cop::Base
21
+ MSG = "Do not use `T.untyped`."
22
+ RESTRICT_ON_SEND = [:untyped].freeze
23
+
24
+ # @!method t_untyped?(node)
21
25
  def_node_matcher(:t_untyped?, "(send (const nil? :T) :untyped)")
22
26
 
23
27
  def on_send(node)
24
- add_offense(node, message: "Do not use `T.untyped`.") if t_untyped?(node)
28
+ add_offense(node) if t_untyped?(node)
25
29
  end
26
30
  end
27
31
  end