sorbet-runtime 0.4.4446 → 0.4.4447

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a800d5e7728111e31a78225eaf32a47c00e3fed
4
- data.tar.gz: e8546195bf3b79b86484089e66a78966d8cbc9ef
3
+ metadata.gz: 3c132d32b8c7d993430e728c4f46c2078c676510
4
+ data.tar.gz: 7359c29f33e709cefbf722379705e15a1ab31f74
5
5
  SHA512:
6
- metadata.gz: c2cc3a61f53c8073bcbc091bb5a244059714de8ef38d4f101f5d4d626ab928cfd546a504ce6ef77d1a972b824d0fbfaffdbf11f6fd7e85b6ad8f238131fee3d2
7
- data.tar.gz: 8db326b0147134aabba33d5500065d5438ed2d362fc86f90ac36c8d53318c228439ace3c4ccb194ec35d8d42991a26a63d0c2ee433867ddbd98ad9710f8abcf6
6
+ metadata.gz: 38f93ace75826198d0d1ad340d15fbfabad353b70ce557e35c78b6b41e80ff6f58b331fc999ea741d27182ac7696f21f43dc81a9dc0615db3b953a6ac21fa3e8
7
+ data.tar.gz: 43691e7d1b193dba7306b0b00c1f175b0cb24df57bcf9dab5abf2ea39b23e43eb73d8aea0c7e67ccd9a3db3e5c63d8fc5b2eda11ef159666a4f4dead2a230407
@@ -29,6 +29,7 @@ require_relative 'types/private/runtime_levels'
29
29
  require_relative 'types/private/methods/_methods'
30
30
  require_relative 'types/sig'
31
31
  require_relative 'types/helpers'
32
+ require_relative 'types/private/final'
32
33
 
33
34
  # The types themselves. First base classes
34
35
  require_relative 'types/types/base'
data/lib/types/helpers.rb CHANGED
@@ -16,6 +16,10 @@ module T::Helpers
16
16
  Private::Abstract::Declare.declare_abstract(self, type: :interface)
17
17
  end
18
18
 
19
+ def final!
20
+ Private::Final.declare(self)
21
+ end
22
+
19
23
  # Causes a mixin to also mix in class methods from the named module.
20
24
  #
21
25
  # Nearly equivalent to
@@ -9,6 +9,9 @@ module T::Private::Abstract::Declare
9
9
  if AbstractUtils.abstract_module?(mod)
10
10
  raise "#{mod.name} is already declared as abstract"
11
11
  end
12
+ if T::Private::Final.final_module?(mod)
13
+ raise "#{mod.name} was already declared as final and cannot be declared as abstract"
14
+ end
12
15
 
13
16
  Abstract::Data.set(mod, :can_have_abstract_methods, true)
14
17
  Abstract::Data.set(mod.singleton_class, :can_have_abstract_methods, true)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+ # typed: false
3
+
4
+ module T::Private::Final
5
+ module NoInherit
6
+ def inherited(arg)
7
+ super(arg)
8
+ raise "#{self.name} was declared as final and cannot be inherited"
9
+ end
10
+ end
11
+
12
+ module NoIncludeExtend
13
+ def included(arg)
14
+ super(arg)
15
+ raise "#{self.name} was declared as final and cannot be included"
16
+ end
17
+
18
+ def extended(arg)
19
+ super(arg)
20
+ raise "#{self.name} was declared as final and cannot be extended"
21
+ end
22
+ end
23
+
24
+ def self.declare(mod)
25
+ if !mod.is_a?(Module)
26
+ raise "#{mod.name} is not a class or module and cannot be declared as final with `final!`"
27
+ end
28
+ if final_module?(mod)
29
+ raise "#{mod.name} was already declared as final and cannot be re-declared as final"
30
+ end
31
+ if T::AbstractUtils.abstract_module?(mod)
32
+ raise "#{mod.name} was already declared as abstract and cannot be declared as final"
33
+ end
34
+ mod.extend(mod.is_a?(Class) ? NoInherit : NoIncludeExtend)
35
+ mark_as_final_module(mod)
36
+ mark_as_final_module(mod.singleton_class)
37
+ T::Private::Methods.install_hooks(mod)
38
+ end
39
+
40
+ def self.final_module?(mod)
41
+ mod.instance_variable_defined?(:@sorbet_final_module)
42
+ end
43
+
44
+ private_class_method def self.mark_as_final_module(mod)
45
+ mod.instance_variable_set(:@sorbet_final_module, true)
46
+ T::Private::Methods.add_module_with_final(mod)
47
+ end
48
+ end
@@ -168,6 +168,9 @@ module T::Private::Methods
168
168
  mod = is_singleton_method ? hook_mod.singleton_class : hook_mod
169
169
  original_method = mod.instance_method(method_name)
170
170
 
171
+ if T::Private::Final.final_module?(mod) && (current_declaration.nil? || !current_declaration.final)
172
+ raise "`#{mod.name}` was declared as final but its method `#{method_name}` was not declared as final"
173
+ end
171
174
  _check_final_ancestors(mod, mod.ancestors, [method_name])
172
175
 
173
176
  return if current_declaration.nil?
@@ -182,6 +185,8 @@ module T::Private::Methods
182
185
  # This wrapper is very slow, so it will subsequently re-wrap with a much faster wrapper
183
186
  # (or unwrap back to the original method).
184
187
  new_method = nil
188
+ # this prevents us from running the final checks twice for every method def.
189
+ T::Private::DeclState.current.skip_next_on_method_added = true
185
190
  T::Private::ClassUtils.replace_method(mod, method_name) do |*args, &blk|
186
191
  if !T::Private::Methods.has_sig_block_for_method(new_method)
187
192
  # This should only happen if the user used alias_method to grab a handle
@@ -408,6 +413,9 @@ module T::Private::Methods
408
413
 
409
414
  private_class_method def self.install_singleton_method_added_hook(singleton_klass)
410
415
  attached = nil
416
+ # this prevents the final checks from triggering about singleton_method_added not being a final method even if the
417
+ # module is final.
418
+ T::Private::DeclState.current.skip_next_on_method_added = true
411
419
  original_singleton_method = T::Private::ClassUtils.replace_method(singleton_klass, :singleton_method_added) do |name|
412
420
  attached = self
413
421
  T::Private::Methods._on_method_added(self, name, is_singleton_method: true)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorbet-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4446
4
+ version: 0.4.4447
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
@@ -75,6 +75,7 @@ files:
75
75
  - lib/types/private/class_utils.rb
76
76
  - lib/types/private/decl_state.rb
77
77
  - lib/types/private/error_handler.rb
78
+ - lib/types/private/final.rb
78
79
  - lib/types/private/methods/_methods.rb
79
80
  - lib/types/private/methods/call_validation.rb
80
81
  - lib/types/private/methods/decl_builder.rb