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
@@ -5,7 +5,7 @@ require "rubocop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop checks that every Ruby file contains a valid Sorbet sigil.
8
+ # Checks that every Ruby file contains a valid Sorbet sigil.
9
9
  # Adapted from: https://gist.github.com/clarkdave/85aca4e16f33fd52aceb6a0a29936e52
10
10
  #
11
11
  # Options:
@@ -13,9 +13,11 @@ module RuboCop
13
13
  # * `RequireSigilOnAllFiles`: make offense if the Sorbet typed is not found in the file (default: false)
14
14
  # * `SuggestedStrictness`: Sorbet strictness level suggested in offense messages (default: 'false')
15
15
  # * `MinimumStrictness`: If set, make offense if the strictness level in the file is below this one
16
+ # * `ExactStrictness`: If set, make offense if the strictness level in the file is different than this one
16
17
  #
17
- # If a `MinimumStrictness` level is specified, it will be used in offense messages and autocorrect.
18
- class ValidSigil < RuboCop::Cop::Cop
18
+ # If an `ExactStrictness` level is specified, it will be used in offense messages and autocorrect.
19
+ # Otherwise, if a `MinimumStrictness` level is specified, it will be used in offense messages and autocorrect.
20
+ class ValidSigil < RuboCop::Cop::Cop # rubocop:todo InternalAffairs/InheritDeprecatedCopClass
19
21
  @registry = Cop.registry # So we can properly subclass this cop
20
22
 
21
23
  def investigate(processed_source)
@@ -36,7 +38,7 @@ module RuboCop
36
38
  return unless extract_sigil(processed_source).nil?
37
39
 
38
40
  token = processed_source.tokens.first
39
- replace_with = suggested_strictness_level(minimum_strictness, suggested_strictness)
41
+ replace_with = suggested_strictness_level
40
42
  sigil = "# typed: #{replace_with}"
41
43
  if token.text.start_with?("#!") # shebang line
42
44
  corrector.insert_after(token.pos, "\n#{sigil}")
@@ -70,34 +72,37 @@ module RuboCop
70
72
 
71
73
  token = processed_source.tokens.first
72
74
  if require_sigil_on_all_files?
73
- strictness = suggested_strictness_level(minimum_strictness, suggested_strictness)
75
+ strictness = suggested_strictness_level
74
76
  add_offense(
75
77
  token,
76
78
  location: token.pos,
77
79
  message: "No Sorbet sigil found in file. " \
78
- "Try a `typed: #{strictness}` to start (you can also use `rubocop -a` to automatically add this)."
80
+ "Try a `typed: #{strictness}` to start (you can also use `rubocop -a` to automatically add this).",
79
81
  )
80
82
  end
81
83
  false
82
84
  end
83
85
 
84
- def suggested_strictness_level(minimum_strictness, suggested_strictness)
86
+ def suggested_strictness_level
87
+ return exact_strictness if exact_strictness
85
88
  # if no minimum strictness is set (eg. using Sorbet/HasSigil without config) then
86
89
  # we always use the suggested strictness which defaults to `false`
87
90
  return suggested_strictness unless minimum_strictness
88
91
 
89
92
  # special case: if you're using Sorbet/IgnoreSigil without config, we should recommend `ignore`
90
- return "ignore" if minimum_strictness == "ignore" && cop_config["SuggestedStrictness"].nil?
93
+ return "ignore" if minimum_strictness == "ignore" && cop_config["SuggestedStrictness"].nil? # rubocop:todo InternalAffairs/UndefinedConfig
91
94
 
92
95
  # if a minimum strictness is set (eg. you're using Sorbet/FalseSigil)
93
96
  # we want to compare the minimum strictness and suggested strictness. this is because
94
97
  # the suggested strictness might be higher than the minimum (eg. if you want all new files
95
98
  # at a higher strictness level, without having to migrate existing files at lower levels).
96
99
 
97
- suggested_level = STRICTNESS_LEVELS.index(suggested_strictness)
98
- minimum_level = STRICTNESS_LEVELS.index(minimum_strictness)
100
+ levels = [
101
+ STRICTNESS_LEVELS.index(suggested_strictness),
102
+ STRICTNESS_LEVELS.index(minimum_strictness),
103
+ ]
99
104
 
