spoom 1.5.0 → 1.7.2

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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +14 -0
  3. data/lib/spoom/backtrace_filter/minitest.rb +3 -4
  4. data/lib/spoom/cli/deadcode.rb +1 -2
  5. data/lib/spoom/cli/helper.rb +41 -31
  6. data/lib/spoom/cli/srb/assertions.rb +48 -0
  7. data/lib/spoom/cli/srb/bump.rb +1 -2
  8. data/lib/spoom/cli/srb/coverage.rb +1 -1
  9. data/lib/spoom/cli/srb/metrics.rb +68 -0
  10. data/lib/spoom/cli/srb/sigs.rb +209 -0
  11. data/lib/spoom/cli/srb/tc.rb +16 -1
  12. data/lib/spoom/cli/srb.rb +16 -4
  13. data/lib/spoom/cli.rb +1 -2
  14. data/lib/spoom/colors.rb +2 -6
  15. data/lib/spoom/context/bundle.rb +8 -9
  16. data/lib/spoom/context/exec.rb +3 -6
  17. data/lib/spoom/context/file_system.rb +12 -19
  18. data/lib/spoom/context/git.rb +14 -19
  19. data/lib/spoom/context/sorbet.rb +14 -27
  20. data/lib/spoom/context.rb +4 -8
  21. data/lib/spoom/counters.rb +22 -0
  22. data/lib/spoom/coverage/d3/base.rb +6 -8
  23. data/lib/spoom/coverage/d3/circle_map.rb +6 -16
  24. data/lib/spoom/coverage/d3/pie.rb +14 -19
  25. data/lib/spoom/coverage/d3/timeline.rb +46 -47
  26. data/lib/spoom/coverage/d3.rb +2 -4
  27. data/lib/spoom/coverage/report.rb +41 -79
  28. data/lib/spoom/coverage/snapshot.rb +8 -14
  29. data/lib/spoom/coverage.rb +3 -5
  30. data/lib/spoom/deadcode/definition.rb +12 -14
  31. data/lib/spoom/deadcode/erb.rb +10 -8
  32. data/lib/spoom/deadcode/index.rb +21 -25
  33. data/lib/spoom/deadcode/indexer.rb +5 -6
  34. data/lib/spoom/deadcode/plugins/action_mailer.rb +2 -3
  35. data/lib/spoom/deadcode/plugins/action_mailer_preview.rb +2 -3
  36. data/lib/spoom/deadcode/plugins/actionpack.rb +19 -22
  37. data/lib/spoom/deadcode/plugins/active_model.rb +2 -3
  38. data/lib/spoom/deadcode/plugins/active_record.rb +62 -53
  39. data/lib/spoom/deadcode/plugins/active_support.rb +3 -2
  40. data/lib/spoom/deadcode/plugins/base.rb +29 -32
  41. data/lib/spoom/deadcode/plugins/graphql.rb +2 -3
  42. data/lib/spoom/deadcode/plugins/minitest.rb +4 -4
  43. data/lib/spoom/deadcode/plugins/namespaces.rb +5 -5
  44. data/lib/spoom/deadcode/plugins/rails.rb +5 -5
  45. data/lib/spoom/deadcode/plugins/rubocop.rb +5 -5
  46. data/lib/spoom/deadcode/plugins/ruby.rb +3 -4
  47. data/lib/spoom/deadcode/plugins/sorbet.rb +12 -6
  48. data/lib/spoom/deadcode/plugins/thor.rb +2 -3
  49. data/lib/spoom/deadcode/plugins.rb +23 -31
  50. data/lib/spoom/deadcode/remover.rb +58 -79
  51. data/lib/spoom/deadcode/send.rb +2 -8
  52. data/lib/spoom/file_collector.rb +11 -19
  53. data/lib/spoom/file_tree.rb +36 -51
  54. data/lib/spoom/location.rb +9 -20
  55. data/lib/spoom/model/builder.rb +54 -17
  56. data/lib/spoom/model/model.rb +71 -74
  57. data/lib/spoom/model/namespace_visitor.rb +4 -3
  58. data/lib/spoom/model/reference.rb +4 -8
  59. data/lib/spoom/model/references_visitor.rb +50 -30
  60. data/lib/spoom/parse.rb +4 -4
  61. data/lib/spoom/poset.rb +22 -24
  62. data/lib/spoom/printer.rb +10 -13
  63. data/lib/spoom/rbs.rb +77 -0
  64. data/lib/spoom/sorbet/config.rb +17 -24
  65. data/lib/spoom/sorbet/errors.rb +87 -45
  66. data/lib/spoom/sorbet/lsp/base.rb +10 -16
  67. data/lib/spoom/sorbet/lsp/errors.rb +8 -16
  68. data/lib/spoom/sorbet/lsp/structures.rb +65 -91
  69. data/lib/spoom/sorbet/lsp.rb +20 -22
  70. data/lib/spoom/sorbet/metrics/code_metrics_visitor.rb +236 -0
  71. data/lib/spoom/sorbet/metrics/metrics_file_parser.rb +34 -0
  72. data/lib/spoom/sorbet/metrics.rb +2 -32
  73. data/lib/spoom/sorbet/sigils.rb +16 -23
  74. data/lib/spoom/sorbet/translate/rbs_comments_to_sorbet_sigs.rb +242 -0
  75. data/lib/spoom/sorbet/translate/sorbet_assertions_to_rbs_comments.rb +123 -0
  76. data/lib/spoom/sorbet/translate/sorbet_sigs_to_rbs_comments.rb +293 -0
  77. data/lib/spoom/sorbet/translate/strip_sorbet_sigs.rb +23 -0
  78. data/lib/spoom/sorbet/translate/translator.rb +71 -0
  79. data/lib/spoom/sorbet/translate.rb +49 -0
  80. data/lib/spoom/sorbet.rb +6 -12
  81. data/lib/spoom/source/rewriter.rb +167 -0
  82. data/lib/spoom/source.rb +4 -0
  83. data/lib/spoom/timeline.rb +4 -6
  84. data/lib/spoom/version.rb +1 -1
  85. data/lib/spoom/visitor.rb +298 -151
  86. data/lib/spoom.rb +4 -3
  87. data/rbi/spoom.rbi +3567 -0
  88. metadata +62 -8
