sorbet-runtime 0.6.13294 → 0.6.13295

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: 68497e0df01e0e6fc5bc0484584697a261360be3be24d179d25de375d23814c0
4
- data.tar.gz: 2560a9fecde787001fce90f7c9d80cf05dd2fa742443c5f63be7c86779979b15
3
+ metadata.gz: 1ba71f6fa762bdc985e7d0571384bdb516de33f4c9be69115cf1139975638da8
4
+ data.tar.gz: 557f176df1c801a3a1da3a9b7c28e112eada5cab30e23762b6d67ca1d1be6a8a
5
5
  SHA512:
6
- metadata.gz: 9d9becdde0a5c869407f6fc487385a8a217a5c5054994d4ea516c0b6f96ac5df553ae4dafa03ad741617e7860a2a70d22e6c25978ae1c0127ea44e45cc29f961
7
- data.tar.gz: 3632721eecefe01e67e32d39ece6653317360ef10ba6108bac84e64de733efa6205f5e974a8bcd742dc2c261108945f383cceb799414b7eeba483c46bf1dd834
6
+ metadata.gz: e7f17791a3f3e4c7dba12f932ae31f7c7e0a3379399d64037d89c78da0604472a64e55b3c6bad8d350304696f2ac8bc974e9ed1dd32e17542226d04b3e60734f
7
+ data.tar.gz: 82600633223a670039f18fa7cc0b857bb45a57210a8919a07e523181efdb66d416bf76f53f2c99b1473c5655d8fdfad964e364334f10c0471ad0aab132e99417
@@ -25,7 +25,9 @@ require_relative 'types/private/class_utils'
25
25
  require_relative 'types/private/runtime_levels'
26
26
  require_relative 'types/private/methods/_methods'
27
27
  require_relative 'types/sig'
28
+ require_relative 'types/def_mods'
28
29
  require_relative 'types/helpers'
30
+ require_relative 'types/syntax'
29
31
  require_relative 'types/private/final'
30
32
  require_relative 'types/private/sealed'
