Fix bug when onEach extension call is not found for arrays
This commit is contained in:
committed by
Yan Zhulanow
parent
aa7f1073e6
commit
7c417a59dc
+31
-7
@@ -6,18 +6,22 @@ import com.intellij.debugger.streams.kotlin.psi.KotlinPsiUtil
|
||||
import com.intellij.debugger.streams.kotlin.psi.callName
|
||||
import com.intellij.debugger.streams.kotlin.psi.resolveType
|
||||
import com.intellij.debugger.streams.psi.ChainTransformer
|
||||
import com.intellij.debugger.streams.trace.impl.handler.type.GenericType
|
||||
import com.intellij.debugger.streams.wrapper.CallArgument
|
||||
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
|
||||
import com.intellij.debugger.streams.wrapper.QualifierExpression
|
||||
import com.intellij.debugger.streams.wrapper.StreamChain
|
||||
import com.intellij.debugger.streams.wrapper.impl.*
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
@@ -37,15 +41,10 @@ class KotlinChainTransformerImpl(private val typeExtractor: CallTypeExtractor) :
|
||||
terminationsPsiCall.valueArguments.map { createCallArgument(terminationsPsiCall, it) },
|
||||
typeBeforeTerminator, resultType, terminationsPsiCall.textRange)
|
||||
|
||||
val qualifierTypeAfter =
|
||||
val typeAfterQualifier =
|
||||
if (intermediateCalls.isEmpty()) typeBeforeTerminator else intermediateCalls.first().typeBefore
|
||||
|
||||
val firstCall = callChain.first()
|
||||
val parent = firstCall.parent
|
||||
val qualifier = if (parent is KtDotQualifiedExpression)
|
||||
QualifierExpressionImpl(parent.receiverExpression.text, parent.receiverExpression.textRange, qualifierTypeAfter)
|
||||
else // This is possible only when {@code this} inherits Stream/Iterable/Sequence/etc
|
||||
QualifierExpressionImpl("", TextRange.EMPTY_RANGE, qualifierTypeAfter)
|
||||
val qualifier = createQualifier(callChain.first(), typeAfterQualifier)
|
||||
|
||||
return StreamChainImpl(qualifier, intermediateCalls, terminationCall, context)
|
||||
}
|
||||
@@ -61,4 +60,29 @@ class KotlinChainTransformerImpl(private val typeExtractor: CallTypeExtractor) :
|
||||
val parameter = resolvedCall.getParameterForArgument(arg) ?: return arg.toCallArgument()
|
||||
return CallArgumentImpl(KotlinPsiUtil.getTypeName(parameter.type), arg.text)
|
||||
}
|
||||
|
||||
private fun createQualifier(expression: PsiElement, typeAfter: GenericType): QualifierExpression {
|
||||
val parent = expression.parent as? KtDotQualifiedExpression
|
||||
?: return QualifierExpressionImpl("", TextRange.EMPTY_RANGE, typeAfter)
|
||||
val receiver = parent.receiverExpression
|
||||
val qualifier = QualifierExpressionImpl(receiver.text, receiver.textRange, typeAfter)
|
||||
if (receiver.resolveType().isArray) {
|
||||
return WrappedQualifier(qualifier)
|
||||
}
|
||||
|
||||
return qualifier
|
||||
}
|
||||
|
||||
/**
|
||||
* Kotlin arrays has not {@code onEach} extension. But current implementation uses onEach to increment a time counter.
|
||||
* We use asIterable to avoid further issues with the transformed expression evaluation
|
||||
*/
|
||||
private class WrappedQualifier(private val qualifierExpression: QualifierExpression)
|
||||
: QualifierExpression by qualifierExpression {
|
||||
override val text: String
|
||||
get() = qualifierExpression.text + ".asIterable()"
|
||||
}
|
||||
|
||||
private val KotlinType.isArray: Boolean
|
||||
get() = KotlinBuiltIns.isArray(this) || KotlinBuiltIns.isPrimitiveArray(this)
|
||||
}
|
||||
|
||||
+12
-9
@@ -2,15 +2,18 @@ LineBreakpoint created at FilterPrimitiveAsTermination.kt:5
|
||||
Run Java
|
||||
Connected to the target VM
|
||||
FilterPrimitiveAsTermination.kt:5
|
||||
Exception caught: junit.framework.AssertionFailedError: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
|
||||
@SinceKotlin public inline fun <S : CharSequence> ???.onEach(action: (Char) -> Unit): ??? defined in kotlin.text
|
||||
@SinceKotlin public inline fun <T, C : Iterable<???>> ByteArray.onEach(action: (???) -> Unit): ByteArray defined in kotlin.collections
|
||||
@SinceKotlin public inline fun <K, V, M : Map<out ???, ???>> ByteArray.onEach(action: (Map.Entry<???, ???>) -> Unit): ByteArray defined in kotlin.collections
|
||||
@SinceKotlin public fun <T> Sequence<???>.onEach(action: (???) -> Unit): Sequence<???> defined in kotlin.sequences, Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
|
||||
@SinceKotlin public inline fun <S : CharSequence> ???.onEach(action: (Char) -> Unit): ??? defined in kotlin.text
|
||||
@SinceKotlin public inline fun <T, C : Iterable<???>> ByteArray.onEach(action: (???) -> Unit): ByteArray defined in kotlin.collections
|
||||
@SinceKotlin public inline fun <K, V, M : Map<out ???, ???>> ByteArray.onEach(action: (Map.Entry<???, ???>) -> Unit): ByteArray defined in kotlin.collections
|
||||
@SinceKotlin public fun <T> Sequence<???>.onEach(action: (???) -> Unit): Sequence<???> defined in kotlin.sequences
|
||||
byteArrayOf(1, 3, 50).asIterable()
|
||||
.filter({ it == 50.toByte() })
|
||||
filter
|
||||
before: 4,6,8
|
||||
after: 8
|
||||
mappings for filter
|
||||
direct:
|
||||
4 -> nothing
|
||||
6 -> nothing
|
||||
8 -> 8
|
||||
reverse:
|
||||
8 <- 8
|
||||
Disconnected from the target VM
|
||||
|
||||
WRONG!
|
||||
|
||||
Reference in New Issue
Block a user