all: add `nitish` tag for code-blocks skipped by nitunit
[nit.git] / src / model / model.nit
index eab60f7..9be5738 100644 (file)
@@ -362,35 +362,20 @@ class MClass
 
        # 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
@@ -409,6 +394,22 @@ class MClass
                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)
@@ -417,15 +418,11 @@ class MClass
        # 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`.
        #
@@ -451,7 +448,7 @@ class MClass
        # 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`
@@ -494,7 +491,7 @@ class MClassDef
        var mmodule: MModule
 
        # The associated `MClass`
-       var mclass: MClass
+       var mclass: MClass is noinit
 
        # The bounded type associated to the mclassdef
        #
@@ -513,16 +510,17 @@ class 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
 
@@ -734,6 +732,7 @@ abstract class MType
        # types to their bounds.
        #
        # Example
+       #
        #     class A end
        #     class B super A end
        #     class X end
@@ -745,6 +744,7 @@ abstract class MType
        #       super G[B]
        #       redef type U: Y
        #     end
+       #
        # Map[T,U]  anchor_to  H  #->  Map[B,Y]
        #
        # Explanation of the example:
@@ -773,9 +773,13 @@ abstract class MType
        # 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)`
@@ -809,9 +813,11 @@ abstract class MType
        #
        # ## 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]
@@ -829,30 +835,34 @@ abstract class MType
        #
        # ## 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`.
        #
@@ -860,7 +870,7 @@ abstract class MType
        #
        # 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`)
        #
@@ -882,11 +892,15 @@ abstract class MType
        #     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)`
@@ -988,10 +1002,7 @@ class MClassType
 
        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`
@@ -1081,11 +1092,13 @@ end
 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
@@ -1100,9 +1113,9 @@ class MGenericType
 
        # 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
@@ -1226,7 +1239,6 @@ class MVirtualType
                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.
 
@@ -1244,11 +1256,6 @@ class MVirtualType
        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
@@ -1263,19 +1270,20 @@ end
 # 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
 
@@ -1374,13 +1382,6 @@ class MParameterType
                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"
@@ -1392,13 +1393,12 @@ class MNullableType
 
        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
@@ -1443,10 +1443,6 @@ end
 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
@@ -1494,7 +1490,7 @@ class MSignature
        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
@@ -1504,15 +1500,13 @@ class MSignature
                                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
@@ -1570,12 +1564,6 @@ class MParameter
        # 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
@@ -1632,11 +1620,8 @@ abstract class MProperty
        # 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)
@@ -1648,11 +1633,11 @@ abstract class MProperty
        # 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
 
@@ -1821,11 +1806,6 @@ class MMethod
 
        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
@@ -1856,10 +1836,6 @@ class MAttribute
 
        redef type MPROPDEF: MAttributeDef
 
-       init(intro_mclassdef: MClassDef, name: String, visibility: MVisibility)
-       do
-               super
-       end
 end
 
 # A global virtual type
@@ -1868,11 +1844,6 @@ class MVirtualTypeProp
 
        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
@@ -1891,22 +1862,23 @@ abstract class MPropDef
        # 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
 
@@ -1917,7 +1889,7 @@ abstract class MPropDef
 
        # 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
@@ -1948,11 +1920,6 @@ class MMethodDef
        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
 
@@ -1977,6 +1944,16 @@ class MMethodDef
 
        # 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
@@ -1986,11 +1963,6 @@ class MAttributeDef
        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
@@ -2002,11 +1974,6 @@ class MVirtualTypeDef
        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
 
@@ -2029,11 +1996,8 @@ class MClassKind
 
        # 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