spoom 1.7.15 → 1.8.0

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.
@@ -0,0 +1,214 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Spoom
5
+ module Sorbet
6
+ module Translate
7
+ # Checks that a translation preserved the lines of every "landmark" (e.g. classes, method defs, and so on)
8
+ # so line numbers in the rewritten output still line up with the original source.
9
+ module Validator
10
+ # A description of a landmark, like "class C", "def foo", etc.
11
+ #: type landmarkID = String
12
+
13
+ # The integer line numbers where each landmark appears.
14
+ #: type landmarks = Hash[landmarkID, Array[Integer]]
15
+
16
+ class << self
17
+ # Compares the landmarks in both sources and returns a result describing
18
+ # what changed:
19
+ # missing_from_rewritten_output - dropped: an occurrence in the original
20
+ # that is gone from the rewrite
21
+ # excess_in_rewritten_output - added: an occurrence in the rewrite with
22
+ # no match in the original
23
+ # on_wrong_line - survived but moved to a different line
24
+ #: (String original, String rewritten) -> ValidationResult
25
+ def validate(original, rewritten)
26
+ original_landmarks = LandmarkFinder.find_landmarks_in(original)
27
+ rewritten_landmarks = LandmarkFinder.find_landmarks_in(rewritten)
28
+
29
+ missing = []
30
+ excess = []
31
+ on_wrong_line = []
32
+
33
+ (original_landmarks.keys | rewritten_landmarks.keys).each do |landmark_id|
34
+ original_lines = original_landmarks.fetch(landmark_id, [])
35
+ rewritten_lines = rewritten_landmarks.fetch(landmark_id, [])
36
+
37
+ dropped = original_lines - rewritten_lines
38
+ added = rewritten_lines - original_lines
39
+
40
+ if dropped.any? && added.any?
41
+ # Present in both but on different lines: the landmark moved.
42
+ on_wrong_line << { landmark_id:, expected: dropped, actual: added }
43
+ else
44
+ dropped.each { |line| missing << { landmark_id:, line: } }
45
+ added.each { |line| excess << { landmark_id:, line: } }
46
+ end
47
+ end
48
+
49
+ if original.lines.count != rewritten.lines.count
50
+ on_wrong_line << { landmark_id: "EOF", expected: [original.lines.count], actual: [rewritten.lines.count] }
51
+ end
52
+
53
+ ValidationResult.new(
54
+ missing_from_rewritten_output: missing,
55
+ excess_in_rewritten_output: excess,
56
+ on_wrong_line: on_wrong_line,
57
+ )
58
+ end
59
+ end
60
+ end
61
+
62
+ # The outcome of comparing an original source with its rewritten form.
63
+ class ValidationResult
64
+ # A landmark dropped from, or added to, the rewritten output.
65
+ #: type landmark_location = { landmark_id: String, line: Integer }
66
+
67
+ # A landmark present in both sources, but on different lines.
68
+ #: type moved_landmark = { landmark_id: String, expected: Array[Integer], actual: Array[Integer] }
69
+
70
+ # Landmarks present in the original but missing from the rewrite.
71
+ #: Array[landmark_location]
72
+ attr_reader :missing_from_rewritten_output
73
+
74
+ # Landmarks present in the rewrite with no match in the original.
75
+ #: Array[landmark_location]
76
+ attr_reader :excess_in_rewritten_output
77
+
78
+ # Landmarks present in both sources, but that moved to a different line.
79
+ #: Array[moved_landmark]
80
+ attr_reader :on_wrong_line
81
+
82
+ #: (
83
+ #| missing_from_rewritten_output: Array[landmark_location],
84
+ #| excess_in_rewritten_output: Array[landmark_location],
85
+ #| on_wrong_line: Array[moved_landmark]
86
+ #| ) -> void
87
+ def initialize(missing_from_rewritten_output:, excess_in_rewritten_output:, on_wrong_line:)
88
+ @missing_from_rewritten_output = missing_from_rewritten_output
89
+ @excess_in_rewritten_output = excess_in_rewritten_output
90
+ @on_wrong_line = on_wrong_line
91
+ end
92
+
93
+ # True when every landmark survived the rewrite on its original line.
94
+ #: -> bool
95
+ def valid?
96
+ @missing_from_rewritten_output.empty? &&
97
+ @excess_in_rewritten_output.empty? &&
98
+ @on_wrong_line.empty?
99
+ end
100
+
101
+ # Human-readable, one-per-line descriptions of every difference. Empty when
102
+ # the result is valid.
103
+ #: -> Array[String]
104
+ def errors
105
+ errors = @missing_from_rewritten_output.map do |entry|
106
+ "missing `#{entry[:landmark_id]}` (expected at line #{entry[:line]})"
107
+ end
108
+ errors += @excess_in_rewritten_output.map do |entry|
109
+ "excess `#{entry[:landmark_id]}` (found at line #{entry[:line]})"
110
+ end
111
+ errors += @on_wrong_line.map do |entry|
112
+ "`#{entry[:landmark_id]}` on the wrong line " \
113
+ "(expected at #{format_lines(entry[:expected])}, found at #{format_lines(entry[:actual])})"
114
+ end
115
+ errors
116
+ end
117
+
118
+ #: (untyped) -> void
119
+ def pretty_print(printer)
120
+ if valid?
121
+ printer.text("#<#{self.class.name} valid>")
122
+ return
123
+ end
124
+
125
+ printer.text("#<#{self.class.name} invalid")
126
+ errors.each do |error|
127
+ printer.breakable
128
+ printer.text(" #{error}")
129
+ end
130
+ printer.breakable
131
+ printer.text(">")
132
+ end
133
+
134
+ private
135
+
136
+ #: (Array[Integer]) -> String
137
+ def format_lines(lines)
138
+ "#{lines.size == 1 ? "line" : "lines"} #{lines.join(", ")}"
139
+ end
140
+ end
141
+
142
+ # Walks a Prism AST and records the locations of various bits of code
143
+ # whose locations we want to remain constant after a rewriter.
144
+ class LandmarkFinder < Prism::Visitor
145
+ #: Validator::landmarks
146
+ attr_reader :landmarks
147
+
148
+ class << self
149
+ #: (String) -> Hash[String, Array[Integer]]
150
+ def find_landmarks_in(source)
151
+ visitor = new
152
+ Prism.parse(source).value.accept(visitor)
153
+ visitor.landmarks
154
+ end
155
+ end
156
+
157
+ #: -> void
158
+ def initialize
159
+ super
160
+ @landmarks = Hash.new { |h, landmark_id| h[landmark_id] = [] } #: Validator::landmarks
161
+ end
162
+
163
+ # @override
164
+ #: (Prism::ClassNode) -> void
165
+ def visit_class_node(node)
166
+ record("class #{node.name}", node)
167
+ super # keep descending so nested classes/modules/defs are recorded too
168
+ end
169
+
170
+ # @override
171
+ #: (Prism::ModuleNode) -> void
172
+ def visit_module_node(node)
173
+ record("module #{node.name}", node)
174
+ super
175
+ end
176
+
177
+ # @override
178
+ #: (Prism::SingletonClassNode) -> void
179
+ def visit_singleton_class_node(node)
180
+ # `class << self` (or `class << obj`); record its opening location.
181
+ record("class << #{node.expression.slice}", node)
182
+ super
183
+ end
184
+
185
+ # @override
186
+ #: (Prism::DefNode) -> void
187
+ def visit_def_node(node)
188
+ # `def self.foo` (and `def Foo.bar`) carry a receiver; include it so
189
+ # singleton methods read like their source and key separately from
190
+ # same-named instance methods.
191
+ receiver = node.receiver
192
+ receiver_description = receiver ? "#{receiver.slice}." : ""
193
+ record("def #{receiver_description}#{node.name}", node)
194
+ super
195
+ end
196
+
197
+ # @override
198
+ #: (Prism::SourceLineNode) -> void
199
+ def visit_source_line_node(node)
200
+ record("__LINE__", node) # its value changes if the line moves
201
+ super
202
+ end
203
+
204
+ private
205
+
206
+ #: (String landmark_id, Prism::Node) -> void
207
+ def record(landmark_id, node)
208
+ (@landmarks[landmark_id] ||= []) << node.location.start_line
209
+ end
210
+ end
211
+ private_constant :LandmarkFinder
212
+ end
213
+ end
214
+ end
@@ -5,6 +5,7 @@ require "rbi"
5
5
 
