abstract class Crystal::Type
inherits Reference
¶
Abstract base class of all types
Included modules
Crystal::Annotatable
Direct known subclasses
Crystal::GenericClassInstanceMetaclassType
Crystal::GenericInstanceType
Crystal::GenericModuleInstanceMetaclassType
Crystal::LiteralType
Crystal::NamedType
Crystal::TypeParameter
Crystal::TypeSplat
Crystal::UnionType
Crystal::VirtualMetaclassType
Crystal::VirtualType
Constants¶
ONE_ARG = [Arg.new("a1")]
¶
[Arg.new("a1")]
SuggestableDefName = /\A[a-z_]/
¶
/\A[a-z_]/
Class methods¶
Methods¶
#abstract_leaf?
¶
Returns true if this type is abstract and it has no
concrete subclasses. This can happen if this type has abstract
subclasses, or non-abstract generic subclasses without instantiations.
#all?
¶
Yields self and returns true if the block returns a truthy value. UnionType overrides it and yields all types in turn and returns true if for each of them the block returns true.
#all_subclasses
¶
Returns all subclasses of this type, including subclasses of subclasses recursively.
#allowed_in_lib?
¶
Returns true if this type can be used in a lib declaration:
in a fun, struct/union member, or typedef.
#allows_instance_vars?
¶
Returns true if this type can have instance vars.
Primitive types, and types like Reference and Object,
can't have instance vars.
#can_be_stored?
¶
Returns true if this type can be assigned to an instance or class
variable, or used in a generic type argument.
As of now, abstract base type such as Object, Reference, Value,
Int, and unbound generic types such as Array(T), can't be stored.
#check_restriction_exception
¶
Checks whether an exception needs to be raised because of a restriction failure. Only overwritten by literal types (NumberLiteralType and SymbolLiteralType) when they produce an ambiguous call.
#class_var_owner
¶
Returns the type that owns class vars for a type.
This method returns self, but subclasses might override. For example, a metaclass' class_var_owner is the instance type.
#defs : Hash(String, Array(DefWithMetadata))?
¶
: Hash(String, Array(DefWithMetadata))?
Returns the methods defined in this type, indexed by their name. This does not include methods defined in ancestors.
#devirtualize
¶
Returns the non-virtual type of a given type (returns self if self is already non-virtual)
#each_namespace(& : ModuleType -> ) : Nil
¶
(& : ModuleType -> ) : Nil
Yields each namespace this type belongs to, excluding the Program itself.
#extern?
¶
Returns true if this is an extern C struct or union (extern_union? tells which one)
#has_inner_pointers?
¶
Returns true if the type has inner pointers.
This is useful to know because if a type doesn't have
inner pointers we can use malloc_atomic instead of
malloc in Pointer.malloc for a tiny performance boost.
This behaviour is documented in Pointer.malloc
#has_protected_access_to?(type, allow_same_namespace = true)
¶
(type, allow_same_namespace = true)
Determines if self can access type assuming it's a protected access.
If allow_same_namespace is true (the default), protected also means
the types are in the same namespace. Otherwise, it means they are just
in the same type hierarchy.
#implicitly_converted_in_c_to?(expected_type)
¶
(expected_type)
Returns true if this type can be implicitly converted to
expected_type when this is a lib fun argument, without
involving to_unsafe or numeric conversions.
For example nil can be passed to an argument of type pointer.
#inspect(io : IO) : Nil
¶
(io : IO) : Nil
Appends a String representation of this object which includes its class name, its object address and the values of all instance variables.
class Person
def initialize(@name : String, @age : Int32)
end
end
Person.new("John", 32).inspect # => #<Person:0x10fd31f20 @name="John", @age=32>
#lookup_defs(name : String, all_defs : Array(Def), lookup_ancestors_for_new : Bool? = false)
¶
(name : String, all_defs : Array(Def), lookup_ancestors_for_new : Bool? = false)
#lookup_macro(name, args : Array, named_args)
¶
(name, args : Array, named_args)
Looks up a macro with the given name and matching the given args
and named_args. Returns:
- a Macro, if found
- nil, if not found
- DefInMacroLookup if not found and a Def was found instead
In the case of DefInMacroLookup, it means that macros shouldn't
be looked up in implicit enclosing scopes such as Object
or the Program.
#lookup_macros(name)
¶
(name)
Looks up macros with the given name. Returns:
- an Array of Macro if found
- nil if not found
- DefInMacroLookup if not found and some Defs were found instead
#lookup_matches(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)
¶
(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)
#lookup_matches_with_modules(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)
¶
(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)
#lookup_matches_without_parents(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)
¶
(signature, owner = self, path_lookup = self, matches_array = nil, analyze_all = false)
#lookup_new_in_ancestors?
¶
Should new be looked up in ancestors?
This is true if this type doesn't define any
initialize methods.
#lookup_path(names : Array(String), lookup_in_namespace = true, include_private = false, location = nil) : Type | ASTNode | Nil
¶
(names : Array(String), lookup_in_namespace = true, include_private = false, location = nil) : Type | ASTNode | Nil
Looks up a path (for example: Foo::Bar::Baz) relative to self.
For example, given:
class Foo
class Bar
class Baz
end
end
end
If self is Foo and we invoke lookup_path(["Bar", "Baz"]) on it,
we'll get Foo::Bar::Baz as the return value.
The path is searched in the current type's ancestors, and optionally in its namespace, according to lookup_in_namespace.
Returns nil if the path can't be found.
include_private controls whether private types are found inside other types (when doing Foo::Bar, Bar won't be found if it's private).
location can be passed and is the location where the lookup happens, and is useful to find file-private types.
The result can be an ASTNode in the case the path denotes a type variable
whose variable is an ASTNode. One such example is the N of StaticArray(T, N)
for some instantiated StaticArray.
If the path is global (for example ::Foo::Bar), the search starts at the top level.
#lookup_path(path : Path, lookup_in_namespace = true, include_private = false, location = path.location) : Type | ASTNode | Nil
¶
(path : Path, lookup_in_namespace = true, include_private = false, location = path.location) : Type | ASTNode | Nil
Looks up a path (for example: Foo::Bar::Baz) relative to self.
For example, given:
class Foo
class Bar
class Baz
end
end
end
If self is Foo and we invoke lookup_path(["Bar", "Baz"]) on it,
we'll get Foo::Bar::Baz as the return value.
The path is searched in the current type's ancestors, and optionally in its namespace, according to lookup_in_namespace.
Returns nil if the path can't be found.
include_private controls whether private types are found inside other types (when doing Foo::Bar, Bar won't be found if it's private).
location can be passed and is the location where the lookup happens, and is useful to find file-private types.
The result can be an ASTNode in the case the path denotes a type variable
whose variable is an ASTNode. One such example is the N of StaticArray(T, N)
for some instantiated StaticArray.
If the path is global (for example ::Foo::Bar), the search starts at the top level.
#lookup_path_item(name : String, lookup_in_namespace, include_private, location) : Type | ASTNode | Nil
¶
(name : String, lookup_in_namespace, include_private, location) : Type | ASTNode | Nil
Looks up a single path item relative to *self`.
If lookup_in_namespace is true, if the type is not found
in self or self's parents, the path item is searched in this
type's namespace. This parameter is useful because when writing
Foo::Bar::Baz, Foo should be searched in enclosing namespaces,
but Bar and Baz not.
#lookup_type(node : ASTNode, self_type = self.instance_type, allow_typeof = true, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true) : Type
¶
(node : ASTNode, self_type = self.instance_type, allow_typeof = true, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true) : Type
Searches the type that corresponds to the given node, relative
to self.
This method handles AST nodes in the type grammar:
- Path: Foo::Bar::Baz
- Union: T | U
- Metaclass: T.class
- Generic: Foo(T)
- ProcNotation: T -> U
- TypeOf: typeof(...)
- Self: self
Passing other AST nodes will raise an exception.
self_type is the type that will be used when self is encountered
in the node.
If allow_typeof is false, this method raises if there's a typeof
in the given node.
If free_vars is given, when resolving a Path, types will be first searched in the given Hash.
If find_root_generic_type_parameters is true (the default), type parameters
relative to self_type will be found. If false, they won't be found.
For example, given:
class Foo
class Bar(T)
end
class Baz
end
end
If self is Foo and Bar(Baz) is given, the result will be Foo::Bar(Baz).
#lookup_type?(node : ASTNode, self_type = self.instance_type, allow_typeof = true, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true) : Type?
¶
(node : ASTNode, self_type = self.instance_type, allow_typeof = true, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true) : Type?
Similar to lookup_type, but returns nil if a type can't be found.
#lookup_type_var(node : Path, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true, remove_alias = true) : Type | ASTNode
¶
(node : Path, free_vars : Hash(String, TypeVar)? = nil, find_root_generic_type_parameters = true, remove_alias = true) : Type | ASTNode
Similar to lookup_type, but the result might also be an ASTNode, for example when
looking N relative to a StaticArray.
#lookup_type_var?(node : Path, free_vars : Hash(String, TypeVar)? = nil, raise = false, find_root_generic_type_parameters = true) : Type | ASTNode | Nil
¶
(node : Path, free_vars : Hash(String, TypeVar)? = nil, raise = false, find_root_generic_type_parameters = true) : Type | ASTNode | Nil
Similar to lookup_type_var, but might return nil.
#macros : Hash(String, Array(Macro))?
¶
: Hash(String, Array(Macro))?
Returns all macros defines in this type, indexed by their name. This does not include methods defined in ancestors.
#metaclass : Type
¶
: Type
Returns this type's metaclass, which holds class methods for this type.
#namespace : ModuleType
¶
: ModuleType
The namespace this type belongs to. Every type belongs to
a namespace, and, when not explicit, the namespace is the Program itself.
#opaque_id
¶
An opaque id of every type. 0 for Nil, non zero for others, so we can sort types by opaque_id and have Nil in the beginning.
#packed?
¶
Returns true if this type has the @[Packed] annotation on it
(only applicable for C structs)
#passed_as_self?
¶
Returns true if this type is passed as a self argument
in the codegen phase. For example a method whose receiver is
the Program, or a Metaclass, doesn't have a self argument.
#passed_by_value?
¶
Returns true if this type passed by value (if it's not a primitive type).
In the codegen phase these types are passed as byval pointers.
#reference_like?
¶
Returns true if this type inherits from Reference or if this
is a union type where all types are reference types or nil.
In this case this type can be represented with a single pointer.
#replace_type_parameters(instance) : Type
¶
(instance) : Type
Replace type parameters in this type with the type parameters of the given instance type.
#sizeof_type
¶
Returns the type that has to be used in sizeof and instance_sizeof computations
#to_s(io : IO) : Nil
¶
(io : IO) : Nil
Appends a short String representation of this object which includes its class name and its object address.
class Person
def initialize(@name : String, @age : Int32)
end
end
Person.new("John", 32).to_s # => #<Person:0x10a199f20>
abstract
#to_s_with_options(io : IO, skip_union_parens : Bool = false, generic_args : Bool = true, codegen : Bool = false) : Nil
¶
(io : IO, skip_union_parens : Bool = false, generic_args : Bool = true, codegen : Bool = false) : Nil
#type_var?(name)
¶
(name)
Returns true if name if an unbound type variable in this (generic) type.