Improve kotlin jvm run config producers for 181 and as32 branches
Drop KotlinJUnitRunConfigurationProducer, KotlinRunConfigurationProducer
bunch files
Extract differences in behaviour to 'jvmMppUtils.kt'
Improve 'isConfigurationFromContext' checks for 181 and as32
(this prevents duplicate configurations being created)
KotlinRunConfigurationProducer chooses corresponding jvm module
for common code
#KT-26886 Fixed
This commit is contained in:
+4
-10
@@ -29,8 +29,6 @@ import com.intellij.openapi.util.component2
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer
|
||||
import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
@@ -74,8 +72,7 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP
|
||||
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
|
||||
|
||||
val contextLocation = context.location ?: return false
|
||||
val module = context.module ?: return false
|
||||
if (!module.platform.isJvm) return false
|
||||
val module = context.module?.asJvmModule() ?: return false
|
||||
|
||||
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
|
||||
return false
|
||||
@@ -104,8 +101,7 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP
|
||||
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
|
||||
|
||||
val leaf = context.location?.psiElement ?: return false
|
||||
val module = context.module ?: return false
|
||||
if (!module.platform.isJvm) return false
|
||||
val module = context.module?.asJvmModule() ?: return false
|
||||
|
||||
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
|
||||
return false
|
||||
@@ -141,8 +137,7 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio
|
||||
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
|
||||
|
||||
val contextLocation = context.location ?: return false
|
||||
val module = context.module ?: return false
|
||||
if (!module.platform.isJvm) return false
|
||||
context.module?.asJvmModule() ?: return false
|
||||
|
||||
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
|
||||
return false
|
||||
@@ -168,8 +163,7 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio
|
||||
}
|
||||
|
||||
val contextLocation = context.location ?: return false
|
||||
val module = context.module ?: return false
|
||||
if (!module.platform.isJvm) return false
|
||||
val module = context.module?.asJvmModule() ?: return false
|
||||
|
||||
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
|
||||
|
||||
|
||||
+19
-16
@@ -11,21 +11,21 @@ import com.intellij.execution.actions.ConfigurationFromContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
||||
import com.intellij.execution.junit.*
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
|
||||
class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfiguration>(JUnitConfigurationType.getInstance()) {
|
||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||
@@ -62,7 +62,7 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
|
||||
val template = RunManager.getInstance(configuration.project).getConfigurationTemplate(configurationFactory)
|
||||
val predefinedModule = (template.configuration as ModuleBasedConfiguration<*>).configurationModule.module
|
||||
val configurationModule = configuration.configurationModule.module
|
||||
return configurationModule == context.location?.module || configurationModule == predefinedModule
|
||||
return configurationModule == context.location?.module?.asJvmModule() || configurationModule == predefinedModule
|
||||
}
|
||||
|
||||
override fun setupConfigurationFromContext(
|
||||
@@ -74,6 +74,7 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
|
||||
|
||||
val location = context.location ?: return false
|
||||
val leaf = location.psiElement
|
||||
val module = context.module?.asJvmModule() ?: return false
|
||||
|
||||
if (!ProjectRootsUtil.isInProjectOrLibSource(leaf)) {
|
||||
return false
|
||||
@@ -83,36 +84,38 @@ class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfig
|
||||
return false
|
||||
}
|
||||
|
||||
val module = location.module ?: return false
|
||||
|
||||
val targetPlatform = TargetPlatformDetector.getPlatform(module)
|
||||
if (targetPlatform != JvmPlatform) {
|
||||
return false
|
||||
}
|
||||
|
||||
configuration.setModule(module)
|
||||
|
||||
val methodLocation = getTestMethodLocation(leaf)
|
||||
if (methodLocation != null) {
|
||||
val originalModule = configuration.configurationModule.module
|
||||
configuration.beMethodConfiguration(methodLocation)
|
||||
configuration.restoreOriginalModule(originalModule)
|
||||
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
|
||||
configuration.setSdkAndModule(module)
|
||||
return true
|
||||
}
|
||||
|
||||
val testClass = getTestClass(leaf)
|
||||
if (testClass != null) {
|
||||
val originalModule = configuration.configurationModule.module
|
||||
configuration.beClassConfiguration(testClass)
|
||||
configuration.restoreOriginalModule(originalModule)
|
||||
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
|
||||
configuration.setSdkAndModule(module)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun JUnitConfiguration.setSdkAndModule(module: Module) {
|
||||
if (configurationModule.module == module) {
|
||||
return
|
||||
}
|
||||
|
||||
setModule(module)
|
||||
val sdk = ModuleRootManager.getInstance(module).sdk
|
||||
if (sdk != null) {
|
||||
isAlternativeJrePathEnabled = true
|
||||
alternativeJrePath = sdk.homePath
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
|
||||
val leaf = fromContext.sourceElement
|
||||
getTestClass(leaf)?.let { testClass ->
|
||||
|
||||
-180
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 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.run
|
||||
|
||||
import com.intellij.execution.*
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.ConfigurationFromContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
||||
import com.intellij.execution.junit.*
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
|
||||
class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfiguration>(JUnitConfigurationType.getInstance()) {
|
||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||
return other.isProducedBy(JUnitConfigurationProducer::class.java) || other.isProducedBy(PatternConfigurationProducer::class.java)
|
||||
}
|
||||
|
||||
override fun isConfigurationFromContext(
|
||||
configuration: JUnitConfiguration,
|
||||
context: ConfigurationContext
|
||||
): Boolean {
|
||||
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
|
||||
return false
|
||||
}
|
||||
|
||||
val leaf = context.location?.psiElement ?: return false
|
||||
val methodLocation = getTestMethodLocation(leaf)
|
||||
val testClass = getTestClass(leaf)
|
||||
val testObject = configuration.testObject
|
||||
|
||||
if (!testObject.isConfiguredByElement(configuration, testClass, methodLocation?.psiElement, null, null)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return settingsMatchTemplate(configuration, context)
|
||||
}
|
||||
|
||||
// copied from JUnitConfigurationProducer in IDEA
|
||||
private fun settingsMatchTemplate(configuration: JUnitConfiguration, context: ConfigurationContext): Boolean {
|
||||
val predefinedConfiguration = context.getOriginalConfiguration(JUnitConfigurationType.getInstance())
|
||||
|
||||
val vmParameters = (predefinedConfiguration as? CommonJavaRunConfigurationParameters)?.vmParameters
|
||||
if (vmParameters != null && configuration.vmParameters != vmParameters) return false
|
||||
|
||||
val template = RunManager.getInstance(configuration.project).getConfigurationTemplate(configurationFactory)
|
||||
val predefinedModule = (template.configuration as ModuleBasedConfiguration<*>).configurationModule.module
|
||||
val configurationModule = configuration.configurationModule.module
|
||||
return configurationModule == context.location?.module || configurationModule == predefinedModule
|
||||
}
|
||||
|
||||
override fun setupConfigurationFromContext(
|
||||
configuration: JUnitConfiguration,
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>
|
||||
): Boolean {
|
||||
if (DumbService.getInstance(context.project).isDumb) return false
|
||||
|
||||
val location = context.location ?: return false
|
||||
val leaf = location.psiElement
|
||||
|
||||
if (!ProjectRootsUtil.isInProjectOrLibSource(leaf)) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (leaf.containingFile !is KtFile) {
|
||||
return false
|
||||
}
|
||||
|
||||
val ktFile = leaf.containingFile as KtFile
|
||||
|
||||
val targetPlatform = TargetPlatformDetector.getPlatform(ktFile)
|
||||
if (targetPlatform != JvmPlatform && targetPlatform != TargetPlatform.Common) {
|
||||
return false
|
||||
}
|
||||
|
||||
val methodLocation = getTestMethodLocation(leaf)
|
||||
if (methodLocation != null) {
|
||||
val originalModule = configuration.configurationModule.module
|
||||
configuration.beMethodConfiguration(methodLocation)
|
||||
configuration.restoreOriginalModule(originalModule)
|
||||
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
|
||||
fixJdkForCommonModule(ktFile, configuration)
|
||||
return true
|
||||
}
|
||||
|
||||
val testClass = getTestClass(leaf)
|
||||
if (testClass != null) {
|
||||
val originalModule = configuration.configurationModule.module
|
||||
configuration.beClassConfiguration(testClass)
|
||||
configuration.restoreOriginalModule(originalModule)
|
||||
JavaRunConfigurationExtensionManager.getInstance().extendCreatedConfiguration(configuration, location)
|
||||
fixJdkForCommonModule(ktFile, configuration)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun fixJdkForCommonModule(ktFile: KtFile, configuration: JUnitConfiguration) {
|
||||
val implModule = ktFile.module?.findJvmImplementationModule() ?: return
|
||||
val sdk = ModuleRootManager.getInstance(implModule).sdk
|
||||
if (sdk != null) {
|
||||
configuration.setModule(implModule)
|
||||
configuration.isAlternativeJrePathEnabled = true
|
||||
configuration.alternativeJrePath = sdk.homePath
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
|
||||
val leaf = fromContext.sourceElement
|
||||
getTestClass(leaf)?.let { testClass ->
|
||||
val fromContextSubstitute = object : ConfigurationFromContext() {
|
||||
override fun getConfigurationSettings() = fromContext.configurationSettings
|
||||
|
||||
override fun setConfigurationSettings(configurationSettings: RunnerAndConfigurationSettings) {
|
||||
fromContext.configurationSettings = configurationSettings
|
||||
}
|
||||
|
||||
override fun getSourceElement() = testClass
|
||||
}
|
||||
// TODO: use TestClassConfigurationProducer when constructor becomes public
|
||||
return object : AbstractTestClassConfigurationProducer(JUnitConfigurationType.getInstance()){}
|
||||
.onFirstRun(fromContextSubstitute, context, performRunnable)
|
||||
}
|
||||
|
||||
super.onFirstRun(fromContext, context, performRunnable)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getTestClass(leaf: PsiElement): PsiClass? {
|
||||
val containingFile = leaf.containingFile as? KtFile ?: return null
|
||||
var ktClass = leaf.getParentOfType<KtClass>(false)
|
||||
if (!ktClass.isJUnitTestClass()) {
|
||||
ktClass = getTestClassInFile(containingFile)
|
||||
}
|
||||
return ktClass?.toLightClass()
|
||||
}
|
||||
|
||||
fun getTestMethodLocation(leaf: PsiElement): Location<PsiMethod>? {
|
||||
val function = leaf.getParentOfType<KtNamedFunction>(false) ?: return null
|
||||
val owner = PsiTreeUtil.getParentOfType(function, KtFunction::class.java, KtClass::class.java)
|
||||
|
||||
if (owner is KtClass) {
|
||||
val delegate = owner.toLightClass() ?: return null
|
||||
val method = delegate.methods.firstOrNull() { it.navigationElement == function } ?: return null
|
||||
val methodLocation = PsiLocation.fromPsiElement(method)
|
||||
if (JUnitUtil.isTestMethod(methodLocation, false)) {
|
||||
return methodLocation
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun KtClass?.isJUnitTestClass() =
|
||||
this?.toLightClass()?.let { JUnitUtil.isTestClass(it, false, true) } ?: false
|
||||
|
||||
private fun getTestClassInFile(ktFile: KtFile) =
|
||||
ktFile.declarations.filterIsInstance<KtClass>().singleOrNull { it.isJUnitTestClass() }
|
||||
}
|
||||
}
|
||||
@@ -28,12 +28,10 @@ import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfiguration>(KotlinRunConfigurationType.getInstance()) {
|
||||
@@ -42,7 +40,7 @@ class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfigu
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>): Boolean {
|
||||
val location = context.location ?: return false
|
||||
val module = location.module ?: return false
|
||||
val module = location.module?.asJvmModule() ?: return false
|
||||
val container = getEntryPointContainer(location) ?: return false
|
||||
val startClassFQName = getStartClassFqName(container) ?: return false
|
||||
|
||||
@@ -57,14 +55,7 @@ class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfigu
|
||||
if (location == null) return null
|
||||
if (DumbService.getInstance(location.project).isDumb) return null
|
||||
|
||||
val module = location.module ?: return null
|
||||
|
||||
if (TargetPlatformDetector.getPlatform(module) !is JvmPlatform) {
|
||||
return null
|
||||
}
|
||||
val locationElement = location.psiElement
|
||||
|
||||
return getEntryPointContainer(locationElement)
|
||||
return getEntryPointContainer(location.psiElement)
|
||||
}
|
||||
|
||||
override fun isConfigurationFromContext(configuration: KotlinRunConfiguration, context: ConfigurationContext): Boolean {
|
||||
@@ -72,7 +63,7 @@ class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfigu
|
||||
val startClassFQName = getStartClassFqName(entryPointContainer) ?: return false
|
||||
|
||||
return configuration.runClass == startClassFQName &&
|
||||
context.module == configuration.configurationModule.module
|
||||
context.module?.asJvmModule() == configuration.configurationModule.module
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
-135
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.run
|
||||
|
||||
import com.intellij.execution.Location
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.ClassUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.idea.caches.project.implementingModules
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.platform.impl.isCommon
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KotlinRunConfigurationProducer : RunConfigurationProducer<KotlinRunConfiguration>(KotlinRunConfigurationType.getInstance()) {
|
||||
|
||||
override fun setupConfigurationFromContext(configuration: KotlinRunConfiguration,
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>): Boolean {
|
||||
val location = context.location ?: return false
|
||||
val module = location.module ?: return false
|
||||
val container = getEntryPointContainer(location)
|
||||
val startClassFQName = getStartClassFqName(container) ?: return false
|
||||
|
||||
configuration.setModule(module)
|
||||
configuration.runClass = startClassFQName
|
||||
configuration.setGeneratedName()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun getEntryPointContainer(location: Location<*>?): KtDeclarationContainer? {
|
||||
if (location == null) return null
|
||||
if (DumbService.getInstance(location.project).isDumb) return null
|
||||
|
||||
val module = location.module ?: return null
|
||||
|
||||
if (TargetPlatformDetector.getPlatform(module) !is JvmPlatform && module.findJvmImplementationModule() == null) {
|
||||
return null
|
||||
}
|
||||
val locationElement = location.psiElement
|
||||
|
||||
return getEntryPointContainer(locationElement)
|
||||
}
|
||||
|
||||
override fun isConfigurationFromContext(configuration: KotlinRunConfiguration, context: ConfigurationContext): Boolean {
|
||||
val startClassFQName = getStartClassFqName(getEntryPointContainer(context.location)) ?: return false
|
||||
|
||||
return configuration.runClass == startClassFQName &&
|
||||
context.module == configuration.configurationModule.module
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getEntryPointContainer(locationElement: PsiElement): KtDeclarationContainer? {
|
||||
val psiFile = locationElement.containingFile
|
||||
if (!(psiFile is KtFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null
|
||||
|
||||
val mainFunctionDetector =
|
||||
MainFunctionDetector(psiFile.languageVersionSettings) { it.resolveToDescriptorIfAny(BodyResolveMode.FULL) }
|
||||
|
||||
var currentElement = locationElement.declarationContainer(false)
|
||||
while (currentElement != null) {
|
||||
var entryPointContainer = currentElement
|
||||
if (entryPointContainer is KtClass) {
|
||||
entryPointContainer = entryPointContainer.companionObjects.singleOrNull()
|
||||
}
|
||||
if (entryPointContainer != null && mainFunctionDetector.hasMain(entryPointContainer.declarations)) return entryPointContainer
|
||||
currentElement = (currentElement as PsiElement).declarationContainer(true)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun getStartClassFqName(container: KtDeclarationContainer?): String? = when(container) {
|
||||
null -> null
|
||||
is KtFile -> container.javaFileFacadeFqName.asString()
|
||||
is KtClassOrObject -> {
|
||||
if (!container.isValid) {
|
||||
null
|
||||
}
|
||||
else if (container is KtObjectDeclaration && container.isCompanion()) {
|
||||
val containerClass = container.getParentOfType<KtClass>(true)
|
||||
containerClass?.toLightClass()?.let { ClassUtil.getJVMClassName(it) }
|
||||
}
|
||||
else {
|
||||
container.toLightClass()?.let { ClassUtil.getJVMClassName(it) }
|
||||
}
|
||||
}
|
||||
else -> throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement).text)
|
||||
}
|
||||
|
||||
private fun PsiElement.declarationContainer(strict: Boolean): KtDeclarationContainer? {
|
||||
val element = if (strict)
|
||||
PsiTreeUtil.getParentOfType(this, KtClassOrObject::class.java, KtFile::class.java)
|
||||
else
|
||||
PsiTreeUtil.getNonStrictParentOfType(this, KtClassOrObject::class.java, KtFile::class.java)
|
||||
return element as KtDeclarationContainer?
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun Module.findJvmImplementationModule(): Module? {
|
||||
if (!platform.isCommon) return null
|
||||
return implementingModules.firstOrNull { it.platform.isJvm }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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.run
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
|
||||
fun Module.asJvmModule(): Module? {
|
||||
if (platform.isJvm) return this
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.run
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import org.jetbrains.kotlin.idea.caches.project.implementingModules
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.platform.impl.isCommon
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
|
||||
fun Module.asJvmModule(): Module? {
|
||||
if (platform.isJvm) return this
|
||||
|
||||
if (platform.isCommon) {
|
||||
return implementingModules.firstOrNull { it.platform.isJvm }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user