100
- suggested_level > minimum_level ? suggested_strictness : minimum_strictness
105
+ STRICTNESS_LEVELS[levels.compact.max]
101
106
  end
102
107
 
103
108
  def check_strictness_not_empty(sigil, strictness)
@@ -106,7 +111,7 @@ module RuboCop
106
111
  add_offense(
107
112
  sigil,
108
113
  location: sigil.pos,
109
- message: "Sorbet sigil should not be empty."
114
+ message: "Sorbet sigil should not be empty.",
110
115
  )
111
116
  false
112
117
  end
@@ -117,24 +122,38 @@ module RuboCop
117
122
  add_offense(
118
123
  sigil,
119
124
  location: sigil.pos,
120
- message: "Invalid Sorbet sigil `#{strictness}`."
125
+ message: "Invalid Sorbet sigil `#{strictness}`.",
121
126
  )
122
127
  false
123
128
  end
124
129
 
125
130
  def check_strictness_level(sigil, strictness)
126
- return true unless minimum_strictness
131
+ return true if !minimum_strictness && !exact_strictness
127
132
 
128
- minimum_level = STRICTNESS_LEVELS.index(minimum_strictness)
129
133
  current_level = STRICTNESS_LEVELS.index(strictness)
130
- if current_level < minimum_level
131
- add_offense(
132
- sigil,
133
- location: sigil.pos,
134
- message: "Sorbet sigil should be at least `#{minimum_strictness}` got `#{strictness}`."
135
- )
136
- return false
134
+
135
+ if exact_strictness
136
+ exact_level = STRICTNESS_LEVELS.index(exact_strictness)
137
+ if current_level != exact_level
138
+ add_offense(
139
+ sigil,
140
+ location: sigil.pos,
141
+ message: "Sorbet sigil should be `#{exact_strictness}` got `#{strictness}`.",
142
+ )
143
+ return false
144
+ end
145
+ else
146
+ minimum_level = STRICTNESS_LEVELS.index(minimum_strictness)
147
+ if current_level < minimum_level
148
+ add_offense(
149
+ sigil,
150
+ location: sigil.pos,
151
+ message: "Sorbet sigil should be at least `#{minimum_strictness}` got `#{strictness}`.",
152
+ )
153
+ return false
154
+ end
137
155
  end
156
+
138
157
  true
139
158
  end
140
159
 
@@ -142,18 +161,24 @@ module RuboCop
142
161
 
143
162
  # Default is `false`
144
163
  def require_sigil_on_all_files?
145
- !!cop_config["RequireSigilOnAllFiles"]
164
+ !!cop_config["RequireSigilOnAllFiles"] # rubocop:todo InternalAffairs/UndefinedConfig
146
165
  end
147
166
 
148
167
  # Default is `'false'`
149
168
  def suggested_strictness
150
- config = cop_config["SuggestedStrictness"].to_s
169
+ config = cop_config["SuggestedStrictness"].to_s # rubocop:todo InternalAffairs/UndefinedConfig
151
170
  STRICTNESS_LEVELS.include?(config) ? config : "false"
152
171
  end
153
172
 
154
173
  # Default is `nil`
155
174
  def minimum_strictness
156
- config = cop_config["MinimumStrictness"].to_s
175
+ config = cop_config["MinimumStrictness"].to_s # rubocop:todo InternalAffairs/UndefinedConfig
176
+ config if STRICTNESS_LEVELS.include?(config)
177
+ end
178
+
179
+ # Default is `nil`
180
+ def exact_strictness
181
+ config = cop_config["ExactStrictness"].to_s # rubocop:todo InternalAffairs/UndefinedConfig
157
182
  config if STRICTNESS_LEVELS.include?(config)
158
183
  end
159
184
  end
@@ -5,10 +5,10 @@ require "rubocop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop disallows using `.override(allow_incompatible: true)`.
8
+ # Disallows using `.override(allow_incompatible: true)`.
9
9
  # Using `allow_incompatible` suggests a violation of the Liskov
10
10
  # Substitution Principle, meaning that a subclass is not a valid
11
- # subtype of it's superclass. This Cop prevents these design smells
11
+ # subtype of its superclass. This Cop prevents these design smells
12
12
  # from occurring.
13
13
  #
14
14
  # @example
@@ -18,40 +18,29 @@ module RuboCop
18
18
  #
