convert KotlinRunConfigurationProducer to new API, allowing it to coexist with KotlinJUnitRunConfigurationProducer correctly
#KT-2604 Fixed
This commit is contained in:
committed by
Nikolay Krasko
parent
9d650b6154
commit
49714d0817
@@ -391,7 +391,7 @@
|
||||
<configurationType implementation="org.jetbrains.kotlin.idea.run.JetRunConfigurationType"/>
|
||||
<configurationType implementation="org.jetbrains.kotlin.idea.k2jsrun.K2JSRunConfigurationType"/>
|
||||
<programRunner implementation="org.jetbrains.kotlin.idea.k2jsrun.K2JSBrowserProgramRunner"/>
|
||||
<configurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer"/>
|
||||
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.kotlin.idea.highlighter.markers.KotlinLineMarkerProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="jet" implementationClass="org.jetbrains.kotlin.idea.highlighter.KotlinRecursiveCallLineMarkerProvider"/>
|
||||
<codeInsight.lineMarkerProvider language="JAVA"
|
||||
|
||||
@@ -19,13 +19,14 @@ package org.jetbrains.kotlin.idea.run
|
||||
import com.intellij.execution.Location
|
||||
import com.intellij.execution.RunnerAndConfigurationSettings
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.RunConfigurationProducer
|
||||
import com.intellij.execution.junit.RuntimeConfigurationProducer
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.util.Comparing
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.impl.ElementBase
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.util.NotNullFunction
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
@@ -36,46 +37,38 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
|
||||
public class KotlinRunConfigurationProducer : RuntimeConfigurationProducer(JetRunConfigurationType.getInstance()), Cloneable {
|
||||
override fun clone(): KotlinRunConfigurationProducer {
|
||||
return super<RuntimeConfigurationProducer>.clone() as KotlinRunConfigurationProducer
|
||||
public class KotlinRunConfigurationProducer : RunConfigurationProducer<JetRunConfiguration>(JetRunConfigurationType.getInstance()) {
|
||||
|
||||
override fun setupConfigurationFromContext(configuration: JetRunConfiguration,
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>): Boolean {
|
||||
val location = context.getLocation() ?: return false
|
||||
val module = context.getModule() ?: return false
|
||||
val container = getEntryPointContainer(location)
|
||||
val startClassFQName = getStartClassFqName(container) ?: return false
|
||||
|
||||
setupConfigurationByQName(module, configuration, startClassFQName)
|
||||
return true
|
||||
}
|
||||
|
||||
private var mySourceElement: PsiElement? = null
|
||||
|
||||
override fun getSourceElement(): PsiElement? {
|
||||
return mySourceElement
|
||||
}
|
||||
|
||||
override fun createConfigurationByElement(location: Location<*>, configurationContext: ConfigurationContext): RunnerAndConfigurationSettings? {
|
||||
val container = getEntryPointContainer(location) ?: return null
|
||||
|
||||
mySourceElement = container as PsiElement?
|
||||
|
||||
val startClassFQName = getStartClassFqName(container)
|
||||
if (startClassFQName == null) return null
|
||||
|
||||
val module = location.getModule()
|
||||
assert(module != null)
|
||||
|
||||
return createConfigurationByQName(module, configurationContext, startClassFQName)
|
||||
}
|
||||
|
||||
private fun getStartClassFqName(container: JetDeclarationContainer?): FqName? {
|
||||
if (container == null) return null
|
||||
if (container is JetFile) return PackageClassUtils.getPackageClassFqName((container as JetFile?).getPackageFqName())
|
||||
if (container is JetClassOrObject) {
|
||||
private fun getStartClassFqName(container: JetDeclarationContainer?): FqName? = when(container) {
|
||||
null -> null
|
||||
is JetFile -> PackageClassUtils.getPackageClassFqName(container.getPackageFqName())
|
||||
is JetClassOrObject -> {
|
||||
if (container is JetObjectDeclaration && container.isCompanion()) {
|
||||
val containerClass = PsiTreeUtil.getParentOfType<JetClass>(container, javaClass<JetClass>())
|
||||
return containerClass?.getFqName()
|
||||
val containerClass = container.getParentOfType<JetClass>(true)
|
||||
containerClass?.getFqName()
|
||||
} else {
|
||||
container.getFqName()
|
||||
}
|
||||
return container?.getFqName()
|
||||
}
|
||||
throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement?).getText())
|
||||
else -> throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement).getText())
|
||||
}
|
||||
|
||||
private fun getEntryPointContainer(location: Location<*>): JetDeclarationContainer? {
|
||||
private fun getEntryPointContainer(location: Location<*>?): JetDeclarationContainer? {
|
||||
if (location == null) return null
|
||||
if (DumbService.getInstance(location.getProject()).isDumb()) return null
|
||||
|
||||
val module = location.getModule() ?: return null
|
||||
@@ -88,51 +81,41 @@ public class KotlinRunConfigurationProducer : RuntimeConfigurationProducer(JetRu
|
||||
if (!(psiFile is JetFile && ProjectRootsUtil.isInProjectOrLibSource(psiFile))) return null
|
||||
|
||||
val resolutionFacade = psiFile.getResolutionFacade()
|
||||
val mainFunctionDetector = MainFunctionDetector(object : NotNullFunction<JetNamedFunction, FunctionDescriptor> {
|
||||
override fun `fun`(function: JetNamedFunction): FunctionDescriptor {
|
||||
return resolutionFacade.resolveToDescriptor(function) as FunctionDescriptor
|
||||
}
|
||||
})
|
||||
val mainFunctionDetector = MainFunctionDetector { resolutionFacade.resolveToDescriptor(it) as FunctionDescriptor }
|
||||
|
||||
var currentElement = PsiTreeUtil.getNonStrictParentOfType<PsiElement>(locationElement, javaClass<JetClassOrObject>(), javaClass<JetFile>()) as JetDeclarationContainer
|
||||
var currentElement = locationElement.declarationContainer(false)
|
||||
while (currentElement != null) {
|
||||
var entryPointContainer = currentElement
|
||||
if (entryPointContainer is JetClass) {
|
||||
entryPointContainer = entryPointContainer.getCompanionObjects().singleOrNull() as JetDeclarationContainer
|
||||
entryPointContainer = entryPointContainer.getCompanionObjects().singleOrNull()
|
||||
}
|
||||
if (entryPointContainer != null && mainFunctionDetector.hasMain(entryPointContainer.getDeclarations())) return entryPointContainer
|
||||
currentElement = PsiTreeUtil.getParentOfType<PsiElement>(currentElement as PsiElement?, javaClass<JetClassOrObject>(), javaClass<JetFile>()) as JetDeclarationContainer
|
||||
currentElement = (currentElement as PsiElement).declarationContainer(true)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun createConfigurationByQName(module: Module, context: ConfigurationContext, fqName: FqName): RunnerAndConfigurationSettings {
|
||||
val settings = cloneTemplateConfiguration(module.getProject(), context)
|
||||
val configuration = settings.getConfiguration() as JetRunConfiguration
|
||||
private fun PsiElement.declarationContainer(strict: Boolean): JetDeclarationContainer? {
|
||||
val element = if (strict)
|
||||
PsiTreeUtil.getParentOfType(this, javaClass<JetClassOrObject>(), javaClass<JetFile>())
|
||||
else
|
||||
PsiTreeUtil.getNonStrictParentOfType(this, javaClass<JetClassOrObject>(), javaClass<JetFile>())
|
||||
return element as JetDeclarationContainer?
|
||||
}
|
||||
|
||||
private fun setupConfigurationByQName(module: Module,
|
||||
configuration: JetRunConfiguration,
|
||||
fqName: FqName) {
|
||||
configuration.setModule(module)
|
||||
configuration.setName(StringUtil.trimEnd(fqName.asString(), "." + PackageClassUtils.getPackageClassName(fqName)))
|
||||
configuration.setRunClass(fqName.asString())
|
||||
return settings
|
||||
}
|
||||
|
||||
override fun findExistingByElement(location: Location<*>?, existingConfigurations: List<RunnerAndConfigurationSettings>, context: ConfigurationContext?): RunnerAndConfigurationSettings? {
|
||||
val startClassFQName = getStartClassFqName(getEntryPointContainer(location)) ?: return null
|
||||
override fun isConfigurationFromContext(configuration: JetRunConfiguration, context: ConfigurationContext): Boolean {
|
||||
val startClassFQName = getStartClassFqName(getEntryPointContainer(context.getLocation())) ?: return false
|
||||
|
||||
for (existingConfiguration in existingConfigurations) {
|
||||
if (existingConfiguration.getType() is JetRunConfigurationType) {
|
||||
val jetConfiguration = existingConfiguration.getConfiguration() as JetRunConfiguration
|
||||
if (Comparing.equal(jetConfiguration.getRunClass(), startClassFQName.asString())) {
|
||||
if (Comparing.equal<Module>(location!!.getModule(), jetConfiguration.getConfigurationModule().getModule())) {
|
||||
return existingConfiguration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun compareTo(o: Any?): Int {
|
||||
return RuntimeConfigurationProducer.PREFERED
|
||||
return configuration.getRunClass() == startClassFQName.asString() &&
|
||||
context.getModule() == configuration.getConfigurationModule().getModule()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user