31
33
 
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ # Optional mixin providing `abstract`, `override`, `overridable`, and `final`
5
+ # as method-level DSL keywords. Use with `extend T::DefMods`.
6
+ #
7
+ # These are alternatives to writing modifiers inside a `sig { ... }` block:
8
+ #
9
+ # sig { void }
10
+ # abstract def foo; end
11
+ #
12
+ # is equivalent to:
13
+ #
14
+ # sig { abstract.void }
15
+ # def foo; end
16
+ #
17
+ # They all return the method name, so that they can be chained with methods
18
+ # like `private`. However, unlike those methods, these methods use the `sig`
19
+ # declaration to discover the most-recently-defined method, instead of needing
20
+ # `*_class_method` variants, like `private_class_method`.
21
+ module T::DefMods
22
+ def abstract(method_name)
23
+ Kernel.raise TypeError.new("abstract accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
24
+
25
+ begin
26
+ T::Private::Methods.declare_abstract(T.unsafe(self), method_name)
27
+ rescue T::Private::Methods::DeclBuilder::BuilderError => e
28
+ T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
29
+ end
30
+
31
+ method_name
32
+ end
33
+
34
+ def override(method_name, allow_incompatible: false)
35
+ Kernel.raise TypeError.new("override accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
36
+
37
+ begin
38
+ T::Private::Methods.declare_override(T.unsafe(self), method_name, allow_incompatible: allow_incompatible)
39
+ rescue T::Private::Methods::DeclBuilder::BuilderError => e
40
+ T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
41
+ end
42
+
43
+ method_name
44
+ end
45
+
46
+ def final(method_name)
47
+ Kernel.raise TypeError.new("final accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
48
+
49
+ begin
50
+ T::Private::Methods.declare_final(T.unsafe(self), method_name)
51
+ rescue T::Private::Methods::DeclBuilder::BuilderError => e
52
+ T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
53
+ end
54
+
55
+ method_name
56
+ end
57
+
58
+ def overridable(method_name)
59
+ Kernel.raise TypeError.new("overridable accepts a Symbol, got #{method_name.class}") unless method_name.is_a?(Symbol)
60
+
61
+ begin
62
+ T::Private::Methods.declare_overridable(T.unsafe(self), method_name)
63
+ rescue T::Private::Methods::DeclBuilder::BuilderError => e
64
+ T::Configuration.sig_builder_error_handler(e, Kernel.caller_locations(1, 1)&.first)
65
+ end
66
+
67
+ method_name
68
+ end
69
+ end
@@ -48,7 +48,7 @@ module T::Private::Methods
48
48
  # (This can matter for circular load-time behavior, where a method is
49
49
  # called while its Signature is being built)
50
50
  # - It's `nil` if we've finished building the sig
51
- DeclarationBlock = Struct.new(:mod, :loc, :blk_or_decl, :final)
51
+ DeclarationBlock = Struct.new(:mod, :method_name, :loc, :blk_or_decl, :final, :abstract, :override, :overridable)
52
52
 
53
53
  def self.declare_sig(mod, loc, arg, &blk)
54
54
  if T::Private::DeclState.current.active_declaration
@@ -60,13 +60,122 @@ module T::Private::Methods
60
60
  raise "Invalid argument to `sig`: #{arg}"
61
61
  end
62
62
 
63
- T::Private::DeclState.current.active_declaration = DeclarationBlock.new(mod, loc, blk, arg == :final)
63
+ method_name = nil # will be filled in once the next method is defined
64
+ abstract = nil
65
+ override = nil
66
+ overridable = nil
67
+ T::Private::DeclState.current.active_declaration = DeclarationBlock.new(mod, method_name, loc, blk, arg == :final, abstract, override, overridable)
68
+
69
+ nil
70
+ end
71
+
72
+ private_class_method def self.ensure_valid_declare_dsl!(mod, method_name, dsl_name)
73
+ previous_declaration = T::Private::DeclState.current.previous_declaration
74
+ if previous_declaration.nil?
75
+ # TODO(jez) Eventually, relax this and allow these DSLs without a preceding `sig`
76
+ raise DeclBuilder::BuilderError.new("You must declare a `sig` before using `#{dsl_name}` on the method `#{method_name}`")
77
+ end
78
+
79
+ if !previous_declaration.blk_or_decl.is_a?(Proc)
80
+ raise DeclBuilder::BuilderError.new("Cannot call `#{dsl_name} #{method_name.inspect}`, because the sig block has already run")
81
+ end
82
+
83
+ # previous_declaration.mod is the method owner (which for `def self.foo`
84
+ # is the singleton class). The DSL caller's `self` is the class itself,
85
+ # so we also accept mod.singleton_class == previous_declaration.mod.
86
+ mod_matches = previous_declaration.mod == mod || previous_declaration.mod == mod.singleton_class
87
+ if !mod_matches || previous_declaration.method_name != method_name
88
+ raise DeclBuilder::BuilderError.new(
89
+ "Can only call `#{dsl_name} #{method_name.inspect}` for the previously sig'd method. " \
90
+ "Expected: #{previous_declaration.mod}##{previous_declaration.method_name}"
91
+ )
92
+ end
93
+
94
+ previous_declaration
95
+ end
96
+
97
+ def self.declare_abstract(mod, method_name)
98
+ previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :abstract)
99
+ return unless previous_declaration
100
+
101
+ if previous_declaration.abstract
102
+ raise DeclBuilder::BuilderError.new("Cannot call `abstract` twice for the method `#{method_name}`")
103
+ end
104
+
105
+ previous_declaration.abstract = true
106
+
107
+ # # TODO(jez) In the future, we will want some logic like this, but ONLY if
108
+ # # the method did not have a sig. The first-call sig wrapper is normally in
109
+ # # charge of running the sig block (even for abstract methods) If we know
110
+ # # for sure that we're not going to have a sig, but we want the runtime
111
+ # # `super` logic (possibly because there is an RBS method annotation), we
112
+ # # are safe to eagerly call `create_abstract_wrapper` to overwrite the
113
+ # # user's method.
114
+ # #
115
+ # # (Omitting this until we support DSL methods without runtime `sig`'s)
116
+ # original_visibility = T::Private::ClassUtils.visibility_method_name(mod, method_name)
117
+ # T::Private::Methods::CallValidation.create_abstract_wrapper(mod, method_name, original_visibility)
118
+
119
+ nil
120
+ end
121
+
122
+ def self.declare_override(mod, method_name, allow_incompatible:)
123
+ previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :override)
124
+ return unless previous_declaration
125
+
126
+ if previous_declaration.override
127
+ raise DeclBuilder::BuilderError.new("Cannot call `override` twice for the method `#{method_name}`")
128
+ end
129
+
130
+ method = mod.instance_method(method_name)
131
+ super_method = method.super_method
132
+ if super_method.nil?
133
+ source_loc = Kernel.caller_locations(2, 1)&.map { |loc| [loc.path || "<unknown>", loc.lineno] }&.first
134
+ T::Private::Methods::SignatureValidation.validate_non_override_mode(Modes.override, method_name, method, source_loc)
135
+ end
136
+
137
+ previous_declaration.override = {allow_incompatible: allow_incompatible}
138
+
139
+ nil
140
+ end
141
+
142
+ def self.declare_final(mod, method_name)
143
+ previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :final)
144
+ return unless previous_declaration
145
+
146
+ if previous_declaration.final
147
+ raise DeclBuilder::BuilderError.new("Cannot declare `#{method_name}` final twice (from `sig(:final)` nor `final def`)")
148
+ end
149
+
150
+ previous_declaration.final = true
151
+
152
+ # Register final bookkeeping that _on_method_added would have done if it
153
+ # had seen final=true at that time. Use previous_declaration.mod (the actual
154
+ # method owner, which is the singleton_class for `def self.foo`).
155
+ add_module_with_final_method(previous_declaration.mod, method_name)
156
+
157
+ nil
158
+ end
159
+
160
+ def self.declare_overridable(mod, method_name)
161
+ previous_declaration = ensure_valid_declare_dsl!(mod, method_name, :overridable)
162
+ return unless previous_declaration
163
+
164
+ if previous_declaration.overridable
165
+ raise DeclBuilder::BuilderError.new("Cannot call `overridable` twice for the method `#{method_name}`")
166
+ end
167
+
168
+ previous_declaration.overridable = true
64
169
 
