rubocop-sorbet 0.4.0 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +3 -3
- data/config/default.yml +25 -2
- data/lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb +24 -1
- data/lib/rubocop/cop/sorbet/forbid_extend_t_sig_helpers_in_shims.rb +53 -0
- data/lib/rubocop/cop/sorbet/forbid_include_const_literal.rb +0 -40
- data/lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb +0 -17
- data/lib/rubocop/cop/sorbet/one_ancestor_per_line.rb +75 -0
- data/lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb +10 -0
- data/lib/rubocop/cop/sorbet/signatures/enforce_signatures.rb +19 -10
- data/lib/rubocop/cop/sorbet/signatures/signature_build_order.rb +22 -3
- data/lib/rubocop/cop/sorbet/single_line_rbi_class_module_definitions.rb +46 -0
- data/lib/rubocop/cop/sorbet_cops.rb +3 -0
- data/lib/rubocop/sorbet/version.rb +1 -1
- data/manual/cops.md +3 -0
- data/manual/cops_sorbet.md +93 -3
- data/service.yml +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b80b70b68c03033dcda68e2661cba6ccbe10c647618cbf6068175c635288f7e4
|
4
|
+
data.tar.gz: 794956ee0b9ca5301f680fd79d3d414551284bce1f8dc218e1980da204b13689
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5f81c72e557eb0888383137198f6138a52b9e043e4d2e02857419658a34407cf90bf08d4fc662fdd4ac9b0c10771aa79876dce08ded2ca61a8b2bea0561dad3
|
7
|
+
data.tar.gz: 5f8926ae82a56c9edf3fde4552d3ef84b942dbb1f317ecf603ac32b39fc08acc1bef5d8ed459ab28513b667ed901617510a72a3bf34cf8ea7b4d2ffba1ab982a
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubocop-sorbet (0.
|
4
|
+
rubocop-sorbet (0.6.1)
|
5
5
|
rubocop
|
6
6
|
|
7
7
|
GEM
|
@@ -25,7 +25,7 @@ GEM
|
|
25
25
|
ast (~> 2.4.0)
|
26
26
|
procto (0.0.3)
|
27
27
|
rainbow (3.0.0)
|
28
|
-
rake (
|
28
|
+
rake (13.0.1)
|
29
29
|
regexp_parser (1.7.0)
|
30
30
|
rexml (3.2.4)
|
31
31
|
rspec (3.8.0)
|
@@ -71,7 +71,7 @@ PLATFORMS
|
|
71
71
|
ruby
|
72
72
|
|
73
73
|
DEPENDENCIES
|
74
|
-
rake (
|
74
|
+
rake (>= 12.3.3)
|
75
75
|
rspec
|
76
76
|
rubocop-shopify
|
77
77
|
rubocop-sorbet!
|
data/config/default.yml
CHANGED
@@ -53,15 +53,26 @@ Sorbet/FalseSigil:
|
|
53
53
|
- db/**/*.rb
|
54
54
|
- script/**/*
|
55
55
|
|
56
|
+
Sorbet/ForbidExtendTSigHelpersInShims:
|
57
|
+
Description: 'Forbid the use of `extend T::Sig` and `extend T::Helpers` in RBI shims'
|
58
|
+
Enabled: true
|
59
|
+
VersionAdded: '0.6.0'
|
60
|
+
Include:
|
61
|
+
- "**/*.rbi"
|
62
|
+
|
56
63
|
Sorbet/ForbidIncludeConstLiteral:
|
57
64
|
Description: 'Forbids include of non-literal constants.'
|
58
|
-
Enabled:
|
65
|
+
Enabled: false
|
59
66
|
VersionAdded: 0.2.0
|
67
|
+
VersionChanged: 0.5.0
|
60
68
|
|
61
69
|
Sorbet/ForbidSuperclassConstLiteral:
|
62
70
|
Description: 'Forbid superclasses which are non-literal constants.'
|
63
|
-
Enabled:
|
71
|
+
Enabled: false
|
64
72
|
VersionAdded: 0.2.0
|
73
|
+
VersionChanged: 0.6.1
|
74
|
+
Exclude:
|
75
|
+
- db/migrate/*.rb
|
65
76
|
|
66
77
|
Sorbet/ForbidUntypedStructProps:
|
67
78
|
Description: >-
|
@@ -90,6 +101,11 @@ Sorbet/KeywordArgumentOrdering:
|
|
90
101
|
Enabled: true
|
91
102
|
VersionAdded: 0.2.0
|
92
103
|
|
104
|
+
Sorbet/OneAncestorPerLine:
|
105
|
+
Description: 'Enforces one ancestor per call to requires_ancestor'
|
106
|
+
Enabled: false
|
107
|
+
VersionAdded: '0.6.0'
|
108
|
+
|
93
109
|
Sorbet/ParametersOrderingInSignature:
|
94
110
|
Description: 'Enforces same parameter order between a method and its signature.'
|
95
111
|
Enabled: true
|
@@ -105,6 +121,13 @@ Sorbet/SignatureBuildOrder:
|
|
105
121
|
Enabled: true
|
106
122
|
VersionAdded: 0.3.0
|
107
123
|
|
124
|
+
Sorbet/SingleLineRbiClassModuleDefinitions:
|
125
|
+
Description: 'Empty class and module definitions in RBI must be on a single line.'
|
126
|
+
Enabled: false
|
127
|
+
VersionAdded: '0.6.0'
|
128
|
+
Include:
|
129
|
+
- "**/*.rbi"
|
130
|
+
|
108
131
|
Sorbet/StrictSigil:
|
109
132
|
Description: 'All files must be at least at strictness `strict`.'
|
110
133
|
Enabled: false
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
# FooOrBar = T.type_alias { T.any(Foo, Bar) }
|
18
18
|
class BindingConstantWithoutTypeAlias < RuboCop::Cop::Cop
|
19
19
|
def_node_matcher(:binding_unaliased_type?, <<-PATTERN)
|
20
|
-
(casgn _ _ [#not_nil? #not_t_let? #method_needing_aliasing_on_t?])
|
20
|
+
(casgn _ _ [#not_nil? #not_t_let? #not_dynamic_type_creation_with_block? #not_generic_parameter_decl? #method_needing_aliasing_on_t?])
|
21
21
|
PATTERN
|
22
22
|
|
23
23
|
def_node_matcher(:using_type_alias?, <<-PATTERN)
|
@@ -48,6 +48,21 @@ module RuboCop
|
|
48
48
|
)
|
49
49
|
PATTERN
|
50
50
|
|
51
|
+
def_node_matcher(:dynamic_type_creation_with_block?, <<-PATTERN)
|
52
|
+
(block
|
53
|
+
(send
|
54
|
+
const :new ...)
|
55
|
+
_
|
56
|
+
_
|
57
|
+
)
|
58
|
+
PATTERN
|
59
|
+
|
60
|
+
def_node_matcher(:generic_parameter_decl?, <<-PATTERN)
|
61
|
+
(
|
62
|
+
send nil? {:type_template :type_member} ...
|
63
|
+
)
|
64
|
+
PATTERN
|
65
|
+
|
51
66
|
def_node_search(:method_needing_aliasing_on_t?, <<-PATTERN)
|
52
67
|
(
|
53
68
|
send
|
@@ -61,6 +76,14 @@ module RuboCop
|
|
61
76
|
!t_let?(node)
|
62
77
|
end
|
63
78
|
|
79
|
+
def not_dynamic_type_creation_with_block?(node)
|
80
|
+
!dynamic_type_creation_with_block?(node)
|
81
|
+
end
|
82
|
+
|
83
|
+
def not_generic_parameter_decl?(node)
|
84
|
+
!generic_parameter_decl?(node)
|
85
|
+
end
|
86
|
+
|
64
87
|
def not_nil?(node)
|
65
88
|
!node.nil?
|
66
89
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# This cop ensures RBI shims do not include a call to extend T::Sig
|
7
|
+
# or to extend T::Helpers
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# module SomeModule
|
13
|
+
# extend T::Sig
|
14
|
+
# extend T::Helpers
|
15
|
+
#
|
16
|
+
# sig { returns(String) }
|
17
|
+
# def foo; end
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# module SomeModule
|
22
|
+
# sig { returns(String) }
|
23
|
+
# def foo; end
|
24
|
+
# end
|
25
|
+
class ForbidExtendTSigHelpersInShims < RuboCop::Cop::Cop
|
26
|
+
include RangeHelp
|
27
|
+
|
28
|
+
MSG = 'Extending T::Sig or T::Helpers in a shim is unnecessary'
|
29
|
+
RESTRICT_ON_SEND = [:extend]
|
30
|
+
|
31
|
+
def_node_matcher :extend_t_sig?, <<~PATTERN
|
32
|
+
(send nil? :extend (const (const nil? :T) :Sig))
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def_node_matcher :extend_t_helpers?, <<~PATTERN
|
36
|
+
(send nil? :extend (const (const nil? :T) :Helpers))
|
37
|
+
PATTERN
|
38
|
+
|
39
|
+
def autocorrect(node)
|
40
|
+
-> (corrector) do
|
41
|
+
corrector.remove(
|
42
|
+
range_by_whole_lines(node.source_range, include_final_newline: true)
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_send(node)
|
48
|
+
add_offense(node) if extend_t_helpers?(node) || extend_t_sig?(node)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -14,15 +14,6 @@ require 'rubocop'
|
|
14
14
|
# end
|
15
15
|
# ```
|
16
16
|
#
|
17
|
-
# This cop replaces them by:
|
18
|
-
#
|
19
|
-
# ```ruby
|
20
|
-
# class MyClass
|
21
|
-
# MyClassInclude = send_expr
|
22
|
-
# include MyClassInclude
|
23
|
-
# end
|
24
|
-
# ```
|
25
|
-
#
|
26
17
|
# Multiple occurences of this can be found in Shopify's code base like:
|
27
18
|
#
|
28
19
|
# ```ruby
|
@@ -61,37 +52,6 @@ module RuboCop
|
|
61
52
|
return unless [:module, :class, :sclass].include?(parent.type)
|
62
53
|
add_offense(node)
|
63
54
|
end
|
64
|
-
|
65
|
-
def autocorrect(node)
|
66
|
-
lambda do |corrector|
|
67
|
-
# Find parent class node
|
68
|
-
parent = node.parent
|
69
|
-
parent = parent.parent if parent.type == :begin
|
70
|
-
|
71
|
-
# Build include variable name
|
72
|
-
class_name = (parent.child_nodes.first.const_name || 'Anon').split('::').last
|
73
|
-
include_name = find_free_name("#{class_name}Include")
|
74
|
-
used_names << include_name
|
75
|
-
|
76
|
-
# Apply fix
|
77
|
-
indent = ' ' * node.loc.column
|
78
|
-
fix = "#{include_name} = #{node.child_nodes.first.source}\n#{indent}"
|
79
|
-
corrector.insert_before(node.loc.expression, fix)
|
80
|
-
corrector.replace(node.child_nodes.first.loc.expression, include_name)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# Find a free local variable name
|
85
|
-
#
|
86
|
-
# Since each include uses its own local variable to store the send result,
|
87
|
-
# we need to ensure that we don't use the same name twice in the same
|
88
|
-
# module.
|
89
|
-
def find_free_name(base_name)
|
90
|
-
return base_name unless used_names.include?(base_name)
|
91
|
-
i = 2
|
92
|
-
i += 1 while used_names.include?("#{base_name}#{i}")
|
93
|
-
"#{base_name}#{i}"
|
94
|
-
end
|
95
55
|
end
|
96
56
|
end
|
97
57
|
end
|
@@ -12,13 +12,6 @@ require 'rubocop'
|
|
12
12
|
# class Foo < send_expr; end
|
13
13
|
# ```
|
14
14
|
#
|
15
|
-
# This cop replaces them by:
|
16
|
-
#
|
17
|
-
# ```ruby
|
18
|
-
# FooParent = send_expr
|
19
|
-
# class Foo < FooParent; end
|
20
|
-
# ```
|
21
|
-
#
|
22
15
|
# Multiple occurences of this can be found in Shopify's code base like:
|
23
16
|
#
|
24
17
|
# ```ruby
|
@@ -46,16 +39,6 @@ module RuboCop
|
|
46
39
|
return unless not_lit_const_superclass?(node)
|
47
40
|
add_offense(node.child_nodes[1])
|
48
41
|
end
|
49
|
-
|
50
|
-
def autocorrect(node)
|
51
|
-
lambda do |corrector|
|
52
|
-
class_name = node.parent.child_nodes.first.const_name
|
53
|
-
parent_name = "#{class_name}Parent"
|
54
|
-
indent = ' ' * node.parent.loc.column
|
55
|
-
corrector.insert_before(node.parent.loc.expression, "#{parent_name} = #{node.source}\n#{indent}")
|
56
|
-
corrector.replace(node.loc.expression, parent_name)
|
57
|
-
end
|
58
|
-
end
|
59
42
|
end
|
60
43
|
end
|
61
44
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rubocop'
|
5
|
+
|
6
|
+
module RuboCop
|
7
|
+
module Cop
|
8
|
+
module Sorbet
|
9
|
+
# This cop ensures one ancestor per requires_ancestor line
|
10
|
+
# rather than chaining them as a comma-separated list.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# # bad
|
15
|
+
# module SomeModule
|
16
|
+
# requires_ancestor Kernel, Minitest::Assertions
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# module SomeModule
|
21
|
+
# requires_ancestor Kernel
|
22
|
+
# requires_ancestor Minitest::Assertions
|
23
|
+
# end
|
24
|
+
class OneAncestorPerLine < RuboCop::Cop::Cop
|
25
|
+
MSG = 'Cannot require more than one ancestor per line'
|
26
|
+
|
27
|
+
def_node_search :requires_ancestors, <<~PATTERN
|
28
|
+
(send nil? :requires_ancestor ...)
|
29
|
+
PATTERN
|
30
|
+
|
31
|
+
def_node_matcher :more_than_one_ancestor, <<~PATTERN
|
32
|
+
(send nil? :requires_ancestor const const+)
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def_node_search :abstract?, <<~PATTERN
|
36
|
+
(send nil? :abstract!)
|
37
|
+
PATTERN
|
38
|
+
|
39
|
+
def on_module(node)
|
40
|
+
return unless node.body
|
41
|
+
return unless requires_ancestors(node)
|
42
|
+
process_node(node)
|
43
|
+
end
|
44
|
+
|
45
|
+
def on_class(node)
|
46
|
+
return unless abstract?(node)
|
47
|
+
return unless requires_ancestors(node)
|
48
|
+
process_node(node)
|
49
|
+
end
|
50
|
+
|
51
|
+
def autocorrect(node)
|
52
|
+
-> (corrector) do
|
53
|
+
ra_call = node.parent
|
54
|
+
split_ra_calls = ra_call.source.gsub(/,\s+/, new_ra_line(ra_call.loc.column))
|
55
|
+
corrector.replace(ra_call, split_ra_calls)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def process_node(node)
|
62
|
+
requires_ancestors(node).each do |ra|
|
63
|
+
add_offense(ra.child_nodes[1]) if more_than_one_ancestor(ra)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def new_ra_line(indent_count)
|
68
|
+
indents = " " * indent_count
|
69
|
+
indented_ra_call = "#{indents}requires_ancestor "
|
70
|
+
"\n#{indented_ra_call}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -28,6 +28,8 @@ module RuboCop
|
|
28
28
|
# Only `typed`, `(en)?coding`, `warn_indent` and `frozen_string_literal` magic comments are considered,
|
29
29
|
# other comments or magic comments are left in the same place.
|
30
30
|
class EnforceSigilOrder < ValidSigil
|
31
|
+
include RangeHelp
|
32
|
+
|
31
33
|
def investigate(processed_source)
|
32
34
|
return if processed_source.tokens.empty?
|
33
35
|
|
@@ -49,6 +51,14 @@ module RuboCop
|
|
49
51
|
tokens.each_with_index do |token, index|
|
50
52
|
corrector.replace(token.pos, expected[index].text)
|
51
53
|
end
|
54
|
+
|
55
|
+
# Remove blank lines between the magic comments
|
56
|
+
lines = tokens.map(&:line).to_set
|
57
|
+
(lines.min...lines.max).each do |line|
|
58
|
+
next if lines.include?(line)
|
59
|
+
next unless processed_source[line - 1].empty?
|
60
|
+
corrector.remove(source_range(processed_source.buffer, line, 0))
|
61
|
+
end
|
52
62
|
end
|
53
63
|
end
|
54
64
|
|
@@ -27,6 +27,11 @@ module RuboCop
|
|
27
27
|
# * `ParameterTypePlaceholder`: placeholders used for parameter types (default: 'T.untyped')
|
28
28
|
# * `ReturnTypePlaceholder`: placeholders used for return types (default: 'T.untyped')
|
29
29
|
class EnforceSignatures < SignatureCop
|
30
|
+
def initialize(config = nil, options = nil)
|
31
|
+
super(config, options)
|
32
|
+
@last_sig_for_scope = {}
|
33
|
+
end
|
34
|
+
|
30
35
|
def_node_matcher(:accessor?, <<-PATTERN)
|
31
36
|
(send nil? {:attr_reader :attr_writer :attr_accessor} ...)
|
32
37
|
PATTERN
|
@@ -40,8 +45,11 @@ module RuboCop
|
|
40
45
|
end
|
41
46
|
|
42
47
|
def on_send(node)
|
43
|
-
|
44
|
-
|
48
|
+
check_node(node) if accessor?(node)
|
49
|
+
end
|
50
|
+
|
51
|
+
def on_block(node)
|
52
|
+
@last_sig_for_scope[scope(node)] = node if signature?(node)
|
45
53
|
end
|
46
54
|
|
47
55
|
def autocorrect(node)
|
@@ -63,22 +71,23 @@ module RuboCop
|
|
63
71
|
end
|
64
72
|
end
|
65
73
|
|
74
|
+
def scope(node)
|
75
|
+
return nil unless node.parent
|
76
|
+
return node.parent if [:begin, :block, :class, :module].include?(node.parent.type)
|
77
|
+
scope(node.parent)
|
78
|
+
end
|
79
|
+
|
66
80
|
private
|
67
81
|
|
68
82
|
def check_node(node)
|
69
|
-
|
70
|
-
unless
|
83
|
+
scope = self.scope(node)
|
84
|
+
unless @last_sig_for_scope[scope]
|
71
85
|
add_offense(
|
72
86
|
node,
|
73
87
|
message: "Each method is required to have a signature."
|
74
88
|
)
|
75
89
|
end
|
76
|
-
|
77
|
-
|
78
|
-
def previous_node(node)
|
79
|
-
parent = node.parent
|
80
|
-
return nil unless parent
|
81
|
-
parent.children[node.sibling_index - 1]
|
90
|
+
@last_sig_for_scope[scope] = nil
|
82
91
|
end
|
83
92
|
|
84
93
|
def param_type_placeholder
|
@@ -55,9 +55,9 @@ module RuboCop
|
|
55
55
|
return nil unless can_autocorrect?
|
56
56
|
|
57
57
|
lambda do |corrector|
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
tree = call_chain(node_reparsed_with_modern_features(node))
|
59
|
+
.sort_by { |call| ORDER[call.method_name] }
|
60
|
+
.reduce(nil) do |receiver, caller|
|
61
61
|
caller.updated(nil, [receiver] + caller.children.drop(1))
|
62
62
|
end
|
63
63
|
|
@@ -68,8 +68,27 @@ module RuboCop
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
# Create a subclass of AST Builder that has modern features turned on
|
72
|
+
class ModernBuilder < RuboCop::AST::Builder
|
73
|
+
modernize
|
74
|
+
end
|
75
|
+
private_constant :ModernBuilder
|
76
|
+
|
71
77
|
private
|
72
78
|
|
79
|
+
# This method exists to reparse the current node with modern features enabled.
|
80
|
+
# Modern features include "index send" emitting, which is necessary to unparse
|
81
|
+
# "index sends" (i.e. `[]` calls) back to index accessors (i.e. as `foo[bar]``).
|
82
|
+
# Otherwise, we would get the unparsed node as `foo.[](bar)`.
|
83
|
+
def node_reparsed_with_modern_features(node)
|
84
|
+
# Create a new parser with a modern builder class instance
|
85
|
+
parser = Parser::CurrentRuby.new(ModernBuilder.new)
|
86
|
+
# Create a new source buffer with the node source
|
87
|
+
buffer = Parser::Source::Buffer.new(processed_source.path, source: node.source)
|
88
|
+
# Re-parse the buffer
|
89
|
+
parser.parse(buffer)
|
90
|
+
end
|
91
|
+
|
73
92
|
def can_autocorrect?
|
74
93
|
defined?(::Unparser)
|
75
94
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Sorbet
|
6
|
+
# This cop ensures empty class/module definitions in RBI files are
|
7
|
+
# done on a single line rather than being split across multiple lines.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# module SomeModule
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# module SomeModule; end
|
17
|
+
class SingleLineRbiClassModuleDefinitions < RuboCop::Cop::Cop
|
18
|
+
MSG = 'Empty class/module definitions in RBI files should be on a single line.'
|
19
|
+
|
20
|
+
def on_module(node)
|
21
|
+
process_node(node)
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_class(node)
|
25
|
+
process_node(node)
|
26
|
+
end
|
27
|
+
|
28
|
+
def autocorrect(node)
|
29
|
+
-> (corrector) { corrector.replace(node, convert_newlines(node.source)) }
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def convert_newlines(source)
|
35
|
+
source.sub(/[\r\n]+\s*[\r\n]*/, "; ")
|
36
|
+
end
|
37
|
+
|
38
|
+
def process_node(node)
|
39
|
+
return if node.body
|
40
|
+
return if node.single_line?
|
41
|
+
add_offense(node)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require_relative 'sorbet/binding_constants_without_type_alias'
|
3
3
|
require_relative 'sorbet/constants_from_strings'
|
4
|
+
require_relative 'sorbet/forbid_extend_t_sig_helpers_in_shims'
|
4
5
|
require_relative 'sorbet/forbid_superclass_const_literal'
|
5
6
|
require_relative 'sorbet/forbid_include_const_literal'
|
6
7
|
require_relative 'sorbet/forbid_untyped_struct_props'
|
8
|
+
require_relative 'sorbet/single_line_rbi_class_module_definitions'
|
9
|
+
require_relative 'sorbet/one_ancestor_per_line'
|
7
10
|
|
8
11
|
require_relative 'sorbet/signatures/allow_incompatible_override'
|
9
12
|
require_relative 'sorbet/signatures/checked_true_in_signature'
|
data/manual/cops.md
CHANGED
@@ -12,15 +12,18 @@ In the following section you find all available cops:
|
|
12
12
|
* [Sorbet/EnforceSigilOrder](cops_sorbet.md#sorbetenforcesigilorder)
|
13
13
|
* [Sorbet/EnforceSignatures](cops_sorbet.md#sorbetenforcesignatures)
|
14
14
|
* [Sorbet/FalseSigil](cops_sorbet.md#sorbetfalsesigil)
|
15
|
+
* [Sorbet/ForbidExtendTSigHelpersInShims](cops_sorbet.md#sorbetforbidextendtsighelpersinshims)
|
15
16
|
* [Sorbet/ForbidIncludeConstLiteral](cops_sorbet.md#sorbetforbidincludeconstliteral)
|
16
17
|
* [Sorbet/ForbidSuperclassConstLiteral](cops_sorbet.md#sorbetforbidsuperclassconstliteral)
|
17
18
|
* [Sorbet/ForbidUntypedStructProps](cops_sorbet.md#sorbetforbiduntypedstructprops)
|
18
19
|
* [Sorbet/HasSigil](cops_sorbet.md#sorbethassigil)
|
19
20
|
* [Sorbet/IgnoreSigil](cops_sorbet.md#sorbetignoresigil)
|
20
21
|
* [Sorbet/KeywordArgumentOrdering](cops_sorbet.md#sorbetkeywordargumentordering)
|
22
|
+
* [Sorbet/OneAncestorPerLine](cops_sorbet.md#sorbetoneancestorperline)
|
21
23
|
* [Sorbet/ParametersOrderingInSignature](cops_sorbet.md#sorbetparametersorderinginsignature)
|
22
24
|
* [Sorbet/SignatureBuildOrder](cops_sorbet.md#sorbetsignaturebuildorder)
|
23
25
|
* [Sorbet/SignatureCop](cops_sorbet.md#sorbetsignaturecop)
|
26
|
+
* [Sorbet/SingleLineRbiClassModuleDefinitions](cops_sorbet.md#sorbetsinglelinerbiclassmoduledefinitions)
|
24
27
|
* [Sorbet/StrictSigil](cops_sorbet.md#sorbetstrictsigil)
|
25
28
|
* [Sorbet/StrongSigil](cops_sorbet.md#sorbetstrongsigil)
|
26
29
|
* [Sorbet/TrueSigil](cops_sorbet.md#sorbettruesigil)
|
data/manual/cops_sorbet.md
CHANGED
@@ -171,11 +171,45 @@ SuggestedStrictness | `true` | Boolean
|
|
171
171
|
Include | `**/*.rb`, `**/*.rbi`, `**/*.rake`, `**/*.ru` | Array
|
172
172
|
Exclude | `bin/**/*`, `db/**/*.rb`, `script/**/*` | Array
|
173
173
|
|
174
|
+
## Sorbet/ForbidExtendTSigHelpersInShims
|
175
|
+
|
176
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
177
|
+
--- | --- | --- | --- | ---
|
178
|
+
Enabled | Yes | Yes | 0.6.0 | -
|
179
|
+
|
180
|
+
This cop ensures RBI shims do not include a call to extend T::Sig
|
181
|
+
or to extend T::Helpers
|
182
|
+
|
183
|
+
### Examples
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
# bad
|
187
|
+
module SomeModule
|
188
|
+
extend T::Sig
|
189
|
+
extend T::Helpers
|
190
|
+
|
191
|
+
sig { returns(String) }
|
192
|
+
def foo; end
|
193
|
+
end
|
194
|
+
|
195
|
+
# good
|
196
|
+
module SomeModule
|
197
|
+
sig { returns(String) }
|
198
|
+
def foo; end
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
### Configurable attributes
|
203
|
+
|
204
|
+
Name | Default value | Configurable values
|
205
|
+
--- | --- | ---
|
206
|
+
Include | `**/*.rbi` | Array
|
207
|
+
|
174
208
|
## Sorbet/ForbidIncludeConstLiteral
|
175
209
|
|
176
210
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
177
211
|
--- | --- | --- | --- | ---
|
178
|
-
|
212
|
+
Disabled | Yes | No | 0.2.0 | 0.5.0
|
179
213
|
|
180
214
|
No documentation
|
181
215
|
|
@@ -183,15 +217,21 @@ No documentation
|
|
183
217
|
|
184
218
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
185
219
|
--- | --- | --- | --- | ---
|
186
|
-
|
220
|
+
Disabled | Yes | No | 0.2.0 | 0.6.1
|
187
221
|
|
188
222
|
No documentation
|
189
223
|
|
224
|
+
### Configurable attributes
|
225
|
+
|
226
|
+
Name | Default value | Configurable values
|
227
|
+
--- | --- | ---
|
228
|
+
Exclude | `db/migrate/*.rb` | Array
|
229
|
+
|
190
230
|
## Sorbet/ForbidUntypedStructProps
|
191
231
|
|
192
232
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
193
233
|
--- | --- | --- | --- | ---
|
194
|
-
Enabled | Yes | No | 0.
|
234
|
+
Enabled | Yes | No | 0.4.0 | -
|
195
235
|
|
196
236
|
This cop disallows use of `T.untyped` or `T.nilable(T.untyped)`
|
197
237
|
as a prop type for `T::Struct`.
|
@@ -258,6 +298,30 @@ sig { params(b: String, a: Integer).void }
|
|
258
298
|
def foo(b:, a: 1); end
|
259
299
|
```
|
260
300
|
|
301
|
+
## Sorbet/OneAncestorPerLine
|
302
|
+
|
303
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
304
|
+
--- | --- | --- | --- | ---
|
305
|
+
Disabled | Yes | Yes | 0.6.0 | -
|
306
|
+
|
307
|
+
This cop ensures one ancestor per requires_ancestor line
|
308
|
+
rather than chaining them as a comma-separated list.
|
309
|
+
|
310
|
+
### Examples
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
# bad
|
314
|
+
module SomeModule
|
315
|
+
requires_ancestor Kernel, Minitest::Assertions
|
316
|
+
end
|
317
|
+
|
318
|
+
# good
|
319
|
+
module SomeModule
|
320
|
+
requires_ancestor Kernel
|
321
|
+
requires_ancestor Minitest::Assertions
|
322
|
+
end
|
323
|
+
```
|
324
|
+
|
261
325
|
## Sorbet/ParametersOrderingInSignature
|
262
326
|
|
263
327
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
@@ -298,6 +362,32 @@ Abstract cop specific to Sorbet signatures
|
|
298
362
|
|
299
363
|
You can subclass it to use the `on_signature` trigger and the `signature?` node matcher.
|
300
364
|
|
365
|
+
## Sorbet/SingleLineRbiClassModuleDefinitions
|
366
|
+
|
367
|
+
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
368
|
+
--- | --- | --- | --- | ---
|
369
|
+
Disabled | Yes | Yes | 0.6.0 | -
|
370
|
+
|
371
|
+
This cop ensures empty class/module definitions in RBI files are
|
372
|
+
done on a single line rather than being split across multiple lines.
|
373
|
+
|
374
|
+
### Examples
|
375
|
+
|
376
|
+
```ruby
|
377
|
+
# bad
|
378
|
+
module SomeModule
|
379
|
+
end
|
380
|
+
|
381
|
+
# good
|
382
|
+
module SomeModule; end
|
383
|
+
```
|
384
|
+
|
385
|
+
### Configurable attributes
|
386
|
+
|
387
|
+
Name | Default value | Configurable values
|
388
|
+
--- | --- | ---
|
389
|
+
Include | `**/*.rbi` | Array
|
390
|
+
|
301
391
|
## Sorbet/StrictSigil
|
302
392
|
|
303
393
|
Enabled by default | Safe | Supports autocorrection | VersionAdded | VersionChanged
|
data/service.yml
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop-sorbet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ufuk Kayserilioglu
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2021-03-17 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rspec
|
@@ -85,9 +85,11 @@ files:
|
|
85
85
|
- lib/rubocop-sorbet.rb
|
86
86
|
- lib/rubocop/cop/sorbet/binding_constants_without_type_alias.rb
|
87
87
|
- lib/rubocop/cop/sorbet/constants_from_strings.rb
|
88
|
+
- lib/rubocop/cop/sorbet/forbid_extend_t_sig_helpers_in_shims.rb
|
88
89
|
- lib/rubocop/cop/sorbet/forbid_include_const_literal.rb
|
89
90
|
- lib/rubocop/cop/sorbet/forbid_superclass_const_literal.rb
|
90
91
|
- lib/rubocop/cop/sorbet/forbid_untyped_struct_props.rb
|
92
|
+
- lib/rubocop/cop/sorbet/one_ancestor_per_line.rb
|
91
93
|
- lib/rubocop/cop/sorbet/sigils/enforce_sigil_order.rb
|
92
94
|
- lib/rubocop/cop/sorbet/sigils/false_sigil.rb
|
93
95
|
- lib/rubocop/cop/sorbet/sigils/has_sigil.rb
|
@@ -103,6 +105,7 @@ files:
|
|
103
105
|
- lib/rubocop/cop/sorbet/signatures/parameters_ordering_in_signature.rb
|
104
106
|
- lib/rubocop/cop/sorbet/signatures/signature_build_order.rb
|
105
107
|
- lib/rubocop/cop/sorbet/signatures/signature_cop.rb
|
108
|
+
- lib/rubocop/cop/sorbet/single_line_rbi_class_module_definitions.rb
|
106
109
|
- lib/rubocop/cop/sorbet_cops.rb
|
107
110
|
- lib/rubocop/sorbet.rb
|
108
111
|
- lib/rubocop/sorbet/inject.rb
|