@@ -0,0 +1,167 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Spoom
5
+ # This module provides a simple API to rewrite source code.
6
+ #
7
+ # Using a `Rewriter`, you can build a list of changes to apply to a source file
8
+ # and apply them all at once. Edits are applied from bottom to top, so that the
9
+ # line numbers are not remapped after each edit.
10
+ #
11
+ # The source code is represented as an array of bytes, so that it can be
12
+ # manipulated in place. The client is responsible for `string <-> bytes`
13
+ # conversions and encoding handling.
14
+ #
15
+ # ```ruby
16
+ # bytes = "def foo; end".bytes
17
+ #
18
+ # rewriter = Spoom::Source::Rewriter.new
19
+ # rewriter << Spoom::Source::Replace.new(4, 6, "baz")
20
+ # rewriter << Spoom::Source::Insert.new(0, "def bar; end\n")
21
+ # rewriter.rewrite!(bytes)
22
+ #
23
+ # puts bytes.pack("C*") # => "def bar; end\ndef baz; end"
24
+ # ```
25
+ module Source
26
+ class PositionError < Spoom::Error; end
27
+
28
+ # @abstract
29
+ class Edit
30
+ # @abstract
31
+ #: (Array[Integer]) -> void
32
+ def apply(bytes); end
33
+
34
+ # @abstract
35
+ #: -> [Integer, Integer]
36
+ def range; end
37
+ end
38
+
39
+ class Insert < Edit
40
+ #: Integer
41
+ attr_reader :position
42
+
43
+ #: String
44
+ attr_reader :text
45
+
46
+ #: (Integer, String) -> void
47
+ def initialize(position, text)
48
+ super()
49
+
50
+ @position = position
51
+ @text = text
52
+ end
53
+
54
+ # @override
55
+ #: (Array[Integer]) -> void
56
+ def apply(bytes)
57
+ raise PositionError, "Position is out of bounds" if position < 0 || position > bytes.size
58
+
59
+ bytes #: untyped
60
+ .insert(position, *text.bytes)
61
+ end
62
+
63
+ # @override
64
+ #: -> [Integer, Integer]
65
+ def range
66
+ [position, position]
67
+ end
68
+
69
+ # @override
70
+ #: -> String
71
+ def to_s
72
+ "Insert `#{text}` at #{position}"
73
+ end
74
+ end
75
+
76
+ class Replace < Edit
77
+ #: Integer
78
+ attr_reader :from, :to
79
+
80
+ #: String
81
+ attr_reader :text
82
+
83
+ #: (Integer, Integer, String) -> void
84
+ def initialize(from, to, text)
85
+ super()
86
+
87
+ @from = from
88
+ @to = to
89
+ @text = text
90
+ end
91
+
92
+ # @override
93
+ #: (Array[Integer]) -> void
94
+ def apply(bytes)
95
+ raise PositionError, "Position is out of bounds" if from < 0 || to < 0 || from > bytes.size || to > bytes.size || from > to
96
+
97
+ bytes[from..to] = *text.bytes
98
+ end
99
+
100
+ # @override
101
+ #: -> [Integer, Integer]
102
+ def range
103
+ [from, to]
104
+ end
105
+
106
+ # @override
107
+ #: -> String
108
+ def to_s
109
+ "Replace #{from}-#{to} with `#{text}`"
110
+ end
111
+ end
112
+
113
+ class Delete < Edit
114
+ #: Integer
115
+ attr_reader :from, :to
116
+
117
+ #: (Integer, Integer) -> void
118
+ def initialize(from, to)
119
+ super()
120
+
121
+ @from = from
122
+ @to = to
123
+ end
124
+
125
+ # @override
126
+ #: (Array[untyped]) -> void
127
+ def apply(bytes)
128
+ raise PositionError, "Position is out of bounds" if from < 0 || to < 0 || from > bytes.size || to > bytes.size || from > to
129
+
130
+ bytes[from..to] = "".bytes
131
+ end
132
+
133
+ # @override
134
+ #: -> [Integer, Integer]
135
+ def range
136
+ [from, to]
137
+ end
138
+
139
+ # @override
140
+ #: -> String
141
+ def to_s
142
+ "Delete #{from}-#{to}"
143
+ end
144
+ end
145
+
146
+ class Rewriter
147
+ #: -> void
148
+ def initialize
149
+ @edits = [] #: Array[Edit]
150
+ end
151
+
152
+ #: (Edit) -> void
153
+ def <<(other)
154
+ @edits << other
155
+ end
156
+
157
+ #: (Array[Integer]) -> void
158
+ def rewrite!(bytes)
159
+ # To avoid remapping positions after each edit,
160
+ # we sort the changes by position and apply them in reverse order.
161
+ @edits.sort_by(&:range).reverse_each do |edit|
162
+ edit.apply(bytes)
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,4 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "source/rewriter"
@@ -3,9 +3,7 @@
3
3
 
