X-Git-Url: http://nitlanguage.org diff --git a/src/model/model.nit b/src/model/model.nit index c356f8d..6732a16 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 @@ -222,7 +223,12 @@ redef class MModule print("Fatal Error: no primitive class {name}") exit(1) end - assert cla.length == 1 else print cla.join(", ") + if cla.length != 1 then + var msg = "Fatal Error: more than one primitive class {name}:" + for c in cla do msg += " {c.full_name}" + print msg + exit(1) + end return cla.first end @@ -287,6 +293,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 +420,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 +552,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 +1423,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 @@ -1461,6 +1472,15 @@ class MParameter # Is the parameter a vararg? var is_vararg: Bool + redef fun to_s + do + if is_vararg then + return "{name}: {mtype}..." + else + return "{name}: {mtype}" + end + end + fun resolve_for(mtype: MType, anchor: nullable MClassType, mmodule: MModule, cleanup_virtual: Bool): MParameter do if not self.mtype.need_anchor then return self @@ -1482,6 +1502,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 +1583,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 +1596,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 +1617,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 +1634,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 @@ -1719,6 +1718,10 @@ class MMethod 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 writable = false + # Is the property a constructor? # Warning, this property can be inherited by subclasses with or without being a constructor # therefore, you should use `is_init_for` the verify if the property is a legal constructor for a given class @@ -1768,6 +1771,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 +1840,14 @@ 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 + + # Is the method definition extern? + var is_extern writable = false end # A local definition of an attribute @@ -1892,10 +1902,28 @@ class MClassKind self.to_s = s self.need_init = need_init end + + # Can a class of kind `self` specializes a class of kine `other`? + fun can_specialize(other: MClassKind): Bool + do + if other == interface_kind then return true # everybody can specialize interfaces + if self == interface_kind or self == enum_kind then + # no other case for interfaces + return false + else if self == extern_kind then + # only compatible with themselve + return self == other + else if other == enum_kind or other == extern_kind then + # abstract_kind and concrete_kind are incompatible + return false + end + # remain only abstract_kind and concrete_kind + return true + end end fun abstract_kind: MClassKind do return once new MClassKind("abstract class", true) fun concrete_kind: MClassKind do return once new MClassKind("class", true) fun interface_kind: MClassKind do return once new MClassKind("interface", false) fun enum_kind: MClassKind do return once new MClassKind("enum", false) -fun extern_kind: MClassKind do return once new MClassKind("extern", false) +fun extern_kind: MClassKind do return once new MClassKind("extern class", false)