rubocop-sorbet 0.6.11 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +3 -1
  3. data/.github/workflows/cla.yml +22 -0
  4. data/.github/workflows/stale.yml +24 -0
  5. data/.rubocop.yml +12 -1
  6. data/.yardopts +1 -0
  7. data/Gemfile +1 -0
  8. data/Gemfile.lock +23 -17
  9. data/README.md +1 -1
  10. data/Rakefile +6 -6
  11. data/bin/rspec +4 -2
  12. data/bin/rubocop +4 -2
  13. data/config/default.yml +40 -3
  14. data/dev.yml +1 -1
  15. data/lib/rubocop/cop/sorbet/binding_constant_without_type_alias.rb +105 -0
  16. data/lib/rubocop/cop/sorbet/callback_conditionals_binding.rb +39 -11
  17. data/lib/rubocop/cop/sorbet/constants_from_strings.rb +5 -3
  18. data/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb +27 -23
  19. data/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb +26 -27
  20. data/lib/rubocop/cop/sorbet/forbid_t_unsafe.rb +7 -3
  21. data/lib/rubocop/cop/sorbet/forbid_t_untyped.rb +7 -3
  22. data/lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb +15 -9
  23. data/lib/rubocop/cop/sorbet/implicit_conversion_method.rb +56 -0
  24. data/lib/rubocop/cop/sorbet/mixin/target_sorbet_version.rb +49 -0
  25. data/lib/rubocop/cop/sorbet/mutable_constant_sorbet_aware_behaviour.rb +8 -5
  26. data/lib/rubocop/cop/sorbet/obsolete_strict_memoization.rb +92 -0
  27. data/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb +8 -3
  28. data/lib/rubocop/cop/sorbet/rbi/forbid_extend_t_sig_helpers_in_shims.rb +12 -18
  29. data/lib/rubocop/cop/sorbet/rbi/forbid_rbi_outside_of_allowed_paths.rb +10 -8
  30. data/lib/rubocop/cop/sorbet/rbi/single_line_rbi_class_module_definitions.rb +12 -18
  31. data/lib/rubocop/cop/sorbet/redundant_extend_t_sig.rb +49 -0
  32. data/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb +5 -4
  33. data/lib/rubocop/cop/sorbet/sigils/enforce_single_sigil.rb +6 -5
  34. data/lib/rubocop/cop/sorbet/sigils/false_sigil.rb +1 -1
  35. data/lib/rubocop/cop/sorbet/sigils/has_sigil.rb +1 -1
  36. data/lib/rubocop/cop/sorbet/sigils/ignore_sigil.rb +1 -1
  37. data/lib/rubocop/cop/sorbet/sigils/strict_sigil.rb +1 -1
  38. data/lib/rubocop/cop/sorbet/sigils/strong_sigil.rb +1 -1
  39. data/lib/rubocop/cop/sorbet/sigils/true_sigil.rb +1 -1
  40. data/lib/rubocop/cop/sorbet/sigils/valid_sigil.rb +50 -25
  41. data/lib/rubocop/cop/sorbet/signatures/allow_incompatible_override.rb +19 -30
  42. data/lib/rubocop/cop/sorbet/signatures/checked_true_in_signature.rb +3 -2
  43. data/lib/rubocop/cop/sorbet/signatures/empty_line_after_sig.rb +57 -0
  44. data/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb +8 -4
  45. data/lib/rubocop/cop/sorbet/signatures/keyword_argument_ordering.rb +5 -4
  46. data/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb +10 -3
  47. data/lib/rubocop/cop/sorbet/signatures/signature_cop.rb +11 -9
  48. data/lib/rubocop/cop/sorbet/type_alias_name.rb +10 -17
  49. data/lib/rubocop/cop/sorbet_cops.rb +8 -1
  50. data/lib/rubocop/sorbet/inject.rb +9 -7
  51. data/lib/rubocop/sorbet/version.rb +2 -1
  52. data/lib/rubocop/sorbet.rb +1 -0
  53. data/manual/cops.md +4 -0
  54. data/manual/cops_sorbet.md +195 -38
  55. data/rubocop-sorbet.gemspec +1 -0
  56. data/service.yml +0 -1
  57. data/tasks/cops_documentation.rake +16 -5
  58. metadata +12 -6
  59. data/.github/probots.yml +0 -3
  60. data/.github/stale.yml +0 -20
  61. 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: 0a3b043348a2ad38724ebb70db4bb8db09a6a02d9c9bbc56a262e0de4b90d5eb