6
6
  require "spoom/source/rewriter"
7
7
  require "spoom/sorbet/translate/translator"
8
+ require "spoom/sorbet/translate/validator"
8
9
  require "spoom/sorbet/translate/rbs_comments_to_sorbet_sigs"
9
10
  require "spoom/sorbet/translate/sorbet_assertions_to_rbs_comments"
10
11
  require "spoom/sorbet/translate/sorbet_sigs_to_rbs_comments"
@@ -53,9 +54,14 @@ module Spoom
53
54
 
54
55
  # Converts all the RBS comments in the given Ruby code to `sig` nodes.
55
56
  # It also handles type members and class annotations.
56
- #: (String ruby_contents, file: String, ?max_line_length: Integer?) -> String
57
- def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: nil)
58
- RBSCommentsToSorbetSigs.rewrite_if_needed(ruby_contents, file: file, max_line_length: max_line_length)
57
+ #: (String ruby_contents, file: String, ?max_line_length: Integer?, ?overloads_strategy: Symbol) -> String
58
+ def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: nil, overloads_strategy: :translate_all)
59
+ RBSCommentsToSorbetSigs.rewrite_if_needed(
60
+ ruby_contents,
61
+ file: file,
62
+ max_line_length: max_line_length,
63
+ overloads_strategy: overloads_strategy,
64
+ )
59
65
  end
