Add explicit fast path in TypeCheckerContext::anySupertype

This commit is contained in:
Denis Zharkov
2017-10-03 19:36:53 +03:00
parent b99658b8eb
commit f81c7a1a47
@@ -70,6 +70,8 @@ open class TypeCheckerContext(val errorTypeEqualsToAnything: Boolean, val allowe
predicate: (SimpleType) -> Boolean, predicate: (SimpleType) -> Boolean,
supertypesPolicy: (SimpleType) -> SupertypesPolicy supertypesPolicy: (SimpleType) -> SupertypesPolicy
): Boolean { ): Boolean {
if (predicate(start)) return true
initialize() initialize()
val deque = supertypesDeque!! val deque = supertypesDeque!!
@@ -81,18 +83,17 @@ open class TypeCheckerContext(val errorTypeEqualsToAnything: Boolean, val allowe
error("Too many supertypes for type: $start. Supertypes = ${visitedSupertypes.joinToString()}") error("Too many supertypes for type: $start. Supertypes = ${visitedSupertypes.joinToString()}")
} }
val current = deque.pop() val current = deque.pop()
if (!visitedSupertypes.add(current)) continue
if (!visitedSupertypes.add(current)) {
continue
}
if (predicate(current)) {
clear()
return true
}
val policy = supertypesPolicy(current).takeIf { it != SupertypesPolicy.None } ?: continue val policy = supertypesPolicy(current).takeIf { it != SupertypesPolicy.None } ?: continue
for (supertype in current.constructor.supertypes) deque.add(policy.transformType(supertype)) for (supertype in current.constructor.supertypes) {
val newType = policy.transformType(supertype)
if (predicate(newType)) {
clear()
return true
}
deque.add(newType)
}
} }
clear() clear()