Given a function that returns a sequence of a superclass/interface, such as [1]:
fun PsiElement.descendants(): Sequence<PsiElement> {
return PsiElementWalker(firstChild, PsiElement::getFirstChild).asSequence()
}
using first/firstOrNull to find an element of a given class:
val module: PsiElement? = children().firstOrNull { e -> e is XQueryModule }
val versionDecl: XQueryVersionDecl? = module?.descendants()?.firstOrNull { e -> e is XQueryVersionDecl } as? XQueryVersionDecl
requires an additional cast (as seen in the versionDecl example). That is, expressions of the following forms require an extra cast:
val item: T = items.first { e -> e is T } as T
val item: T? = items.firstOrNull { e -> e is T } as? T
That is, the as
is redundant due to the is
check. It would be useful if Kotlin could infer the type and avoid the duplicated cast. This would be generally applicable to any predicate that checks for a type. This would then support the following:
val item: T = items.first { e -> e is T }
val item: T? = items.firstOrNull { e -> e is T }
In Java, I can do this by using things like:
public interface Sequence<A> {
<B extends A> B first(Predicate<A> matcher);
default <B extends A> B first(Class<B> c) {
return findFirst(c::isInstance);
}
}
and use:
T item = items.first(T.class)