Add additional classes and interfaces to infer types of chain items
This commit is contained in:
committed by
Yan Zhulanow
parent
d14cc77003
commit
4969de404e
@@ -0,0 +1,15 @@
|
|||||||
|
package com.intellij.debugger.streams.kotlin.psi
|
||||||
|
|
||||||
|
import com.intellij.debugger.streams.trace.impl.handler.type.GenericType
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vitaliy.Bibaev
|
||||||
|
*/
|
||||||
|
interface CallTypeExtractor {
|
||||||
|
fun extractIntermediateCallTypes(call: KtCallExpression): IntermediateCallTypes
|
||||||
|
fun extractTerminalCallTypes(call: KtCallExpression): TerminatorCallTypes
|
||||||
|
|
||||||
|
data class IntermediateCallTypes(val typeBefore: GenericType, val typeAfter: GenericType)
|
||||||
|
data class TerminatorCallTypes(val typeBefore: GenericType, val resultType: GenericType)
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package com.intellij.debugger.streams.kotlin.psi.impl
|
||||||
|
|
||||||
|
import com.intellij.debugger.streams.kotlin.psi.CallTypeExtractor
|
||||||
|
import com.intellij.debugger.streams.kotlin.psi.CallTypeExtractor.IntermediateCallTypes
|
||||||
|
import com.intellij.debugger.streams.kotlin.psi.CallTypeExtractor.TerminatorCallTypes
|
||||||
|
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinTypes
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vitaliy.Bibaev
|
||||||
|
*/
|
||||||
|
class JavaStreamChainTypeExtractor : CallTypeExtractor {
|
||||||
|
override fun extractIntermediateCallTypes(call: KtCallExpression): IntermediateCallTypes =
|
||||||
|
IntermediateCallTypes(KotlinTypes.NULLABLE_ANY, KotlinTypes.NULLABLE_ANY)
|
||||||
|
|
||||||
|
override fun extractTerminalCallTypes(call: KtCallExpression): TerminatorCallTypes =
|
||||||
|
TerminatorCallTypes(KotlinTypes.NULLABLE_ANY, KotlinTypes.NULLABLE_ANY)
|
||||||
|
}
|
||||||
+16
-12
@@ -1,9 +1,9 @@
|
|||||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||||
package com.intellij.debugger.streams.kotlin.psi.impl
|
package com.intellij.debugger.streams.kotlin.psi.impl
|
||||||
|
|
||||||
|
import com.intellij.debugger.streams.kotlin.psi.CallTypeExtractor
|
||||||
import com.intellij.debugger.streams.kotlin.psi.callName
|
import com.intellij.debugger.streams.kotlin.psi.callName
|
||||||
import com.intellij.debugger.streams.kotlin.psi.resolveType
|
import com.intellij.debugger.streams.kotlin.psi.resolveType
|
||||||
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinTypes.NULLABLE_ANY
|
|
||||||
import com.intellij.debugger.streams.psi.ChainTransformer
|
import com.intellij.debugger.streams.psi.ChainTransformer
|
||||||
import com.intellij.debugger.streams.wrapper.CallArgument
|
import com.intellij.debugger.streams.wrapper.CallArgument
|
||||||
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
|
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
|
||||||
@@ -23,26 +23,30 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
/**
|
/**
|
||||||
* @author Vitaliy.Bibaev
|
* @author Vitaliy.Bibaev
|
||||||
*/
|
*/
|
||||||
class KotlinChainTransformerImpl : ChainTransformer<KtCallExpression> {
|
class KotlinChainTransformerImpl(private val typeExtractor: CallTypeExtractor) : ChainTransformer<KtCallExpression> {
|
||||||
override fun transform(callChain: List<KtCallExpression>, context: PsiElement): StreamChain {
|
override fun transform(callChain: List<KtCallExpression>, context: PsiElement): StreamChain {
|
||||||
val firstCall = callChain.first()
|
|
||||||
val parent = firstCall.parent
|
|
||||||
val qualifier = if (parent is KtDotQualifiedExpression)
|
|
||||||
QualifierExpressionImpl(parent.receiverExpression.text, parent.receiverExpression.textRange, NULLABLE_ANY)
|
|
||||||
else
|
|
||||||
QualifierExpressionImpl("", TextRange.EMPTY_RANGE, NULLABLE_ANY) // This is possible only when this inherits Stream
|
|
||||||
|
|
||||||
val intermediateCalls = mutableListOf<IntermediateStreamCall>()
|
val intermediateCalls = mutableListOf<IntermediateStreamCall>()
|
||||||
for (call in callChain.subList(0, callChain.size - 1)) {
|
for (call in callChain.subList(0, callChain.size - 1)) {
|
||||||
|
val (typeBefore, typeAfter) = typeExtractor.extractIntermediateCallTypes(call)
|
||||||
intermediateCalls += IntermediateStreamCallImpl(call.callName(),
|
intermediateCalls += IntermediateStreamCallImpl(call.callName(),
|
||||||
call.valueArguments.map { createCallArgument(call, it) }, NULLABLE_ANY, NULLABLE_ANY, call.textRange)
|
call.valueArguments.map { createCallArgument(call, it) }, typeBefore, typeAfter, call.textRange)
|
||||||
}
|
}
|
||||||
|
|
||||||
val terminationsPsiCall = callChain.last()
|
val terminationsPsiCall = callChain.last()
|
||||||
// TODO: infer true types
|
val (typeBeforeTerminator, resultType) = typeExtractor.extractTerminalCallTypes(terminationsPsiCall)
|
||||||
val terminationCall = TerminatorStreamCallImpl(terminationsPsiCall.callName(),
|
val terminationCall = TerminatorStreamCallImpl(terminationsPsiCall.callName(),
|
||||||
terminationsPsiCall.valueArguments.map { createCallArgument(terminationsPsiCall, it) },
|
terminationsPsiCall.valueArguments.map { createCallArgument(terminationsPsiCall, it) },
|
||||||
NULLABLE_ANY, NULLABLE_ANY, terminationsPsiCall.textRange)
|
typeBeforeTerminator, resultType, terminationsPsiCall.textRange)
|
||||||
|
|
||||||
|
val qualifierTypeAfter =
|
||||||
|
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)
|
||||||
|
|
||||||
return StreamChainImpl(qualifier, intermediateCalls, terminationCall, context)
|
return StreamChainImpl(qualifier, intermediateCalls, terminationCall, context)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -9,7 +9,8 @@ import org.jetbrains.kotlin.psi.KtCallExpression
|
|||||||
/**
|
/**
|
||||||
* @author Vitaliy.Bibaev
|
* @author Vitaliy.Bibaev
|
||||||
*/
|
*/
|
||||||
class KotlinCollectionChainBuilder : KotlinChainBuilderBase(KotlinChainTransformerImpl()) {
|
class KotlinCollectionChainBuilder
|
||||||
|
: KotlinChainBuilderBase(KotlinChainTransformerImpl(KotlinCollectionsTypeExtractor())) {
|
||||||
private companion object {
|
private companion object {
|
||||||
// TODO: Avoid enumeration of all available types
|
// TODO: Avoid enumeration of all available types
|
||||||
val SUPPORTED_RECEIVERS = setOf("kotlin.collections.List", "kotlin.collections.Set")
|
val SUPPORTED_RECEIVERS = setOf("kotlin.collections.List", "kotlin.collections.Set")
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package com.intellij.debugger.streams.kotlin.psi.impl
|
||||||
|
|
||||||
|
import com.intellij.debugger.streams.kotlin.psi.CallTypeExtractor
|
||||||
|
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinTypes
|
||||||
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vitaliy.Bibaev
|
||||||
|
*/
|
||||||
|
class KotlinCollectionsTypeExtractor : CallTypeExtractor {
|
||||||
|
override fun extractIntermediateCallTypes(call: KtCallExpression): CallTypeExtractor.IntermediateCallTypes =
|
||||||
|
CallTypeExtractor.IntermediateCallTypes(KotlinTypes.NULLABLE_ANY, KotlinTypes.NULLABLE_ANY)
|
||||||
|
|
||||||
|
override fun extractTerminalCallTypes(call: KtCallExpression): CallTypeExtractor.TerminatorCallTypes =
|
||||||
|
CallTypeExtractor.TerminatorCallTypes(KotlinTypes.NULLABLE_ANY, KotlinTypes.NULLABLE_ANY)
|
||||||
|
}
|
||||||
+2
-2
@@ -4,13 +4,13 @@ package com.intellij.debugger.streams.kotlin.psi.impl
|
|||||||
import com.intellij.debugger.streams.kotlin.psi.StreamCallChecker
|
import com.intellij.debugger.streams.kotlin.psi.StreamCallChecker
|
||||||
import com.intellij.debugger.streams.kotlin.psi.previousCall
|
import com.intellij.debugger.streams.kotlin.psi.previousCall
|
||||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vitaliy.Bibaev
|
* @author Vitaliy.Bibaev
|
||||||
*/
|
*/
|
||||||
class KotlinJavaStreamChainBuilder(private val callChecker: StreamCallChecker) : KotlinChainBuilderBase(KotlinChainTransformerImpl()) {
|
class KotlinJavaStreamChainBuilder(private val callChecker: StreamCallChecker)
|
||||||
|
: KotlinChainBuilderBase(KotlinChainTransformerImpl(JavaStreamChainTypeExtractor())) {
|
||||||
override val existenceChecker: ExistenceChecker = MyExistenceChecker()
|
override val existenceChecker: ExistenceChecker = MyExistenceChecker()
|
||||||
|
|
||||||
override fun createChainsBuilder(): ChainBuilder = MyBuilderVisitor()
|
override fun createChainsBuilder(): ChainBuilder = MyBuilderVisitor()
|
||||||
|
|||||||
Reference in New Issue
Block a user