sorbet-runtime 0.5.10805 → 0.5.10810
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:
|
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
|