X-Git-Url: http://nitlanguage.org?ds=sidebyside diff --git a/src/model/model.nit b/src/model/model.nit index c356f8d..bebfa5c 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -31,7 +31,8 @@ module model import poset import location -import model_base +import mmodule +import mdoc private import more_collections redef class Model @@ -287,6 +288,8 @@ end # belong to a hierarchy since the property and the # hierarchy of a class depends of a module. class MClass + super MEntity + # The module that introduce the class # While classes are not bound to a specific module, # the introducing module is used for naming an visibility @@ -412,6 +415,8 @@ end # class. Unlike `MClass`, a `MClassDef` is a local definition that belong to # a specific module class MClassDef + super MEntity + # The module where the definition is var mmodule: MModule @@ -542,6 +547,7 @@ end # * foo(anchor, mmodule, othertype) # * foo(othertype, mmodule, anchor) abstract class MType + super MEntity # The model of the type fun model: Model is abstract @@ -1412,7 +1418,7 @@ class MSignature redef fun to_s do - var b = new Buffer + var b = new FlatBuffer if not mparameters.is_empty then b.append("(") for i in [0..mparameters.length[ do @@ -1482,6 +1488,8 @@ end # of any dynamic type). # For instance, a call site "x.foo" is associated to a `MProperty`. abstract class MProperty + super MEntity + # The associated MPropDef subclass. # The two specialization hierarchy are symmetric. type MPROPDEF: MPropDef @@ -1561,37 +1569,7 @@ abstract class MProperty end # Second, filter the most specific ones - var res = new Array[MPROPDEF] - for pd1 in candidates do - var cd1 = pd1.mclassdef - var c1 = cd1.mclass - var keep = true - for pd2 in candidates do - if pd2 == pd1 then continue # do not compare with self! - var cd2 = pd2.mclassdef - var c2 = cd2.mclass - if c2.mclass_type == c1.mclass_type then - if cd2.mmodule.in_importation <= cd1.mmodule then - # cd2 refines cd1; therefore we skip pd1 - keep = false - break - end - else if cd2.bound_mtype.is_subtype(mmodule, null, cd1.bound_mtype) then - # cd2 < cd1; therefore we skip pd1 - keep = false - break - end - end - if keep then - res.add(pd1) - end - end - if res.is_empty then - print "All lost! {candidates.join(", ")}" - # FIXME: should be abort! - end - self.lookup_definitions_cache[mmodule, mtype] = res - return res + return select_most_specific(mmodule, candidates) end private var lookup_definitions_cache: HashMap2[MModule, MType, Array[MPROPDEF]] = new HashMap2[MModule, MType, Array[MPROPDEF]] @@ -1604,13 +1582,13 @@ abstract class MProperty # If you want the really most specific property, then look at `lookup_next_definition` # # FIXME: Move to `MPropDef`? - fun lookup_super_definitions(mmodule: MModule, mtype: MType): Array[MPropDef] + fun lookup_super_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do assert not mtype.need_anchor if mtype isa MNullableType then mtype = mtype.mtype # First, select all candidates - var candidates = new Array[MPropDef] + var candidates = new Array[MPROPDEF] for mpropdef in self.mpropdefs do # If the definition is not imported by the module, then skip if not mmodule.in_importation <= mpropdef.mclassdef.mmodule then continue @@ -1625,7 +1603,14 @@ abstract class MProperty if candidates.length <= 1 then return candidates # Second, filter the most specific ones - var res = new Array[MPropDef] + return select_most_specific(mmodule, candidates) + end + + # Return an array containing olny the most specific property definitions + # This is an helper function for `lookup_definitions` and `lookup_super_definitions` + private fun select_most_specific(mmodule: MModule, candidates: Array[MPROPDEF]): Array[MPROPDEF] + do + var res = new Array[MPROPDEF] for pd1 in candidates do var cd1 = pd1.mclassdef var c1 = cd1.mclass @@ -1635,12 +1620,12 @@ abstract class MProperty var cd2 = pd2.mclassdef var c2 = cd2.mclass if c2.mclass_type == c1.mclass_type then - if cd2.mmodule.in_importation <= cd1.mmodule then + if cd2.mmodule.in_importation < cd1.mmodule then # cd2 refines cd1; therefore we skip pd1 keep = false break end - else if cd2.bound_mtype.is_subtype(mmodule, null, cd1.bound_mtype) then + else if cd2.bound_mtype.is_subtype(mmodule, null, cd1.bound_mtype) and cd2.bound_mtype != cd1.bound_mtype then # cd2 < cd1; therefore we skip pd1 keep = false break @@ -1768,6 +1753,7 @@ end # Unlike `MProperty`, a `MPropDef` is a local definition that belong to a # specific class definition (which belong to a specific module) abstract class MPropDef + super MEntity # The associated `MProperty` subclass. # the two specialization hierarchy are symmetric @@ -1836,8 +1822,11 @@ class MMethodDef # The signature attached to the property definition var msignature: nullable MSignature writable = null - # The the method definition abstract? + # Is the method definition abstract? var is_abstract: Bool writable = false + + # Is the method definition intern? + var is_intern writable = false end # A local definition of an attribute