Skip to content

Commit fd290ef

Browse files
committed
Enable strict typing in Library/Homebrew/rubocops/
1 parent 730d145 commit fd290ef

28 files changed

+388
-204
lines changed

Library/Homebrew/rubocops/bottle.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def audit_formula(formula_nodes)
1717

1818
sha256_nodes = find_method_calls_by_name(bottle_node.body, :sha256)
1919
cellar_node = find_node_method_by_name(bottle_node.body, :cellar)
20-
cellar_source = cellar_node&.first_argument&.source
20+
cellar_source = T.cast(cellar_node, T.nilable(RuboCop::AST::SendNode))&.first_argument&.source
2121

2222
if sha256_nodes.present? && cellar_node.present?
2323
offending_node(cellar_node)

Library/Homebrew/rubocops/cask/array_alphabetization.rb

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# typed: true # rubocop:todo Sorbet/StrictSigil
1+
# typed: strict
22
# frozen_string_literal: true
33

44
module RuboCop
@@ -35,6 +35,7 @@ def on_send(node)
3535
end
3636
end
3737

38+
sig { params(source: T::Array[String]).returns(T::Array[String]) }
3839
def sort_array(source)
3940
# Combine each comment with the line(s) below so that they remain in the same relative location
4041
combined_source = source.each_with_index.filter_map do |line, index|
@@ -50,17 +51,22 @@ def sort_array(source)
5051

5152
# Sort the lines that should be sorted
5253
to_sort.sort! do |a, b|
53-
a_non_comment = a.split("\n").reject { |line| line.strip.start_with?("#") }.first
54-
b_non_comment = b.split("\n").reject { |line| line.strip.start_with?("#") }.first
55-
a_non_comment.downcase <=> b_non_comment.downcase
54+
a_non_comment = a.split("\n").reject { |line| line.strip.start_with?("#") }.fetch(0)
55+
b_non_comment = b.split("\n").reject { |line| line.strip.start_with?("#") }.fetch(0)
56+
a_non_comment.downcase <=> b_non_comment.downcase || raise("Expected non-comment lines to be present")
5657
end
5758

5859
# Merge the sorted lines and the unsorted lines, preserving the original positions of the unsorted lines
59-
combined_source.map { |line| to_keep.include?(line) ? line : to_sort.shift }
60+
combined_source.map do |line|
61+
next line if to_keep.include?(line)
62+
63+
to_sort.shift || raise("Expected to_sort to be present")
64+
end
6065
end
6166

67+
sig { params(source: T::Array[String], index: Integer, line: String).returns(String) }
6268
def recursively_find_comments(source, index, line)
63-
if source[index - 1].strip.start_with?("#")
69+
if source.fetch(index - 1).strip.start_with?("#")
6470
return recursively_find_comments(source, index - 1, "#{source[index - 1]}\n#{line}")
6571
end
6672

Library/Homebrew/rubocops/cask/ast/cask_header.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# typed: true # rubocop:todo Sorbet/StrictSigil
1+
# typed: strict
22
# frozen_string_literal: true
33

44
module RuboCop
@@ -7,35 +7,42 @@ module AST
77
# This class wraps the AST method node that represents the cask header. It
88
# includes various helper methods to aid cops in their analysis.
99
class CaskHeader
10+
sig { params(method_node: T.all(RuboCop::AST::Node, RuboCop::AST::ParameterizedNode::RestArguments)).void }
1011
def initialize(method_node)
1112
@method_node = method_node
1213
end
1314

15+
sig { returns(T.all(RuboCop::AST::Node, RuboCop::AST::ParameterizedNode::RestArguments)) }
1416
attr_reader :method_node
1517

18+
sig { returns(String) }
1619
def header_str
17-
@header_str ||= source_range.source
20+
@header_str ||= T.let(source_range.source, T.nilable(String))
1821
end
1922

23+
sig { returns(Parser::Source::Range) }
2024
def source_range
21-
@source_range ||= method_node.loc.expression
25+
@source_range ||= T.let(method_node.loc.expression, T.nilable(Parser::Source::Range))
2226
end
2327

2428
sig { returns(String) }
2529
def preferred_header_str
2630
"cask '#{cask_token}'"
2731
end
2832

33+
sig { returns(String) }
2934
def cask_token
30-
@cask_token ||= method_node.first_argument.str_content
35+
@cask_token ||= T.let(method_node.first_argument.str_content, T.nilable(String))
3136
end
3237

