# 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
if is_fixed(mmodule, resolved_reciever) then return res
# If the resolved type isa intern class, then there is no possible valid redefinition in any potential subclass. self is just fixed. so simply return the resolution
if res isa MClassType and res.mclass.kind == enum_kind then return res
- # TODO: Add 'fixed' virtual type in the specification.
# TODO: What if bound to a MParameterType?
# Note that Nullable types can always be redefined by the non nullable version, so there is no specific case on it.
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`.
#
# Note that parameter types are shared among class refinements.
# Therefore parameter only have an internal name (see `to_s` for details).
-# TODO: Add a `name_for` to get better messages.
class MParameterType
super MType
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
# Is the method definition extern?
var is_extern = false is writable
+
+ # An optional constant value returned in functions.
+ #
+ # Only some specific primitife value are accepted by engines.
+ # Is used when there is no better implementation available.
+ #
+ # Currently used only for the implementation of the `--define`
+ # command-line option.
+ # SEE: module `mixin`.
+ var constant_value: nullable Object = null is writable
end
# A local definition of an attribute
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