Js run configuration producers: get module from ConfigurationContext

Delegate mpp concerns to MultipleRunLocationsProvider EP
Restore old behaviour via bunch files
This commit is contained in:
Pavel V. Talanov
2018-09-10 20:36:49 +02:00
parent 456bf9808d
commit 3a2d25a422
15 changed files with 444 additions and 77 deletions
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.idea.core.platform.impl
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.Library
@@ -21,6 +23,7 @@ import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
import org.jetbrains.kotlin.idea.highlighter.KotlinTestRunLineMarkerContributor.Companion.getTestStateIcon
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
import org.jetbrains.kotlin.idea.run.multiplatform.KotlinMultiplatformRunLocationsProvider
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
@@ -61,13 +64,15 @@ class JsIdePlatformKindTooling : IdePlatformKindTooling() {
override fun getTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
if (!descriptor.isTest()) return null
val contexts by lazy { computeConfigurationContexts(declaration) }
val runConfigData = RunConfigurationProducer
.getProducers(declaration.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { it.isForTests }
.mapNotNull { it.getConfigurationData(declaration) }
.firstOrNull() ?: return null
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.firstOrNull { it != null } ?: return null
val locations = ArrayList<String>()
@@ -93,13 +98,22 @@ class JsIdePlatformKindTooling : IdePlatformKindTooling() {
}
override fun acceptsAsEntryPoint(function: KtFunction): Boolean {
val contexts by lazy { computeConfigurationContexts(function) }
return RunConfigurationProducer
.getProducers(function.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { !it.isForTests }
.mapNotNull { it.getConfigurationData(function) }
.firstOrNull() != null
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.any { it != null }
}
private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence<ConfigurationContext> {
val location = PsiLocation(declaration)
return KotlinMultiplatformRunLocationsProvider().getAlternativeLocations(location).map {
ConfigurationContext.createEmptyContextForLocation(it)
}.ifEmpty { listOf(ConfigurationContext.createEmptyContextForLocation(location)) }.asSequence()
}
private fun DeclarationDescriptor.isIgnored(): Boolean =
@@ -0,0 +1,127 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.core.platform.impl
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.gradle.KotlinPlatform
import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
import org.jetbrains.kotlin.idea.highlighter.KotlinTestRunLineMarkerContributor.Companion.getTestStateIcon
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.PathUtil
import javax.swing.Icon
class JsIdePlatformKindTooling : IdePlatformKindTooling() {
companion object {
private const val MAVEN_OLD_JS_STDLIB_ID = "kotlin-js-library"
private val TEST_FQ_NAME = FqName("kotlin.test.Test")
private val IGNORE_FQ_NAME = FqName("kotlin.test.Ignore")
}
override val kind = JsIdePlatformKind
override fun compilerArgumentsForProject(project: Project) = Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
override val resolverForModuleFactory = JsAnalyzerFacade
override val mavenLibraryIds = listOf(PathUtil.JS_LIB_NAME, MAVEN_OLD_JS_STDLIB_ID)
override val gradlePluginId = "kotlin-platform-js"
override val gradlePlatformIds: List<KotlinPlatform> get() = listOf(KotlinPlatform.JS)
override val libraryKind = JSLibraryKind
override fun getLibraryDescription(project: Project) = JSLibraryStdDescription(project)
override fun getLibraryVersionProvider(project: Project) = { library: Library ->
JsLibraryStdDetectionUtil.getJsLibraryStdVersion(library, project)
}
override fun getTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
if (!descriptor.isTest()) return null
val contexts by lazy { computeConfigurationContexts(declaration) }
val runConfigData = RunConfigurationProducer
.getProducers(declaration.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { it.isForTests }
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.firstOrNull { it != null } ?: return null
val locations = ArrayList<String>()
locations += FileUtil.toSystemDependentName(runConfigData.jsOutputFilePath)
val klass = when (declaration) {
is KtClassOrObject -> declaration
is KtNamedFunction -> declaration.containingClassOrObject ?: return null
else -> return null
}
locations += klass.parentsWithSelf.filterIsInstance<KtNamedDeclaration>().mapNotNull { it.name }.toList().asReversed()
val testName = (declaration as? KtNamedFunction)?.name
if (testName != null) {
locations += "$testName"
}
val prefix = if (testName != null) "test://" else "suite://"
val url = prefix + locations.joinWithEscape('.')
return getTestStateIcon(url, declaration.project)
}
override fun acceptsAsEntryPoint(function: KtFunction): Boolean {
val contexts by lazy { computeConfigurationContexts(function) }
return RunConfigurationProducer
.getProducers(function.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { !it.isForTests }
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.any { it != null }
}
private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence<ConfigurationContext> {
return sequenceOf(ConfigurationContext(declaration))
}
private fun DeclarationDescriptor.isIgnored(): Boolean =
annotations.any { it.fqName == IGNORE_FQ_NAME } || ((containingDeclaration as? ClassDescriptor)?.isIgnored() ?: false)
private fun DeclarationDescriptor.isTest(): Boolean {
if (isIgnored()) return false
if (annotations.any { it.fqName == TEST_FQ_NAME }) return true
if (this is ClassDescriptorWithResolutionScopes) {
return declaredCallableMembers.any { it.isTest() }
}
return false
}
}
@@ -0,0 +1,127 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.core.platform.impl
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.gradle.KotlinPlatform
import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
import org.jetbrains.kotlin.idea.highlighter.KotlinTestRunLineMarkerContributor.Companion.getTestStateIcon
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.PathUtil
import javax.swing.Icon
class JsIdePlatformKindTooling : IdePlatformKindTooling() {
companion object {
private const val MAVEN_OLD_JS_STDLIB_ID = "kotlin-js-library"
private val TEST_FQ_NAME = FqName("kotlin.test.Test")
private val IGNORE_FQ_NAME = FqName("kotlin.test.Ignore")
}
override val kind = JsIdePlatformKind
override fun compilerArgumentsForProject(project: Project) = Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
override val resolverForModuleFactory = JsAnalyzerFacade
override val mavenLibraryIds = listOf(PathUtil.JS_LIB_NAME, MAVEN_OLD_JS_STDLIB_ID)
override val gradlePluginId = "kotlin-platform-js"
override val gradlePlatformIds: List<KotlinPlatform> get() = listOf(KotlinPlatform.JS)
override val libraryKind = JSLibraryKind
override fun getLibraryDescription(project: Project) = JSLibraryStdDescription(project)
override fun getLibraryVersionProvider(project: Project) = { library: Library ->
JsLibraryStdDetectionUtil.getJsLibraryStdVersion(library, project)
}
override fun getTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
if (!descriptor.isTest()) return null
val contexts by lazy { computeConfigurationContexts(declaration) }
val runConfigData = RunConfigurationProducer
.getProducers(declaration.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { it.isForTests }
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.firstOrNull { it != null } ?: return null
val locations = ArrayList<String>()
locations += FileUtil.toSystemDependentName(runConfigData.jsOutputFilePath)
val klass = when (declaration) {
is KtClassOrObject -> declaration
is KtNamedFunction -> declaration.containingClassOrObject ?: return null
else -> return null
}
locations += klass.parentsWithSelf.filterIsInstance<KtNamedDeclaration>().mapNotNull { it.name }.toList().asReversed()
val testName = (declaration as? KtNamedFunction)?.name
if (testName != null) {
locations += "$testName"
}
val prefix = if (testName != null) "test://" else "suite://"
val url = prefix + locations.joinWithEscape('.')
return getTestStateIcon(url, declaration.project)
}
override fun acceptsAsEntryPoint(function: KtFunction): Boolean {
val contexts by lazy { computeConfigurationContexts(function) }
return RunConfigurationProducer
.getProducers(function.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { !it.isForTests }
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.any { it != null }
}
private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence<ConfigurationContext> {
return sequenceOf(ConfigurationContext(declaration))
}
private fun DeclarationDescriptor.isIgnored(): Boolean =
annotations.any { it.fqName == IGNORE_FQ_NAME } || ((containingDeclaration as? ClassDescriptor)?.isIgnored() ?: false)
private fun DeclarationDescriptor.isTest(): Boolean {
if (isIgnored()) return false
if (annotations.any { it.fqName == TEST_FQ_NAME }) return true
if (this is ClassDescriptorWithResolutionScopes) {
return declaredCallableMembers.any { it.isTest() }
}
return false
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.js
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.openapi.module.Module
import com.intellij.psi.PsiElement
@@ -16,5 +17,5 @@ interface KotlinJSRunConfigurationData {
interface KotlinJSRunConfigurationDataProvider<out T : KotlinJSRunConfigurationData> {
val isForTests: Boolean
fun getConfigurationData(element: PsiElement): T?
fun getConfigurationData(context: ConfigurationContext): T?
}
@@ -19,12 +19,10 @@ package org.jetbrains.kotlin.idea.js
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.CompilerModuleExtension
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.idea.caches.project.implementingModules
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.isGradleModule
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.idea.project.platform
import org.jetbrains.kotlin.platform.impl.isJavaScript
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
val Module.jsTestOutputFilePath: String?
@@ -49,11 +47,7 @@ val Module.jsProductionOutputFilePath: String?
return JpsPathUtil.urlToPath("$outputDir/$name.js")
}
fun Module.jsOrJsImpl() = when (TargetPlatformDetector.getPlatform(this)) {
is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform }
is JsPlatform -> this
else -> null
}
fun Module.asJsModule(): Module? = takeIf { it.platform.isJavaScript }
val Module.shouldUseJpsOutput: Boolean
get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake)
@@ -0,0 +1,59 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.js
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.CompilerModuleExtension
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.idea.caches.project.implementingModules
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.isGradleModule
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
val Module.jsTestOutputFilePath: String?
get() {
if (!shouldUseJpsOutput) {
(KotlinFacet.get(this)?.configuration?.settings?.testOutputPath)?.let { return it }
}
val compilerExtension = CompilerModuleExtension.getInstance(this)
val outputDir = compilerExtension?.compilerOutputUrlForTests ?: return null
return JpsPathUtil.urlToPath("$outputDir/${name}_test.js")
}
val Module.jsProductionOutputFilePath: String?
get() {
if (!shouldUseJpsOutput) {
(KotlinFacet.get(this)?.configuration?.settings?.productionOutputPath)?.let { return it }
}
val compilerExtension = CompilerModuleExtension.getInstance(this)
val outputDir = compilerExtension?.compilerOutputUrl ?: return null
return JpsPathUtil.urlToPath("$outputDir/$name.js")
}
fun Module.asJsModule(): Module? = when (TargetPlatformDetector.getPlatform(this)) {
is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform }
is JsPlatform -> this
else -> null
}
val Module.shouldUseJpsOutput: Boolean
get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake)
@@ -0,0 +1,59 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.js
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.CompilerModuleExtension
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.idea.caches.project.implementingModules
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.isGradleModule
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
val Module.jsTestOutputFilePath: String?
get() {
if (!shouldUseJpsOutput) {
(KotlinFacet.get(this)?.configuration?.settings?.testOutputPath)?.let { return it }
}
val compilerExtension = CompilerModuleExtension.getInstance(this)
val outputDir = compilerExtension?.compilerOutputUrlForTests ?: return null
return JpsPathUtil.urlToPath("$outputDir/${name}_test.js")
}
val Module.jsProductionOutputFilePath: String?
get() {
if (!shouldUseJpsOutput) {
(KotlinFacet.get(this)?.configuration?.settings?.productionOutputPath)?.let { return it }
}
val compilerExtension = CompilerModuleExtension.getInstance(this)
val outputDir = compilerExtension?.compilerOutputUrl ?: return null
return JpsPathUtil.urlToPath("$outputDir/$name.js")
}
fun Module.asJsModule(): Module? = when (TargetPlatformDetector.getPlatform(this)) {
is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform }
is JsPlatform -> this
else -> null
}
val Module.shouldUseJpsOutput: Boolean
get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake)
+2
View File
@@ -36,6 +36,8 @@ dependencies {
compile(project(":idea:idea-core")) { isTransitive = false }
compile(project(":idea:ide-common")) { isTransitive = false }
compile(project(":idea:idea-gradle")) { isTransitive = false }
compile(project(":compiler:util")) { isTransitive = false }
compile(project(":idea:idea-jps-common")) { isTransitive = false }
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
if (intellijUltimateEnabled) {
+2
View File
@@ -36,6 +36,8 @@ dependencies {
compile(project(":idea:idea-core")) { isTransitive = false }
compile(project(":idea:ide-common")) { isTransitive = false }
compile(project(":idea:idea-gradle")) { isTransitive = false }
compile(project(":compiler:util")) { isTransitive = false }
compile(project(":idea:idea-jps-common")) { isTransitive = false }
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
if (intellijUltimateEnabled) {
+2
View File
@@ -38,6 +38,8 @@ dependencies {
compile(project(":idea:idea-core")) { isTransitive = false }
compile(project(":idea:ide-common")) { isTransitive = false }
compile(project(":idea:idea-gradle")) { isTransitive = false }
compile(project(":compiler:util")) { isTransitive = false }
compile(project(":idea:idea-jps-common")) { isTransitive = false }
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
if (intellijUltimateEnabled) {
+2
View File
@@ -38,6 +38,8 @@ dependencies {
compile(project(":idea:idea-core")) { isTransitive = false }
compile(project(":idea:ide-common")) { isTransitive = false }
compile(project(":idea:idea-gradle")) { isTransitive = false }
compile(project(":compiler:util")) { isTransitive = false }
compile(project(":idea:idea-jps-common")) { isTransitive = false }
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
if (intellijUltimateEnabled) {
@@ -17,12 +17,11 @@ import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.js.jsOrJsImpl
import org.jetbrains.kotlin.idea.js.asJsModule
import org.jetbrains.kotlin.idea.js.jsProductionOutputFilePath
import org.jetbrains.kotlin.idea.nodejs.TestElementPath
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
import org.jetbrains.kotlin.idea.run.addBuildTask
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
@@ -45,27 +44,27 @@ private class KotlinNodeJsRunConfigurationProducer :
override val isForTests: Boolean
get() = false
private fun getConfigurationData(element: PsiElement, context: ConfigurationContext?): NodeJsConfigData? {
if (context != null && !context.isAcceptable) return null
val jsModule = element.module?.jsOrJsImpl() ?: return null
val jsFilePath = jsModule.jsProductionOutputFilePath ?: return null
override fun getConfigurationData(context: ConfigurationContext): NodeJsConfigData? {
if (!context.isAcceptable) return null
val element = context.psiLocation ?: return null
val module = context.module?.asJsModule() ?: return null
val jsFilePath = module.jsProductionOutputFilePath ?: return null
val declaration = element.getNonStrictParentOfType<KtNamedDeclaration>()
if (declaration is KtNamedFunction) {
val detector = MainFunctionDetector { it.resolveToDescriptorIfAny() }
if (!detector.isMain(declaration, false)) return null
} else if (!TestElementPath.isModuleAssociatedDir(element, jsModule)) return null
return NodeJsConfigData(element, jsModule, jsFilePath)
} else if (!TestElementPath.isModuleAssociatedDir(element, module)) return null
return NodeJsConfigData(element, module, jsFilePath)
}
override fun getConfigurationData(element: PsiElement) = getConfigurationData(element, null)
override fun setupConfigurationFromContext(
configuration: NodeJsRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val psiElement = sourceElement.get() ?: return false
val configData = getConfigurationData(psiElement, context) ?: return false
val configData = getConfigurationData(context) ?: return false
if (configuration.workingDirectory.isNullOrBlank()) {
configuration.workingDirectory = FileUtil.toSystemDependentName(psiElement.project.baseDir.path)
@@ -79,8 +78,7 @@ private class KotlinNodeJsRunConfigurationProducer :
}
override fun isConfigurationFromContext(configuration: NodeJsRunConfiguration, context: ConfigurationContext): Boolean {
val contextPsi = context.psiLocation ?: return false
val configData = getConfigurationData(contextPsi, context) ?: return false
val configData = getConfigurationData(context) ?: return false
return configuration.inputPath == configData.jsOutputFilePath
}
}
@@ -14,16 +14,14 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiUtilCore
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData
import org.jetbrains.kotlin.idea.js.jsOrJsImpl
import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.js.asJsModule
import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath
import org.jetbrains.kotlin.idea.nodejs.TestElementInfo
import org.jetbrains.kotlin.idea.nodejs.TestElementPath
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
import org.jetbrains.kotlin.idea.run.addBuildTask
import org.jetbrains.kotlin.idea.util.projectStructure.module
typealias JestTestElementInfo = TestElementInfo<JestRunSettings>
@@ -74,29 +72,24 @@ class KotlinJestRunConfigurationProducer :
override val isForTests: Boolean
get() = true
override fun getConfigurationData(element: PsiElement): JestConfigData? {
val module = element.module
val jsModule = module?.jsOrJsImpl() ?: return null
override fun getConfigurationData(
context: ConfigurationContext
): JestConfigData? {
val element = context.psiLocation ?: return null
val module = context.module?.asJsModule() ?: return null
val file = if (jsModule != module) {
jsModule.moduleFile
} else {
PsiUtilCore.getVirtualFile(element)
} ?: return null
val file = module.moduleFile
val project = module.project
if (!isTestRunnerPackageAvailableFor(project, file)) return null
if (!isTestRunnerPackageAvailableFor(module.project, file)) return null
val testFilePath = module.jsTestOutputFilePath ?: return null
val testElementPath = TestElementPath.forElement(element, module) ?: return null
return JestConfigData(element, jsModule, testFilePath, testElementPath)
return JestConfigData(element, module, testFilePath, testElementPath)
}
override fun isConfigurationFromCompatibleContext(configuration: JestRunConfiguration, context: ConfigurationContext): Boolean {
val element = context.psiLocation ?: return false
val configData = getConfigurationData(element) ?: return false
val configData = getConfigurationData(context) ?: return false
val (thisRunSettings, _) = createTestElementRunInfo(configData, configuration.runSettings)
val thatRunSettings = configuration.runSettings
@@ -117,8 +110,7 @@ class KotlinJestRunConfigurationProducer :
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val element = context.psiLocation ?: return false
val configData = getConfigurationData(element) ?: return false
val configData = getConfigurationData(context) ?: return false
val (runSettings, enclosingTestElement) = createTestElementRunInfo(configData, configuration.runSettings)
configuration.runSettings = runSettings
sourceElement.set(enclosingTestElement)
@@ -26,20 +26,18 @@ import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiUtilCore
import com.intellij.util.SmartList
import com.intellij.util.containers.SmartHashSet
import com.jetbrains.nodejs.mocha.MochaUtil
import com.jetbrains.nodejs.mocha.execution.*
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.js.jsOrJsImpl
import org.jetbrains.kotlin.idea.js.asJsModule
import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath
import org.jetbrains.kotlin.idea.nodejs.TestElementInfo
import org.jetbrains.kotlin.idea.nodejs.TestElementPath
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
import org.jetbrains.kotlin.idea.run.addBuildTask
import org.jetbrains.kotlin.idea.util.projectStructure.module
private typealias MochaTestElementInfo = TestElementInfo<MochaRunSettings>
@@ -104,22 +102,18 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer(), Kot
return MochaTestElementInfo(builder.build(), configData.element)
}
private fun getConfigurationData(element: PsiElement, context: ConfigurationContext?): MochaConfigData? {
val module = element.module
val jsModule = module?.jsOrJsImpl() ?: return null
val file = if (jsModule != module) {
jsModule.moduleFile
} else {
PsiUtilCore.getVirtualFile(element)
} ?: return null
override fun getConfigurationData(context: ConfigurationContext): MochaConfigData? {
val module = context.module?.asJsModule() ?: return null
val element = context.psiLocation ?: return null
val file = module.moduleFile ?: return null
val project = module.project
val testFilePath = module.jsTestOutputFilePath ?: return null
val testElementPath = TestElementPath.forElement(element, module) ?: return null
val configData = MochaConfigData(element, jsModule, testFilePath, testElementPath)
val configData = MochaConfigData(element, module, testFilePath, testElementPath)
if (context?.getOriginalConfiguration(MochaConfigurationType.getInstance()) is MochaRunConfiguration) return configData
if (context.getOriginalConfiguration(MochaConfigurationType.getInstance()) is MochaRunConfiguration) return configData
if (isTestRunnerPackageAvailableFor(project, file)) return configData
@@ -139,13 +133,8 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer(), Kot
override val isForTests: Boolean
get() = true
override fun getConfigurationData(element: PsiElement): MochaConfigData? {
return getConfigurationData(element, null)
}
override fun isConfigurationFromCompatibleContext(configuration: MochaRunConfiguration, context: ConfigurationContext): Boolean {
val element = context.psiLocation ?: return false
val configData = getConfigurationData(element) ?: return false
val configData = getConfigurationData(context) ?: return false
val (thisRunSettings, _) = createTestElementRunInfo(configData, configuration.runSettings)
val thatRunSettings = configuration.runSettings
val thisTestKind = thisRunSettings.testKind
@@ -165,8 +154,7 @@ class KotlinMochaRunConfigurationProducer : MochaRunConfigurationProducer(), Kot
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
val element = context.psiLocation ?: return false
val configData = getConfigurationData(element, context) ?: return false
val configData = getConfigurationData(context) ?: return false
val (runSettings, enclosingTestElement) = createTestElementRunInfo(configData, configuration.runSettings)
if (runSettings.testKind == MochaTestKind.DIRECTORY) return false
configuration.runSettings = runSettings
@@ -19,13 +19,12 @@ package org.jetbrains.kotlin.idea.nodejs.protractor
import com.intellij.execution.actions.CompatibleRunConfigurationProducer
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationData
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.js.jsOrJsImpl
import org.jetbrains.kotlin.idea.js.asJsModule
import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath
import org.jetbrains.kotlin.idea.nodejs.TestElementPath
import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
@@ -43,11 +42,13 @@ class KotlinProtractorRunConfigurationProducer :
override val isForTests: Boolean
get() = true
override fun getConfigurationData(element: PsiElement): ProtractorConfigData? {
val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return null
override fun getConfigurationData(
context: ConfigurationContext
): ProtractorConfigData? {
val module = context.module?.asJsModule() ?: return null
val element = context.psiLocation ?: return null
if (!TestElementPath.isModuleAssociatedDir(element, module)) return null
val jsModule = module.jsOrJsImpl() ?: return null
val testFilePath = jsModule.jsTestOutputFilePath ?: return null
val testFilePath = module.jsTestOutputFilePath ?: return null
return ProtractorConfigData(element, module, testFilePath)
}
@@ -55,8 +56,7 @@ class KotlinProtractorRunConfigurationProducer :
configuration: KotlinProtractorRunConfiguration,
context: ConfigurationContext
): Boolean {
val contextPsi = context.psiLocation ?: return false
val configData = getConfigurationData(contextPsi) ?: return false
val configData = getConfigurationData(context) ?: return false
return configuration.runSettings.testFileSystemDependentPath == FileUtil.toSystemDependentName(configData.jsOutputFilePath)
}
@@ -66,7 +66,7 @@ class KotlinProtractorRunConfigurationProducer :
sourceElement: Ref<PsiElement>
): Boolean {
val element = context.psiLocation ?: return false
val configData = getConfigurationData(element) ?: return false
val configData = getConfigurationData(context) ?: return false
sourceElement.set(element)
configuration.runSettings = configuration.runSettings.copy(
testFilePath = configData.jsOutputFilePath,