MType are global to the model; it means that a MType
is not bound to a
specific MModule
.
This characteristic helps the reasoning about static types in a program
since a single MType
object always denote the same type.
However, because a MType
is global, it does not really have properties
nor have subtypes to a hierarchy since the property and the class hierarchy
depends of a module.
Moreover, virtual types an formal generic parameter types also depends on
a receiver to have sense.
Therefore, most method of the types require a module and an anchor. The module is used to know what are the classes and the specialization links. The anchor is used to know what is the bound of the virtual types and formal generic parameter types.
MType are not directly usable to get properties. See the anchor_to
method
and the MClassType
class.
FIXME: the order of the parameters is not the best. We mus pick on from:
nitc :: MType :: _as_nullable_cache
nitc :: MType :: _is_java_primitive
Is the associated Java type a primitive one?nitc :: MType :: as_nullable_cache
nitc :: MType :: as_nullable_cache=
nitc :: MType :: call_arg_field
Field to store this type in the C structurenit_call_arg
nitc :: MType :: can_resolve_for
Can the type be resolved?nitc :: MType :: cname_blind
Representation of this type in C for the internal of the systemnitc :: MType :: cname_normal_class
Name of this type in C for normal classes (not extern and not primitive)nitc :: MType :: collect_mclassdefs
Compute all the classdefs inherited/imported.nitc :: MType :: collect_mclasses
Compute all the super-classes.nitc :: MType :: collect_mtypes
Compute all the declared super-types.nitc :: MType :: compile_extern_type
nitc :: MType :: ctype_extern
C type outside of the compiler code and in boxesnitc :: MType :: defaultinit
nitc :: MType :: gen_arg_convert
Write code intemplate
to parse the argument arg_name
to this parameter type
nitc :: MType :: has_mproperty
Is the property in self for a given modulenitc :: MType :: is_cprimitive
Does this type have a primitive representation?nitc :: MType :: is_java_primitive
Is the associated Java type a primitive one?nitc :: MType :: is_java_primitive=
Is the associated Java type a primitive one?nitc :: MType :: is_legal_in
Is the type legal in a givenmmodule
(with an optional anchor
)?
nitc :: MType :: is_subtype
Return true ifself
is an subtype of sup
.
nitc :: MType :: is_subtype_invar
Return true ifself
is a invariant subtype of sup
.
nitc :: MType :: java_is_nit_object
Is this type opaque in Java? As so it is represented bynit.app.NitObject
.
nitc :: MType :: jni_signature_alt
Type name appearing within JNI function names.nitc :: MType :: lookup_bound
Resolve formal type to its verbatim bound.nitc :: MType :: lookup_fixed
Resolve the formal type to its simplest equivalent form.nitc :: MType :: mangled_cname
Representation of this type in mangled Cnitc :: MType :: need_anchor
Doesself
contain a virtual type or a formal generic parameter type?
nitc :: MType :: needs_type_check
Does this parameter type needs to be checked before calling the method?nitc :: MType :: resolve_for
Replace formals generic types in self with resolved values inmtype
nitc :: MType :: signature_depth
nitc :: MType :: supertype_to
Return the supertype when adapted to a class.nitc :: on_demand_compiler $ MType :: cname_blind
The interpreter FFI usevoid*
to represent intern data types
nitc :: java $ MType :: compile_callback_to_java
Compile C and Java code to implement this callbacknitc :: api_base $ MType :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: json_model $ MType :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: astbuilder $ MType :: create_ast_representation
Build a ANode fromself
nitc :: html_model $ MType :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: java $ MType :: jni_methods_declaration
Returns the list of C functions to link with extern Java methods, as requirednitc :: MType :: _as_nullable_cache
nitc :: MEntity :: _const_color
nitc :: MEntity :: _css_classes
CSS classes used to decorateself
nitc :: MEntity :: _deprecation
Is the entity deprecated?nitc :: MEntity :: _html_full_name
The MEntityfull_name
escaped for HTML
nitc :: MEntity :: _is_broken
The indication that the entity did not pass some semantic verifications.nitc :: MType :: _is_java_primitive
Is the associated Java type a primitive one?serialization :: Serializable :: accept_inspect_serializer_core
serialization :: Serializable :: accept_json_serializer
Refinable service to customize the serialization of this class to JSONserialization :: Serializable :: accept_msgpack_attribute_counter
Hook to customize the behavior of theAttributeCounter
serialization :: Serializable :: accept_msgpack_serializer
Hook to customize the serialization of this class to MessagePacknitc :: MEntity :: add_doc_to_infobox
Append an entry for the doc in the given infoboxserialization :: Serializable :: add_to_bundle
Called by[]=
to dynamically choose the appropriate method according
nitc :: MType :: as_nullable_cache
nitc :: MType :: as_nullable_cache=
nitc :: MType :: call_arg_field
Field to store this type in the C structurenit_call_arg
nitc :: MType :: can_resolve_for
Can the type be resolved?core :: Object :: class_factory
Implementation used byget_class
to create the specific class.
nitc :: MType :: cname_blind
Representation of this type in C for the internal of the systemnitc :: MType :: cname_normal_class
Name of this type in C for normal classes (not extern and not primitive)nitc :: MEntity :: collect_ancestors
Collectself
ancestors (direct and indirect)
nitc :: MEntity :: collect_children
Collectself
children (direct descendants)
nitc :: MEntity :: collect_descendants
Collectself
descendants (direct and direct)
nitc :: MEntity :: collect_linearization
Collectself
linearization anchored on mainmodule
nitc :: MType :: collect_mclassdefs
Compute all the classdefs inherited/imported.nitc :: MType :: collect_mclasses
Compute all the super-classes.nitc :: MEntity :: collect_metrics
nitc :: MEntity :: collect_modifiers
Collect modifier keywords likeredef
, private
etc
nitc :: MType :: collect_mtypes
Compute all the declared super-types.nitc :: MEntity :: collect_parents
Collectself
parents (direct ancestors)
nitc :: NitniCallback :: compile_callback_to_java
Compile C and Java code to implement this callbacknitc :: NitniCallback :: compile_callback_to_objc
Compile this callback to be callable from Objective-Cnitc :: MType :: compile_extern_type
nitc :: MEntity :: const_color
nitc :: MEntity :: const_color=
nitc :: MEntity :: core_serialize_base
serialization :: Serializable :: core_serialize_to
Actual serialization ofself
to serializer
nitc :: MEntity :: create_ast_representation
Build a ANode fromself
nitc :: MEntity :: cs_comment
Returns the comment of this MEntity formatted for console.nitc :: MEntity :: cs_declaration
Returns the complete MEntity declaration (modifiers + name + signature).nitc :: MEntity :: cs_full_name
Returnsself.full_name
formatted for console
nitc :: MEntity :: cs_list_item
Returnsself
as a list element that can be displayed in console.
nitc :: MEntity :: cs_location
Source code location of this MEntity formatted for consolenitc :: MEntity :: cs_short_comment
Returns the comment of this MEntity formatted for console.nitc :: MEntity :: cs_signature
Returnsself
signature formatted for console.
nitc :: MEntity :: cs_source_code
Source code associated to this MEntity.nitc :: MEntity :: css_classes=
CSS classes used to decorateself
nitc :: MType :: ctype_extern
C type outside of the compiler code and in boxesnitc :: MEntity :: defaultinit
core :: Object :: defaultinit
nitc :: HInfoBoxable :: defaultinit
nitc :: NitniCallback :: defaultinit
nitc :: MType :: defaultinit
nitc :: MEntity :: deprecation=
Is the entity deprecated?nitc :: MEntity :: field_separator
serialization :: Serializable :: from_deserializer
Create an instance of this class from thedeserializer
nitc :: MType :: gen_arg_convert
Write code intemplate
to parse the argument arg_name
to this parameter type
nitc :: MType :: has_mproperty
Is the property in self for a given modulenitc :: MEntity :: hierarchy_poset
Build a poset representingself
in it's own hierarchy
nitc :: MEntity :: html_declaration
Returns the complete MEntity declaration decorated with HTMLnitc :: MEntity :: html_full_name=
The MEntityfull_name
escaped for HTML
nitc :: MEntity :: html_name=
The MEntity name escaped for HTMLnitc :: MEntity :: html_namespace
Returnsfull_name
decorated with HTML links
nitc :: MEntity :: html_signature
Returns the MEntity signature decorated with HTMLnitc :: HInfoBoxable :: infobox
An new infobox documenting the entitynitc :: MEntity :: is_broken=
The indication that the entity did not pass some semantic verifications.nitc :: MType :: is_cprimitive
Does this type have a primitive representation?nitc :: MEntity :: is_fictive=
Isself
created for internal purpose?
nitc :: MType :: is_java_primitive
Is the associated Java type a primitive one?nitc :: MType :: is_java_primitive=
Is the associated Java type a primitive one?nitc :: MType :: is_legal_in
Is the type legal in a givenmmodule
(with an optional anchor
)?
core :: Object :: is_same_instance
Return true ifself
and other
are the same instance (i.e. same identity).
core :: Object :: is_same_serialized
Isself
the same as other
in a serialization context?
core :: Object :: is_same_type
Return true ifself
and other
have the same dynamic type.
nitc :: MType :: is_subtype
Return true ifself
is an subtype of sup
.
nitc :: MType :: is_subtype_invar
Return true ifself
is a invariant subtype of sup
.
nitc :: MType :: java_is_nit_object
Is this type opaque in Java? As so it is represented bynit.app.NitObject
.
nitc :: NitniCallback :: jni_methods_declaration
Returns the list of C functions to link with extern Java methods, as requirednitc :: MType :: jni_signature_alt
Type name appearing within JNI function names.nitc :: MEntity :: json_namespace
Returnself.full_name
as an object that can be serialized to json.
nitc :: MEntity :: line_separator
nitc :: MEntity :: linkto_text
Link to theself
with a specific text.
nitc :: MType :: lookup_bound
Resolve formal type to its verbatim bound.nitc :: MType :: lookup_fixed
Resolve the formal type to its simplest equivalent form.nitc :: MType :: mangled_cname
Representation of this type in mangled Cnitc :: MEntity :: mdoc_or_fallback
The documentation associated to the entity or their main nested entity.serialization :: Serializable :: msgpack_extra_array_items
Hook to request a larger than usual metadata arraycore :: Object :: native_class_name
The class name of the object in CString format.nitc :: MType :: need_anchor
Doesself
contain a virtual type or a formal generic parameter type?
nitc :: MType :: needs_type_check
Does this parameter type needs to be checked before calling the method?core :: Object :: output_class_name
Display class name on stdout (debug only).mentity
nitc :: MEntity :: ratings_by_dimension
Get the ratings of adimension
nitc :: MType :: resolve_for
Replace formals generic types in self with resolved values inmtype
serialization :: Serializable :: serialize_msgpack
Serializeself
to MessagePack bytes
serialization :: Serializable :: serialize_to
Serializeself
to serializer
serialization :: Serializable :: serialize_to_json
Serializeself
to JSON
serialization :: Serializable :: serialize_to_or_delay
Accept references or force direct serialization (usingserialize_to
)
nitc :: MType :: signature_depth
nitc :: MEntity :: source_url
Render a HTML link for the MEntity locationnitc :: MType :: supertype_to
Return the supertype when adapted to a class.serialization :: Serializable :: to_pretty_json
Serializeself
to plain pretty JSON
nitc :: MEntity :: tpl_module
Builds a dot UML package diagram entity fromself
v.enter_visit
on all nested entities.
nitc :: MEntity :: write_extra_doc
Extra auto documentation to append to thestream
nitc :: MEntity :: write_location
Location (file and line when available) of related declarationsSerializer::serialize
nitc :: MErrorType
A special type used as a silent error marker when building types.
# A global static type
#
# MType are global to the model; it means that a `MType` is not bound to a
# specific `MModule`.
# This characteristic helps the reasoning about static types in a program
# since a single `MType` object always denote the same type.
#
# However, because a `MType` is global, it does not really have properties
# nor have subtypes to a hierarchy since the property and the class hierarchy
# depends of a module.
# Moreover, virtual types an formal generic parameter types also depends on
# a receiver to have sense.
#
# Therefore, most method of the types require a module and an anchor.
# The module is used to know what are the classes and the specialization
# links.
# The anchor is used to know what is the bound of the virtual types and formal
# generic parameter types.
#
# MType are not directly usable to get properties. See the `anchor_to` method
# and the `MClassType` class.
#
# FIXME: the order of the parameters is not the best. We mus pick on from:
# * foo(mmodule, anchor, othertype)
# * foo(othertype, anchor, mmodule)
# * foo(anchor, mmodule, othertype)
# * foo(othertype, mmodule, anchor)
abstract class MType
super MEntity
redef fun name do return to_s
# Return true if `self` is an subtype of `sup`.
# The typing is done using the standard typing policy of Nit.
#
# REQUIRE: `anchor == null implies not self.need_anchor and not sup.need_anchor`
# REQUIRE: `anchor != null implies self.can_resolve_for(anchor, null, mmodule) and sup.can_resolve_for(anchor, null, mmodule)`
fun is_subtype(mmodule: MModule, anchor: nullable MClassType, sup: MType): Bool
do
var sub = self
if sub == sup then return true
#print "1.is {sub} a {sup}? ===="
if anchor == null then
assert not sub.need_anchor
assert not sup.need_anchor
else
# First, resolve the formal types to the simplest equivalent forms in the receiver
assert sub.can_resolve_for(anchor, null, mmodule)
sub = sub.lookup_fixed(mmodule, anchor)
assert sup.can_resolve_for(anchor, null, mmodule)
sup = sup.lookup_fixed(mmodule, anchor)
end
# Does `sup` accept null or not?
# Discard the nullable marker if it exists
var sup_accept_null = false
if sup isa MNullableType then
sup_accept_null = true
sup = sup.mtype
else if sup isa MNotNullType then
sup = sup.mtype
else if sup isa MNullType then
sup_accept_null = true
end
# Can `sub` provide null or not?
# Thus we can match with `sup_accept_null`
# Also discard the nullable marker if it exists
var sub_reject_null = false
if sub isa MNullableType then
if not sup_accept_null then return false
sub = sub.mtype
else if sub isa MNotNullType then
sub_reject_null = true
sub = sub.mtype
else if sub isa MNullType then
return sup_accept_null
end
# Now the case of direct null and nullable is over.
# If `sub` is a formal type, then it is accepted if its bound is accepted
while sub isa MFormalType do
#print "3.is {sub} a {sup}?"
# A unfixed formal type can only accept itself
if sub == sup then return true
assert anchor != null
sub = sub.lookup_bound(mmodule, anchor)
if sub_reject_null then sub = sub.as_notnull
#print "3.is {sub} a {sup}?"
# Manage the second layer of null/nullable
if sub isa MNullableType then
if not sup_accept_null and not sub_reject_null then return false
sub = sub.mtype
else if sub isa MNotNullType then
sub_reject_null = true
sub = sub.mtype
else if sub isa MNullType then
return sup_accept_null
end
end
#print "4.is {sub} a {sup}? <- no more resolution"
if sub isa MBottomType or sub isa MErrorType then
return true
end
assert sub isa MClassType else print_error "{sub} <? {sup}" # It is the only remaining type
# Handle sup-type when the sub-type is class-based (other cases must have be identified before).
if sup isa MFormalType or sup isa MNullType or sup isa MBottomType or sup isa MErrorType then
# These types are not super-types of Class-based types.
return false
end
assert sup isa MClassType else print_error "got {sup} {sub.inspect}" # It is the only remaining type
# Now both are MClassType, we need to dig
if sub == sup then return true
if anchor == null then anchor = sub # UGLY: any anchor will work
var resolved_sub = sub.anchor_to(mmodule, anchor)
var res = resolved_sub.collect_mclasses(mmodule).has(sup.mclass)
if not res then return false
if not sup isa MGenericType then return true
var sub2 = sub.supertype_to(mmodule, anchor, sup.mclass)
assert sub2.mclass == sup.mclass
for i in [0..sup.mclass.arity[ do
var sub_arg = sub2.arguments[i]
var sup_arg = sup.arguments[i]
res = sub_arg.is_subtype(mmodule, anchor, sup_arg)
if not res then return false
end
return true
end
# The base class type on which self is based
#
# This base type is used to get property (an internally to perform
# unsafe type comparison).
#
# Beware: some types (like null) are not based on a class thus this
# method will crash
#
# Basically, this function transform the virtual types and parameter
# types to their bounds.
#
# Example
#
# class A end
# class B super A end
# class X end
# class Y super X end
# class G[T: A]
# type U: X
# end
# class H
# super G[B]
# redef type U: Y
# end
#
# Map[T,U] anchor_to H #-> Map[B,Y]
#
# Explanation of the example:
# In H, T is set to B, because "H super G[B]", and U is bound to Y,
# because "redef type U: Y". Therefore, Map[T, U] is bound to
# Map[B, Y]
#
# REQUIRE: `self.need_anchor implies anchor != null`
# ENSURE: `not self.need_anchor implies result == self`
# ENSURE: `not result.need_anchor`
fun anchor_to(mmodule: MModule, anchor: nullable MClassType): MType
do
if not need_anchor then return self
assert anchor != null and not anchor.need_anchor
# Just resolve to the anchor and clear all the virtual types
var res = self.resolve_for(anchor, null, mmodule, true)
assert not res.need_anchor
return res
end
# Does `self` contain a virtual type or a formal generic parameter type?
# In order to remove those types, you usually want to use `anchor_to`.
fun need_anchor: Bool do return true
# Return the supertype when adapted to a class.
#
# In Nit, for each super-class of a type, there is a equivalent super-type.
#
# Example:
#
# ~~~nitish
# class G[T, U] end
# class H[V] super G[V, Bool] end
#
# H[Int] supertype_to G #-> G[Int, Bool]
# ~~~
#
# REQUIRE: `super_mclass` is a super-class of `self`
# REQUIRE: `self.need_anchor implies anchor != null and self.can_resolve_for(anchor, null, mmodule)`
# ENSURE: `result.mclass = super_mclass`
fun supertype_to(mmodule: MModule, anchor: nullable MClassType, super_mclass: MClass): MClassType
do
if super_mclass.arity == 0 then return super_mclass.mclass_type
if self isa MClassType and self.mclass == super_mclass then return self
var resolved_self
if self.need_anchor then
assert anchor != null
resolved_self = self.anchor_to(mmodule, anchor)
else
resolved_self = self
end
var supertypes = resolved_self.collect_mtypes(mmodule)
for supertype in supertypes do
if supertype.mclass == super_mclass then
# FIXME: Here, we stop on the first goal. Should we check others and detect inconsistencies?
return supertype.resolve_for(self, anchor, mmodule, false)
end
end
abort
end
# Replace formals generic types in self with resolved values in `mtype`
# If `cleanup_virtual` is true, then virtual types are also replaced
# with their bounds.
#
# This function returns self if `need_anchor` is false.
#
# ## Example 1
#
# ~~~
# class G[E] end
# class H[F] super G[F] end
# class X[Z] end
# ~~~
#
# * Array[E].resolve_for(H[Int]) #-> Array[Int]
# * Array[E].resolve_for(G[Z], X[Int]) #-> Array[Z]
#
# Explanation of the example:
# * Array[E].need_anchor is true because there is a formal generic parameter type E
# * E makes sense for H[Int] because E is a formal parameter of G and H specialize G
# * Since "H[F] super G[F]", E is in fact F for H
# * More specifically, in H[Int], E is Int
# * So, in H[Int], Array[E] is Array[Int]
#
# This function is mainly used to inherit a signature.
# Because, unlike `anchor_to`, we do not want a full resolution of
# a type but only an adapted version of it.
#
# ## Example 2
#
# ~~~
# class A[E]
# fun foo(e:E):E is abstract
# end
# class B super A[Int] end
# ~~~
#
# The signature on foo is (e: E): E
# If we resolve the signature for B, we get (e:Int):Int
#
# ## Example 3
#
# ~~~nitish
# class A[E]
# fun foo(e:E):E is abstract
# end
# class C[F]
# var a: A[Array[F]]
# fun bar do a.foo(x) # <- x is here
# end
# ~~~
#
# The first question is: is foo available on `a`?
#
# The static type of a is `A[Array[F]]`, that is an open type.
# in order to find a method `foo`, whe must look at a resolved type.
#
# A[Array[F]].anchor_to(C[nullable Object]) #-> A[Array[nullable Object]]
#
# the method `foo` exists in `A[Array[nullable Object]]`, therefore `foo` exists for `a`.
#
# The next question is: what is the accepted types for `x`?
#
# the signature of `foo` is `foo(e:E)`, thus we must resolve the type E
#
# E.resolve_for(A[Array[F]],C[nullable Object]) #-> Array[F]
#
# The resolution can be done because `E` make sense for the class A (see `can_resolve_for`)
#
# FIXME: the parameter `cleanup_virtual` is just a bad idea, but having
# two function instead of one seems also to be a bad idea.
#
# REQUIRE: `can_resolve_for(mtype, anchor, mmodule)`
# ENSURE: `not self.need_anchor implies result == self`
fun resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule, cleanup_virtual: Bool): MType is abstract
# Resolve formal type to its verbatim bound.
# If the type is not formal, just return self
#
# The result is returned exactly as declared in the "type" property (verbatim).
# So it could be another formal type.
#
# In case of conflicts or inconsistencies in the model, the method returns a `MErrorType`.
fun lookup_bound(mmodule: MModule, resolved_receiver: MType): MType do return self
# Resolve the formal type to its simplest equivalent form.
#
# Formal types are either free or fixed.
# When it is fixed, it means that it is equivalent with a simpler type.
# When a formal type is free, it means that it is only equivalent with itself.
# This method return the most simple equivalent type of `self`.
#
# This method is mainly used for subtype test in order to sanely compare fixed.
#
# By default, return self.
# See the redefinitions for specific behavior in each kind of type.
#
# In case of conflicts or inconsistencies in the model, the method returns a `MErrorType`.
fun lookup_fixed(mmodule: MModule, resolved_receiver: MType): MType do return self
# Is the type a `MErrorType` or contains an `MErrorType`?
#
# `MErrorType` are used in result with conflict or inconsistencies.
#
# See `is_legal_in` to check conformity with generic bounds.
fun is_ok: Bool do return true
# Is the type legal in a given `mmodule` (with an optional `anchor`)?
#
# A type is valid if:
#
# * it does not contain a `MErrorType` (see `is_ok`).
# * its generic formal arguments are within their bounds.
fun is_legal_in(mmodule: MModule, anchor: nullable MClassType): Bool do return is_ok
# Can the type be resolved?
#
# In order to resolve open types, the formal types must make sence.
#
# ## Example
#
# class A[E]
# end
# class B[F]
# end
#
# ~~~nitish
# E.can_resolve_for(A[Int]) #-> true, E make sense in A
#
# E.can_resolve_for(B[Int]) #-> false, E does not make sense in B
#
# B[E].can_resolve_for(A[F], B[Object]) #-> true,
# # B[E] is a red hearing only the E is important,
# # E make sense in A
# ~~~
#
# REQUIRE: `anchor != null implies not anchor.need_anchor`
# REQUIRE: `mtype.need_anchor implies anchor != null and mtype.can_resolve_for(anchor, null, mmodule)`
# ENSURE: `not self.need_anchor implies result == true`
fun can_resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule): Bool is abstract
# Return the nullable version of the type
# If the type is already nullable then self is returned
fun as_nullable: MType
do
var res = self.as_nullable_cache
if res != null then return res
res = new MNullableType(self)
self.as_nullable_cache = res
return res
end
# Remove the base type of a decorated (proxy) type.
# Is the type is not decorated, then self is returned.
#
# Most of the time it is used to return the not nullable version of a nullable type.
# In this case, this just remove the `nullable` notation, but the result can still contains null.
# For instance if `self isa MNullType` or self is a formal type bounded by a nullable type.
# If you really want to exclude the `null` value, then use `as_notnull`
fun undecorate: MType
do
return self
end
# Returns the not null version of the type.
# That is `self` minus the `null` value.
#
# For most types, this return `self`.
# For formal types, this returns a special `MNotNullType`
fun as_notnull: MType do return self
private var as_nullable_cache: nullable MType = null
# The depth of the type seen as a tree.
#
# * A -> 1
# * G[A] -> 2
# * H[A, B] -> 2
# * H[G[A], B] -> 3
#
# Formal types have a depth of 1.
# Only `MClassType` and `MFormalType` nodes are counted.
fun depth: Int
do
return 1
end
# The length of the type seen as a tree.
#
# * A -> 1
# * G[A] -> 2
# * H[A, B] -> 3
# * H[G[A], B] -> 4
#
# Formal types have a length of 1.
# Only `MClassType` and `MFormalType` nodes are counted.
fun length: Int
do
return 1
end
# Compute all the classdefs inherited/imported.
# The returned set contains:
# * the class definitions from `mmodule` and its imported modules
# * the class definitions of this type and its super-types
#
# This function is used mainly internally.
#
# REQUIRE: `not self.need_anchor`
fun collect_mclassdefs(mmodule: MModule): Set[MClassDef] is abstract
# Compute all the super-classes.
# This function is used mainly internally.
#
# REQUIRE: `not self.need_anchor`
fun collect_mclasses(mmodule: MModule): Set[MClass] is abstract
# Compute all the declared super-types.
# Super-types are returned as declared in the classdefs (verbatim).
# This function is used mainly internally.
#
# REQUIRE: `not self.need_anchor`
fun collect_mtypes(mmodule: MModule): Set[MClassType] is abstract
# Is the property in self for a given module
# This method does not filter visibility or whatever
#
# REQUIRE: `not self.need_anchor`
fun has_mproperty(mmodule: MModule, mproperty: MProperty): Bool
do
assert not self.need_anchor
return self.collect_mclassdefs(mmodule).has(mproperty.intro_mclassdef)
end
end
src/model/model.nit:822,1--1284,3
redef class MType
# Representation of this type in pure C on the FFI extern side
# Object -> Object
# Pointer -> void*
fun cname: String do return cname_normal_class
# Representation of this type in C for the internal of the system
# Hides extern types.
fun cname_blind: String do return "struct nitni_instance *"
# Representation of this type in mangled C
# Object -> Object
# Pointer -> Pointer
fun mangled_cname: String is abstract
# Does this type have a primitive representation?
#
# type Object is_primitive? false
# type Pointer is_primitive? true
fun is_cprimitive: Bool do return false
# Name of this type in C for normal classes (not extern and not primitive)
protected fun cname_normal_class: String do return mangled_cname
end
src/nitni/nitni_base.nit:66,1--89,3
redef class MType
# Return true if `self` is a invariant subtype of `sup`.
# This is just a copy of the original `is_subtype` method with only two new lines
fun is_subtype_invar(mmodule: MModule, anchor: nullable MClassType, sup: MType): Bool
do
var sub = self
if sub == sup then return true
#print "1.is {sub} a {sup}? ===="
if anchor == null then
assert not sub.need_anchor
assert not sup.need_anchor
else
# First, resolve the formal types to the simplest equivalent forms in the receiver
assert sub.can_resolve_for(anchor, null, mmodule)
sub = sub.lookup_fixed(mmodule, anchor)
assert sup.can_resolve_for(anchor, null, mmodule)
sup = sup.lookup_fixed(mmodule, anchor)
end
# Does `sup` accept null or not?
# Discard the nullable marker if it exists
var sup_accept_null = false
if sup isa MNullableType then
sup_accept_null = true
sup = sup.mtype
else if sup isa MNullType then
sup_accept_null = true
end
# Can `sub` provide null or not?
# Thus we can match with `sup_accept_null`
# Also discard the nullable marker if it exists
if sub isa MNullableType then
if not sup_accept_null then return false
sub = sub.mtype
else if sub isa MNullType then
return sup_accept_null
end
# Now the case of direct null and nullable is over.
# If `sub` is a formal type, then it is accepted if its bound is accepted
while sub isa MFormalType do
#print "3.is {sub} a {sup}?"
# A unfixed formal type can only accept itself
if sub == sup then return true
assert anchor != null
sub = sub.lookup_bound(mmodule, anchor)
#print "3.is {sub} a {sup}?"
# Manage the second layer of null/nullable
if sub isa MNullableType then
if not sup_accept_null then return false
sub = sub.mtype
else if sub isa MNullType then
return sup_accept_null
end
end
#print "4.is {sub} a {sup}? <- no more resolution"
if sub isa MBottomType or sub isa MErrorType then
return true
end
assert sub isa MClassType else print_error "{sub} <? {sup}" # It is the only remaining type
# Handle sup-type when the sub-type is class-based (other cases must have be identified before).
if sup isa MFormalType or sup isa MNullType or sup isa MBottomType or sup isa MErrorType then
# These types are not super-types of Class-based types.
return false
end
assert sup isa MClassType else print_error "got {sup} {sub.inspect}" # It is the only remaining type
# Now both are MClassType, we need to dig
if sub == sup then return true
if anchor == null then anchor = sub # UGLY: any anchor will work
var resolved_sub = sub.anchor_to(mmodule, anchor)
var res = resolved_sub.collect_mclasses(mmodule).has(sup.mclass)
if not res then return false
if not sup isa MGenericType then return true
var sub2 = sub.supertype_to(mmodule, anchor, sup.mclass)
assert sub2.mclass == sup.mclass
for i in [0..sup.mclass.arity[ do
var sub_arg = sub2.arguments[i]
var sup_arg = sup.arguments[i]
res = sub_arg.is_subtype(mmodule, anchor, sup_arg)
if not res then return false
# The two new lines
res = sup_arg.is_subtype(mmodule, anchor, sub_arg)
if not res then return false
# End of the two new lines
end
return true
end
end
src/metrics/detect_covariance.nit:412,1--513,3
redef class MType
redef fun create_ast_representation(astbuilder: nullable ASTBuilder): AType do
return new AType.make(self)
end
end
src/astbuilder.nit:1043,1--1047,3
redef class MType
super NitniCallback
end
src/nitni/nitni_callbacks.nit:160,1--162,3
redef class MType
private fun signature_depth: Int do
var mtype = self.undecorate
if not mtype isa MGenericType then return 0
var depth = 0
for ft in mtype.arguments do
var ftd = ft.signature_depth
if ftd > depth then depth = ftd
end
return depth + 1
end
end
src/metrics/rta_metrics.nit:389,1--401,3
redef class MType
# Write code in `template` to parse the argument `arg_name` to this parameter type
private fun gen_arg_convert(template: Template, arg_name: String)
do
if self.name == "String" or self.name == "nullable String" then
# String are used as is
template.add """
var out_{{{arg_name}}} = in_{{{arg_name}}}
"""
else
# Deserialize everything else
template.add """
var out_{{{arg_name}}} = deserialize_arg(in_{{{arg_name}}}, "{{{self.name}}}")
"""
end
end
# Does this parameter type needs to be checked before calling the method?
#
# Some nullable types do not need to be check as `null` values are acceptable.
private fun needs_type_check: Bool do return true
end
src/nitrestful.nit:122,1--143,3
redef class MType
# Return the Java type associated to a given Nit static type
fun java_type: String do return "RTVal"
# Is the associated Java type a primitive one?
#
# ENSURE `result == (java_type != "RTVal")`
var is_java_primitive: Bool is lazy do return java_type != "RTVal"
end
src/compiler/java_compiler.nit:1298,1--1306,3
redef class MType
# Type name in Java
#
# * Primitives common to both languages use their Java primitive type
# * Nit extern Java classes are represented by their full Java type
# * Other Nit objects are represented by `NitObject` in Java, a class
# encapsulating the pointer to the underlying C structure.
private fun java_type: String do return "nit.app.NitObject"
# Is this type opaque in Java? As so it is represented by `nit.app.NitObject`.
private fun java_is_nit_object: Bool do return true
# JNI type name (in C)
#
# So this is a C type, usually defined in `jni.h`
private fun jni_type: String do return "jobject"
# JNI short type name (for signatures)
#
# Is used by `MMethod::build_jni_format` to pass a Java method signature
# to the JNI function `GetStaticMetodId`.
private fun jni_format: String do return "Lnit/app/NitObject;"
# Type name appearing within JNI function names.
#
# Used by `JavaLanguage::compile_extern_method` when calling JNI's `CallStatic*Method`.
# This strategy is used by JNI to type the return of callbacks to Java.
private fun jni_signature_alt: String do return "Int"
redef fun compile_callback_to_java(mmodule, mainmodule, ccu)
do
if self isa MClassType and mclass.ftype isa ForeignJavaType then return
var java_file = mmodule.java_file
if java_file == null or mmodule.callbacks_used_from_java.callbacks.is_empty then return
for variation in ["incr", "decr"] do
var friendly_name = "{mangled_cname}_{variation}_ref"
# C
var csignature = "void {mmodule.impl_java_class_name}_{friendly_name}(JNIEnv *nit_ffi_jni_env, jclass clazz, jobject object)"
var cf = new CFunction("JNIEXPORT {csignature}")
cf.exprs.add "\tnitni_global_ref_{variation}(nit_ffi_with_java_nit_object_data(nit_ffi_jni_env, object));"
ccu.add_non_static_local_function cf
# Java
java_file.class_content.add "private native static void {friendly_name}(nit.app.NitObject object);\n"
end
end
redef fun jni_methods_declaration(from_mmodule)
do
var arr = new Array[String]
for variation in ["incr", "decr"] do
var friendly_name = "{mangled_cname}_{variation}_ref"
var jni_format = "(Lnit/app/NitObject;)V"
var cname = "{from_mmodule.impl_java_class_name}_{friendly_name}"
arr.add """{"{{{friendly_name}}}", "{{{jni_format}}}", {{{cname}}}}"""
end
return arr
end
end
src/ffi/java.nit:545,1--608,3
redef class MType
# Return the C type associated to a given Nit static type
fun ctype: String do return "val*"
# C type outside of the compiler code and in boxes
fun ctype_extern: String do return "val*"
# Short name of the `ctype` to use in unions
fun ctypename: String do return "val"
# Is the associated C type a primitive one?
#
# ENSURE `result == (ctype != "val*")`
fun is_c_primitive: Bool do return false
end
src/compiler/abstract_compiler.nit:2433,1--2447,3
redef class MType
private fun compile_extern_type(v: AbstractCompilerVisitor, ccu: CCompilationUnit)
do
assert not is_cprimitive
# define friendly type
ccu.header_c_types.add("#ifndef NIT_TYPE_{cname}\n")
ccu.header_c_types.add("#define NIT_TYPE_{cname} 1\n")
ccu.header_c_types.add("typedef struct nitni_instance *{cname};\n")
ccu.header_c_types.add("#endif\n")
end
end
src/compiler/compiler_ffi/light.nit:271,1--282,3
redef class MType
redef fun html_signature(short) do return html_link
end
src/doc/templates/html_model.nit:275,1--277,3
redef class MType
# Are values of `self` tagged?
# If false, it means that the type is not primitive, or is boxed.
var is_tagged = false
# The tag value of the type
#
# ENSURE `is_tagged == (tag_value > 0)`
# ENSURE `not is_tagged == (tag_value == 0)`
var tag_value = 0
end
src/compiler/separate_compiler.nit:2630,1--2640,3
redef class MType
private fun compile_extern_helper_functions(v: AbstractCompilerVisitor, ccu: CCompilationUnit, compile_implementation_too: Bool)
do
# actually, we do not need to do anything when using the bohem garbage collector
var call_context = from_c_call_context
# incr_ref
ccu.header_decl.add "#ifndef {mangled_cname}_incr_ref\n"
ccu.header_decl.add " #define {mangled_cname}_incr_ref(from) nitni_global_ref_incr(({call_context.name_mtype(self)})(from))\n"
ccu.header_decl.add "#endif\n"
# decr_ref
ccu.header_decl.add "#ifndef {mangled_cname}_decr_ref\n"
ccu.header_decl.add " #define {mangled_cname}_decr_ref(from) nitni_global_ref_decr(({call_context.name_mtype(self)})(from))\n"
ccu.header_decl.add "#endif\n"
end
end
src/compiler/compiler_ffi/compiler_ffi.nit:145,1--161,3
redef class MType
# The interpreter FFI use `void*` to represent intern data types
redef fun cname_blind do return "void*"
# Field to store this type in the C structure `nit_call_arg`
private fun call_arg_field: String do return "value_Pointer"
end
src/interpreter/dynamic_loading_ffi/on_demand_compiler.nit:377,1--383,3
redef class MType
redef fun core_serialize_to(v) do
v.serialize_attribute("name", name)
var mdoc = mdoc_or_fallback
if mdoc != null then
v.serialize_attribute("synopsis", mdoc.synopsis)
v.serialize_attribute("html_synopsis", mdoc.html_synopsis.write_to_string)
end
end
end
src/doc/templates/json_model.nit:304,1--314,3
redef class MType
redef fun core_serialize_to(v) do
super
v.serialize_attribute("web_url", web_url)
v.serialize_attribute("api_url", api_url)
end
end
src/doc/api/api_base.nit:201,1--207,3