X-Git-Url: http://nitlanguage.org diff --git a/src/metamodel/static_type.nit b/src/metamodel/static_type.nit index c96a1b8..fc1f684 100644 --- a/src/metamodel/static_type.nit +++ b/src/metamodel/static_type.nit @@ -22,17 +22,17 @@ intrude import abstractmetamodel redef class MMLocalClass # Cached result of get_type - attr _base_type_cache: MMType + var _base_type_cache: nullable MMType # Return the type of self for this class - meth get_type: MMType + fun get_type: MMType do if _base_type_cache == null then _base_type_cache = new MMTypeSimpleClass(self) - return _base_type_cache + return _base_type_cache.as(not null) end # Register a new ancestor - protected meth add_ancestor(a: MMAncestor) + protected fun add_ancestor(a: MMAncestor) do assert not _ancestors.has_key(a.local_class) assert a.local_class != self @@ -40,10 +40,10 @@ redef class MMLocalClass end # Array of ancestor that associate each superclass with the corresponding ancestor - readable attr _ancestors: Map[MMLocalClass, MMAncestor] + readable var _ancestors: nullable Map[MMLocalClass, MMAncestor] # The ancestor type for a given superclass - meth ancestor(c: MMLocalClass): MMType + fun ancestor(c: MMLocalClass): MMType do return _ancestors[c].stype end @@ -51,13 +51,13 @@ end redef class MMLocalProperty # The signature of the property (where it is declared) - readable writable attr _signature: MMSignature + readable writable var _signature: nullable MMSignature - attr _signatures_cache: HashMap[MMType, MMSignature] = new HashMap[MMType, MMSignature] + var _signatures_cache: HashMap[MMType, MMSignature] = new HashMap[MMType, MMSignature] # Return the adapted signature of self for a receiver of type t - meth signature_for(t: MMType): MMSignature do - if t == local_class.get_type then return signature + fun signature_for(t: MMType): MMSignature do + if t == local_class.get_type then return signature.as(not null) if _signatures_cache.has_key(t) then return _signatures_cache[t] @@ -70,34 +70,43 @@ end # Signature for local properties class MMSignature # The type of the reveiver - readable attr _recv: MMType + readable var _recv: MMType # The parameter types - attr _params: Array[MMType] + var _params: Array[MMType] # The return type - readable attr _return_type: MMType + readable var _return_type: nullable MMType # The closure parameters - readable attr _closures: Array[MMClosure] = new Array[MMClosure] + readable var _closures: Array[MMClosure] = new Array[MMClosure] + + # Return the closure named 'name'. Null if no such a closure exists. + fun closure_named(name: Symbol): nullable MMClosure + do + for c in _closures do + if c.name == name then return c + end + return null + end # Number of parameters - meth arity: Int + fun arity: Int do - assert _params != null return _params.length end # Is self a valid subtype of an other signature - meth <(s: MMSignature): Bool + fun <(s: MMSignature): Bool do - assert s != null if self == s then return true end - assert _recv.module == s.recv.module - if arity != s.arity or (_return_type == null) != (s.return_type == null) then return false - if _return_type != null and not _return_type < s.return_type then + assert _recv.mmmodule == s.recv.mmmodule + var rt = _return_type + var srt = s.return_type + if arity != s.arity or (rt == null) != (srt == null) then return false + if rt != null and not rt < srt.as(not null) then return false end @@ -115,16 +124,16 @@ class MMSignature end # The type of the i-th parameter - meth [](i: Int): MMType + fun [](i: Int): MMType do assert _params.length > i return _params[i] end - redef meth to_s + redef fun to_s do var s = new Buffer - if _params != null and _params.length > 0 then + if _params.length > 0 then var tmp: String var a = new Array[String].with_capacity(_params.length) for i in [0.._params.length[ do @@ -135,25 +144,21 @@ class MMSignature end s.append("({a.join(",")})") end - if _return_type != null then - s.append(": {_return_type}") - end + var rt = _return_type + if rt != null then s.append(": {rt}") return s.to_s end # Adapt the signature to a different receiver - meth adaptation_to(r: MMType): MMSignature + fun adaptation_to(r: MMType): MMSignature do if _recv == r then return self end - var mod = r.module - var p = _params - if p != null then - p = new Array[MMType] - for i in _params do - p.add(i.for_module(mod).adapt_to(r)) - end + var mod = r.mmmodule + var p = new Array[MMType] + for i in _params do + p.add(i.for_module(mod).adapt_to(r)) end var rv = _return_type if rv != null then @@ -166,42 +171,36 @@ class MMSignature return res end - attr _not_for_self_cache: MMSignature = null + var _not_for_self_cache: nullable MMSignature = null # Return a type approximation if the reveiver is not self # Useful for virtual types - meth not_for_self: MMSignature + fun not_for_self: MMSignature do - var res = _not_for_self_cache - if res != null then return res + if _not_for_self_cache != null then return _not_for_self_cache.as(not null) var need_for_self = false - var p = _params - if p != null then - p = new Array[MMType] - for i in _params do - var i2 = i.not_for_self - if i != i2 then need_for_self = true - p.add(i2) - end + var p = new Array[MMType] + for i in _params do + var i2 = i.not_for_self + if i != i2 then need_for_self = true + p.add(i2) end - + var rv = _return_type if rv != null then rv = rv.not_for_self if rv != _return_type then need_for_self = true end - - var clos = _closures - if clos != null then - clos = new Array[MMClosure] - for c in _closures do - var c2 = c.not_for_self - if c2 != c then need_for_self = true - clos.add(c2) - end + + var clos = new Array[MMClosure] + for c in _closures do + var c2 = c.not_for_self + if c2 != c then need_for_self = true + clos.add(c2) end + var res: MMSignature if need_for_self then res = new MMSignature(p, rv, _recv) res.closures.add_all(clos) @@ -213,9 +212,8 @@ class MMSignature return res end - init(params: Array[MMType], return_type: MMType, r: MMType) + init(params: Array[MMType], return_type: nullable MMType, r: MMType) do - assert params != null _params = params _return_type = return_type _recv = r @@ -224,41 +222,45 @@ end # A closure in a signature class MMClosure + # The name of the closure (without the !) + readable var _name: Symbol + # The signature of the closure - readable attr _signature: MMSignature + readable var _signature: MMSignature # Is the closure a brek one # aka is defined with the break keyword thus does not return - readable attr _is_break: Bool + readable var _is_break: Bool # Is the closure optional? # ie is there a default definition - readable attr _is_optional: Bool + readable var _is_optional: Bool # Adapt the signature to a different receiver - meth adaptation_to(r: MMType): MMClosure + fun adaptation_to(r: MMType): MMClosure do - return new MMClosure(_signature.adaptation_to(r), _is_break, _is_optional) + return new MMClosure(_name, _signature.adaptation_to(r), _is_break, _is_optional) end - init(s: MMSignature, is_break: Bool, is_optional: Bool) + init(name: Symbol, s: MMSignature, is_break: Bool, is_optional: Bool) do + _name = name _signature = s _is_break = is_break _is_optional = is_optional end - meth not_for_self: MMClosure + fun not_for_self: MMClosure do var sig = _signature.not_for_self if sig != _signature then - return new MMClosure(sig, _is_break, _is_optional) + return new MMClosure(_name, sig, _is_break, _is_optional) else return self end end - meth <(c: MMClosure): Bool + fun <(c: MMClosure): Bool do if c.is_optional and not is_optional then return false if not c.is_break and is_break then return false @@ -269,25 +271,31 @@ end # Inheritance relation between two types abstract class MMAncestor # The inherited type - readable writable attr _stype: MMType = null + writable var _stype: nullable MMType = null + + # The inherited type + fun stype: MMType do return _stype.as(not null) + + # The inheriter (heir) type + writable var _inheriter: nullable MMType = null # The inheriter (heir) type - readable writable attr _inheriter: MMType = null + fun inheriter: MMType do return _inheriter.as(not null) - meth is_reffinement: Bool do - return stype.module != stype.module + fun is_reffinement: Bool do + return stype.mmmodule != stype.mmmodule end - meth is_specialisation: Bool do + fun is_specialisation: Bool do return stype.local_class.global != inheriter.local_class.global end # The inherited class - meth local_class: MMLocalClass is abstract + fun local_class: MMLocalClass is abstract - redef meth to_s + redef fun to_s do - if stype == null then + if _stype == null then return local_class.to_s else return stype.to_s @@ -299,29 +307,29 @@ end # Note that static type a related to a specific module abstract class MMType # The module where self makes sence - meth module: MMModule is abstract + fun mmmodule: MMModule is abstract # The local class that self direclty or indirectly refers to - meth local_class: MMLocalClass is abstract + fun local_class: MMLocalClass is abstract # Is the type a valid one # For instance, circular dependency on formal types is invalid - meth is_valid: Bool do return true + fun is_valid: Bool do return true # Is self a valid subtype of t - meth <(t : MMType): Bool is abstract + fun <(t : MMType): Bool is abstract # Is self a valid supertype of t # This method must be only called within definition of < if # a double dispatch is needed - meth is_supertype(t: MMType): Bool is abstract + fun is_supertype(t: MMType): Bool is abstract # Adapt self to another module - meth for_module(mod: MMModule): MMType is abstract + fun for_module(mod: MMModule): MMType is abstract # Get the type adapted to another receiver type # Useful for formal types - meth adapt_to(recv: MMType): MMType is abstract + fun adapt_to(recv: MMType): MMType is abstract # Adapt self to another local class context # Useful for genericity @@ -343,21 +351,21 @@ abstract class MMType # 'D'.upcast_for('C') -> 'C[Float]' # 'D'.upcast_for('B') -> 'C[String]' # 'D'.upcast_for('A') -> 'A[String]' - meth upcast_for(c: MMLocalClass): MMType is abstract + fun upcast_for(c: MMLocalClass): MMType is abstract # Return a type approximation if the reveiver is not self # Useful for virtual types - meth not_for_self: MMType do return self + fun not_for_self: MMType do return self # The nullable version of self (if needed) - attr _as_nullable_cache: MMType = null + var _as_nullable_cache: nullable MMType = null # IS the type can accept null? - meth is_nullable: Bool do return false + fun is_nullable: Bool do return false # Return the nullable version of the type # Noop if already nullable - meth as_nullable: MMType do + fun as_nullable: MMType do var cache = _as_nullable_cache if cache != null then return cache var res = new MMNullableType(self) @@ -367,79 +375,75 @@ abstract class MMType # Return the not null version of the type # Noop if already not null - meth as_notnull: MMType do return self + fun as_notnull: MMType do return self end class MMNullableType -special MMType - attr _base_type: MMType - redef meth is_valid do return _base_type.is_valid - redef meth is_nullable: Bool do return true - redef meth as_notnull do return _base_type - redef meth as_nullable do return self + super MMType + var _base_type: MMType + redef fun is_valid do return _base_type.is_valid + redef fun is_nullable: Bool do return true + redef fun as_notnull do return _base_type + redef fun as_nullable do return self init(t: MMType) do _base_type = t - redef meth module do return _base_type.module + redef fun mmmodule do return _base_type.mmmodule - redef meth local_class do return _base_type.local_class + redef fun local_class do return _base_type.local_class - redef meth <(t) + redef fun <(t) do return t isa MMNullableType and _base_type < t.as_notnull end - redef meth to_s + redef fun to_s do return "nullable {_base_type}" end - redef meth is_supertype(t) + redef fun is_supertype(t) do return _base_type.is_supertype(t) end - redef meth for_module(mod) + redef fun for_module(mod) do return _base_type.for_module(mod).as_nullable end - redef meth adapt_to(recv) + redef fun adapt_to(recv) do return _base_type.adapt_to(recv).as_nullable end - redef meth upcast_for(c) + redef fun upcast_for(c) do return _base_type.upcast_for(c) end - redef meth not_for_self + redef fun not_for_self do return _base_type.not_for_self.as_nullable end end class MMTypeClass -special MMType - redef readable attr _local_class: MMLocalClass - redef meth module do return _local_class.module end - redef meth <(t) do return t != null and t.is_supertype(self) + super MMType + redef readable var _local_class: MMLocalClass + redef fun mmmodule do return _local_class.mmmodule end + redef fun <(t) do return t.is_supertype(self) - redef meth to_s + redef fun to_s do return _local_class.to_s end - redef meth upcast_for(c) + redef fun upcast_for(c) do - assert _local_class != null - assert c != null - var t: MMType = self if _local_class != c then t = _local_class.ancestor(c) end - assert t != null return t end @@ -450,23 +454,22 @@ special MMType end class MMTypeSimpleClass -special MMTypeClass - redef meth is_supertype(t) + super MMTypeClass + redef fun is_supertype(t) do return t.local_class.cshe <= _local_class end - redef meth for_module(mod) + redef fun for_module(mod) do var t: MMType = self - if module != mod then + if mmmodule != mod then t = _local_class.for_module(mod).get_type end - assert t != null return t end - redef meth adapt_to(recv) do return self + redef fun adapt_to(recv) do return self init(c: MMLocalClass) do @@ -476,21 +479,27 @@ end # The type of null class MMTypeNone -special MMType - redef readable attr _module: MMModule - redef meth is_nullable: Bool do return true - redef meth <(t) do return t isa MMTypeNone or t isa MMNullableType - redef meth to_s do return "null" - redef meth is_supertype(t) do return false - redef meth local_class do abort - redef meth upcast_for(c) do abort - redef meth as_nullable do return self - redef meth as_notnull do abort - - private init(m: MMModule) do _module = m + super MMType + redef readable var _mmmodule: MMModule + redef fun is_nullable: Bool do return true + redef fun <(t) do return t isa MMTypeNone or t isa MMNullableType + redef fun to_s do return "null" + redef fun is_supertype(t) do return false + redef fun local_class do abort + redef fun upcast_for(c) do abort + redef fun as_nullable do return self + redef fun as_notnull do abort + + private init(m: MMModule) do _mmmodule = m end redef class MMModule # The type of null - readable attr _type_none: MMTypeNone = new MMTypeNone(self) + readable var _type_none: MMTypeNone = new MMTypeNone(self) + + # The type of bool + fun type_bool: MMType + do + return class_by_name(once ("Bool".to_symbol)).get_type + end end