38+
sig { returns(T.all(RuboCop::AST::Node, RuboCop::AST::ParameterizedNode::RestArguments)) }
3339
def hash_node
34-
@hash_node ||= method_node.each_child_node(:hash).first
40+
@hash_node ||= T.let(method_node.each_child_node(:hash).first, T.nilable(RuboCop::AST::Node))
3541
end
3642

43+
sig { returns(T.all(RuboCop::AST::Node, RuboCop::AST::ParameterizedNode::RestArguments)) }
3744
def pair_node
38-
@pair_node ||= hash_node.each_child_node(:pair).first
45+
@pair_node ||= T.let(hash_node.each_child_node(:pair).first, T.nilable(RuboCop::AST::Node))
3946
end
4047
end
4148
end

Library/Homebrew/rubocops/cask/ast/stanza.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Stanza
1414

1515
sig {
1616
params(
17-
method_node: RuboCop::AST::Node,
17+
method_node: T.any(RuboCop::AST::AsgnNode, RuboCop::AST::BlockNode, RuboCop::AST::SendNode),
1818
all_comments: T::Array[T.any(String, Parser::Source::Comment)],
1919
).void
2020
}
@@ -23,7 +23,7 @@ def initialize(method_node, all_comments)
2323
@all_comments = all_comments
2424
end
2525

26-
sig { returns(RuboCop::AST::Node) }
26+
sig { returns(T.any(RuboCop::AST::AsgnNode, RuboCop::AST::BlockNode, RuboCop::AST::SendNode)) }
2727
attr_reader :method_node
2828
alias stanza_node method_node
2929

Library/Homebrew/rubocops/cask/extend/node.rbi

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ class RuboCop::AST::Node
1919
sig { returns(T::Boolean) }
2020
def begin_block?; end
2121
end
22+
23+
class RuboCop::AST::BlockNode < RuboCop::AST::Node
24+
sig { returns(RuboCop::AST::SendNode) }
25+
def method_node; end
26+
end

Library/Homebrew/rubocops/cask/stanza_grouping.rb

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# typed: true # rubocop:todo Sorbet/StrictSigil
1+
# typed: strict
22
# frozen_string_literal: true
33

44
require "forwardable"
@@ -17,9 +17,10 @@ class StanzaGrouping < Base
1717
MISSING_LINE_MSG = "stanza groups should be separated by a single empty line"
1818
EXTRA_LINE_MSG = "stanzas within the same group should have no lines between them"
1919

20+
sig { override.params(cask_block: RuboCop::Cask::AST::CaskBlock).void }
2021
def on_cask(cask_block)
21-
@cask_block = cask_block
22-
@line_ops = {}
22+
@cask_block = T.let(cask_block, T.nilable(RuboCop::Cask::AST::CaskBlock))
23+
@line_ops = T.let({}, T.nilable(T::Hash[Integer, Symbol]))
2324
cask_stanzas = cask_block.toplevel_stanzas
2425
add_offenses(cask_stanzas)
2526

@@ -33,13 +34,15 @@ def on_cask(cask_block)
3334

3435
private
3536

36-
attr_reader :cask_block, :line_ops
37+
sig { returns(T.nilable(RuboCop::Cask::AST::CaskBlock)) }
38+
attr_reader :cask_block
3739

3840
def_delegators :cask_block, :cask_node, :toplevel_stanzas
3941

42+
sig { params(stanzas: T::Array[RuboCop::Cask::AST::Stanza]).void }
4043
def add_offenses(stanzas)
4144
stanzas.each_cons(2) do |stanza, next_stanza|
42-
next unless next_stanza
45+
next if !stanza || !next_stanza
4346

4447
if missing_line_after?(stanza, next_stanza)
4548
add_offense_missing_line(stanza)
@@ -49,28 +52,39 @@ def add_offenses(stanzas)
4952
end
5053
end
5154

55+
sig { returns(T::Hash[Integer, Symbol]) }
56+
def line_ops
57+
@line_ops || raise("Call to line_ops before it has been initialized")
58+
end
59+
60+
sig { params(stanza: RuboCop::Cask::AST::Stanza, next_stanza: RuboCop::Cask::AST::Stanza).returns(T::Boolean) }
5261
def missing_line_after?(stanza, next_stanza)
5362
!(stanza.same_group?(next_stanza) ||
5463
empty_line_after?(stanza))
5564
end
5665

66+
sig { params(stanza: RuboCop::Cask::AST::Stanza, next_stanza: RuboCop::Cask::AST::Stanza).returns(T::Boolean) }
5767
def extra_line_after?(stanza, next_stanza)
5868
stanza.same_group?(next_stanza) &&
5969
empty_line_after?(stanza)
6070
end
6171

