X-Git-Url: http://nitlanguage.org diff --git a/src/metamodel/static_type.nit b/src/metamodel/static_type.nit index bf4616f..25b41f8 100644 --- a/src/metamodel/static_type.nit +++ b/src/metamodel/static_type.nit @@ -82,6 +82,9 @@ class MMSignature # The return type readable attr _return_type: MMType + # The closure parameters + readable attr _closures: Array[MMClosure] = new Array[MMClosure] + # Number of parameters meth arity: Int do @@ -107,6 +110,11 @@ class MMSignature return false end end + + if closures.length != s.closures.length then return false + for i in [0..closures.length[ do + if not s.closures[i] < closures[i] then return false + end return true end @@ -119,7 +127,7 @@ class MMSignature redef meth to_s do - var s: String + var s = new Buffer if _params != null and _params.length > 0 then var tmp: String var a = new Array[String].with_capacity(_params.length) @@ -129,14 +137,12 @@ class MMSignature #a.add("{pn}: {p}") a.add(p.to_s) end - s = "({a.join(",")})" - else - s = "" + s.append("({a.join(",")})") end if _return_type != null then s.append(": {_return_type}") end - return s + return s.to_s end # Adapt the signature to a different receiver @@ -157,10 +163,14 @@ class MMSignature if rv != null then rv = rv.for_module(mod).adapt_to(r) end - return new MMSignature(p,rv,r) + var res = new MMSignature(p,rv,r) + for clos in _closures do + res.closures.add(clos.adaptation_to(r)) + end + return res end - attr _not_for_self_cache: MMSignature + attr _not_for_self_cache: MMSignature = null # Return a type approximation if the reveiver is not self # Useful for virtual types @@ -176,18 +186,29 @@ class MMSignature for i in _params do var i2 = i.not_for_self if i != i2 then need_for_self = true - p.add(i.not_for_self) + p.add(i2) end end var rv = _return_type if rv != null then - var rv = rv.not_for_self + 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 + end if need_for_self then res = new MMSignature(p, rv, _recv) + res.closures.add_all(clos) else res = self end @@ -205,6 +226,50 @@ class MMSignature end end +# A closure in a signature +class MMClosure + # The signature of the closure + readable attr _signature: MMSignature + + # Is the closure a brek one + # aka is defined with the break keyword thus does not return + readable attr _is_break: Bool + + # Is the closure optional? + # ie is there a default definition + readable attr _is_optional: Bool + + # Adapt the signature to a different receiver + meth adaptation_to(r: MMType): MMClosure + do + return new MMClosure(_signature.adaptation_to(r), _is_break, _is_optional) + end + + init(s: MMSignature, is_break: Bool, is_optional: Bool) + do + _signature = s + _is_break = is_break + _is_optional = is_optional + end + + meth not_for_self: MMClosure + do + var sig = _signature.not_for_self + if sig != _signature then + return new MMClosure(sig, _is_break, _is_optional) + else + return self + end + end + + meth <(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 + return c.signature < signature + end +end + # Inheritance relation between two types abstract class MMAncestor # The inherited type @@ -260,6 +325,24 @@ abstract class MMType # Adapt self to another local class context # Useful for genericity + # 'c' Must be a super-class of self + # Example: + # class A[E] + # class B[F] special A[F] + # class C[G] special B[String] + # class D special C[Float] + # 'A[Int]'.upcast_for('A') -> 'A[Int]' + # 'A[Int]'.upcast_for('B') -> abort + # 'B[Int]'.upcast_for('B') -> 'B[Int]' + # 'B[Int]'.upcast_for('A') -> 'A[Int]' + # 'B[Int]'.upcast_for('C') -> abort + # 'C[Int]'.upcast_for('C') -> 'C[Int]' + # 'C[Int]'.upcast_for('B') -> 'B[String]' + # 'C[Int]'.upcast_for('A') -> 'A[String]' + # 'D'.upcast_for('D') -> 'D' + # '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 # Return a type approximation if the reveiver is not self @@ -325,11 +408,12 @@ end # The type of null class MMTypeNone special MMType - redef readable attr _module: MMModule - redef meth <(t) do return true - redef meth is_supertype(t) do return false - redef meth local_class do abort - redef meth upcast_for(c) do return self + redef readable attr _module: MMModule + redef meth <(t) do return true + 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 private init(m: MMModule) do _module = m end