@@ -4966,41 +4966,57 @@ object Types {
4966
4966
}
4967
4967
4968
4968
class TypeSizeAccumulator (implicit ctx : Context ) extends TypeAccumulator [Int ] {
4969
- def apply (n : Int , tp : Type ): Int = tp match {
4970
- case tp : AppliedType =>
4971
- foldOver(n + 1 , tp)
4972
- case tp : RefinedType =>
4973
- foldOver(n + 1 , tp)
4974
- case tp : TypeRef if tp.info.isTypeAlias =>
4975
- apply(n, tp.superType)
4976
- case tp : TypeParamRef =>
4977
- apply(n, ctx.typeComparer.bounds(tp))
4978
- case _ =>
4979
- foldOver(n, tp)
4969
+ val seen : util.HashSet [Type ] = new util.HashSet [Type ](64 ) {
4970
+ override def hash (x : Type ): Int = System .identityHashCode(x)
4971
+ override def isEqual (x : Type , y : Type ) = x.eq(y)
4972
+ }
4973
+ def apply (n : Int , tp : Type ): Int =
4974
+ if (seen contains tp) n
4975
+ else {
4976
+ seen.addEntry(tp)
4977
+ tp match {
4978
+ case tp : AppliedType =>
4979
+ foldOver(n + 1 , tp)
4980
+ case tp : RefinedType =>
4981
+ foldOver(n + 1 , tp)
4982
+ case tp : TypeRef if tp.info.isTypeAlias =>
4983
+ apply(n, tp.superType)
4984
+ case tp : TypeParamRef if ! seen(tp) =>
4985
+ apply(n, ctx.typeComparer.bounds(tp))
4986
+ case _ =>
4987
+ foldOver(n, tp)
4988
+ }
4980
4989
}
4981
4990
}
4982
4991
4983
4992
class CoveringSetAccumulator (implicit ctx : Context ) extends TypeAccumulator [Set [Symbol ]] {
4993
+ val seen : util.HashSet [Type ] = new util.HashSet [Type ](64 ) {
4994
+ override def hash (x : Type ): Int = System .identityHashCode(x)
4995
+ override def isEqual (x : Type , y : Type ) = x.eq(y)
4996
+ }
4984
4997
def apply (cs : Set [Symbol ], tp : Type ): Set [Symbol ] = {
4985
- val sym = tp.typeSymbol
4986
- tp match {
4987
- case tp if tp.isTopType || tp.isBottomType =>
4988
- cs
4989
- case tp : AppliedType =>
4990
- foldOver(cs + sym, tp)
4991
- case tp : RefinedType =>
4992
- foldOver(cs + sym, tp)
4993
- case tp : TypeRef if tp.info.isTypeAlias =>
4994
- apply(cs, tp.superType)
4995
- case tp : TypeRef if sym.isClass =>
4996
- foldOver(cs + sym, tp)
4997
- case tp : TermRef =>
4998
- val tsym = if (tp.termSymbol.is(Param )) tp.underlying.typeSymbol else tp.termSymbol
4999
- foldOver(cs + tsym, tp)
5000
- case tp : TypeParamRef =>
5001
- apply(cs, ctx.typeComparer.bounds(tp))
5002
- case other =>
5003
- foldOver(cs, tp)
4998
+ if (seen contains tp) cs
4999
+ else {
5000
+ seen.addEntry(tp)
5001
+ tp match {
5002
+ case tp if tp.isTopType || tp.isBottomType =>
5003
+ cs
5004
+ case tp : AppliedType =>
5005
+ foldOver(cs + tp.typeSymbol, tp)
5006
+ case tp : RefinedType =>
5007
+ foldOver(cs + tp.typeSymbol, tp)
5008
+ case tp : TypeRef if tp.info.isTypeAlias =>
5009
+ apply(cs, tp.superType)
5010
+ case tp : TypeRef if tp.typeSymbol.isClass =>
5011
+ foldOver(cs + tp.typeSymbol, tp)
5012
+ case tp : TermRef =>
5013
+ val tsym = if (tp.termSymbol.is(Param )) tp.underlying.typeSymbol else tp.termSymbol
5014
+ foldOver(cs + tsym, tp)
5015
+ case tp : TypeParamRef =>
5016
+ apply(cs, ctx.typeComparer.bounds(tp))
5017
+ case other =>
5018
+ foldOver(cs, tp)
5019
+ }
5004
5020
}
5005
5021
}
5006
5022
}
0 commit comments