60
66
 
61
67
  # Converts all `T.let` and `T.cast` nodes to RBS comments in the given Ruby code.
data/lib/spoom/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Spoom
5
- VERSION = "1.7.15"
5
+ VERSION = "1.8.0"
6
6
  end
data/lib/spoom.rb CHANGED
@@ -22,3 +22,5 @@ require "spoom/counters"
22
22
  require "spoom/sorbet"
23
23
  require "spoom/cli"
24
24
  require "spoom/version"
25
+
26
+ require "spoom/ext/prism_types"
data/rbi/spoom.rbi CHANGED
@@ -1150,8 +1150,15 @@ Spoom::Deadcode::Plugins::ActiveJob::CALLBACKS = T.let(T.unsafe(nil), Array)
1150
1150
  class Spoom::Deadcode::Plugins::ActiveModel < ::Spoom::Deadcode::Plugins::Base
1151
1151
  sig { override.params(send: ::Spoom::Deadcode::Send).void }
1152
1152
  def on_send(send); end
1153
+
1154
+ private
1155
+
1156
+ sig { params(hash_node: ::Prism::HashNode, location: ::Spoom::Location).void }
1157
+ def reference_nested_symbol_options(hash_node, location); end
1153
1158
  end
1154
1159
 
1160
+ Spoom::Deadcode::Plugins::ActiveModel::NESTED_METHOD_REFERENCE_KEYS = T.let(T.unsafe(nil), Array)
1161
+
1155
1162
  class Spoom::Deadcode::Plugins::ActiveRecord < ::Spoom::Deadcode::Plugins::Base
1156
1163
  sig { override.params(send: ::Spoom::Deadcode::Send).void }
1157
1164
  def on_send(send); end
@@ -1275,8 +1282,22 @@ end
1275
1282
  class Spoom::Deadcode::Plugins::GraphQL < ::Spoom::Deadcode::Plugins::Base
1276
1283
  sig { override.params(send: ::Spoom::Deadcode::Send).void }
1277
1284
  def on_send(send); end
1285
+
1286
+ private
1287
+
1288
+ sig { params(send: ::Spoom::Deadcode::Send).void }
1289
+ def on_argument(send); end
1290
+
1291
+ sig { params(send: ::Spoom::Deadcode::Send).void }
1292
+ def on_builds(send); end
1293
+
1294
+ sig { params(send: ::Spoom::Deadcode::Send).void }
1295
+ def on_field(send); end
1278
1296
  end
1279
1297
 
1298
+ Spoom::Deadcode::Plugins::GraphQL::ARGUMENT_SYMBOL_OPTION_KEYS = T.let(T.unsafe(nil), Array)
1299
+ Spoom::Deadcode::Plugins::GraphQL::FIELD_SYMBOL_OPTION_KEYS = T.let(T.unsafe(nil), Array)
1300
+
1280
1301
  class Spoom::Deadcode::Plugins::Minitest < ::Spoom::Deadcode::Plugins::Base
1281
1302
  sig { override.params(definition: ::Spoom::Model::Method).void }
1282
1303
  def on_define_method(definition); end
@@ -2551,6 +2572,8 @@ class Spoom::Printer
2551
2572
  def printt; end
2552
2573
  end
2553
2574
 
