spoom 1.7.16 → 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"
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.16"
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
@@ -2897,18 +2933,73 @@ end
2897
2933
 
2898
2934
  class Spoom::Sorbet::Translate::Error < ::Spoom::Error; end
2899
2935
 
2900
- 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
2901
2991
  include ::Spoom::RBS::ExtractRBSComments
2902
2992
 
2993
+ abstract!
2994
+
2903
2995
  sig do
2904
2996
  params(
2905
2997
  ruby_contents: ::String,
2906
2998
  file: ::String,
2907
- max_line_length: T.nilable(::Integer),
2908
- overloads_strategy: ::Symbol
2999
+ options: ::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::Options
2909
3000
  ).void
2910
3001
  end
2911
- def initialize(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil)); end
3002
+ def initialize(ruby_contents, file:, options: T.unsafe(nil)); end
2912
3003
 
2913
3004
  sig { override.params(node: ::Prism::CallNode).void }
2914
3005
  def visit_call_node(node); end
@@ -2938,10 +3029,26 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs < ::Spoom::Sorbet::Trans
2938
3029
  end
2939
3030
  def already_extends?(node, constant_regex); end
2940
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
+
2941
3043
  sig { params(node: T.any(::Prism::ClassNode, ::Prism::ModuleNode, ::Prism::SingletonClassNode)).void }
2942
3044
  def apply_class_annotations(node); end
2943
3045
 
2944
- 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
2945
3052
  def apply_member_annotations(annotations, sig); end
2946
3053
 
2947
3054
  sig do
@@ -2959,31 +3066,164 @@ class Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs < ::Spoom::Sorbet::Trans
2959
3066
  sig { params(comments: T::Array[::Prism::Comment]).returns(T::Array[::Spoom::RBS::TypeAlias]) }
2960
3067
  def collect_type_aliases(comments); end
2961
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
+
2962
3095
  sig { params(def_node: ::Prism::DefNode, comments: ::Spoom::RBS::Comments).void }
2963
3096
  def rewrite_def(def_node, comments); end
2964
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
+
2965
3107
  sig { params(node: ::Prism::CallNode).void }
2966
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
2967
3117
 
2968
3118
  class << self
2969
- sig { params(source: ::String).returns(T::Boolean) }
2970
- def contains_rbs_syntax?(source); end
3119
+ sig { returns(::Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::HumanReadableRBIFormat) }
3120
+ def default; end
3121
+ end
3122
+ end
2971
3123
 
2972
- sig do
2973
- params(
2974
- ruby_contents: ::String,
2975
- file: ::String,
2976
- max_line_length: T.nilable(::Integer),
2977
- overloads_strategy: ::Symbol
2978
- ).returns(::String)
2979
- end
2980
- def rewrite_if_needed(ruby_contents, file:, max_line_length: T.unsafe(nil), overloads_strategy: T.unsafe(nil)); end
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
3197
+
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
2981
3223
  end
2982
3224
  end
2983
3225
 
2984
- Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::ALLOWED_OVERLOAD_STRATEGIES = T.let(T.unsafe(nil), Array)
2985
- Spoom::Sorbet::Translate::RBSCommentsToSorbetSigs::RBS_ANNOTATION_MARKERS = T.let(T.unsafe(nil), Array)
2986
- 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)
2987
3227
 
2988
3228
  class Spoom::Sorbet::Translate::SorbetAssertionsToRBSComments < ::Spoom::Sorbet::Translate::Translator
2989
3229
  sig do
@@ -3141,6 +3381,52 @@ class Spoom::Sorbet::Translate::Translator < ::Spoom::Visitor
3141
3381
  def sorbet_sig?(node); end
3142
3382
  end
3143
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]] }
3144
3430
  module Spoom::Source; end
3145
3431
 
3146
3432
  class Spoom::Source::Delete < ::Spoom::Source::Edit
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spoom
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.16
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexandre Terrasa
@@ -217,6 +217,7 @@ files:
217
217
  - lib/spoom/deadcode/plugins/thor.rb
218
218
  - lib/spoom/deadcode/remover.rb
219
219
  - lib/spoom/deadcode/send.rb
220
+ - lib/spoom/ext/prism_types.rb
220
221
  - lib/spoom/file_collector.rb
221
222
  - lib/spoom/file_tree.rb
222
223
  - lib/spoom/location.rb
@@ -243,10 +244,15 @@ files:
243
244
  - lib/spoom/sorbet/sigils.rb
244
245
  - lib/spoom/sorbet/translate.rb
245
246
  - lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb
247
+ - lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/base_translator.rb
248
+ - lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/human_readable_translator.rb
249
+ - lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/line_matching_translator.rb
250
+ - lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs/options.rb
246
251
  - lib/spoom/sorbet/translate/sorbet_assertions_to_rbs_comments.rb
247
252
  - lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb
248
253
  - lib/spoom/sorbet/translate/strip_sorbet_sigs.rb
249
254
  - lib/spoom/sorbet/translate/translator.rb
255
+ - lib/spoom/sorbet/translate/validator.rb
250
256
  - lib/spoom/source.rb
251
257
  - lib/spoom/source/rewriter.rb
252
258
  - lib/spoom/timeline.rb
@@ -268,7 +274,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
268
274
  requirements:
269
275
  - - ">="
270
276
  - !ruby/object:Gem::Version
271
- version: '3.2'
277
+ version: '3.3'
272
278
  required_rubygems_version: !ruby/object:Gem::Requirement
273
279
  requirements:
274
280
  - - ">="