19
19
  # # good
20
20
  # sig.override
21
- class AllowIncompatibleOverride < RuboCop::Cop::Cop
22
- def_node_search(:sig?, <<-PATTERN)
23
- (
24
- send
25
- nil?
26
- :sig
27
- ...
28
- )
29
- PATTERN
21
+ class AllowIncompatibleOverride < RuboCop::Cop::Base
22
+ MSG = "Usage of `allow_incompatible` suggests a violation of the Liskov Substitution Principle. " \
23
+ "Instead, strive to write interfaces which respect subtyping principles and remove `allow_incompatible`"
24
+ RESTRICT_ON_SEND = [:override].freeze
30
25
 
31
- def not_nil?(node)
32
- !node.nil?
33
- end
34
-
35
- def_node_search(:allow_incompatible?, <<-PATTERN)
36
- (pair (sym :allow_incompatible) (true))
37
- PATTERN
38
-
39
- def_node_matcher(:allow_incompatible_override?, <<-PATTERN)
40
- (
41
- send
42
- [#not_nil? #sig?]
26
+ # @!method allow_incompatible_override?(node)
27
+ def_node_matcher(:allow_incompatible_override?, <<~PATTERN)
28
+ (send
29
+ #sig?
43
30
  :override
44
- [#not_nil? #allow_incompatible?]
31
+ (hash <$(pair (sym :allow_incompatible) true) ...>)
45
32
  )
46
33
  PATTERN
47
34
 
35
+ # @!method sig?(node)
36
+ def_node_search :sig?, <<~PATTERN
37
+ (send _ :sig ...)
38
+ PATTERN
39
+
48
40
  def on_send(node)
49
- return unless allow_incompatible_override?(node)
50
- add_offense(
51
- node.children[2],
52
- message: "Usage of `allow_incompatible` suggests a violation of the Liskov Substitution Principle. "\
53
- "Instead, strive to write interfaces which respect subtyping principles and remove `allow_incompatible`",
54
- )
41
+ allow_incompatible_override?(node) do |allow_incompatible_pair|
42
+ add_offense(allow_incompatible_pair)
43
+ end
55
44
  end
56
45
  end
57
46
  end
@@ -6,7 +6,7 @@ require_relative "signature_cop"
6
6
  module RuboCop
7
7
  module Cop
8
8
  module Sorbet
9
- # This cop disallows the usage of `checked(true)`. This usage could cause
9
+ # Disallows the usage of `checked(true)`. This usage could cause
10
10
  # confusion; it could lead some people to believe that a method would be checked
11
11
  # even if runtime checks have not been enabled on the class or globally.
12
12
  # Additionally, in the event where checks are enabled, `checked(true)` would
@@ -22,6 +22,7 @@ module RuboCop
22
22
  class CheckedTrueInSignature < SignatureCop
23
23
  include(RuboCop::Cop::RangeHelp)
24
24
 
25
+ # @!method offending_node(node)
25
26
  def_node_search(:offending_node, <<~PATTERN)
26
27
  (send _ :checked (true))
27
28
  PATTERN
@@ -44,7 +45,7 @@ module RuboCop
44
45
  error.location.line,
45
46
  (error.location.selector.begin_pos)..(error.location.end.begin_pos),
46
47
  ),
47
- message: MESSAGE
48
+ message: MESSAGE,
48
49
  )
49
50
  end
50
51
  end
@@ -5,7 +5,7 @@ require_relative "signature_cop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop checks for blank lines after signatures.
8
+ # Checks for blank lines after signatures.
9
9
  #
10
10
  # It also suggests an autocorrect
11
11
  #
@@ -31,10 +31,10 @@ module RuboCop
31
31
  end
32
32
 
33
33
  def autocorrect(node)
34
- -> (corrector) do
34
+ ->(corrector) do
35
35
  offending_range = node.source_range.with(
36
36
  begin_pos: node.source_range.end_pos + 1,
37
- end_pos: processed_source.buffer.line_range(next_method(node).line).begin_pos
37
+ end_pos: processed_source.buffer.line_range(next_method(node).line).begin_pos,
38
38
  )
39
39
  corrector.remove(offending_range)
40
40
  clean_range = offending_range.source.split("\n").reject(&:empty?).join("\n")
@@ -7,7 +7,7 @@ require_relative "signature_cop"
7
7
  module RuboCop
8
8
  module Cop
9
9
  module Sorbet
10
- # This cop checks that every method definition and attribute accessor has a Sorbet signature.
10
+ # Checks that every method definition and attribute accessor has a Sorbet signature.
11
11
  #
12
12
  # It also suggest an autocorrect with placeholders so the following code:
13
13
  #
@@ -32,6 +32,7 @@ module RuboCop
32
32
  @last_sig_for_scope = {}
33
33
  end
34
34
 
35
+ # @!method accessor?(node)
35
36
  def_node_matcher(:accessor?, <<-PATTERN)
36
37
  (send nil? {:attr_reader :attr_writer :attr_accessor} ...)
37
38
  PATTERN
@@ -67,13 +68,14 @@ module RuboCop
67
68
  suggest.returns = "void" if method == :attr_writer
68
69
  end
69
70
 
70
- corrector.insert_before(node.loc.expression, suggest.to_autocorrect)
71
+ corrector.insert_before(node, suggest.to_autocorrect)
71
72
  end
72
73
  end
73
74
 
74
75
  def scope(node)
75
- return nil unless node.parent
76
+ return unless node.parent
76
77
  return node.parent if [:begin, :block, :class, :module].include?(node.parent.type)
78
+
77
79
  scope(node.parent)
78
80
  end
79
81
 
@@ -84,7 +86,7 @@ module RuboCop
84
86
  unless @last_sig_for_scope[scope]
85
87
  add_offense(
86
88
  node,
87
- message: "Each method is required to have a signature."
89
+ message: "Each method is required to have a signature.",
88
90
  )
89
91
  end
90
92
  @last_sig_for_scope[scope] = nil
@@ -123,6 +125,7 @@ module RuboCop
123
125
 
124
126
  def generate_params
125
127
  return if @params.empty?
128
+
126
129
  out = StringIO.new
127
130
  out << "params("
128
131
  out << @params.map do |param|
@@ -135,6 +138,7 @@ module RuboCop
135
138
  def generate_return
136
139
  return "returns(#{@return_placeholder})" if @returns.nil?
137
140
  return @returns if @returns == "void"
141
+
138
142
  "returns(#{@returns})"
139
143
  end
140
144
  end
@@ -6,7 +6,7 @@ require_relative "signature_cop"
6
6
  module RuboCop
7
7
  module Cop
8
8
  module Sorbet
9
- # This cop checks for the ordering of keyword arguments required by
9
+ # Checks for the ordering of keyword arguments required by
10
10
  # sorbet-runtime. The ordering requires that all keyword arguments
11
11
  # are at the end of the parameters list, and all keyword arguments
12
12
  # with a default value must be after those without default values.
@@ -24,6 +24,7 @@ module RuboCop
24
24
  def on_signature(node)
25
25
  method_node = node.parent.children[node.sibling_index + 1]
26
26
  return if method_node.nil?
27
+
27
28
  method_parameters = method_node.arguments
28
29
 
29
30
  check_order_for_kwoptargs(method_parameters)
@@ -35,13 +36,13 @@ module RuboCop
35
36
  out_of_kwoptarg = false
36
37
 
37
38
  parameters.reverse.each do |param|
38
- out_of_kwoptarg = true unless param.type == :kwoptarg || param.type == :blockarg || param.type == :kwrestarg
39
+ out_of_kwoptarg = true unless param.kwoptarg_type? || param.blockarg_type? || param.kwrestarg_type?
39
40
 
40
- next unless param.type == :kwoptarg && out_of_kwoptarg
41
+ next unless param.kwoptarg_type? && out_of_kwoptarg
41
42
 
42
43
  add_offense(
43
44
  param,
44
- message: "Optional keyword arguments must be at the end of the parameter list."
45
+ message: "Optional keyword arguments must be at the end of the parameter list.",
45
46
  )
46
47
  end
47
48
  end
@@ -27,13 +27,18 @@ module RuboCop
27
27
  :on_failure,
28
28
  ].each_with_index.to_h.freeze