2575
+ module Spoom::PrismTypes; end
2576
+ Spoom::PrismTypes::AnyScopeNode = T.type_alias { T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode) }
2554
2577
  module Spoom::RBS; end
2555
2578
  class Spoom::RBS::Annotation < ::Spoom::RBS::Comment; end
2556
2579
 
@@ -2590,7 +2613,20 @@ module Spoom::RBS::ExtractRBSComments
2590
2613
  def node_rbs_comments(node); end
2591
2614
  end
2592
2615
 
2593
- class Spoom::RBS::Signature < ::Spoom::RBS::Comment; end
2616
+ class Spoom::RBS::Signature < ::Spoom::RBS::Comment
2617
+ sig do
2618
+ params(
2619
+ string: ::String,
2620
+ location: ::Prism::Location,
2621
+ continuation_locations: T::Array[::Prism::Location]
2622
+ ).void
2623
+ end
2624
+ def initialize(string, location, continuation_locations: T.unsafe(nil)); end
2625
+
2626
+ sig { returns(T::Array[::Prism::Location]) }
2627
+ def continuation_locations; end
2628
+ end
2629
+
2594
2630
  class Spoom::RBS::TypeAlias < ::Spoom::RBS::Comment; end
2595
2631
  Spoom::SPOOM_PATH = T.let(T.unsafe(nil), String)
2596
2632
  module Spoom::Sorbet; end
@@ -2854,8 +2890,15 @@ Spoom::Sorbet::Sigils::VALID_STRICTNESS = T.let(T.unsafe(nil), Array)
2854
2890
 
2855
2891
  module Spoom::Sorbet::Translate
2856
2892
  class << self
2857
- sig { params(ruby_contents: ::String, file: ::String, max_line_length: T.nilable(::Integer)).returns(::String) }
2858
- def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: T.unsafe(nil)); end
2893
+ sig do
2894
+ params(
2895
+ ruby_contents: ::String,
2896
+ file: ::String,
2897
+ max_line_length: T.nilable(::Integer),
2898
+ overloads_strategy: ::Symbol
2899
+ ).returns(::String)
2900
+ end
2901
+ def rbs_comments_to_sorbet_sigs(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil)); end
2859
2902
 
2860
2903
  sig do
2861
2904
  params(
@@ -2890,11 +2933,73 @@ end
2890
2933
 
2891
2934
  class Spoom::Sorbet::Translate::Error < ::Spoom::Error; end
2892
2935
 
2893
- class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs < ::Spoom::Sorbet::Translate::Translator
2936
+ class Spoom::Sorbet::Translate::LandmarkFinder < ::Prism::Visitor
2937
+ sig { void }
2938
+ def initialize; end
2939
+
2940
+ sig { returns(T::Hash[::String, T::Array[::Integer]]) }
2941
+ def landmarks; end
2942
+
2943
+ sig { override.params(node: ::Prism::ClassNode).void }
2944
+ def visit_class_node(node); end
2945
+
2946
+ sig { override.params(node: ::Prism::DefNode).void }
2947
+ def visit_def_node(node); end
2948
+
2949
+ sig { override.params(node: ::Prism::ModuleNode).void }
2950
+ def visit_module_node(node); end
2951
+
2952
+ sig { override.params(node: ::Prism::SingletonClassNode).void }
2953
+ def visit_singleton_class_node(node); end
2954
+
2955
+ sig { override.params(node: ::Prism::SourceLineNode).void }
2956
+ def visit_source_line_node(node); end
2957
+
2958
+ private
2959
+
2960
+ sig { params(landmark_id: ::String, node: ::Prism::Node).void }
2961
+ def record(landmark_id, node); end
2962
+
2963
+ class << self
2964
+ sig { params(source: ::String).returns(T::Hash[::String, T::Array[::Integer]]) }
2965
+ def find_landmarks_in(source); end
2966
+ end
2967
+ end
2968
+
2969
+ module Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs
2970
+ class << self
2971
+ sig { params(source: ::String).returns(T::Boolean) }
2972
+ def contains_rbs_syntax?(source); end
2973
+
2974
+ sig do
2975
+ params(
2976
+ ruby_contents: ::String,
2977
+ file: ::String,
2978
+ max_line_length: T.nilable(::Integer),
2979
+ overloads_strategy: ::Symbol
2980
+ ).returns(::String)
2981
+ end
2982
+ def rewrite_if_needed(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil)); end
2983
+ end
2984
+ end
2985
+
2986
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat
2987
+ abstract!
2988
+ end
2989
+
2990
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator < ::Spoom::Sorbet::Translate::Translator
2894
2991
  include ::Spoom::RBS::ExtractRBSComments