72+
sig { params(stanza: RuboCop::Cask::AST::Stanza).returns(T::Boolean) }
6273
def empty_line_after?(stanza)
6374
source_line_after(stanza).empty?
6475
end
6576

77+
sig { params(stanza: RuboCop::Cask::AST::Stanza).returns(String) }
6678
def source_line_after(stanza)
6779
processed_source[index_of_line_after(stanza)]
6880
end
6981

82+
sig { params(stanza: RuboCop::Cask::AST::Stanza).returns(Integer) }
7083
def index_of_line_after(stanza)
7184
stanza.source_range.last_line
7285
end
7386

87+
sig { params(stanza: RuboCop::Cask::AST::Stanza).void }
7488
def add_offense_missing_line(stanza)
7589
line_index = index_of_line_after(stanza)
7690
line_ops[line_index] = :insert
@@ -79,6 +93,7 @@ def add_offense_missing_line(stanza)
7993
end
8094
end
8195

96+
sig { params(stanza: RuboCop::Cask::AST::Stanza).void }
8297
def add_offense_extra_line(stanza)
8398
line_index = index_of_line_after(stanza)
8499
line_ops[line_index] = :remove
@@ -87,11 +102,14 @@ def add_offense_extra_line(stanza)
87102
end
88103
end
89104

90-
def add_offense(line_index, message:)
105+
sig { params(line_index: Integer, message: String, block: T.proc.params(corrector: RuboCop::Cop::Corrector).void).void }
106+
def add_offense(line_index, message:, &block)
91107
line_length = [processed_source[line_index].size, 1].max
92-
@range = source_range(processed_source.buffer, line_index + 1, 0,
93-
line_length)
94-
super(@range, message:)
108+
@range = T.let(
109+
source_range(processed_source.buffer, line_index + 1, 0, line_length),
110+
T.nilable(Parser::Source::Range),
111+
)
112+
super(@range, message:, &block)
95113
end
96114
end
97115
end

Library/Homebrew/rubocops/cask/stanza_order.rb

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# typed: true # rubocop:todo Sorbet/StrictSigil
1+
# typed: strict
22
# frozen_string_literal: true
33

44
require "forwardable"
@@ -15,6 +15,7 @@ class StanzaOrder < Base
1515

1616
MESSAGE = "`%<stanza>s` stanza out of order"
1717

18+
sig { override.params(stanza_block: RuboCop::Cask::AST::StanzaBlock).void }
1819
def on_cask_stanza_block(stanza_block)
1920
stanzas = stanza_block.stanzas
2021
ordered_stanzas = sort_stanzas(stanzas)
@@ -32,7 +33,7 @@ def on_cask_stanza_block(stanza_block)
3233

3334
corrector.replace(
3435
stanza_before.source_range_with_comments,
35-
stanza_after.source_with_comments,
36+
T.must(stanza_after).source_with_comments,
3637
)
3738

3839
# Ignore node so that nested content is not auto-corrected and clobbered.
@@ -41,6 +42,7 @@ def on_cask_stanza_block(stanza_block)
4142
end
4243
end
4344

45+
sig { override.void }
4446
def on_new_investigation
4547
super
4648

@@ -49,6 +51,7 @@ def on_new_investigation
4951

5052
private
5153

54+
sig { params(stanzas: T::Array[RuboCop::Cask::AST::Stanza]).returns(T::Array[RuboCop::Cask::AST::Stanza]) }
5255
def sort_stanzas(stanzas)
5356
stanzas.sort do |stanza1, stanza2|
5457
i1 = stanza1.stanza_index
@@ -59,14 +62,9 @@ def sort_stanzas(stanzas)
5962
i2 = stanzas.index(stanza2)
6063
end
6164

62-
i1 - i2
65+
T.must(i1) - T.must(i2)
6366
end
6467
end
65-
66-
def stanza_order_index(stanza)
67-
stanza_name = stanza.respond_to?(:method_name) ? stanza.method_name : stanza.stanza_name
68-
RuboCop::Cask::Constants::STANZA_ORDER.index(stanza_name)
69-
end
7068
end
7169
end
7270
end

Library/Homebrew/rubocops/cask/url.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def on_url_stanza(stanza)
3737
url_stanza = stanza_node.first_argument
3838
hash_node = stanza_node.last_argument
3939

40-
audit_url(:cask, [stanza.stanza_node], [], livecheck_url: false)
40+
audit_url(:cask, [stanza_node], [], livecheck_url: false)
4141

4242
# Check for http:// URLs in homebrew-cask (skip deprecated/disabled casks)
4343
# TODO: Remove the deprecated/disabled check after Homebrew/cask has no more

0 commit comments

Comments
 (0)