4
- data.tar.gz: 50e5a9d5e61b0e95343a8d4699f81910bff19f10387119ae97bfec688906c6d9
3
+ metadata.gz: c0d4456bcb92b2f40f1208842fce6a102f6ce2ba88ff491840d77a3001784677
4
+ data.tar.gz: 5e389a2c6c772f68aaf95555da670732ac70a9c5262be18c0418e0d787feb5de
5
5
  SHA512:
6
- metadata.gz: e749a4ac82f0e9b76a5f3bb2e77bbefeec539a939b107b3dc59c1d20c83b4f4b4766a6792938a03cd8d7e8044ec58a53d8af4d346ec5177390993fb2ddcd181e
7
- data.tar.gz: 417259e5915b4836c8b90939d7922d34ab02e2d4d7955482d9fdb7dac58cb728114bd08e0437650b10687e64cdbfd75361ed586dd21cfb9de5bbacd1fc816db7
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' ]
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
@@ -22,5 +22,7 @@ jobs:
22
22
  bundler-cache: true
23
23
  - name: Lint Ruby files
24
24
  run: bin/rubocop
25
+ - name: Verify documentation is up to date
26
+ run: bundle exec rake generate_cops_documentation
25
27
  - name: Run tests
26
28
  run: bin/rspec
@@ -0,0 +1,22 @@
1
+ name: Contributor License Agreement (CLA)
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [opened, synchronize, reopened]
6
+ issue_comment:
7
+ types: [created]
8
+
9
+ jobs:
10
+ cla:
11
+ runs-on: ubuntu-latest
12
+ if: |
13
+ (github.event.issue.pull_request
14
+ && !github.event.issue.pull_request.merged_at
15
+ && contains(github.event.comment.body, 'signed')
16
+ )
17
+ || (github.event.pull_request && !github.event.pull_request.merged)
18
+ steps:
19
+ - uses: Shopify/shopify-cla-action@v1
20
+ with:
21
+ github-token: ${{ secrets.GITHUB_TOKEN }}
22
+ cla-token: ${{ secrets.CLA_TOKEN }}
@@ -0,0 +1,24 @@
1
+ name: "Close stale PRs"
2
+
3
+ permissions:
4
+ pull-requests: write
5
+ issues: write
6
+
7
+ on:
8
+ schedule:
9
+ - cron: "55 1 * * *"
10
+
11
+ jobs:
12
+ stale:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/stale@v5
16
+ with:
17
+ stale-pr-message: >
18
+ This PR has been automatically marked as stale because it has not had
19
+ recent activity. It will be closed if no further activity occurs. Thank you
20
+ for your contributions.
21
+ days-before-stale: 30
22
+ days-before-issue-stale: -1
23
+ days-before-close: 7
24
+ exempt-pr-labels: pinned,security
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.6.11)
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,19 +18,19 @@ 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
 
25
- github_user = %x(git config github.user).chop
26
- github_user = "Shopify" if github_user.empty?
27
-
28
- generator = RuboCop::Cop::Generator.new(cop_name, github_user)
25
+ generator = RuboCop::Cop::Generator.new(cop_name)
29
26
 
30
27
  generator.write_source
31
28
  generator.write_spec
32
29
  generator.inject_require(root_file_path: "lib/rubocop/cop/sorbet_cops.rb")
33
30
  generator.inject_config(config_file_path: "config/default.yml")
34
31
 