29
29
 
30
+ # @!method root_call(node)
30
31
  def_node_search(:root_call, <<~PATTERN)
31
32
  (send nil? {#{ORDER.keys.map(&:inspect).join(" ")}} ...)
32
33
  PATTERN
33
34
 
34
35
  def on_signature(node)
35
36
  calls = call_chain(node.children[2]).map(&:method_name)
36
- return unless calls.any?
37
+ return if calls.empty?
38
+
39
+ # While the developer is typing, we may have an incomplete call statement, which means `ORDER[call]` will
40
+ # return `nil`. In that case, invoking `sort_by` will raise
41
+ return if calls.any? { |call| ORDER[call].nil? }
37
42
 
38
43
  expected_order = calls.sort_by { |call| ORDER[call] }
39
44
  return if expected_order == calls
@@ -52,7 +57,7 @@ module RuboCop
52
57
  end
53
58
 
54
59
  def autocorrect(node)
55
- return nil unless can_autocorrect?
60
+ return unless can_autocorrect?
56
61
 
57
62
  lambda do |corrector|
58
63
  tree = call_chain(node_reparsed_with_modern_features(node))
@@ -62,7 +67,7 @@ module RuboCop
62
67
  end
63
68
 
64
69
  corrector.replace(
65
- node.source_range,
70
+ node,
66
71
  Unparser.unparse(tree),
67
72
  )
68
73
  end
@@ -8,9 +8,10 @@ module RuboCop
8
8
  # Abstract cop specific to Sorbet signatures
9
9
  #
10
10
  # You can subclass it to use the `on_signature` trigger and the `signature?` node matcher.
11
- class SignatureCop < RuboCop::Cop::Cop
11
+ class SignatureCop < RuboCop::Cop::Cop # rubocop:todo InternalAffairs/InheritDeprecatedCopClass
12
12
  @registry = Cop.registry # So we can properly subclass this cop
13
13
 
14
+ # @!method signature?(node)
14
15
  def_node_matcher(:signature?, <<~PATTERN)
15
16
  (block (send
16
17
  {nil? #with_runtime? #without_runtime?}
@@ -19,10 +20,12 @@ module RuboCop
19
20
  ) (args) ...)
20
21
  PATTERN
21
22
 
23
+ # @!method with_runtime?(node)
22
24
  def_node_matcher(:with_runtime?, <<~PATTERN)
23
25
  (const (const nil? :T) :Sig)
24
26
  PATTERN
25
27
 
28
+ # @!method without_runtime?(node)
26
29
  def_node_matcher(:without_runtime?, <<~PATTERN)
27
30
  (const (const (const nil? :T) :Sig) :WithoutRuntime)
28
31
  PATTERN
@@ -31,6 +34,8 @@ module RuboCop
31
34
  on_signature(node) if signature?(node)
32
35
  end
33
36
 
37
+ alias_method :on_numblock, :on_block
38
+
34
39
  def on_signature(_)
35
40
  # To be defined in subclasses
36
41
  end
@@ -5,7 +5,7 @@ require "rubocop"
5
5
  module RuboCop
6
6
  module Cop
7
7
  module Sorbet
8
- # This cop ensures all constants used as `T.type_alias` are using CamelCase.
8
+ # Ensures all constants used as `T.type_alias` are using CamelCase.
9
9
  #
10
10
  # @example
11
11
  #
@@ -14,30 +14,23 @@ module RuboCop
14
14
  #
15
15
  # # good
16
16
  # FooOrBar = T.type_alias { T.any(Foo, Bar) }
17
- class TypeAliasName < RuboCop::Cop::Cop
17
+ class TypeAliasName < RuboCop::Cop::Base
18
18
  MSG = "Type alias constant name should be in CamelCase"
19
19
 
20
- def_node_matcher(:casgn_type_alias?, <<-PATTERN)
20
+ # @!method underscored_type_alias?(node)
21
+ def_node_matcher(:underscored_type_alias?, <<-PATTERN)
21
22
  (casgn
22
23
  _
23
- _
24
+ /_/ # Name matches underscore
24
25
  (block
25
- (send
26
- (const nil? :T) :type_alias)
27
- _
28
- _
29
- ))
26
+ (send (const nil? :T) :type_alias)
27
+ ...
28
+ )
29
+ )
30
30
  PATTERN
31
31
 
32
32
  def on_casgn(node)
33
- return unless casgn_type_alias?(node)
34
-
35
- name = node.children[1]
36
-
37
- # From https://github.com/rubocop/rubocop/blob/master/lib/rubocop/cop/naming/class_and_module_camel_case.rb
38
- return unless /_/.match?(name)
39
-
40
- add_offense(node)
33
+ add_offense(node) if underscored_type_alias?(node)
41
34
  end
42
35
  end
43
36
  end
@@ -1,15 +1,20 @@
1
1
  # frozen_string_literal: true
2
- require_relative "sorbet/binding_constants_without_type_alias"
2
+
3
+ require_relative "sorbet/mixin/target_sorbet_version.rb"
4
+
5
+ require_relative "sorbet/binding_constant_without_type_alias"
3
6
  require_relative "sorbet/constants_from_strings"
4
7
  require_relative "sorbet/forbid_superclass_const_literal"
5
8
  require_relative "sorbet/forbid_include_const_literal"
6
9
  require_relative "sorbet/forbid_untyped_struct_props"
10
+ require_relative "sorbet/implicit_conversion_method"
7
11
  require_relative "sorbet/one_ancestor_per_line"
8
12
  require_relative "sorbet/callback_conditionals_binding"
9
13
  require_relative "sorbet/forbid_t_unsafe"
10
14
  require_relative "sorbet/forbid_t_untyped"
11
15
  require_relative "sorbet/redundant_extend_t_sig"
12
16
  require_relative "sorbet/type_alias_name"
17
+ require_relative "sorbet/obsolete_strict_memoization"
13
18
 
14
19
  require_relative "sorbet/rbi/forbid_extend_t_sig_helpers_in_shims"
15
20
  require_relative "sorbet/rbi/forbid_rbi_outside_of_allowed_paths"
@@ -7,13 +7,15 @@ module RuboCop
7
7
  # Because RuboCop doesn't yet support plugins, we have to monkey patch in a
8
8
  # bit of our configuration.
9
9
  module Inject
10
- def self.defaults!
11
- path = CONFIG_DEFAULT.to_s
12
- hash = ConfigLoader.send(:load_yaml_configuration, path)
13
- config = Config.new(hash, path).tap(&:make_excludes_absolute)
14
- puts "configuration from #{path}" if ConfigLoader.debug?
15
- config = ConfigLoader.merge_with_default(config, path)
16
- ConfigLoader.instance_variable_set(:@default_configuration, config)
10
+ class << self
11
+ def defaults!
12
+ path = CONFIG_DEFAULT.to_s
13
+ hash = ConfigLoader.send(:load_yaml_configuration, path)
14
+ config = Config.new(hash, path).tap(&:make_excludes_absolute)
15
+ puts "configuration from #{path}" if ConfigLoader.debug?
16
+ config = ConfigLoader.merge_with_default(config, path)
17
+ ConfigLoader.instance_variable_set(:@default_configuration, config)
18
+ end
17
19
  end
18
20
  end
19
21
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module RuboCop
3
4
  module Sorbet
4
- VERSION = "0.7.0"
5
+ VERSION = "0.7.1"
5
6
  end
6
7
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require "rubocop/sorbet/version"
3
4
  require "yaml"
4
5
 
data/manual/cops.md CHANGED
@@ -24,7 +24,9 @@ In the following section you find all available cops:
24
24
  * [Sorbet/ForbidUntypedStructProps](cops_sorbet.md#sorbetforbiduntypedstructprops)
25
25
  * [Sorbet/HasSigil](cops_sorbet.md#sorbethassigil)
26
26
  * [Sorbet/IgnoreSigil](cops_sorbet.md#sorbetignoresigil)
27
+ * [Sorbet/ImplicitConversionMethod](cops_sorbet.md#sorbetimplicitconversionmethod)
27
28
  * [Sorbet/KeywordArgumentOrdering](cops_sorbet.md#sorbetkeywordargumentordering)
29
+ * [Sorbet/ObsoleteStrictMemoization](cops_sorbet.md#sorbetobsoletestrictmemoization)
28
30
  * [Sorbet/OneAncestorPerLine](cops_sorbet.md#sorbetoneancestorperline)
29
31
  * [Sorbet/RedundantExtendTSig](cops_sorbet.md#sorbetredundantextendtsig)
30
32
  * [Sorbet/SignatureBuildOrder](cops_sorbet.md#sorbetsignaturebuildorder)