65
170
  nil
66
171
  end
67
172
 
68
173
  def self.start_proc
69
- DeclBuilder.new(PROC_TYPE)
174
+ # abstract/override/overridable don't make sense on procs
175
+ abstract = false
176
+ override = nil
177
+ overridable = false
178
+ DeclBuilder.new(PROC_TYPE, abstract, override, overridable)
70
179
  end
71
180
 
72
181
  def self.finalize_proc(decl)
@@ -211,6 +320,8 @@ module T::Private::Methods
211
320
  return
212
321
  end
213
322
 
323
+ current_declaration.method_name = method_name
324
+
214
325
  if method_name == :method_added || method_name == :singleton_method_added
215
326
  raise(
216
327
  "Putting a `sig` on `#{method_name}` is not supported" \
@@ -350,7 +461,12 @@ module T::Private::Methods
350
461
  raise "DeclarationBlock for #{declaration_block.mod} at #{declaration_block.loc} should have already been unwrapped"
351
462
  end
352
463
 
353
- builder = DeclBuilder.new(declaration_block.mod)
464
+ builder = DeclBuilder.new(
465
+ declaration_block.mod,
466
+ declaration_block.abstract,
467
+ declaration_block.override,
468
+ declaration_block.overridable
469
+ )
354
470
  decl = builder.instance_exec(&blk_or_decl).finalize!.decl
355
471
  # Record that we've already run `blk` once and constructed a `Declaration`
356
472
  declaration_block.blk_or_decl = decl
@@ -15,7 +15,7 @@ module T::Private::Methods
15
15
  end
16
16
  end
17
17
 
18
- def initialize(mod)
18
+ def initialize(mod, abstract, override, overridable)
19
19
  @decl = Declaration.new(
20
20
  mod,
21
21
  ARG_NOT_PROVIDED, # params
@@ -28,6 +28,21 @@ module T::Private::Methods
28
28
  false, # override_allow_incompatible
29
29
  ARG_NOT_PROVIDED, # type_parameters
30
30
  )
31
+
32
+ # Call the methods after the fact (instead of setting them in the constructor)
33
+ # so we get the BuilderError's, if applicable
34
+
35
+ if abstract
36
+ self.abstract
37
+ end
38
+
39
+ if override
40
+ self.override(**override)
41
+ end
42
+
43
+ if overridable
44
+ self.overridable
45
+ end
31
46
  end
32
47
 
33
48
  def params(*unused_positional_params, **params)
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+ # typed: strict
3
+
4
+ # Used as a shortcut for mixing in the three most common "syntax" extensions
5
+ # that Sorbet provides: `sig`, the various sig DSL methods like `abstract` and
6
+ # `override`, and the `final!`/`interface!` etc. syntax for class-level
7
+ # annotations
8
+ module T::Syntax
9
+ include T::Sig
10
+ include T::DefMods
11
+ include T::Helpers
12
+
13
+ # ===== NOTE: Must keep in sync with `T::Sig`! ==============================
14
+ #
15
+ # However, there are some slight differences:
16
+ #
17
+ # - We don't need the extra `include ... MethodHooks` lines, because those
18
+ # come from the `include T::Sig` (c.f. `T::DefMods` though, where those
19
+ # extra `include` *are* required because there is otherwise no inheritance
20
+ # relationship between `T::Sig` and `T::DefMods`)
21
+ #
22
+ # - We don't do the TOP_SELF things, because it's not clear that you ever
23
+ # really want this for TOP_SELF. e.g. what would it mean to write
24
+ # `interface!` there?
25
+ #
26
+ # Rather than encourage people to write `extend T::Syntax` in their script
27
+ # top-levels, let's encourage people to just write `extend T::Sig` to keep
28
+ # things simpler.
29
+ #
30
+ # (We could revisit this in the future if people do really want this.)
31
+
32
+ private_class_method def self.included(other)
33
+ return unless Module == other
34
+ other.prepend(T::Private::Methods::MethodHooks)
35
+ end
36
+
37
+ private_class_method def self.extended(other)
38
+ return unless Module.===(other) && other.singleton_class?
39
+ other.include(T::Private::Methods::SingletonMethodHooks)
40
+ end
41
+ # ===========================================================================
42
+ end
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.6.13294
4
+ version: 0.6.13295
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
@@ -162,6 +162,7 @@ files:
162
162
  - lib/types/boolean.rb
163
163
  - lib/types/compatibility_patches.rb
164
164
  - lib/types/configuration.rb
165
+ - lib/types/def_mods.rb
165
166
  - lib/types/enum.rb
166
167
  - lib/types/generic.rb
167
168
  - lib/types/helpers.rb
@@ -212,6 +213,7 @@ files:
212
213
  - lib/types/props/weak_constructor.rb
213
214
  - lib/types/sig.rb
214
215
  - lib/types/struct.rb
216
+ - lib/types/syntax.rb
215
217
  - lib/types/types/anything.rb
216
218
  - lib/types/types/attached_class.rb
217
219
  - lib/types/types/base.rb