Module: Tapioca::Runtime::GenericTypeRegistry
- Extended by:
- T::Sig
- Defined in:
- lib/tapioca/runtime/generic_type_registry.rb
Overview
This class is responsible for storing and looking up information related to generic types.
The class stores 2 different kinds of data, in two separate lookup tables:
1. a lookup of generic type instances by name: `@generic_instances`
2. a lookup of type variable serializer by constant and type variable
instance: `@type_variables`
By storing the above data, we can cheaply query each constant against this registry to see if it declares any generic type variables. This becomes a simple lookup in the ‘@type_variables` hash table with the given constant.
If there is no entry, then we can cheaply know that we can skip generic type information generation for this type.
On the other hand, if we get a result, then the result will be a hash of type variable to type variable serializers. This allows us to associate type variables to the constant names that represent them, easily.
Defined Under Namespace
Classes: GenericType
Class Method Summary collapse
-
.generic_type_instance?(instance) ⇒ Boolean
: (Object instance) -> bool.
-
.lookup_type_variables(constant) ⇒ Object
: (Module constant) -> Array?.
-
.register_type(constant, types) ⇒ Object
This method is responsible for building the name of the instantiated concrete type and cloning the given constant so that we can return a type that is the same as the current type but is a different instance and has a different name method.
-
.register_type_variable(constant, type_variable) ⇒ Object
This method is called from intercepted calls to ‘type_member` and `type_template`.
Class Method Details
.generic_type_instance?(instance) ⇒ Boolean
: (Object instance) -> bool
75 76 77 |
# File 'lib/tapioca/runtime/generic_type_registry.rb', line 75 def generic_type_instance?(instance) @generic_instances.values.any? { |generic_type| generic_type === instance } end |
.lookup_type_variables(constant) ⇒ Object
: (Module constant) -> Array?
80 81 82 |
# File 'lib/tapioca/runtime/generic_type_registry.rb', line 80 def lookup_type_variables(constant) @type_variables[constant] end |
.register_type(constant, types) ⇒ Object
This method is responsible for building the name of the instantiated concrete type and cloning the given constant so that we can return a type that is the same as the current type but is a different instance and has a different name method.
We cache those cloned instances by their name in ‘@generic_instances`, so that we don’t keep instantiating a new type every single time it is referenced. For example, ‘[Foo, Foo, Foo, Foo]` will only result in 2 clones (1 for `Foo` and another for `Foo`) and 2 hash lookups (for the other two `Foo`s).
This method returns the created or cached clone of the constant. : (untyped constant, untyped types) -> Module
60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/tapioca/runtime/generic_type_registry.rb', line 60 def register_type(constant, types) # Build the name of the instantiated generic type, # something like `"Foo[X, Y, Z]"` type_list = types.map { |type| T::Utils.coerce(type).name }.join(", ") name = "#{Reflection.name_of(constant)}[#{type_list}]" # Create a generic type with an overridden `name` # method that returns the name we constructed above. # # Also, we try to memoize the generic type based on the name, so that # we don't have to keep recreating them all the time. @generic_instances[name] ||= create_generic_type(constant, name) end |
.register_type_variable(constant, type_variable) ⇒ Object
This method is called from intercepted calls to ‘type_member` and `type_template`. We get passed all the arguments to those methods, as well as the `T::Types::TypeVariable` instance generated by the Sorbet defined `type_member`/`type_template` call on `T::Generic`.
This method creates a ‘String` with that data and stores it in the `@type_variables` lookup table, keyed by the `constant` and `type_variable`.
Finally, the original ‘type_variable` is returned from this method, so that the caller can return it from the original methods as well. : (untyped constant, TypeVariableModule type_variable) -> void
94 95 96 97 98 |
# File 'lib/tapioca/runtime/generic_type_registry.rb', line 94 def register_type_variable(constant, type_variable) type_variables = lookup_or_initialize_type_variables(constant) type_variables << type_variable end |