sorbet-eraser 0.3.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbfc0c7e028bd4e712e64d29a7c74e65d45937087a3f510f01afab434250b3d5
4
- data.tar.gz: 6a89286f19c7ae6ed8e838beba49fcb799426fb14a58ed4b5c3b32d9b59935dc
3
+ metadata.gz: 420576226d037471f75759599ea53397cd251dd546431b24e9d3cf556285902a
4
+ data.tar.gz: 7c6d09a382019245254f55d0a9eff1b4cd2430d066c364efde59567ada2f56c0
5
5
  SHA512:
6
- metadata.gz: efe378c67fa4749ac7461496d895c69e89ef28ca1f71d6c9385952a96320e8849a6ed15604d8219560903d047b0f9a1eda60fb938b07dc633f55da95a1082119
7
- data.tar.gz: af3a02739fbbfdec2fd98c1bbb749b74a2a7f088c237f339966b186ad4b565e8cd353bac2bd4989f2fba8ae7435a096a058c4aca5cded0f209113826e284e994
6
+ metadata.gz: 5478636318a06fe00d279813bd724659d6653efef7364ea583e11566e455cf9528e8c14338dfdab11298e329225ca9ef2c0847df4125b0edea09f4ca5a953452
7
+ data.tar.gz: 26d79c3b183ef5f7a629205b94e61a09862db83ca50884d68e1e7d22954b1543355787e7fd798223ff8b483bdbdcbb5c14a49959d72f19a12bfcedd13f8f51e8
data/.gitignore CHANGED
@@ -6,3 +6,5 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+
10
+ test.rb
data/CHANGELOG.md CHANGED
@@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.5.0] - 2023-07-13
10
+
11
+ ### Added
12
+
13
+ - Replace `typed: strict` comments with empty comments.
14
+ - Replace all `typed:` sigil comments with empty comments instead of `typed: ignore`. Do this because `typed: ignore` longer than other options, which can cause issues with byte ranges, and violates an assumption by this gem that it is only erasing, not adding content.
15
+ - Add a `--verify` option to the CLI to ensure output is valid Ruby.
16
+ - Enhance `sorbet/eraser/autoload` to hook into `load_iseq` even if bootsnap is not present.
17
+
18
+ ## [0.4.0] - 2023-07-03
19
+
20
+ ### Added
21
+
22
+ - `require "t"` now requires a file that only requires `"sorbet/eraser/t"`, so they are effectively the same thing. If you're in a situation where you need to load a different `"t"`, then you can manually require `"sorbet/eraser/t"` and it should work.
23
+ - Replace all `typed:` comments with `typed: ignore`.
24
+
9
25
  ## [0.3.1] - 2023-06-27
10
26
 
11
27
  ### Added
@@ -34,7 +50,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a
34
50
 
35
51
  - Require MFA for releasing.
36
52
 
37
- [unreleased]: https://github.com/kddnewton/sorbet-eraser/compare/v0.3.0...HEAD
53
+ [unreleased]: https://github.com/kddnewton/sorbet-eraser/compare/v0.4.1...HEAD
54
+ [0.4.1]: https://github.com/kddnewton/sorbet-eraser/compare/v0.4.0...v0.4.1
55
+ [0.4.0]: https://github.com/kddnewton/sorbet-eraser/compare/v0.3.1...v0.4.0
56
+ [0.3.1]: https://github.com/kddnewton/sorbet-eraser/compare/v0.3.0...v0.3.1
38
57
  [0.3.0]: https://github.com/kddnewton/sorbet-eraser/compare/v0.2.0...v0.3.0
39
58
  [0.2.0]: https://github.com/kddnewton/sorbet-eraser/compare/v0.1.1...v0.2.0
40
59
  [0.1.1]: https://github.com/kddnewton/sorbet-eraser/compare/f6a712...v0.1.1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorbet-eraser (0.3.1)