4
4
  module Spoom
5
5
  class Timeline
6
- extend T::Sig
7
-
8
- sig { params(context: Context, from: Time, to: Time).void }
6
+ #: (Context context, Time from, Time to) -> void
9
7
  def initialize(context, from, to)
10
8
  @context = context
11
9
  @from = from
@@ -13,13 +11,13 @@ module Spoom
13
11
  end
14
12
 
15
13
  # Return one commit for each month between `from` and `to`
16
- sig { returns(T::Array[Git::Commit]) }
14
+ #: -> Array[Git::Commit]
17
15
  def ticks
18
16
  commits_for_dates(months)
19
17
  end
20
18
 
21
19
  # Return all months between `from` and `to`
22
- sig { returns(T::Array[Time]) }
20
+ #: -> Array[Time]
23
21
  def months
24
22
  d = Date.new(@from.year, @from.month, 1)
25
23
  to = Date.new(@to.year, @to.month, 1)
@@ -32,7 +30,7 @@ module Spoom
32
30
  end
33
31
 
34
32
  # Return one commit for each date in `dates`
35
- sig { params(dates: T::Array[Time]).returns(T::Array[Git::Commit]) }
33
+ #: (Array[Time] dates) -> Array[Git::Commit]
36
34
  def commits_for_dates(dates)
37
35
  dates.map do |t|
38
36
  result = @context.git_log(
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.5.0"
5
+ VERSION = "1.7.2"
6
6
  end