2895
2992
 
2896
- sig { params(ruby_contents: ::String, file: ::String, max_line_length: T.nilable(::Integer)).void }
2897
- def initialize(ruby_contents, file:, max_line_length: T.unsafe(nil)); end
2993
+ abstract!
2994
+
2995
+ sig do
2996
+ params(
2997
+ ruby_contents: ::String,
2998
+ file: ::String,
2999
+ options: ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options
3000
+ ).void
3001
+ end
3002
+ def initialize(ruby_contents, file:, options: T.unsafe(nil)); end
2898
3003
 
2899
3004
  sig { override.params(node: ::Prism::CallNode).void }
2900
3005
  def visit_call_node(node); end
@@ -2924,35 +3029,201 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs < ::Spoom::Sorbet::Trans
2924
3029
  end
2925
3030
  def already_extends?(node, constant_regex); end
2926
3031
 
3032
+ sig do
3033
+ abstract
3034
+ .params(
3035
+ annotation: ::Spoom::RBS::Annotation,
3036
+ parent_node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3037
+ insert_pos: ::Integer,
3038
+ sorbet_replacement: T.nilable(::String)
3039
+ ).void
3040
+ end
3041
+ def apply_class_annotation(annotation, parent_node:, insert_pos:, sorbet_replacement:); end
3042
+
2927
3043
  sig { params(node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode)).void }
2928
3044
  def apply_class_annotations(node); end
2929
3045
 
2930
- sig { params(annotations: T::Array[::Spoom::RBS::Annotation], sig: ::RBI::Sig).void }
3046
+ sig do
3047
+ params(
3048
+ annotations: T::Array[::Spoom::RBS::Annotation],
3049
+ sig: ::RBI::Sig
3050
+ ).returns(T::Array[::Spoom::RBS::Annotation])
3051
+ end
2931
3052
  def apply_member_annotations(annotations, sig); end
2932
3053
 
3054
+ sig do
3055
+ params(
3056
+ signatures: T::Array[::Spoom::RBS::Signature],
3057
+ method_name: ::String,
3058
+ location: ::String
3059
+ ).returns(T::Array[::Spoom::RBS::Signature])
3060
+ end
3061
+ def apply_overloads_strategy(signatures, method_name:, location:); end
3062
+
2933
3063
  sig { params(comments: T::Array[::Prism::Comment]).void }
2934
3064
  def apply_type_aliases(comments); end
2935
3065
 
2936
3066
  sig { params(comments: T::Array[::Prism::Comment]).returns(T::Array[::Spoom::RBS::TypeAlias]) }
2937
3067
  def collect_type_aliases(comments); end
2938
3068
 
3069
+ sig do
3070
+ abstract
3071
+ .params(
3072
+ mixin_name: ::String,
3073
+ into: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3074
+ at: ::Integer
3075
+ ).void
3076
+ end
3077
+ def extend_with(mixin_name, into:, at:); end
3078
+
3079
+ sig do
3080
+ abstract
3081
+ .params(
3082
+ type_member: ::String,
3083
+ parent_node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3084
+ insert_pos: ::Integer
3085
+ ).void
3086
+ end
3087
+ def insert_type_member(type_member, parent_node:, insert_pos:); end
3088
+
3089
+ sig { overridable.params(of: ::String, to_height_of: ::Spoom::RBS::Comment).returns(::String) }
3090
+ def pad_out_line_count(of:, to_height_of:); end
3091
+
3092
+ sig { overridable.params(annotation: ::Spoom::RBS::Annotation, is_known: T::Boolean).void }
3093
+ def rewrite_annotation(annotation, is_known:); end
3094
+
2939
3095
  sig { params(def_node: ::Prism::DefNode, comments: ::Spoom::RBS::Comments).void }
2940
3096
  def rewrite_def(def_node, comments); end
2941
3097
 
3098
+ sig { abstract.params(signature: ::Spoom::RBS::Signature).void }
3099
+ def rewrite_discarded_overload(signature); end
3100
+
3101
+ sig { params(annotations: T::Array[::Spoom::RBS::Annotation], known: T::Array[::Spoom::RBS::Annotation]).void }
3102
+ def rewrite_member_annotations(annotations, known:); end
3103
+
3104
+ sig { abstract.params(signature: ::Spoom::RBS::Signature, type_params: T::Array[::RBS::AST::TypeParam]).void }
3105
+ def rewrite_type_params_signature(signature, type_params:); end
3106
+
2942
3107
  sig { params(node: ::Prism::CallNode).void }