35
- puts generator.todo
32
+ # We don't use Rubocop's changelog automation workflow
33
+ todo_without_changelog_instruction = generator.todo
34
+ .sub(/$\s+4\. Run.*changelog.*for your new cop\.$/m, "")
35
+ puts todo_without_changelog_instruction
36
36
  end
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
@@ -25,6 +25,11 @@ Sorbet/CheckedTrueInSignature:
25
25
  Enabled: true
26
26
  VersionAdded: 0.2.0
27
27
 
28
+ Sorbet/EmptyLineAfterSig:
29
+ Description: 'Ensures that there are no blank lines after signatures'
30
+ Enabled: true
31
+ VersionAdded: 0.7.0
32
+
28
33
  Sorbet/ConstantsFromStrings:
29
34
  Description: >-
30
35
  Forbids constant access through meta-programming.
@@ -42,7 +47,7 @@ Sorbet/EnforceSigilOrder:
42
47
  Sorbet/EnforceSingleSigil:
43
48
  Description: 'Ensures that there is only one Sorbet sigil in a file.'
44
49
  Enabled: true
45
- VersionAdded: '<<next>>'
50
+ VersionAdded: 0.7.0
46
51
 
47
52
  Sorbet/EnforceSignatures:
48
53
  Description: 'Ensures all methods have a valid signature.'
@@ -73,6 +78,7 @@ Sorbet/ForbidRBIOutsideOfAllowedPaths:
73
78
  Enabled: true
74
79
  VersionAdded: 0.6.1
75
80
  AllowedPaths:
81
+ - "rbi/**"
76
82
  - "sorbet/rbi/**"
77
83
  Include:
78
84
  - "**/*.rbi"
@@ -114,7 +120,8 @@ Sorbet/HasSigil:
114
120
  Description: 'Makes the Sorbet typed sigil mandatory in all files.'
115
121
  Enabled: false
116
122
  SuggestedStrictness: "false"
117
- MinimumStrictness: "false"
123
+ MinimumStrictness: nil
124
+ ExactStrictness: nil
118
125
  VersionAdded: 0.3.3
119
126
  Include:
120
127
  - "**/*.{rb,rbi,rake,ru}"
@@ -135,6 +142,13 @@ Sorbet/IgnoreSigil:
135
142
  - db/**/*.rb
136
143
  - script/**/*
137
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
+
138
152
  Sorbet/KeywordArgumentOrdering:
139
153
  Description: >-
140
154
  Enforces a compatible keyword arguments with Sorbet.
@@ -145,11 +159,33 @@ Sorbet/KeywordArgumentOrdering:
145
159
  Enabled: true
146
160
  VersionAdded: 0.2.0
147
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
+
148
174
  Sorbet/OneAncestorPerLine:
149
175
  Description: 'Enforces one ancestor per call to requires_ancestor'
150
176
  Enabled: false
151
177
  VersionAdded: '0.6.0'
152
178
 
179
+ Sorbet/RedundantExtendTSig:
180
+ Description: >-
181
+ Forbid the usage of redundant `extend T::Sig`.
182
+
183
+ Only for use in applications that monkey patch `Module.include(T::Sig)` directly,
184
+ where it is useful to reduce noise.
185
+ Enabled: false
186
+ Safe: false
187
+ VersionAdded: 0.7.0
188
+
153
189
  Sorbet/SignatureBuildOrder:
154
190
  Description: >-
155
191
  Enforces the order of parts in a signature.
@@ -219,7 +255,8 @@ Sorbet/ValidSigil:
219
255
  Enabled: true
220
256
  RequireSigilOnAllFiles: false
221
257
  SuggestedStrictness: "false"
222
- MinimumStrictness: "false"
258
+ MinimumStrictness: nil
259
+ ExactStrictness: nil
223
260
  VersionAdded: 0.3.3
224
261
  Include:
225
262
  - "**/*.{rb,rbi,rake,ru}"
data/dev.yml CHANGED
@@ -3,7 +3,7 @@ name: "rubocop-sorbet"
3
3
  type: "ruby"
4
4
 
5
5
  up:
6
- - ruby: "2.5.5"
6
+ - ruby: "3.2.0"
7
7
  - "bundler"
8
8
 
9
9
  commands:
@@ -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