Module: T
- Defined in:
- lib/types/_types.rb,
lib/types/boolean.rb,
lib/sorbet-runtime.rb,
lib/types/compatibility_patches.rb,
lib/types/compatibility_patches.rb,
lib/types/compatibility_patches.rb
Overview
Work around for sorbet-runtime wrapped methods.
When a sig is defined, sorbet-runtime will replace the sigged method with a wrapper. Those wrapper methods look like ‘foo(*args, &blk)` so that wrappers can handle and pass on all the arguments supplied.
However, that creates a problem with runtime reflection on the methods, since when a sigged method is introspected, it will always return its ‘arity` as `-1`, its `parameters` as `[[:rest, :args], [:block, :blk]]`, and its `source_location` as `[<some_file_in_sorbet>, <some_line_number>]`.
This might be a problem for some applications that rely on getting the correct information from these methods.
This compatibility module, when prepended to the ‘Method` class, would fix the return values of `arity`, `parameters` and `source_location`.
Defined Under Namespace
Modules: AbstractUtils, Array, Class, CompatibilityPatches, Configuration, DefMods, Enumerable, Enumerator, Generic, Hash, Helpers, Module, Private, Props, Range, Set, Sig, Syntax, Types, Utils Classes: Enum, ImmutableStruct, InexactStruct, Struct
Constant Summary collapse
- Boolean =
T::Boolean is a type alias helper for the common ‘T.any(TrueClass, FalseClass)`. Defined separately from _types.rb because it has a dependency on T::Types::Union.
T.type_alias { T.any(TrueClass, FalseClass) }
Class Method Summary collapse
-
.absurd(value) ⇒ Object
A way to ask Sorbet to prove that a certain branch of control flow never happens.
-
.all(type_a, type_b, *types) ⇒ Object
T.all(<Type>, <Type>, …) – matches an object that has all of the types listed.
-
.any(type_a, type_b, *types) ⇒ Object
T.any(<Type>, <Type>, …) – matches any of the types listed.
- .anything ⇒ Object
-
.assert_type!(value, type, checked: true) ⇒ Object
Tells the typechecker to ensure that ‘value` is of type `type` (if not, the typechecker will fail).
-
.attached_class ⇒ Object
Matches the instance type in a singleton-class context.
-
.bind(value, type, checked: true) ⇒ Object
Tells the type checker to treat ‘self` in the current block as `type`.
-
.cast(value, type, checked: true) ⇒ Object
Tells the typechecker that ‘value` is of type `type`.
-
.class_of(klass) ⇒ Object
Matches any class that subclasses or includes the provided class or module.
-
.deprecated_enum(values) ⇒ Object
deprecated
Deprecated.
Use T::Enum instead.
-
.let(value, type, checked: true) ⇒ Object
Tells the typechecker to declare a variable of type ‘type`.
-
.must(arg) ⇒ Object
A convenience method to ‘raise` when the argument is `nil` and return it otherwise.
-
.must_because(arg) ⇒ Object
A convenience method to ‘raise` with a provided error reason when the argument is `nil` and return it otherwise.
-
.nilable(type) ⇒ Object
Shorthand for T.any(type, NilClass).
-
.noreturn ⇒ Object
Indicates a function never returns (e.g. “Kernel#raise”).
-
.proc ⇒ Object
Creates a proc type.
-
.reveal_type(value) ⇒ Object
A way to ask Sorbet to show what type it thinks an expression has.
-
.self_type ⇒ Object
Matches ‘self`:.
-
.type_alias(type = nil, &blk) ⇒ Object
Constructs a type alias.
-
.type_parameter(name) ⇒ Object
References a type parameter which was previously defined with ‘type_parameters`.
-
.unsafe(value) ⇒ Object
For the static type checker, strips all type information from a value and returns the same value, but statically-typed as ‘T.untyped`.
-
.untyped ⇒ Object
Matches any object.
Class Method Details
.absurd(value) ⇒ Object
A way to ask Sorbet to prove that a certain branch of control flow never happens. Commonly used to assert that a case or if statement exhausts all possible cases.
302 303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/types/_types.rb', line 302 def self.absurd(value) msg = "Control flow reached T.absurd." case value when Kernel msg += " Got value: #{value}" end begin raise TypeError.new(msg) rescue TypeError => e # raise into rescue to ensure e.backtrace is populated T::Configuration.inline_type_error_handler(e, {kind: 'T.absurd', value: value, type: nil}) end end |
.all(type_a, type_b, *types) ⇒ Object
T.all(<Type>, <Type>, …) – matches an object that has all of the types listed
55 56 57 |
# File 'lib/types/_types.rb', line 55 def self.all(type_a, type_b, *types) T::Types::Intersection.new([type_a, type_b] + types) end |
.any(type_a, type_b, *types) ⇒ Object
T.any(<Type>, <Type>, …) – matches any of the types listed
27 28 29 30 31 32 |
# File 'lib/types/_types.rb', line 27 def self.any(type_a, type_b, *types) type_a = T::Utils.coerce(type_a) type_b = T::Utils.coerce(type_b) types = types.map { |t| T::Utils.coerce(t) } if !types.empty? T::Types::Union::Private::Pool.union_of_types(type_a, type_b, types) end |
.anything ⇒ Object
50 51 52 |
# File 'lib/types/_types.rb', line 50 def self.anything T::Types::Anything::Private::INSTANCE end |
.assert_type!(value, type, checked: true) ⇒ Object
Tells the typechecker to ensure that ‘value` is of type `type` (if not, the typechecker will fail). Use this for debugging typechecking errors, or to ensure that type information is statically known and being checked appropriately. If `checked` is true, raises an exception at runtime if the value doesn’t match the type.
206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/types/_types.rb', line 206 def self.assert_type!(value, type, checked: true) return value unless checked # Happy paths for Module literals and T.nilable; see T.cast. case type when ::Module return value if value.is_a?(type) when T::Private::Types::SimplePairUnion return value if type.valid?(value) end Private::Casts.cast(value, type, "T.assert_type!") end |
.attached_class ⇒ Object
Matches the instance type in a singleton-class context
76 77 78 |
# File 'lib/types/_types.rb', line 76 def self.attached_class T::Types::AttachedClassType::Private::INSTANCE end |
.bind(value, type, checked: true) ⇒ Object
Tells the type checker to treat ‘self` in the current block as `type`. Useful for blocks that are captured and executed later with instance_exec. Use like:
seconds = lambda do
T.bind(self, NewBinding)
...
end
‘T.bind` behaves like `T.cast` in that it is assumed to be true statically.
If ‘checked` is true, raises an exception at runtime if the value doesn’t match the type (this is the default).
188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/types/_types.rb', line 188 def self.bind(value, type, checked: true) return value unless checked # Happy paths for Module literals and T.nilable; see T.cast. case type when ::Module return value if value.is_a?(type) when T::Private::Types::SimplePairUnion return value if type.valid?(value) end Private::Casts.cast(value, type, "T.bind") end |
.cast(value, type, checked: true) ⇒ Object
Tells the typechecker that ‘value` is of type `type`. Use this to get additional checking after an expression that the typechecker is unable to analyze. If `checked` is true, raises an exception at runtime if the value doesn’t match the type.
Compared to ‘T.let`, `T.cast` is trusted by static system.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/types/_types.rb', line 134 def self.cast(value, type, checked: true) return value unless checked # Happy paths for the two dominant type shapes at inline-cast sites, # duplicated from Private::Casts.cast to skip its call frame: Module # literals (e.g. `T.cast(x, Foo)`) and the SimplePairUnion that # `T.nilable(SomeModule)` produces. Failures and other type shapes take # the full path below. case type when ::Module return value if value.is_a?(type) when T::Private::Types::SimplePairUnion return value if type.valid?(value) end Private::Casts.cast(value, type, "T.cast") end |
.class_of(klass) ⇒ Object
Matches any class that subclasses or includes the provided class or module
82 83 84 |
# File 'lib/types/_types.rb', line 82 def self.class_of(klass) T::Types::ClassOf.new(klass) end |
.deprecated_enum(values) ⇒ Object
Use T::Enum instead.
Matches any of the listed values
61 62 63 |
# File 'lib/types/_types.rb', line 61 def self.deprecated_enum(values) T::Types::Enum.new(values) end |
.let(value, type, checked: true) ⇒ Object
Tells the typechecker to declare a variable of type ‘type`. Use like:
seconds = T.let(0.0, Float)
Compared to ‘T.cast`, `T.let` is checked by static system.
If ‘checked` is true, raises an exception at runtime if the value doesn’t match the type.
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/types/_types.rb', line 161 def self.let(value, type, checked: true) return value unless checked # Happy paths for Module literals and T.nilable; see T.cast. case type when ::Module return value if value.is_a?(type) when T::Private::Types::SimplePairUnion return value if type.valid?(value) end Private::Casts.cast(value, type, "T.let") end |
.must(arg) ⇒ Object
A convenience method to ‘raise` when the argument is `nil` and return it otherwise.
Intended to be used as:
needs_foo(T.must(maybe_gives_foo))
Equivalent to:
foo = maybe_gives_foo
raise "nil" if foo.nil?
needs_foo(foo)
Intended to be used to promise sorbet that a given nilable value happens to contain a non-nil value at this point.
‘sig T.nilable(A)).returns(A)`
253 254 255 256 257 258 259 260 261 262 |
# File 'lib/types/_types.rb', line 253 def self.must(arg) return arg if arg return arg if arg == false begin raise TypeError.new("Passed `nil` into T.must") rescue TypeError => e # raise into rescue to ensure e.backtrace is populated T::Configuration.inline_type_error_handler(e, {kind: 'T.must', value: arg, type: nil}) end end |
.must_because(arg) ⇒ Object
A convenience method to ‘raise` with a provided error reason when the argument is `nil` and return it otherwise.
Intended to be used as:
needs_foo(T.must_because(maybe_gives_foo) {"reason_foo_should_not_be_nil"})
Equivalent to:
foo = maybe_gives_foo
raise "reason_foo_should_not_be_nil" if foo.nil?
needs_foo(foo)
Intended to be used to promise sorbet that a given nilable value happens to contain a non-nil value at this point.
‘sig T.nilable(A), reason_blk: T.proc.returns(String)).returns(A)`
281 282 283 284 285 286 287 288 289 290 |
# File 'lib/types/_types.rb', line 281 def self.must_because(arg) return arg if arg return arg if arg == false begin raise TypeError.new("Unexpected `nil` because #{yield}") rescue TypeError => e # raise into rescue to ensure e.backtrace is populated T::Configuration.inline_type_error_handler(e, {kind: 'T.must_because', value: arg, type: nil}) end end |
.nilable(type) ⇒ Object
Shorthand for T.any(type, NilClass)
35 36 37 |
# File 'lib/types/_types.rb', line 35 def self.nilable(type) T::Types::Union::Private::Pool.union_of_types(T::Utils.coerce(type), T::Utils::Nilable::NIL_TYPE) end |
.noreturn ⇒ Object
Indicates a function never returns (e.g. “Kernel#raise”)
46 47 48 |
# File 'lib/types/_types.rb', line 46 def self.noreturn T::Types::NoReturn::Private::INSTANCE end |
.proc ⇒ Object
Creates a proc type
66 67 68 |
# File 'lib/types/_types.rb', line 66 def self.proc T::Private::Methods.start_proc end |
.reveal_type(value) ⇒ Object
A way to ask Sorbet to show what type it thinks an expression has. This can be useful for debugging and checking assumptions. In the runtime, merely returns the value passed in.
295 296 297 |
# File 'lib/types/_types.rb', line 295 def self.reveal_type(value) value end |
.self_type ⇒ Object
Matches ‘self`:
71 72 73 |
# File 'lib/types/_types.rb', line 71 def self.self_type T::Types::SelfType::Private::INSTANCE end |
.type_alias(type = nil, &blk) ⇒ Object
Constructs a type alias. Used to create a short name for a larger type. In Ruby this returns a wrapper that contains a proc that is evaluated to get the underlying type. This syntax however is needed for support by the static checker.
The name of the type alias is not preserved; Error messages will be printed with reference to the underlying type.
TODO Remove ‘type` parameter. This was left in to make life easier while migrating.
104 105 106 107 108 109 110 |
# File 'lib/types/_types.rb', line 104 def self.type_alias(type=nil, &blk) if blk T::Private::Types::TypeAlias.new(blk) else T::Utils.coerce(type) end end |
.type_parameter(name) ⇒ Object
References a type parameter which was previously defined with ‘type_parameters`.
This is used for generic methods.
125 126 127 |
# File 'lib/types/_types.rb', line 125 def self.type_parameter(name) T::Types::TypeParameter.make(name) end |
.unsafe(value) ⇒ Object
For the static type checker, strips all type information from a value and returns the same value, but statically-typed as ‘T.untyped`. Can be used to tell the static checker to “trust you” by discarding type information you know to be incorrect. Use with care! (This has no effect at runtime.)
We can’t actually write this sig because we ourselves are inside the ‘T::` module and doing this would create a bootstrapping cycle. However, we also don’t actually need to do so; An untyped identity method works just as well here.
‘sig T.untyped).returns(T.untyped)`
232 233 234 |
# File 'lib/types/_types.rb', line 232 def self.unsafe(value) value end |