2943
3108
  def visit_attr(node); end
3109
+ end
3110
+
3111
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableRBIFormat < ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat
3112
+ sig { params(max_line_length: T.nilable(::Integer)).void }
3113
+ def initialize(max_line_length: T.unsafe(nil)); end
3114
+
3115
+ sig { returns(T.nilable(::Integer)) }
3116
+ def max_line_length; end
2944
3117
 
2945
3118
  class << self
2946
- sig { params(source: ::String).returns(T::Boolean) }
2947
- def contains_rbs_syntax?(source); end
3119
+ sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableRBIFormat) }
3120
+ def default; end
3121
+ end
3122
+ end
3123
+
3124
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableTranslator < ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator
3125
+ private
3126
+
3127
+ sig do
3128
+ override
3129
+ .params(
3130
+ annotation: ::Spoom::RBS::Annotation,
3131
+ parent_node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3132
+ insert_pos: ::Integer,
3133
+ sorbet_replacement: T.nilable(::String)
3134
+ ).void
3135
+ end
3136
+ def apply_class_annotation(annotation, parent_node:, insert_pos:, sorbet_replacement:); end
3137
+
3138
+ sig { override.params(mixin_name: ::String, into: ::Prism::Node, at: ::Integer).void }
3139
+ def extend_with(mixin_name, into:, at:); end
3140
+
3141
+ sig do
3142
+ override
3143
+ .params(
3144
+ type_member: ::String,
3145
+ parent_node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3146
+ insert_pos: ::Integer
3147
+ ).void
3148
+ end
3149
+ def insert_type_member(type_member, parent_node:, insert_pos:); end
3150
+
3151
+ sig { override.params(signature: ::Spoom::RBS::Signature).void }
3152
+ def rewrite_discarded_overload(signature); end
3153
+
3154
+ sig { override.params(signature: ::Spoom::RBS::Signature, type_params: T::Array[::RBS::AST::TypeParam]).void }
3155
+ def rewrite_type_params_signature(signature, type_params:); end
3156
+ end
3157
+
3158
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::LineMatchedRBIFormat < ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat
3159
+ class << self
3160
+ sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::LineMatchedRBIFormat) }
3161
+ def default; end
3162
+ end
3163
+ end
3164
+
3165
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::LineMatchingTranslator < ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseTranslator
3166
+ private
3167
+
3168
+ sig do
3169
+ override
3170
+ .params(
3171
+ annotation: ::Spoom::RBS::Annotation,
3172
+ parent_node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3173
+ insert_pos: ::Integer,
3174
+ sorbet_replacement: T.nilable(::String)
3175
+ ).void
3176
+ end
3177
+ def apply_class_annotation(annotation, parent_node:, insert_pos:, sorbet_replacement:); end
3178
+
3179
+ sig { override.params(mixin_name: ::String, into: ::Prism::Node, at: ::Integer).void }
3180
+ def extend_with(mixin_name, into:, at:); end
3181
+
3182
+ sig do
3183
+ override
3184
+ .params(
3185
+ type_member: ::String,
3186
+ parent_node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode),
3187
+ insert_pos: ::Integer
3188
+ ).void
3189
+ end
3190
+ def insert_type_member(type_member, parent_node:, insert_pos:); end
3191
+
3192
+ sig { override.params(of: ::String, to_height_of: ::Spoom::RBS::Comment).returns(::String) }
3193
+ def pad_out_line_count(of:, to_height_of:); end
3194
+
3195
+ sig { override.params(annotation: ::Spoom::RBS::Annotation, is_known: T::Boolean).void }
3196
+ def rewrite_annotation(annotation, is_known:); end
2948
3197
 
