From 6d395dffbb007a00572d526b929c34cee46d37fa Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Sat, 14 Oct 2017 17:19:34 +0300 Subject: [PATCH] Move stream call checks into separate class --- .../lib/JavaStandardLibrarySupportProvider.kt | 3 ++- .../lib/StreamExLibrarySupportProvider.kt | 3 ++- .../streams/kotlin/psi/StreamCallChecker.kt | 13 ++++++++++ .../psi/impl/KotlinJavaStreamChainBuilder.kt | 25 +++++++------------ .../PackageBasedCallChecker.kt} | 21 ++++++---------- 5 files changed, 34 insertions(+), 31 deletions(-) create mode 100644 idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamCallChecker.kt rename idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/{StreamApiUtil.kt => impl/PackageBasedCallChecker.kt} (62%) diff --git a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/JavaStandardLibrarySupportProvider.kt b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/JavaStandardLibrarySupportProvider.kt index 723b65337dc..757402495fa 100644 --- a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/JavaStandardLibrarySupportProvider.kt +++ b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/JavaStandardLibrarySupportProvider.kt @@ -1,6 +1,7 @@ package com.intellij.debugger.streams.kotlin.lib import com.intellij.debugger.streams.kotlin.psi.impl.KotlinJavaStreamChainBuilder +import com.intellij.debugger.streams.kotlin.psi.impl.PackageBasedCallChecker import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinStatementFactory import com.intellij.debugger.streams.kotlin.trace.impl.KotlinTraceExpressionBuilder import com.intellij.debugger.streams.lib.LibrarySupport @@ -16,7 +17,7 @@ import com.intellij.openapi.project.Project */ class JavaStandardLibrarySupportProvider : LibrarySupportProvider { private companion object { - val builder = KotlinJavaStreamChainBuilder() + val builder = KotlinJavaStreamChainBuilder(PackageBasedCallChecker("java.util.stream")) val support = StandardLibrarySupport() val dsl = DslImpl(KotlinStatementFactory()) } diff --git a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/StreamExLibrarySupportProvider.kt b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/StreamExLibrarySupportProvider.kt index 81ea945993d..bcd4addd2ad 100644 --- a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/StreamExLibrarySupportProvider.kt +++ b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/lib/StreamExLibrarySupportProvider.kt @@ -1,6 +1,7 @@ package com.intellij.debugger.streams.kotlin.lib import com.intellij.debugger.streams.kotlin.psi.impl.KotlinJavaStreamChainBuilder +import com.intellij.debugger.streams.kotlin.psi.impl.PackageBasedCallChecker import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinStatementFactory import com.intellij.debugger.streams.kotlin.trace.impl.KotlinTraceExpressionBuilder import com.intellij.debugger.streams.lib.LibrarySupport @@ -16,7 +17,7 @@ import com.intellij.openapi.project.Project */ class StreamExLibrarySupportProvider : LibrarySupportProvider { private companion object { - val streamChainBuilder = KotlinJavaStreamChainBuilder() + val streamChainBuilder = KotlinJavaStreamChainBuilder(PackageBasedCallChecker("one.util.streamex")) val support = StreamExLibrarySupport() val dsl = DslImpl(KotlinStatementFactory()) val expressionBuilder = KotlinTraceExpressionBuilder(dsl, support.createHandlerFactory(dsl)) diff --git a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamCallChecker.kt b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamCallChecker.kt new file mode 100644 index 00000000000..f63a85b3d24 --- /dev/null +++ b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamCallChecker.kt @@ -0,0 +1,13 @@ +package com.intellij.debugger.streams.kotlin.psi + +import org.jetbrains.kotlin.psi.KtCallExpression + +/** + * @author Vitaliy.Bibaev + */ +interface StreamCallChecker { + fun isIntermediateCall(expression: KtCallExpression): Boolean + fun isTerminationCall(expression: KtCallExpression): Boolean + + fun isStreamCall(expression: KtCallExpression): Boolean = isIntermediateCall(expression) || isTerminationCall(expression) +} diff --git a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/KotlinJavaStreamChainBuilder.kt b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/KotlinJavaStreamChainBuilder.kt index f122c90b63a..fb3aa068995 100644 --- a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/KotlinJavaStreamChainBuilder.kt +++ b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/KotlinJavaStreamChainBuilder.kt @@ -15,10 +15,7 @@ */ package com.intellij.debugger.streams.kotlin.psi.impl -import com.intellij.debugger.streams.kotlin.psi.StreamApiUtil -import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.kotlin.idea.caches.resolve.analyze -import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName +import com.intellij.debugger.streams.kotlin.psi.StreamCallChecker import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import java.util.* @@ -26,42 +23,38 @@ import java.util.* /** * @author Vitaliy.Bibaev */ -class KotlinJavaStreamChainBuilder : KotlinChainBuilderBase(KotlinChainTransformerImpl()) { +class KotlinJavaStreamChainBuilder(private val callChecker: StreamCallChecker) : KotlinChainBuilderBase(KotlinChainTransformerImpl()) { override val existenceChecker: ExistenceChecker = MyExistenceChecker() override fun createChainsBuilder(): ChainBuilder = MyBuilderVisitor() - private class MyExistenceChecker : ExistenceChecker() { + private inner class MyExistenceChecker : ExistenceChecker() { override fun visitCallExpression(expression: KtCallExpression) { - // TODO: make the check more sophisticated - val type = expression.analyze().getType(expression) ?: return - - val name = type.getJetTypeFqName(false) - if (StringUtil.getPackageName(name).startsWith("java.util.stream")) { + if (callChecker.isTerminationCall(expression)) { fireElementFound() } } } - private class MyBuilderVisitor : ChainBuilder() { + private inner class MyBuilderVisitor : ChainBuilder() { private val myTerminationCalls = mutableSetOf() private val myPreviousCalls = mutableMapOf() override fun visitCallExpression(expression: KtCallExpression) { super.visitCallExpression(expression) - if (!myPreviousCalls.containsKey(expression) && StreamApiUtil.isStreamCall(expression)) { + if (!myPreviousCalls.containsKey(expression) && callChecker.isStreamCall(expression)) { updateCallTree(expression) } } private fun updateCallTree(expression: KtCallExpression) { - if (StreamApiUtil.isTerminationStreamCall(expression)) { + if (callChecker.isTerminationCall(expression)) { myTerminationCalls.add(expression) } val parent = expression.parent as? KtDotQualifiedExpression ?: return val parentCall = (parent.receiverExpression as? KtDotQualifiedExpression)?.selectorExpression - if (parentCall is KtCallExpression && StreamApiUtil.isStreamCall(parentCall)) { + if (parentCall is KtCallExpression && callChecker.isStreamCall(parentCall)) { myPreviousCalls.put(expression, parentCall) updateCallTree(parentCall) } @@ -73,7 +66,7 @@ class KotlinJavaStreamChainBuilder : KotlinChainBuilderBase(KotlinChainTransform val chain = ArrayList() var current: KtCallExpression? = terminationCall while (current != null) { - if (StreamApiUtil.isProducerStreamCall(current)) { + if (!callChecker.isStreamCall(current)) { break } chain.add(current) diff --git a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamApiUtil.kt b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/PackageBasedCallChecker.kt similarity index 62% rename from idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamApiUtil.kt rename to idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/PackageBasedCallChecker.kt index 668437c0d81..e653b58cda5 100644 --- a/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/StreamApiUtil.kt +++ b/idea/idea-jvm/src/com/intellij/debugger/streams/kotlin/psi/impl/PackageBasedCallChecker.kt @@ -1,5 +1,8 @@ -package com.intellij.debugger.streams.kotlin.psi +package com.intellij.debugger.streams.kotlin.psi.impl +import com.intellij.debugger.streams.kotlin.psi.StreamCallChecker +import com.intellij.debugger.streams.kotlin.psi.receiverType +import com.intellij.debugger.streams.kotlin.psi.resolveType import com.intellij.openapi.util.text.StringUtil import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName import org.jetbrains.kotlin.psi.KtCallExpression @@ -8,20 +11,12 @@ import org.jetbrains.kotlin.types.KotlinType /** * @author Vitaliy.Bibaev */ -object StreamApiUtil { - fun isStreamCall(expression: KtCallExpression): Boolean { - return isIntermediateStreamCall(expression) || isProducerStreamCall(expression) || isTerminationStreamCall(expression) - } - - fun isProducerStreamCall(expression: KtCallExpression): Boolean { - return checkCallSupported(expression, false, true) - } - - private fun isIntermediateStreamCall(expression: KtCallExpression): Boolean { +class PackageBasedCallChecker(private val supportedPackage: String) : StreamCallChecker { + override fun isIntermediateCall(expression: KtCallExpression): Boolean { return checkCallSupported(expression, true, true) } - fun isTerminationStreamCall(expression: KtCallExpression): Boolean { + override fun isTerminationCall(expression: KtCallExpression): Boolean { return checkCallSupported(expression, true, false) } @@ -41,6 +36,6 @@ object StreamApiUtil { } val typeName = type.getJetTypeFqName(false) - return StringUtil.getPackageName(typeName).startsWith("java.util.stream") + return StringUtil.getPackageName(typeName).startsWith(supportedPackage) } } \ No newline at end of file