sorbet-runtime 0.5.10805 → 0.5.10810
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
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ce397971b7d821fb18a9d6e46c976b36f6aff58d41ce9c450b55b556a847038
|
|
4
|
+
data.tar.gz: 27e289b6c887fd4e55b3a4614cd8fd24e4eaf0a5597074f638bdc15832294feb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 761d5c3f85446fb6c2f743868ecdf74f625b3d2c31d2e3045ca91ee626093f09f85f6fdcfdba1d1413896f5e451df450659bb619637fd66fa8d1ed95735d8223
|
|
7
|
+
data.tar.gz: e6e883faf46cfec00205731384229290d7ef8bbaa1044694d87d2e236d8f37172acf7a477e5a11e2077c6b47f53376ab6f5b7495b14eecd651a23635a7112e50
|
|
@@ -27,15 +27,15 @@ module T::Private::Abstract::Declare
|
|
|
27
27
|
raise "Classes can't be interfaces. Use `abstract!` instead of `interface!`."
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
if mod.
|
|
31
|
-
raise "You must call `abstract!` *before* defining
|
|
30
|
+
if mod.method(:new).owner == mod
|
|
31
|
+
raise "You must call `abstract!` *before* defining a `new` method"
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
# Don't need to silence warnings via without_ruby_warnings when calling
|
|
35
35
|
# define_method because of the guard above
|
|
36
36
|
|
|
37
|
-
mod.send(:
|
|
38
|
-
if self
|
|
37
|
+
mod.send(:define_singleton_method, :new) do |*args, &blk|
|
|
38
|
+
if T.unsafe(self) == mod
|
|
39
39
|
raise "#{mod} is declared as abstract; it cannot be instantiated"
|
|
40
40
|
end
|
|
41
41
|
super(*args, &blk)
|
|
@@ -43,10 +43,10 @@ module T::Private::Abstract::Declare
|
|
|
43
43
|
|
|
44
44
|
# Ruby doesn not emit "method redefined" warnings for aliased methods
|
|
45
45
|
# (more robust than undef_method that would create a small window in which the method doesn't exist)
|
|
46
|
-
mod.send(:alias_method, :
|
|
46
|
+
mod.singleton_class.send(:alias_method, :new, :new)
|
|
47
47
|
|
|
48
|
-
if mod.respond_to?(:ruby2_keywords, true)
|
|
49
|
-
mod.send(:ruby2_keywords, :
|
|
48
|
+
if mod.singleton_class.respond_to?(:ruby2_keywords, true)
|
|
49
|
+
mod.singleton_class.send(:ruby2_keywords, :new)
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
end
|
|
@@ -6,14 +6,63 @@ module T::Private::Methods::SignatureValidation
|
|
|
6
6
|
Modes = Methods::Modes
|
|
7
7
|
|
|
8
8
|
def self.validate(signature)
|
|
9
|
+
# Constructors in any language are always a bit weird: they're called in a
|
|
10
|
+
# static context, but their bodies are implemented by instance methods. So
|
|
11
|
+
# a mix of the rules that apply to instance methods and class methods
|
|
12
|
+
# apply.
|
|
13
|
+
#
|
|
14
|
+
# In languages like Java and Scala, static methods/companion object methods
|
|
15
|
+
# are never inherited. (In Java it almost looks like you can inherit them,
|
|
16
|
+
# because `Child.static_parent_method` works, but this method is simply
|
|
17
|
+
# resolved statically to `Parent.static_parent_method`). Even though most
|
|
18
|
+
# instance methods overrides have variance checking done, constructors are
|
|
19
|
+
# not treated like this, because static methods are never
|
|
20
|
+
# inherited/overridden, and the constructor can only ever be called
|
|
21
|
+
# indirectly by way of the static method. (Note: this is only a mental
|
|
22
|
+
# model--there's not actually a static method for the constructor in Java,
|
|
23
|
+
# there's an `invokespecial` JVM instruction that handles this).
|
|
24
|
+
#
|
|
25
|
+
# But Ruby is not like Java: singleton class methods in Ruby *are*
|
|
26
|
+
# inherited, unlike static methods in Java. In fact, this is similar to how
|
|
27
|
+
# JavaScript works. TypeScript simply then sidesteps the issue with
|
|
28
|
+
# structural typing: `typeof Parent` is not compatible with `typeof Child`
|
|
29
|
+
# if their constructors are different. (In a nominal type system, simply
|
|
30
|
+
# having Child descend from Parent should be the only factor in determining
|
|
31
|
+
# whether those types are compatible).
|
|
32
|
+
#
|
|
33
|
+
# Flow has nominal subtyping for classes. When overriding (static and
|
|
34
|
+
# instance) methods in a child class, the overrides must satisfy variance
|
|
35
|
+
# constraints. But it still carves out an exception for constructors,
|
|
36
|
+
# because then literally every class would have to have the same
|
|
37
|
+
# constructor. This is simply unsound. Hack does a similar thing--static
|
|
38
|
+
# method overrides are checked, but not constructors. Though what Hack
|
|
39
|
+
# *does* have is a way to opt into override checking for constructors with
|
|
40
|
+
# a special annotation.
|
|
41
|
+
#
|
|
42
|
+
# It turns out, Sorbet already has this special annotation: either
|
|
43
|
+
# `abstract` or `overridable`. At time of writing, *no* static override
|
|
44
|
+
# checking happens unless marked with these keywords (though at runtime, it
|
|
45
|
+
# always happens). Getting the static system to parity with the runtime by
|
|
46
|
+
# always checking overrides would be a great place to get to one day, but
|
|
47
|
+
# for now we can take advantage of it by only doing override checks for
|
|
48
|
+
# constructors if they've opted in.
|
|
49
|
+
#
|
|
50
|
+
# (When we get around to more widely checking overrides statically, we will
|
|
51
|
+
# need to build a matching special case for constructors statically.)
|
|
52
|
+
#
|
|
53
|
+
# Note that this breaks with tradition: normally, constructors are not
|
|
54
|
+
# allowed to be abstract. But that's kind of a side-effect of everything
|
|
55
|
+
# above: in Java/Scala, singleton class methods are never abstract because
|
|
56
|
+
# they're not inherited, and this extends to constructors. TypeScript
|
|
57
|
+
# simply rejects `new klass()` entirely if `klass` is
|
|
58
|
+
# `typeof AbstractClass`, requiring instead that you write
|
|
59
|
+
# `{ new(): AbstractClass }`. We may want to consider building some
|
|
60
|
+
# analogue to `T.class_of` in the future that works like this `{new():
|
|
61
|
+
# ...}` type.
|
|
9
62
|
if signature.method_name == :initialize && signature.method.owner.is_a?(Class)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
# methods (this is consistent with how they're treated in other languages, e.g. Java)
|
|
13
|
-
if signature.mode != Modes.standard
|
|
14
|
-
raise "`initialize` should not use `.abstract` or `.implementation` or any other inheritance modifiers."
|
|
63
|
+
if signature.mode == Modes.standard
|
|
64
|
+
return
|
|
15
65
|
end
|
|
16
|
-
return
|
|
17
66
|
end
|
|
18
67
|
|
|
19
68
|
super_method = signature.method.super_method
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sorbet-runtime
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.10810
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stripe
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-05-
|
|
11
|
+
date: 2023-05-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|