X-Git-Url: http://nitlanguage.org diff --git a/src/model/model.nit b/src/model/model.nit index 7568e9b..d4d2c1c 100644 --- a/src/model/model.nit +++ b/src/model/model.nit @@ -25,8 +25,6 @@ # FIXME: better handling of the types module model -import poset -import location import mmodule import mdoc import ordered_tree @@ -236,6 +234,13 @@ redef class MModule return get_primitive_class("Sys").mclass_type end + fun finalizable_type: nullable MClassType + do + var clas = self.model.get_mclasses_by_name("Finalizable") + if clas == null then return null + return get_primitive_class("Finalizable").mclass_type + end + # Force to get the primitive class named `name` or abort fun get_primitive_class(name: String): MClass do @@ -887,6 +892,16 @@ abstract class MType return res end + # Return the not nullable version of the type + # Is the type is already not nullable, then self is returned. + # + # Note: this just remove the `nullable` notation, but the result can still contains null. + # For instance if `self isa MNullType` or self is a a formal type bounded by a nullable type. + fun as_notnullable: MType + do + return self + end + private var as_nullable_cache: nullable MType = null @@ -1153,6 +1168,20 @@ class MVirtualType abort end + # Is the virtual type fixed for a given resolved_receiver? + fun is_fixed(mmodule: MModule, resolved_receiver: MType): Bool + do + assert not resolved_receiver.need_anchor + var props = self.mproperty.lookup_definitions(mmodule, resolved_receiver) + if props.is_empty then + abort + end + for p in props do + if p.as(MVirtualTypeDef).is_fixed then return true + end + return false + end + redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do assert can_resolve_for(mtype, anchor, mmodule) @@ -1181,6 +1210,8 @@ class MVirtualType if resolved_reciever.as(MClassType).mclass.kind == enum_kind then return res # If the resolved type isa MVirtualType, it means that self was bound to it, and cannot be unbound. self is just fixed. so return the resolution. if res isa MVirtualType then return res + # If we are final, just return the resolution + if is_fixed(mmodule, resolved_reciever) then return res # It the resolved type isa intern class, then there is no possible valid redefinition is any potentiel 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. @@ -1276,7 +1307,13 @@ class MParameterType #print "{class_name}: {self}/{mtype}/{anchor}?" if mtype isa MGenericType and mtype.mclass == self.mclass then - return mtype.arguments[self.rank] + var res = mtype.arguments[self.rank] + if anchor != null and res.need_anchor then + # Maybe the result can be resolved more if are bound to a final class + var r2 = res.anchor_to(mmodule, anchor) + if r2 isa MClassType and r2.mclass.kind == enum_kind then return r2 + end + return res end # self is a parameter type of mtype (or of a super-class of mtype) @@ -1355,6 +1392,7 @@ class MNullableType redef fun need_anchor do return mtype.need_anchor redef fun as_nullable do return self + redef fun as_notnullable do return mtype redef fun resolve_for(mtype, anchor, mmodule, cleanup_virtual) do var res = self.mtype.resolve_for(mtype, anchor, mmodule, cleanup_virtual) @@ -1620,7 +1658,7 @@ abstract class MProperty fun lookup_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do assert not mtype.need_anchor - if mtype isa MNullableType then mtype = mtype.mtype + mtype = mtype.as_notnullable var cache = self.lookup_definitions_cache[mmodule, mtype] if cache != null then return cache @@ -1659,7 +1697,7 @@ abstract class MProperty fun lookup_super_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do assert not mtype.need_anchor - if mtype isa MNullableType then mtype = mtype.mtype + mtype = mtype.as_notnullable # First, select all candidates var candidates = new Array[MPROPDEF] @@ -1736,7 +1774,7 @@ abstract class MProperty fun lookup_all_definitions(mmodule: MModule, mtype: MType): Array[MPROPDEF] do assert not mtype.need_anchor - if mtype isa MNullableType then mtype = mtype.mtype + mtype = mtype.as_notnullable var cache = self.lookup_all_definitions_cache[mmodule, mtype] if cache != null then return cache @@ -1787,6 +1825,9 @@ class MMethod # therefore, you should use `is_init_for` the verify if the property is a legal constructor for a given class var is_init: Bool writable = false + # The constructor is a (the) root init with empty signature but a set of initializers + var is_root_init: Bool writable = false + # The the property a 'new' contructor? var is_new: Bool writable = false @@ -1905,6 +1946,19 @@ class MMethodDef # The signature attached to the property definition var msignature: nullable MSignature writable = null + # 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 writable = null + + # 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] + # Is the method definition abstract? var is_abstract: Bool writable = false @@ -1945,6 +1999,9 @@ class MVirtualTypeDef # The bound of the virtual type var bound: nullable MType writable = null + + # Is the bound fixed? + var is_fixed writable = false end # A kind of class.