spoom 1.7.6 → 1.7.8
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.
- checksums.yaml +4 -4
- data/lib/spoom/context/file_system.rb +5 -1
- data/lib/spoom/coverage/d3/circle_map.rb +6 -1
- data/lib/spoom/coverage/report.rb +16 -2
- data/lib/spoom/model/model.rb +15 -2
- data/lib/spoom/rbs.rb +7 -1
- data/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb +3 -0
- data/lib/spoom/sorbet/translate/sorbet_assertions_to_rbs_comments.rb +50 -7
- data/lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb +6 -1
- data/lib/spoom/source/rewriter.rb +4 -2
- data/lib/spoom/version.rb +1 -1
- data/rbi/spoom.rbi +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: aedf28669e780fce835616cbafcd7e45183d0cd474127dc26c1e9d169f3b4920
|
|
4
|
+
data.tar.gz: 5ac37ac73623a9158a7ee6d5f60aa93f46d83140fa718129c4fa73fc15ba85f4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c309dba40798848147342ffd5c9c4657ce77e8e724d6ece2ceb4851ab8f4c21b432c4684845d1042a81937d52d6cbb47f6b27f3b6440f091e87ddb6c8e8e4077
|
|
7
|
+
data.tar.gz: aa5e4e6c8021cc62b4147ef76ff6350c3917838c154d7fdf3ce5ebcf2f54f733bc33bf4caff33ef904a6ef58a8e2b8c436996879982639e7c324110787aa343e
|
|
@@ -39,7 +39,11 @@ module Spoom
|
|
|
39
39
|
glob("*")
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
#: (
|
|
42
|
+
#: (
|
|
43
|
+
#| ?allow_extensions: Array[String],
|
|
44
|
+
#| ?allow_mime_types: Array[String],
|
|
45
|
+
#| ?exclude_patterns: Array[String]
|
|
46
|
+
#| ) -> Array[String]
|
|
43
47
|
def collect_files(allow_extensions: [], allow_mime_types: [], exclude_patterns: [])
|
|
44
48
|
collector = FileCollector.new(
|
|
45
49
|
allow_extensions: allow_extensions,
|
|
@@ -145,7 +145,12 @@ module Spoom
|
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
class Sigils < CircleMap
|
|
148
|
-
#: (
|
|
148
|
+
#: (
|
|
149
|
+
#| String id,
|
|
150
|
+
#| FileTree file_tree,
|
|
151
|
+
#| Hash[FileTree::Node, String?] nodes_strictnesses,
|
|
152
|
+
#| Hash[FileTree::Node, Float] nodes_scores
|
|
153
|
+
#| ) -> void
|
|
149
154
|
def initialize(id, file_tree, nodes_strictnesses, nodes_scores)
|
|
150
155
|
@nodes_strictnesses = nodes_strictnesses
|
|
151
156
|
@nodes_scores = nodes_scores
|
|
@@ -138,7 +138,12 @@ module Spoom
|
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
class Map < Card
|
|
141
|
-
#: (
|
|
141
|
+
#: (
|
|
142
|
+
#| file_tree: FileTree,
|
|
143
|
+
#| nodes_strictnesses: Hash[FileTree::Node, String?],
|
|
144
|
+
#| nodes_strictness_scores: Hash[FileTree::Node, Float],
|
|
145
|
+
#| ?title: String
|
|
146
|
+
#| ) -> void
|
|
142
147
|
def initialize(file_tree:, nodes_strictnesses:, nodes_strictness_scores:, title: "Strictness Map")
|
|
143
148
|
super(
|
|
144
149
|
title: title,
|
|
@@ -222,7 +227,16 @@ module Spoom
|
|
|
222
227
|
end
|
|
223
228
|
|
|
224
229
|
class Report < Page
|
|
225
|
-
#: (
|
|
230
|
+
#: (
|
|
231
|
+
#| project_name: String,
|
|
232
|
+
#| palette: D3::ColorPalette,
|
|
233
|
+
#| snapshots: Array[Snapshot],
|
|
234
|
+
#| file_tree: FileTree,
|
|
235
|
+
#| nodes_strictnesses: Hash[FileTree::Node, String?],
|
|
236
|
+
#| nodes_strictness_scores: Hash[FileTree::Node, Float],
|
|
237
|
+
#| ?sorbet_intro_commit: String?,
|
|
238
|
+
#| ?sorbet_intro_date: Time?
|
|
239
|
+
#| ) -> void
|
|
226
240
|
def initialize(
|
|
227
241
|
project_name:,
|
|
228
242
|
palette:,
|
data/lib/spoom/model/model.rb
CHANGED
|
@@ -129,7 +129,13 @@ module Spoom
|
|
|
129
129
|
#: String?
|
|
130
130
|
attr_accessor :superclass_name
|
|
131
131
|
|
|
132
|
-
#: (
|
|
132
|
+
#: (
|
|
133
|
+
#| Symbol symbol,
|
|
134
|
+
#| owner: Namespace?,
|
|
135
|
+
#| location: Location,
|
|
136
|
+
#| ?superclass_name: String?,
|
|
137
|
+
#| ?comments: Array[Comment]
|
|
138
|
+
#| ) -> void
|
|
133
139
|
def initialize(symbol, owner:, location:, superclass_name: nil, comments: [])
|
|
134
140
|
super(symbol, owner: owner, location: location, comments: comments)
|
|
135
141
|
|
|
@@ -160,7 +166,14 @@ module Spoom
|
|
|
160
166
|
#: Array[Sig]
|
|
161
167
|
attr_reader :sigs
|
|
162
168
|
|
|
163
|
-
#: (
|
|
169
|
+
#: (
|
|
170
|
+
#| Symbol symbol,
|
|
171
|
+
#| owner: Namespace?,
|
|
172
|
+
#| location: Location,
|
|
173
|
+
#| visibility: Visibility,
|
|
174
|
+
#| ?sigs: Array[Sig],
|
|
175
|
+
#| ?comments: Array[Comment]
|
|
176
|
+
#| ) -> void
|
|
164
177
|
def initialize(symbol, owner:, location:, visibility:, sigs: [], comments: [])
|
|
165
178
|
super(symbol, owner: owner, location: location, comments: comments)
|
|
166
179
|
|
data/lib/spoom/rbs.rb
CHANGED
|
@@ -39,7 +39,13 @@ module Spoom
|
|
|
39
39
|
def method_annotations
|
|
40
40
|
@annotations.select do |annotation|
|
|
41
41
|
case annotation.string
|
|
42
|
-
when "@abstract",
|
|
42
|
+
when "@abstract",
|
|
43
|
+
"@final",
|
|
44
|
+
"@override",
|
|
45
|
+
"@override(allow_incompatible: true)",
|
|
46
|
+
"@override(allow_incompatible: :visibility)",
|
|
47
|
+
"@overridable",
|
|
48
|
+
"@without_runtime"
|
|
43
49
|
true
|
|
44
50
|
else
|
|
45
51
|
false
|
|
@@ -248,6 +248,9 @@ module Spoom
|
|
|
248
248
|
when "@override(allow_incompatible: true)"
|
|
249
249
|
sig.is_override = true
|
|
250
250
|
sig.allow_incompatible_override = true
|
|
251
|
+
when "@override(allow_incompatible: :visibility)"
|
|
252
|
+
sig.is_override = true
|
|
253
|
+
sig.allow_incompatible_override_visibility = true
|
|
251
254
|
when "@overridable"
|
|
252
255
|
sig.is_overridable = true
|
|
253
256
|
when "@without_runtime"
|
|
@@ -74,8 +74,10 @@ module Spoom
|
|
|
74
74
|
Prism::ClassVariableWriteNode, Prism::ClassVariableAndWriteNode, Prism::ClassVariableOperatorWriteNode, Prism::ClassVariableOrWriteNode,
|
|
75
75
|
Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOperatorWriteNode, Prism::ConstantOrWriteNode,
|
|
76
76
|
Prism::ConstantPathWriteNode, Prism::ConstantPathAndWriteNode, Prism::ConstantPathOperatorWriteNode, Prism::ConstantPathOrWriteNode,
|
|
77
|
-
Prism::GlobalVariableWriteNode, Prism::GlobalVariableAndWriteNode,
|
|
78
|
-
Prism::
|
|
77
|
+
Prism::GlobalVariableWriteNode, Prism::GlobalVariableAndWriteNode,
|
|
78
|
+
Prism::GlobalVariableOperatorWriteNode, Prism::GlobalVariableOrWriteNode,
|
|
79
|
+
Prism::InstanceVariableWriteNode, Prism::InstanceVariableAndWriteNode,
|
|
80
|
+
Prism::InstanceVariableOperatorWriteNode, Prism::InstanceVariableOrWriteNode,
|
|
79
81
|
Prism::LocalVariableWriteNode, Prism::LocalVariableAndWriteNode, Prism::LocalVariableOperatorWriteNode, Prism::LocalVariableOrWriteNode,
|
|
80
82
|
Prism::CallAndWriteNode, Prism::CallOperatorWriteNode, Prism::CallOrWriteNode
|
|
81
83
|
node.value
|
|
@@ -89,18 +91,26 @@ module Spoom
|
|
|
89
91
|
return false unless translatable_annotation?(node)
|
|
90
92
|
return false unless at_end_of_line?(node)
|
|
91
93
|
|
|
94
|
+
trailing_comment, comment_end_offset = extract_trailing_comment(node)
|
|
95
|
+
# If extract_trailing_comment returns nil when there's an RBS annotation, don't translate
|
|
96
|
+
return false if trailing_comment.nil? && has_rbs_annotation?(node)
|
|
97
|
+
|
|
92
98
|
value = T.must(node.arguments&.arguments&.first)
|
|
93
99
|
rbs_annotation = build_rbs_annotation(node)
|
|
94
100
|
|
|
95
101
|
start_offset = node.location.start_offset
|
|
96
|
-
|
|
102
|
+
# If there's a trailing comment, replace up to the end of the comment
|
|
103
|
+
# Otherwise, replace up to the end of the node
|
|
104
|
+
end_offset = comment_end_offset || node.location.end_offset
|
|
97
105
|
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
replacement = if node.name == :bind
|
|
107
|
+
"#{rbs_annotation}#{trailing_comment}"
|
|
100
108
|
else
|
|
101
|
-
|
|
109
|
+
"#{dedent_value(node, value)} #{rbs_annotation}#{trailing_comment}"
|
|
102
110
|
end
|
|
103
111
|
|
|
112
|
+
@rewriter << Source::Replace.new(start_offset, end_offset - 1, replacement)
|
|
113
|
+
|
|
104
114
|
true
|
|
105
115
|
end
|
|
106
116
|
|
|
@@ -166,7 +176,40 @@ module Spoom
|
|
|
166
176
|
def at_end_of_line?(node)
|
|
167
177
|
end_offset = node.location.end_offset
|
|
168
178
|
end_offset += 1 while (@ruby_bytes[end_offset] == " ".ord) && (end_offset < @ruby_bytes.size)
|
|
169
|
-
|
|
179
|
+
# Check if we're at a newline OR at the start of a comment
|
|
180
|
+
@ruby_bytes[end_offset] == LINE_BREAK || @ruby_bytes[end_offset] == "#".ord
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Check if the node has an RBS annotation comment (#:) after it
|
|
184
|
+
#: (Prism::Node) -> bool
|
|
185
|
+
def has_rbs_annotation?(node)
|
|
186
|
+
end_offset = node.location.end_offset
|
|
187
|
+
# Skip spaces
|
|
188
|
+
end_offset += 1 while (@ruby_bytes[end_offset] == " ".ord) && (end_offset < @ruby_bytes.size)
|
|
189
|
+
# Check if there's a comment starting with #:
|
|
190
|
+
@ruby_bytes[end_offset] == "#".ord && @ruby_bytes[end_offset + 1] == ":".ord
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Extract any trailing comment after the node
|
|
194
|
+
# Returns [comment_text, comment_end_offset] or [nil, nil] if no comment or RBS annotation
|
|
195
|
+
#: (Prism::Node) -> [String?, Integer?]
|
|
196
|
+
def extract_trailing_comment(node)
|
|
197
|
+
end_offset = node.location.end_offset
|
|
198
|
+
# Skip spaces
|
|
199
|
+
end_offset += 1 while (@ruby_bytes[end_offset] == " ".ord) && (end_offset < @ruby_bytes.size)
|
|
200
|
+
# Check if there's a comment
|
|
201
|
+
return [nil, nil] unless @ruby_bytes[end_offset] == "#".ord
|
|
202
|
+
|
|
203
|
+
# If it's an RBS annotation comment (#:), return nil to prevent translation
|
|
204
|
+
return [nil, nil] if @ruby_bytes[end_offset + 1] == ":".ord
|
|
205
|
+
|
|
206
|
+
# Find the end of the comment (end of line)
|
|
207
|
+
comment_start = end_offset
|
|
208
|
+
end_offset += 1 while @ruby_bytes[end_offset] != LINE_BREAK && end_offset < @ruby_bytes.size
|
|
209
|
+
|
|
210
|
+
# Extract the comment including the leading space and return the end offset
|
|
211
|
+
range = @ruby_bytes[comment_start...end_offset] #: as !nil
|
|
212
|
+
[" #{range.pack("C*")}", end_offset]
|
|
170
213
|
end
|
|
171
214
|
|
|
172
215
|
#: (Prism::Node, Prism::Node) -> String
|
|
@@ -260,7 +260,10 @@ module Spoom
|
|
|
260
260
|
|
|
261
261
|
arg = body.body.first #: as Prism::Node
|
|
262
262
|
srb_type = RBI::Type.parse_node(arg)
|
|
263
|
-
@rewriter << Source::Insert.new(
|
|
263
|
+
@rewriter << Source::Insert.new(
|
|
264
|
+
parent.location.start_offset,
|
|
265
|
+
"# @requires_ancestor: #{srb_type.rbs_string}\n#{indent}",
|
|
266
|
+
)
|
|
264
267
|
end
|
|
265
268
|
|
|
266
269
|
from = adjust_to_line_start(node.location.start_offset)
|
|
@@ -294,6 +297,8 @@ module Spoom
|
|
|
294
297
|
if sigs.any? { |_, sig| sig.is_override }
|
|
295
298
|
@rewriter << if sigs.any? { |_, sig| sig.allow_incompatible_override }
|
|
296
299
|
Source::Insert.new(insert_pos, "# @override(allow_incompatible: true)\n#{indent}")
|
|
300
|
+
elsif sigs.any? { |_, sig| sig.allow_incompatible_override_visibility }
|
|
301
|
+
Source::Insert.new(insert_pos, "# @override(allow_incompatible: :visibility)\n#{indent}")
|
|
297
302
|
else
|
|
298
303
|
Source::Insert.new(insert_pos, "# @override\n#{indent}")
|
|
299
304
|
end
|
|
@@ -92,7 +92,8 @@ module Spoom
|
|
|
92
92
|
# @override
|
|
93
93
|
#: (Array[Integer]) -> void
|
|
94
94
|
def apply(bytes)
|
|
95
|
-
raise PositionError,
|
|
95
|
+
raise PositionError,
|
|
96
|
+
"Position is out of bounds" if from < 0 || to < 0 || from > bytes.size || to > bytes.size || from > to
|
|
96
97
|
|
|
97
98
|
bytes[from..to] = *text.bytes
|
|
98
99
|
end
|
|
@@ -125,7 +126,8 @@ module Spoom
|
|
|
125
126
|
# @override
|
|
126
127
|
#: (Array[untyped]) -> void
|
|
127
128
|
def apply(bytes)
|
|
128
|
-
raise PositionError,
|
|
129
|
+
raise PositionError,
|
|
130
|
+
"Position is out of bounds" if from < 0 || to < 0 || from > bytes.size || to > bytes.size || from > to
|
|
129
131
|
|
|
130
132
|
bytes[from..to] = "".bytes
|
|
131
133
|
end
|
data/lib/spoom/version.rb
CHANGED
data/rbi/spoom.rbi
CHANGED
|
@@ -2950,6 +2950,12 @@ class Spoom::Sorbet::Translate::SorbetAssertionsToRBSComments < ::Spoom::Sorbet:
|
|
|
2950
2950
|
sig { params(assign: ::Prism::Node, value: ::Prism::Node).returns(::String) }
|
|
2951
2951
|
def dedent_value(assign, value); end
|
|
2952
2952
|
|
|
2953
|
+
sig { params(node: ::Prism::Node).returns([T.nilable(::String), T.nilable(::Integer)]) }
|
|
2954
|
+
def extract_trailing_comment(node); end
|
|
2955
|
+
|
|
2956
|
+
sig { params(node: ::Prism::Node).returns(T::Boolean) }
|
|
2957
|
+
def has_rbs_annotation?(node); end
|
|
2958
|
+
|
|
2953
2959
|
sig { params(node: ::Prism::Node).returns(T::Boolean) }
|
|
2954
2960
|
def maybe_translate_assertion(node); end
|
|
2955
2961
|
|
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.
|
|
4
|
+
version: 1.7.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alexandre Terrasa
|
|
@@ -274,7 +274,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
274
274
|
- !ruby/object:Gem::Version
|
|
275
275
|
version: '0'
|
|
276
276
|
requirements: []
|
|
277
|
-
rubygems_version: 3.7.
|
|
277
|
+
rubygems_version: 3.7.2
|
|
278
278
|
specification_version: 4
|
|
279
279
|
summary: Useful tools for Sorbet enthusiasts.
|
|
280
280
|
test_files: []
|