X-Git-Url: http://nitlanguage.org?ds=sidebyside diff --git a/src/model/model.nit b/src/model/model.nit index e9e3afb..e22ae84 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -159,6 +159,14 @@ class ConcernsTree super OrderedTree[MConcern] end +redef class MGroup + redef var is_test is lazy do + var parent = self.parent + if parent != null and parent.is_test then return true + return name == "tests" + end +end + redef class MModule # All the classes introduced in the module var intro_mclasses = new Array[MClass] @@ -196,19 +204,37 @@ redef class MModule do var res = self.flatten_mclass_hierarchy_cache if res != null then return res - res = new POSet[MClass] + self.flatten_mclass_hierarchy_cache = new POSet[MClass] for m in self.in_importation.greaters do for cd in m.mclassdefs do - var c = cd.mclass - res.add_node(c) - for s in cd.supertypes do - res.add_edge(c, s.mclass) - end + unsafe_update_hierarchy_cache(cd) end end - self.flatten_mclass_hierarchy_cache = res - return res - end + return self.flatten_mclass_hierarchy_cache.as(not null) + end + + # Adds another class definition in the modue. + # Updates the class hierarchy cache. + fun add_mclassdef(mclassdef: MClassDef) + do + self.mclassdefs.add(mclassdef) + if self.flatten_mclass_hierarchy_cache != null then + unsafe_update_hierarchy_cache(mclassdef) + end + end + + # Adds a class definition inside `flatten_mclass_hierarchy_cache` without + # null check. The caller must have initialized the cache. + protected fun unsafe_update_hierarchy_cache(mclassdef: MClassDef) + do + var hierarchy = self.flatten_mclass_hierarchy_cache.as(not null) + # Update the cache + var c = mclassdef.mclass + hierarchy.add_node(c) + for s in mclassdef.supertypes do + hierarchy.add_edge(c, s.mclass) + end + end # Sort a given array of classes using the linearization order of the module # The most general is first, the most specific is last @@ -588,6 +614,8 @@ class MClass # Is `self` and abstract class? var is_abstract: Bool is lazy do return kind == abstract_kind + redef var is_test is lazy do return intro.is_test + redef fun mdoc_or_fallback do # Don’t use `intro.mdoc_or_fallback` because it would create an infinite @@ -641,7 +669,7 @@ class MClassDef init do self.mclass = bound_mtype.mclass - mmodule.mclassdefs.add(self) + mmodule.add_mclassdef(self) mclass.mclassdefs.add(self) if mclass.intro_mmodule == mmodule then assert not isset mclass._intro @@ -750,9 +778,44 @@ class MClassDef # All property introductions and redefinitions in `self` (not inheritance). var mpropdefs = new Array[MPropDef] + # The special default_init constructor + var default_init: nullable MMethodDef = null is writable + # All property introductions and redefinitions (not inheritance) in `self` by its associated property. var mpropdefs_by_property = new HashMap[MProperty, MPropDef] + # Return the direct parent mtype of `self` + # Exemple + # ~~~nitish + # module 1 + # + # class A + # class B + # super A + # + # module 2 + # + # redef class A + # class C + # super B + # + # mclassdef_C.get_direct_supermtype == [B] + # ~~~~ + fun get_direct_supermtype: Collection[MClassType] + do + # Get the potentiel direct parents + var parents = in_hierarchy.direct_greaters + # Stock the potentiel direct parents + var res = supertypes + for parent in parents do + # remove all super parents of the potentiel direct parents + res.remove_all(parent.supertypes) + # if the length of the potentiel direct parent equal 1 break + if res.length == 1 then break + end + return res + end + redef fun mdoc_or_fallback do return mdoc or else mclass.mdoc_or_fallback end @@ -1793,6 +1856,8 @@ class MNullableType if t == mtype then return self return t.as_nullable end + + redef fun mdoc_or_fallback do return mtype.mdoc_or_fallback end # A non-null version of a formal type. @@ -2327,6 +2392,20 @@ abstract class MProperty end private var lookup_all_definitions_cache = new HashMap2[MModule, MType, Array[MPROPDEF]] + + redef var is_test is lazy do return intro.is_test + + # Does self have the `before` annotation? + var is_before: Bool is lazy do return intro.is_before + + # Does self have the `before_all` annotation? + var is_before_all: Bool is lazy do return intro.is_before_all + + # Does self have the `after` annotation? + var is_after: Bool is lazy do return intro.is_after + + # Does self have the `after_all` annotation? + var is_after_all: Bool is lazy do return intro.is_after_all end # A global method @@ -2554,6 +2633,18 @@ abstract class MPropDef end redef fun mdoc_or_fallback do return mdoc or else mproperty.mdoc_or_fallback + + # Does self have the `before` annotation? + var is_before = false is writable + + # Does self have the `before_all` annotation? + var is_before_all = false is writable + + # Does self have the `after` annotation? + var is_after = false is writable + + # Does self have the `after_all` annotation? + var is_after_all = false is writable end # A local definition of a method @@ -2566,19 +2657,21 @@ class MMethodDef # The signature attached to the property definition var msignature: nullable MSignature = null is writable - # The signature attached to the `new` call on a root-init - # This is a concatenation of the signatures of the initializers - # - # REQUIRE `mproperty.is_root_init == (new_msignature != null)` - var new_msignature: nullable MSignature = null is writable - # List of initialisers to call in root-inits # # They could be setters or attributes - # - # REQUIRE `mproperty.is_root_init == (new_msignature != null)` var initializers = new Array[MProperty] + # Does the method take the responsibility to call `init`? + # + # If the method is used as an initializer, then + # using this information prevents to call `init` twice. + var is_calling_init = false is writable + + # Does the method is a old_style_init? + # + var is_old_style_init = false is writable + # Is the method definition abstract? var is_abstract: Bool = false is writable