4
+ sorbet-eraser (0.5.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -12,6 +12,8 @@ Sometimes, you want to use Sorbet for development, but don't want to run `sorbet
12
12
  To handle these use cases, `sorbet-eraser` provides a way to erase all traces of `sorbet-runtime` code from your source code. This means that you can use Sorbet for development, but not have to worry about `sorbet-runtime` in production. For example,
13
13
 
14
14
  ```ruby
15
+ # typed: true
16
+
15
17
  class HelloWorld
16
18
  extend T::Sig
17
19
 
@@ -25,6 +27,8 @@ end
25
27
  will be transformed into
26
28
 
27
29
  ```ruby
30
+ #
31
+
28
32
  class HelloWorld
29
33
 
30
34
 
@@ -93,27 +97,28 @@ Below is a table of the status of each `sorbet-runtime` construct and its curren
93
97
 
94
98
  | Construct | Status | Replacement |
95
99
  | --------------------------------------------------- | ------ | ----------- |
96
- | `extend T::*` | ✅ | Shimmed |
97
- | `abstract!`, `final!`, `interface!`, `sealed!` | ✅ | Shimmed |
98
- | `mixes_in_class_methods(*)`, `requires_ancestor(*)` | ✅ | Shimmed |
99
- | `type_member(*)`, `type_template(*)` | ✅ | Shimmed |
100
- | `class Foo < T::Enum` | ✅ | Shimmed |
101
- | `class Foo < T::InexactStruct` | 🛠 | Shimmed |
102
- | `class Foo < T::Struct` | 🛠 | Shimmed |
103
- | `class Foo < T::ImmutableStruct` | 🛠 | Shimmed |
104
- | `include T::Props` | 🛠 | Shimmed |
105
- | `include T::Props::Serializable` | 🛠 | Shimmed |
106
- | `include T::Props::Constructor` | 🛠 | Shimmed |
107
- | `sig` | | Removed |
108
- | `T.absurd(foo)` | ✅ | Shimmed |
109
- | `T.assert_type!(foo, bar)` | ✅ | `foo` |
110
- | `T.bind(self, foo)` | ✅ | `self` |
111
- | `T.cast(foo, bar)` | ✅ | `foo` |
112
- | `T.let(foo, bar)` | ✅ | `foo` |
113
- | `T.must(foo)` | ✅ | `foo` |
114
- | `T.reveal_type(foo)` | ✅ | `foo` |
115
- | `T.type_alias { foo }` | ✅ | Shimmed |
116
- | `T.unsafe(foo)` | ✅ | `foo` |
100
+ | `# typed: foo` | ✅ | `# ` |
101
+ | `extend T::*` | ✅ | Shimmed |
102
+ | `abstract!`, `final!`, `interface!`, `sealed!` | ✅ | Shimmed |
103
+ | `mixes_in_class_methods(*)`, `requires_ancestor(*)` | ✅ | Shimmed |
104
+ | `type_member(*)`, `type_template(*)` | ✅ | Shimmed |
105
+ | `class Foo < T::Enum` | | Shimmed |
106
+ | `class Foo < T::InexactStruct` | 🛠 | Shimmed |
107
+ | `class Foo < T::Struct` | 🛠 | Shimmed |
108
+ | `class Foo < T::ImmutableStruct` | 🛠 | Shimmed |
109
+ | `include T::Props` | 🛠 | Shimmed |
110
+ | `include T::Props::Serializable` | 🛠 | Shimmed |
111
+ | `include T::Props::Constructor` | 🛠 | Shimmed |
112
+ | `sig` | ✅ | Removed |
113
+ | `T.absurd(foo)` | ✅ | Shimmed |
114
+ | `T.assert_type!(foo, bar)` | ✅ | `foo` |
115
+ | `T.bind(self, foo)` | ✅ | `self` |
116
+ | `T.cast(foo, bar)` | ✅ | `foo` |
117
+ | `T.let(foo, bar)` | ✅ | `foo` |
118
+ | `T.must(foo)` | ✅ | `foo` |
119
+ | `T.reveal_type(foo)` | ✅ | `foo` |
120
+ | `T.type_alias { foo }` | ✅ | Shimmed |
121
+ | `T.unsafe(foo)` | ✅ | `foo` |
117
122
 
118
123
  In the above table, for `Status`:
119
124
 
@@ -2,21 +2,22 @@
2
2
 
3
3
  require "sorbet/eraser"
4
4
 
5
- # Hook into bootsnap so that before the source is compiled through
6
- # RubyVM::InstructionSequence it gets erased through the eraser.
7
- if RubyVM::InstructionSequence.method_defined?(:load_iseq)
8
- load_iseq, = RubyVM::InstructionSequence.method(:load_iseq).source_location
9
-
10
- if load_iseq.include?("/bootsnap/")
11
- module Sorbet::Eraser::Patch
12
- def input_to_storage(contents, filepath)
13
- erased = Sorbet::Eraser.erase(contents)
14
- RubyVM::InstructionSequence.compile(erased, filepath, filepath).to_binary
15
- rescue SyntaxError
16
- raise ::Bootsnap::CompileCache::Uncompilable, "syntax error"
17
- end
5
+ if RubyVM::InstructionSequence.method_defined?(:load_iseq) &&
6
+ RubyVM::InstructionSequence.method(:load_iseq).source_location[0].include?("/bootsnap/")
7
+ # If the load_iseq method is defined by bootsnap, then we need to override it.
8
+ module Sorbet::Eraser::Patch
9
+ def input_to_storage(contents, filepath)
10
+ super(Sorbet::Eraser.erase(contents), filepath)
18
11
  end
12
+ end
19
13
 
20
- Bootsnap::CompileCache::ISeq.singleton_class.prepend(Sorbet::Eraser::Patch)
14
+ Bootsnap::CompileCache::ISeq.singleton_class.prepend(Sorbet::Eraser::Patch)
15
+ else
16
+ # Otherwise if the method isn't defined by bootsnap, then we'll define it
17
+ # ourselves.
18
+ def (RubyVM::InstructionSequence).load_iseq(filepath)
19
+ contents = File.read(filepath)
20
+ erased = Sorbet::Eraser.erase(contents)
21
+ RubyVM::InstructionSequence.compile(erased, filepath, filepath)
21
22
  end
22
23
  end
@@ -7,9 +7,10 @@ module Sorbet
7
7
  class CLI
8
8
  POOL_SIZE = 4
9
9
 
10
- attr_reader :filepaths
10
+ attr_reader :verify, :filepaths
11
11
 
12
- def initialize(filepaths)
12
+ def initialize(verify, filepaths)
13
+ @verify = verify
13
14
  @filepaths = filepaths
14
15
  end
15
16
 
@@ -28,20 +29,36 @@ module Sorbet
28
29
  break if filepath == :eoq
29
30
  process(filepath)
30
31
  end
31
- end
32
+ end.tap { |thread| thread.abort_on_exception = true }
32
33
  end
33
34
 
34
35
  workers.each(&:join)
35
36
  end
36
37
 
37
38
  def self.start(argv)
38
- new(argv.flat_map { |pattern| Dir.glob(pattern) }).start
39
+ verify = false
40
+
41
+ if argv.first == "--verify"
42
+ verify = true
43
+ argv.shift
44
+ end
45
+
46
+ filepaths = []
47
+ argv.each { |pattern| filepaths.concat(Dir.glob(pattern)) }
48
+
49
+ new(verify, filepaths).start
39
50
  end
40
51
 
41
52
  private
42
53
 
43
54
  def process(filepath)
44
- File.write(filepath, Eraser.erase(File.read(filepath)))
55
+ contents = Eraser.erase(File.read(filepath))
56
+
57
+ if verify && Ripper.sexp_raw(contents).nil?
58
+ warn("Internal error while parsing #{filepath}")
59
+ else
60
+ File.write(filepath, contents)
61
+ end
45
62
  rescue Parser::ParsingError => error
46
63
  warn("Could not parse #{filepath}: #{error}")
47
64
  rescue => error
@@ -86,7 +86,7 @@ module Sorbet
86
86
  @line_counts << MultiByteString.new(last_index, line)
87
87
  end
88
88
 
89
- last_index += line.size
89
+ last_index += line.bytesize
90
90
  end
91
91
 
92
92
  @errors = []
@@ -136,18 +136,18 @@ module Sorbet
136
136
 
137
137
  # Better location information for aref.
138
138
  def on_aref(recv, arg)
139
- rend = arg.range.end + source[arg.range.end..].index("]") + 1
139
+ rend = arg.range.end + source.byteslice(arg.range.end..).index("]") + 1
140
140
  Node.new(:aref, [recv, arg], recv.range.begin...rend)
141
141
  end
142
142
 
143
143
  # Better location information for arg_paren.
144
144
  def on_arg_paren(arg)
145
145
  if arg
146
- rbegin = source[..arg.range.begin].rindex("(")
147
- rend = arg.range.end + source[arg.range.end..].index(")") + 1
146
+ rbegin = source.byteslice(..arg.range.begin).rindex("(")
147
+ rend = arg.range.end + source.byteslice(arg.range.end..).index(")") + 1
148
148
  Node.new(:arg_paren, [arg], rbegin...rend)
149
149
  else
150
- segment = source[..loc]
150
+ segment = source.byteslice(..loc)
151
151
  Node.new(:arg_paren, [arg], segment.rindex("(")...(segment.rindex(")") + 1))
152
152
  end
153
153
  end
@@ -159,11 +159,11 @@ module Sorbet
159
159
  def on_array(arg)
160
160
  case arg&.event
161
161
  when nil
162
- segment = source[..loc]
162
+ segment = source.byteslice(..loc)
163
163
  Node.new(:array, [arg], segment.rindex("[")...(segment.rindex("]") + 1))
164
164
  when :qsymbols, :qwords, :symbols, :words
165
- rbegin = source[...arg.range.begin].rindex(LISTS.fetch(arg.event))
166
- rend = source[arg.range.end..].index(TERMINATORS.fetch(source[rbegin + 2]) { source[rbegin + 2] }) + arg.range.end + 1
165
+ rbegin = source.byteslice(...arg.range.begin).rindex(LISTS.fetch(arg.event))
166
+ rend = source.byteslice(arg.range.end..).index(TERMINATORS.fetch(source.byteslice(rbegin + 2)) { source.byteslice(rbegin + 2) }) + arg.range.end + 1
167
167
  Node.new(:array, [arg], rbegin...rend)
168
168
  else
169
169
  Node.new(:array, [arg], arg.range)
@@ -173,14 +173,14 @@ module Sorbet
173
173
  # Better location information for brace_block.
174
174
  def on_brace_block(params, body)
175
175
  if params || body.range
176
- rbegin = source[...(params || body).range.begin].rindex("{")
176
+ rbegin = source.byteslice(...(params || body).range.begin).rindex("{")
177
177
 
178
178
  rend = body.range&.end || params.range.end
179
- rend = rend + source[rend..].index("}") + 1
179
+ rend = rend + source.byteslice(rend..).index("}") + 1
180
180
 
181
181
  Node.new(:brace_block, [params, body], rbegin...rend)
182
182
  else
183
- segment = source[..loc]
183
+ segment = source.byteslice(..loc)
184
184
  Node.new(:brace_block, [params, body], segment.rindex("{")...(segment.rindex("}") + 1))
185
185
  end
186
186
  end
@@ -188,14 +188,14 @@ module Sorbet
188
188
  # Better location information for do_block.
189
189
  def on_do_block(params, body)
190
190
  if params || body.range
191
- rbegin = source[...(params || body).range.begin].rindex("do")
191
+ rbegin = source.byteslice(...(params || body).range.begin).rindex("do")
192
192
 
193
193
  rend = body.range&.end || params.range.end
194
- rend = rend + source[rend..].index("end") + 3
194
+ rend = rend + source.byteslice(rend..).index("end") + 3
195
195
 
196
196
  Node.new(:do_block, [params, body], rbegin...rend)
197
197
  else
198
- segment = source[..loc]
198
+ segment = source.byteslice(..loc)
199
199
  Node.new(:do_block, [params, body], segment.rindex("do")...(segment.rindex("end") + 3))
200
200
  end
201
201
  end
@@ -205,7 +205,7 @@ module Sorbet
205
205
  if arg
206
206
  Node.new(:hash, [arg], arg.range)
207
207
  else
208
- segment = source[..loc]
208
+ segment = source.byteslice(..loc)
209
209
  Node.new(:hash, [arg], segment.rindex("{")...(segment.rindex("}") + 1))
210
210
  end
211
211
  end
@@ -213,7 +213,7 @@ module Sorbet
213
213
  # Track the open heredocs so we can replace the string literal ranges with
214
214
  # the range of their declarations.
215
215
  def on_heredoc_beg(value)
216
- range = loc.then { |start| start...(start + value.size) }
216
+ range = loc.then { |start| start...(start + value.bytesize) }
217
217
  heredocs << [range, value, nil]
218
218
 
219
219
  Node.new(:@heredoc_beg, [value], range)
@@ -222,7 +222,7 @@ module Sorbet
222
222
  # If a heredoc ends, then the next string literal event will be the
223
223
  # heredoc.
224
224
  def on_heredoc_end(value)
225
- range = loc.then { |start| start...(start + value.size) }
225
+ range = loc.then { |start| start...(start + value.bytesize) }
226
226
  heredocs.find { |(_, beg_arg, end_arg)| beg_arg.include?(value.strip) && end_arg.nil? }[2] = value
227
227
 
228
228
  Node.new(:@heredoc_end, [value], range)
@@ -239,7 +239,7 @@ module Sorbet
239
239
  if heredoc = heredocs.find { |(_, _, end_arg)| end_arg }
240
240
  Node.new(:string_literal, [arg], heredocs.delete(heredoc)[0])
241
241
  else
242
- Node.new(:string_literal, [arg], arg.range)
242
+ Node.new(:string_literal, [arg], (arg.range.begin - 1)...(arg.range.end + 1))
243
243
  end
244
244
  end
245
245
 
@@ -251,7 +251,7 @@ module Sorbet
251
251
  next if handled.include?(:"on_#{event}")
252
252
 
253
253
  define_method(:"on_#{event}") do |value|
254
- range = loc.then { |start| start...(start + (value&.size || 0)) }
254
+ range = loc.then { |start| start...(start + (value&.bytesize || 0)) }
255
255
  Node.new(:"@#{event}", [value], range)
256
256
  end
257
257
  end
@@ -13,14 +13,11 @@ module Sorbet
13
13
  end
14
14
 
15
15
  def erase(source)
16
- original = source[range]
17
- replaced = replace(original)
16
+ encoding = source.encoding
17
+ source.force_encoding(Encoding::ASCII_8BIT)
18
18
 
19
- # puts "Replacing #{original} (len=#{original.length}) " \
20
- # "with #{replaced} (len=#{replaced.length})"
21
-
22
- source[range] = replaced
23
- source
19
+ source[range] = replace(source[range])
20
+ source.force_encoding(encoding)
24
21
  end
25
22
 
26
23
  def blank(segment)
@@ -57,11 +54,11 @@ module Sorbet
57
54
  # We can't really rely on regex here because commas have semantic
58
55
  # meaning and you might have some in the value of the first argument.
59
56
  comma = metadata.fetch(:comma)
60
- pre, post = 0..comma, (comma + 1)..-1
57
+ pre, post = 0...comma, comma..-1
61
58
 
62
59
  replacement[pre] =
63
- replacement[pre].gsub(/(T\s*\.(?:assert_type!|bind|cast|let)\(\s*)(.+)(\s*,)(.*)/m) do
64
- "#{blank($1)}#{$2}#{blank($3)}#{$4}"
60
+ replacement[pre].gsub(/(T\s*\.(?:assert_type!|bind|cast|let)\(\s*)(.+)/m) do
61
+ "#{blank($1)}#{$2}"
65
62
  end
66
63
 
67
64
  replacement[post] = blank(replacement[post])
@@ -100,6 +97,32 @@ module Sorbet
100
97
  end
101
98
  end
102
99
 
100
+ # typed: ignore => #
101
+ # typed: false => #
102
+ # typed: true => #
103
+ # typed: strict => #
104
+ # typed: strong => #
105
+ class TypedCommentPattern < Pattern
106
+ def replace(segment)
107
+ segment.gsub(/\A#(\s*typed:\s*(?:ignore|false|true|strict|strong)(\s*))\z/) do
108
+ "##{blank($1)}"
109
+ end
110
+ end
111
+ end
112
+
113
+ def on_comment(comment)
114
+ super.tap do |node|
115
+ if lineno == 1 && comment.match?(/\A#\s*typed:\s*(?:ignore|false|true|strict|strong)\s*\z/)
116
+ # typed: ignore
117
+ # typed: false
118
+ # typed: true
119
+ # typed: strict
120
+ # typed: strong
121
+ patterns << TypedCommentPattern.new(node.range)
122
+ end
123
+ end
124
+ end
125
+
103
126
  def on_method_add_arg(call, arg_paren)
104
127
  if call.match?(/\A<call <var_ref <@const T>> <@period \.> <@ident (?:must|reveal_type|unsafe)>>\z/) && arg_paren.match?(/\A<arg_paren <args_add_block <args .+> false>>\z/)
105
128
  # T.must(foo)
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sorbet/eraser/t/enum"
4
+ require "sorbet/eraser/t/props"
5
+ require "sorbet/eraser/t/struct"
6
+
7
+ # For some constructs, it doesn't make as much sense to entirely remove them
8
+ # since they're actually used to change runtime behavior. For example, T.absurd
9
+ # will always raise an error. In this case instead of removing the content, we
10
+ # can just shim it.
11
+ module T
12
+ # These methods should really not be being called in a loop or any other kind
13
+ # of hot path, so here we're just going to shim them.
14
+ module Helpers
15
+ def abstract!; end
16
+ def interface!; end
17
+ def final!; end
18
+ def sealed!; end
19
+ def mixes_in_class_methods(*); end
20
+ def requires_ancestor(*); end
21
+ end
22
+
23
+ # Similar to the Helpers module, these things should only be called a couple
24
+ # of times, so shimming them here.
25
+ module Generic
26
+ include Helpers
27
+ def type_member(*, **); end
28
+ def type_template(*, **); end
29
+ end
30
+
31
+ # Keeping this module as a thing so that if there's any kind of weird
32
+ # reflection going on like is_a?(T::Sig) it will still work.
33
+ module Sig
34
+ end
35
+
36
+ # I really don't want to be shimming this, but there are places where people
37
+ # try to reference these values.
38
+ module Private
39
+ module RuntimeLevels
40
+ def self.default_checked_level; :never; end
41
+ end
42
+
43
+ module Methods
44
+ module MethodHooks
45
+ end
46
+
47
+ module SingletonMethodHooks
48
+ end
49
+
50
+ def self.signature_for_method(method); method; end
51
+ end
52
+ end
53
+
54
+ # I also don't want to shim this, but there are places where people will
55
+ # reference it.
56
+ module Configuration
57
+ class << self
58
+ attr_accessor :inline_type_error_handler,
59
+ :call_validation_error_handler,
60
+ :sig_builder_error_handler
61
+ end
62
+ end
63
+
64
+ # Type aliases don't actually do anything, but they are usually assigned to
65
+ # constants, so in that case we need to return something.
66
+ def self.type_alias
67
+ Object.new
68
+ end
69
+
70
+ # Absurd always raises a TypeError within Sorbet, so mirroring that behavior
71
+ # here when T.absurd is called.
72
+ def self.absurd(value)
73
+ raise TypeError, value
74
+ end
75
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sorbet
4
4
  module Eraser
5
- VERSION = "0.3.1"
5
+ VERSION = "0.5.0"
6
6
  end
7
7
  end
data/lib/t.rb CHANGED
@@ -1,75 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "t/enum"
4
- require "t/props"
5
- require "t/struct"
6
-
7
- # For some constructs, it doesn't make as much sense to entirely remove them
8
- # since they're actually used to change runtime behavior. For example, T.absurd
9
- # will always raise an error. In this case instead of removing the content, we
10
- # can just shim it.
11
- module T
12
- # These methods should really not be being called in a loop or any other kind
13
- # of hot path, so here we're just going to shim them.
14
- module Helpers
15
- def abstract!; end
16
- def interface!; end
17
- def final!; end
18
- def sealed!; end
19
- def mixes_in_class_methods(*); end
20
- def requires_ancestor(*); end
21
- end
22
-
23
- # Similar to the Helpers module, these things should only be called a couple
24
- # of times, so shimming them here.
25
- module Generic
26
- include Helpers
27
- def type_member(*, **); end
28
- def type_template(*, **); end
29
- end
30
-
31
- # Keeping this module as a thing so that if there's any kind of weird
32
- # reflection going on like is_a?(T::Sig) it will still work.
33
- module Sig
34
- end
35
-
36
- # I really don't want to be shimming this, but there are places where people
37
- # try to reference these values.
38
- module Private
39
- module RuntimeLevels
40
- def self.default_checked_level; :never; end
41
- end
42
-
43
- module Methods
44
- module MethodHooks
45
- end
46
-
47
- module SingletonMethodHooks
48
- end
49
-
50
- def self.signature_for_method(method); method; end
51
- end
52
- end
53
-
54
- # I also don't want to shim this, but there are places where people will
55
- # reference it.
56
- module Configuration
57
- class << self
58
- attr_accessor :inline_type_error_handler,
59
- :call_validation_error_handler,
60
- :sig_builder_error_handler
61
- end
62
- end
63
-
64
- # Type aliases don't actually do anything, but they are usually assigned to
65
- # constants, so in that case we need to return something.
66
- def self.type_alias
67
- Object.new
68
- end
69
-
70
- # Absurd always raises a TypeError within Sorbet, so mirroring that behavior
71
- # here when T.absurd is called.
72
- def self.absurd(value)
73
- raise TypeError, value
74
- end
75
- end
3
+ require "sorbet/eraser/t"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-eraser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Newton
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-27 00:00:00.000000000 Z
11
+ date: 2023-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -77,18 +77,19 @@ files:
77
77
  - lib/sorbet/eraser/cli.rb
78
78
  - lib/sorbet/eraser/parser.rb
79
79
  - lib/sorbet/eraser/patterns.rb
80
+ - lib/sorbet/eraser/t.rb
81
+ - lib/sorbet/eraser/t/enum.rb
82
+ - lib/sorbet/eraser/t/props.rb
83
+ - lib/sorbet/eraser/t/struct.rb
80
84
  - lib/sorbet/eraser/version.rb
81
85
  - lib/t.rb
82
- - lib/t/enum.rb
83
- - lib/t/props.rb
84
- - lib/t/struct.rb
85
86
  - sorbet-eraser.gemspec
86
87
  homepage: https://github.com/kddnewton/sorbet-eraser
87
88
  licenses:
88
89
  - MIT
89
90
  metadata:
90
91
  bug_tracker_uri: https://github.com/kddnewton/sorbet-eraser/issues
91
- changelog_uri: https://github.com/kddnewton/sorbet-eraser/blob/v0.3.1/CHANGELOG.md
92
+ changelog_uri: https://github.com/kddnewton/sorbet-eraser/blob/v0.5.0/CHANGELOG.md
92
93
  source_code_uri: https://github.com/kddnewton/sorbet-eraser
93
94
  rubygems_mfa_required: 'true'
94
95
  post_install_message:
File without changes
File without changes
File without changes