self.mparameters = mparametertypes
var mclass_type = new MGenericType(self, mparametertypes)
self.mclass_type = mclass_type
- self.get_mtype_cache.add(mclass_type)
+ self.get_mtype_cache[mparametertypes] = mclass_type
else
self.mclass_type = new MClassType(self)
end
do
assert mtype_arguments.length == self.arity
if self.arity == 0 then return self.mclass_type
- for t in self.get_mtype_cache do
- if t.arguments == mtype_arguments then
- return t
- end
- end
- var res = new MGenericType(self, mtype_arguments)
- self.get_mtype_cache.add res
+ var res = get_mtype_cache.get_or_null(mtype_arguments)
+ if res != null then return res
+ res = new MGenericType(self, mtype_arguments)
+ self.get_mtype_cache[mtype_arguments.to_a] = res
return res
end
- private var get_mtype_cache = new Array[MGenericType]
+ private var get_mtype_cache = new HashMap[Array[MType], MGenericType]
end
# In Nit, for each super-class of a type, there is a equivalent super-type.
#
# Example:
+ #
+ # ~~~nitish
# class G[T, U] end
# class H[V] super G[V, Bool] end
+ #
# H[Int] supertype_to G #-> G[Int, Bool]
+ # ~~~
#
# REQUIRE: `super_mclass` is a super-class of `self`
# REQUIRE: `self.need_anchor implies anchor != null and self.can_resolve_for(anchor, null, mmodule)`
#
# ## Example 1
#
- # class G[E] end
- # class H[F] super G[F] end
- # class X[Z] end
+ # ~~~
+ # class G[E] end
+ # class H[F] super G[F] end
+ # class X[Z] end
+ # ~~~
#
# * Array[E].resolve_for(H[Int]) #-> Array[Int]
# * Array[E].resolve_for(G[Z], X[Int]) #-> Array[Z]
#
# ## Example 2
#
- # class A[E]
- # fun foo(e:E):E is abstract
- # end
- # class B super A[Int] end
+ # ~~~
+ # class A[E]
+ # fun foo(e:E):E is abstract
+ # end
+ # class B super A[Int] end
+ # ~~~
#
# The signature on foo is (e: E): E
# If we resolve the signature for B, we get (e:Int):Int
#
# ## Example 3
#
- # class A[E]
- # fun foo(e:E) is abstract
- # end
- # class B[F]
- # var a: A[Array[F]]
- # fun bar do a.foo(x) # <- x is here
- # end
+ # ~~~nitish
+ # class A[E]
+ # fun foo(e:E):E is abstract
+ # end
+ # class C[F]
+ # var a: A[Array[F]]
+ # fun bar do a.foo(x) # <- x is here
+ # end
+ # ~~~
#
# The first question is: is foo available on `a`?
#
# The static type of a is `A[Array[F]]`, that is an open type.
# in order to find a method `foo`, whe must look at a resolved type.
#
- # A[Array[F]].anchor_to(B[nullable Object]) #-> A[Array[nullable Object]]
+ # A[Array[F]].anchor_to(C[nullable Object]) #-> A[Array[nullable Object]]
#
# the method `foo` exists in `A[Array[nullable Object]]`, therefore `foo` exists for `a`.
#
#
# the signature of `foo` is `foo(e:E)`, thus we must resolve the type E
#
- # E.resolve_for(A[Array[F]],B[nullable Object]) #-> Array[F]
+ # E.resolve_for(A[Array[F]],C[nullable Object]) #-> Array[F]
#
# The resolution can be done because `E` make sense for the class A (see `can_resolve_for`)
#
redef fun collect_mclasses(mmodule)
do
+ if collect_mclasses_last_module == mmodule then return collect_mclasses_last_module_cache
assert not self.need_anchor
var cache = self.collect_mclasses_cache
if not cache.has_key(mmodule) then
self.collect_things(mmodule)
end
- return cache[mmodule]
+ var res = cache[mmodule]
+ collect_mclasses_last_module = mmodule
+ collect_mclasses_last_module_cache = res
+ return res
end
+ private var collect_mclasses_last_module: nullable MModule = null
+ private var collect_mclasses_last_module_cache: Set[MClass] is noinit
+
redef fun collect_mtypes(mmodule)
do
assert not self.need_anchor