2949
- sig { params(ruby_contents: ::String, file: ::String, max_line_length: T.nilable(::Integer)).returns(::String) }
2950
- def rewrite_if_needed(ruby_contents, file:, max_line_length: T.unsafe(nil)); end
3198
+ sig { override.params(signature: ::Spoom::RBS::Signature).void }
3199
+ def rewrite_discarded_overload(signature); end
3200
+
3201
+ sig { override.params(signature: ::Spoom::RBS::Signature, type_params: T::Array[::RBS::AST::TypeParam]).void }
3202
+ def rewrite_type_params_signature(signature, type_params:); end
3203
+ end
3204
+
3205
+ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options
3206
+ sig do
3207
+ params(
3208
+ overloads_strategy: ::Symbol,
3209
+ output_format: ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat
3210
+ ).void
3211
+ end
3212
+ def initialize(overloads_strategy: T.unsafe(nil), output_format: T.unsafe(nil)); end
3213
+
3214
+ sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::BaseRBIFormat) }
3215
+ def output_format; end
3216
+
3217
+ sig { returns(::Symbol) }
3218
+ def overloads_strategy; end
3219
+
3220
+ class << self
3221
+ sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options) }
3222
+ def default; end
2951
3223
  end
2952
3224
  end
2953
3225
 
2954
- Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::RBS_ANNOTATION_MARKERS = T.let(T.unsafe(nil), Array)
2955
- Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::RBS_REWRITE_PATTERN = T.let(T.unsafe(nil), Regexp)
3226
+ Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options::ALLOWED_OVERLOAD_STRATEGIES = T.let(T.unsafe(nil), Array)
2956
3227
 
2957
3228
  class Spoom::Sorbet::Translate::SorbetAssertionsToRBSComments < ::Spoom::Sorbet::Translate::Translator
2958
3229
  sig do
@@ -3110,6 +3381,52 @@ class Spoom::Sorbet::Translate::Translator < ::Spoom::Visitor
3110
3381
  def sorbet_sig?(node); end
3111
3382
  end
3112
3383
 
3384
+ class Spoom::Sorbet::Translate::ValidationResult
3385
+ sig do
3386
+ params(
3387
+ missing_from_rewritten_output: T::Array[{landmark_id: ::String, line: ::Integer}],
3388
+ excess_in_rewritten_output: T::Array[{landmark_id: ::String, line: ::Integer}],
3389
+ on_wrong_line: T::Array[{landmark_id: ::String, expected: T::Array[::Integer], actual: T::Array[::Integer]}]
3390
+ ).void
3391
+ end
3392
+ def initialize(missing_from_rewritten_output:, excess_in_rewritten_output:, on_wrong_line:); end
3393
+
3394
+ sig { returns(T::Array[::String]) }
3395
+ def errors; end
3396
+
3397
+ sig { returns(T::Array[{landmark_id: ::String, line: ::Integer}]) }
3398
+ def excess_in_rewritten_output; end
3399
+
3400
+ sig { returns(T::Array[{landmark_id: ::String, line: ::Integer}]) }
3401
+ def missing_from_rewritten_output; end
3402
+
3403
+ sig { returns(T::Array[{landmark_id: ::String, expected: T::Array[::Integer], actual: T::Array[::Integer]}]) }
3404
+ def on_wrong_line; end
3405
+
3406
+ sig { params(printer: T.untyped).void }
3407
+ def pretty_print(printer); end
3408
+
3409
+ sig { returns(T::Boolean) }
3410
+ def valid?; end
3411
+
3412
+ private
3413
+
3414
+ sig { params(lines: T::Array[::Integer]).returns(::String) }
3415
+ def format_lines(lines); end
3416
+ end
3417
+
3418
+ Spoom::Sorbet::Translate::ValidationResult::LandmarkLocation = T.type_alias { {landmark_id: ::String, line: ::Integer} }
3419
+ Spoom::Sorbet::Translate::ValidationResult::MovedLandmark = T.type_alias { {landmark_id: ::String, expected: T::Array[::Integer], actual: T::Array[::Integer]} }
3420
+
3421
+ module Spoom::Sorbet::Translate::Validator
3422
+ class << self
3423
+ sig { params(original: ::String, rewritten: ::String).returns(::Spoom::Sorbet::Translate::ValidationResult) }
3424
+ def validate(original, rewritten); end
3425
+ end
3426
+ end
3427
+
3428
+ Spoom::Sorbet::Translate::Validator::LandmarkID = T.type_alias { ::String }
3429
+ Spoom::Sorbet::Translate::Validator::Landmarks = T.type_alias { T::Hash[::String, T::Array[::Integer]] }
3113
3430
  module Spoom::Source; end
3114
3431
 
3115
3432
  class Spoom::Source::Delete < ::Spoom::Source::Edit