# The number of generic formal parameters
# 0 if the class is not generic
- var arity: Int
+ var arity: Int is noinit
# Each generic formal parameters in order.
# is empty if the class is not generic
var mparameters = new Array[MParameterType]
- # The kind of the class (interface, abstract class, etc.)
- # In Nit, the kind of a class cannot evolve in refinements
- var kind: MClassKind
-
- # The visibility of the class
- # In Nit, the visibility of a class cannot evolve in refinements
- var visibility: MVisibility
-
- init(intro_mmodule: MModule, name: String, parameter_names: nullable Array[String], kind: MClassKind, visibility: MVisibility)
+ protected fun setup_parameter_names(parameter_names: nullable Array[String]) is
+ autoinit
do
- self.intro_mmodule = intro_mmodule
- self.name = name
if parameter_names == null then
self.arity = 0
else
self.arity = parameter_names.length
end
- self.kind = kind
- self.visibility = visibility
- intro_mmodule.intro_mclasses.add(self)
- var model = intro_mmodule.model
- model.mclasses_by_name.add_one(name, self)
- model.mclasses.add(self)
# Create the formal parameter types
if arity > 0 then
end
end
+ # The kind of the class (interface, abstract class, etc.)
+ # In Nit, the kind of a class cannot evolve in refinements
+ var kind: MClassKind
+
+ # The visibility of the class
+ # In Nit, the visibility of a class cannot evolve in refinements
+ var visibility: MVisibility
+
+ init
+ do
+ intro_mmodule.intro_mclasses.add(self)
+ var model = intro_mmodule.model
+ model.mclasses_by_name.add_one(name, self)
+ model.mclasses.add(self)
+ end
+
redef fun model do return intro_mmodule.model
# All class definitions (introduction and refinements)
# Alias for `name`
redef fun to_s do return self.name
- # The definition that introduced the class
- # Warning: the introduction is the first `MClassDef` object associated
- # to self. If self is just created without having any associated
- # definition, this method will abort
- fun intro: MClassDef
- do
- assert has_a_first_definition: not mclassdefs.is_empty
- return mclassdefs.first
- end
+ # The definition that introduces the class.
+ #
+ # Warning: such a definition may not exist in the early life of the object.
+ # In this case, the method will abort.
+ var intro: MClassDef is noinit
# Return the class `self` in the class hierarchy of the module `mmodule`.
#
# To get other types based on a generic class, see `get_mtype`.
#
# ENSURE: `mclass_type.mclass == self`
- var mclass_type: MClassType
+ var mclass_type: MClassType is noinit
# Return a generic type based on the class
# Is the class is not generic, then the result is `mclass_type`
var mmodule: MModule
# The associated `MClass`
- var mclass: MClass
+ var mclass: MClass is noinit
# The bounded type associated to the mclassdef
#
# Internal name combining the module and the class
# Example: "mymodule#MyClass"
- redef var to_s: String
+ redef var to_s: String is noinit
- init(mmodule: MModule, bound_mtype: MClassType, location: Location)
+ init
do
- self.bound_mtype = bound_mtype
- self.mmodule = mmodule
self.mclass = bound_mtype.mclass
- self.location = location
mmodule.mclassdefs.add(self)
mclass.mclassdefs.add(self)
+ if mclass.intro_mmodule == mmodule then
+ assert not isset mclass._intro
+ mclass.intro = self
+ end
self.to_s = "{mmodule}#{mclass}"
end
# types to their bounds.
#
# Example
+ #
# class A end
# class B super A end
# class X end
# super G[B]
# redef type U: Y
# end
+ #
# Map[T,U] anchor_to H #-> Map[B,Y]
#
# Explanation of the example:
# 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)`
#
# ## Example 1
#
- # class G[E] end
- # class H[F] super G[F] end
- # class X[Z] end
+ # ~~~
+ # 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]
#
# ## Example 2
#
- # class A[E]
- # fun foo(e:E):E is abstract
- # end
- # class B super A[Int] end
+ # ~~~
+ # 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
#
- # class A[E]
- # fun foo(e:E) is abstract
- # end
- # class B[F]
- # var a: A[Array[F]]
- # fun bar do a.foo(x) # <- x is here
- # end
+ # ~~~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(B[nullable Object]) #-> A[Array[nullable Object]]
+ # 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 signature of `foo` is `foo(e:E)`, thus we must resolve the type E
#
- # E.resolve_for(A[Array[F]],B[nullable Object]) #-> Array[F]
+ # 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`)
#
# class B[F]
# end
#
- # * 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
+ # ~~~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)`
redef fun model do return self.mclass.intro_mmodule.model
- private init(mclass: MClass)
- do
- self.mclass = mclass
- end
+ # TODO: private init because strongly bounded to its mclass. see `mclass.mclass_type`
# The formal arguments of the type
# ENSURE: `result.length == self.mclass.arity`
class MGenericType
super MClassType
- private init(mclass: MClass, arguments: Array[MType])
+ redef var arguments
+
+ # TODO: private init because strongly bounded to its mclass. see `mclass.get_mtype`
+
+ init
do
- super(mclass)
assert self.mclass.arity == arguments.length
- self.arguments = arguments
self.need_anchor = false
for t in arguments do
# Recursively print the type of the arguments within brackets.
# Example: `"Map[String, List[Int]]"`
- redef var to_s: String
+ redef var to_s: String is noinit
- redef var need_anchor: Bool
+ redef var need_anchor: Bool is noinit
redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual)
do
end
redef fun to_s do return self.mproperty.to_s
-
- init(mproperty: MProperty)
- do
- self.mproperty = mproperty
- end
end
# The type associated to a formal parameter generic type of a class
# directly to the parameter types of the super-classes.
#
# Example:
+#
# class A[E]
# fun e: E is abstract
# end
# class B[F]
# super A[Array[F]]
# end
+#
# In the class definition B[F], `F` is a valid type but `E` is not.
# However, `self.e` is a valid method call, and the signature of `e` is
# declared `e: E`.
end
return mtype.collect_mclassdefs(mmodule).has(mclass.intro)
end
-
- init(mclass: MClass, rank: Int, name: String)
- do
- self.mclass = mclass
- self.rank = rank
- self.name = name
- end
end
# A type prefixed with "nullable"
redef fun model do return self.mtype.model
- init(mtype: MType)
+ init
do
- self.mtype = mtype
self.to_s = "nullable {mtype}"
end
- redef var to_s: String
+ redef var to_s: String is noinit
redef fun need_anchor do return mtype.need_anchor
redef fun as_nullable do return self
class MNullType
super MType
redef var model: Model
- protected init(model: Model)
- do
- self.model = model
- end
redef fun to_s do return "null"
redef fun as_nullable do return self
redef fun need_anchor do return false
end
# REQUIRE: 1 <= mparameters.count p -> p.is_vararg
- init(mparameters: Array[MParameter], return_mtype: nullable MType)
+ init
do
var vararg_rank = -1
for i in [0..mparameters.length[ do
vararg_rank = i
end
end
- self.mparameters = mparameters
- self.return_mtype = return_mtype
self.vararg_rank = vararg_rank
end
# The rank of the ellipsis (`...`) for vararg (starting from 0).
# value is -1 if there is no vararg.
# Example: for "(a: Int, b: Bool..., c: Char)" #-> vararg_rank=1
- var vararg_rank: Int
+ var vararg_rank: Int is noinit
# The number or parameters
fun arity: Int do return mparameters.length
# Is the parameter a vararg?
var is_vararg: Bool
- init(name: String, mtype: MType, is_vararg: Bool) do
- self.name = name
- self.mtype = mtype
- self.is_vararg = is_vararg
- end
-
redef fun to_s
do
if is_vararg then
# The visibility of the property
var visibility: MVisibility
- init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
+ init
do
- self.intro_mclassdef = intro_mclassdef
- self.name = name
- self.visibility = visibility
intro_mclassdef.intro_mproperties.add(self)
var model = intro_mclassdef.mmodule.model
model.mproperties_by_name.add_one(name, self)
# The other are redefinitions (in refinements and in subclasses)
var mpropdefs = new Array[MPROPDEF]
- # The definition that introduced the property
- # Warning: the introduction is the first `MPropDef` object
- # associated to self. If self is just created without having any
- # associated definition, this method will abort
- fun intro: MPROPDEF do return mpropdefs.first
+ # The definition that introduces the property.
+ #
+ # Warning: such a definition may not exist in the early life of the object.
+ # In this case, the method will abort.
+ var intro: MPROPDEF is noinit
redef fun model do return intro.model
redef type MPROPDEF: MMethodDef
- init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
- do
- super
- end
-
# Is the property defined at the top_level of the module?
# Currently such a property are stored in `Object`
var is_toplevel: Bool = false is writable
redef type MPROPDEF: MAttributeDef
- init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
- do
- super
- end
end
# A global virtual type
redef type MPROPDEF: MVirtualTypeDef
- init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
- do
- super
- end
-
# The formal type associated to the virtual type property
var mvirtualtype = new MVirtualType(self)
end
# Self class
type MPROPDEF: MPropDef
- # The origin of the definition
- var location: Location
-
# The class definition where the property definition is
var mclassdef: MClassDef
# The associated global property
var mproperty: MPROPERTY
- init(mclassdef: MClassDef, mproperty: MPROPERTY, location: Location)
+ # The origin of the definition
+ var location: Location
+
+ init
do
- self.mclassdef = mclassdef
- self.mproperty = mproperty
- self.location = location
mclassdef.mpropdefs.add(self)
mproperty.mpropdefs.add(self)
+ if mproperty.intro_mclassdef == mclassdef then
+ assert not isset mproperty._intro
+ mproperty.intro = self
+ end
self.to_s = "{mclassdef}#{mproperty}"
end
# Internal name combining the module, the class and the property
# Example: "mymodule#MyClass#mymethod"
- redef var to_s: String
+ redef var to_s: String is noinit
# Is self the definition that introduce the property?
fun is_intro: Bool do return mproperty.intro == self
redef type MPROPERTY: MMethod
redef type MPROPDEF: MMethodDef
- init(mclassdef: MClassDef, mproperty: MPROPERTY, location: Location)
- do
- super
- end
-
# The signature attached to the property definition
var msignature: nullable MSignature = null is writable
redef type MPROPERTY: MAttribute
redef type MPROPDEF: MAttributeDef
- init(mclassdef: MClassDef, mproperty: MPROPERTY, location: Location)
- do
- super
- end
-
# The static type of the attribute
var static_mtype: nullable MType = null is writable
end
redef type MPROPERTY: MVirtualTypeProp
redef type MPROPDEF: MVirtualTypeDef
- init(mclassdef: MClassDef, mproperty: MPROPERTY, location: Location)
- do
- super
- end
-
# The bound of the virtual type
var bound: nullable MType = null is writable
# Is a constructor required?
var need_init: Bool
- private init(s: String, need_init: Bool)
- do
- self.to_s = s
- self.need_init = need_init
- end
+
+ # TODO: private init because enumeration.
# Can a class of kind `self` specializes a class of kine `other`?
fun can_specialize(other: MClassKind): Bool