diff --git a/idea/src/org/jetbrains/kotlin/idea/run/JetRunConfiguration.java b/idea/src/org/jetbrains/kotlin/idea/run/JetRunConfiguration.java index 57a41b23f6a..ae2407f1958 100644 --- a/idea/src/org/jetbrains/kotlin/idea/run/JetRunConfiguration.java +++ b/idea/src/org/jetbrains/kotlin/idea/run/JetRunConfiguration.java @@ -36,7 +36,10 @@ import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.listeners.RefactoringElementAdapter; +import com.intellij.refactoring.listeners.RefactoringElementListener; import kotlin.KotlinPackage; import kotlin.jvm.functions.Function1; import org.jdom.Element; @@ -51,6 +54,7 @@ import org.jetbrains.kotlin.idea.stubindex.JetTopLevelFunctionFqnNameIndex; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.JetDeclaration; +import org.jetbrains.kotlin.psi.JetDeclarationContainer; import org.jetbrains.kotlin.psi.JetNamedFunction; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; @@ -58,7 +62,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode; import java.util.*; public class JetRunConfiguration extends ModuleBasedConfiguration - implements CommonJavaRunConfigurationParameters { + implements CommonJavaRunConfigurationParameters, RefactoringListenerProvider { public String MAIN_CLASS_NAME; public String VM_PARAMETERS; @@ -218,6 +222,36 @@ public class JetRunConfiguration extends ModuleBasedConfiguration null - is JetFile -> PackageClassUtils.getPackageClassFqName(container.getPackageFqName()) - is JetClassOrObject -> { - if (container is JetObjectDeclaration && container.isCompanion()) { - val containerClass = container.getParentOfType(true) - containerClass?.getFqName() - } else { - container.getFqName() - } - } - else -> throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement).getText()) - } - private fun getEntryPointContainer(location: Location<*>?): JetDeclarationContainer? { if (location == null) return null if (DumbService.getInstance(location.getProject()).isDumb()) return null @@ -77,31 +63,7 @@ public class KotlinRunConfigurationProducer : RunConfigurationProducer(), javaClass()) - else - PsiTreeUtil.getNonStrictParentOfType(this, javaClass(), javaClass()) - return element as JetDeclarationContainer? + return getEntryPointContainer(locationElement) } private fun setupConfigurationByQName(module: Module, @@ -118,4 +80,49 @@ public class KotlinRunConfigurationProducer : RunConfigurationProducer null + is JetFile -> PackageClassUtils.getPackageClassFqName(container.getPackageFqName()) + is JetClassOrObject -> { + if (container is JetObjectDeclaration && container.isCompanion()) { + val containerClass = container.getParentOfType(true) + containerClass?.getFqName() + } else { + container.getFqName() + } + } + else -> throw IllegalArgumentException("Invalid entry-point container: " + (container as PsiElement).getText()) + } + + private fun PsiElement.declarationContainer(strict: Boolean): JetDeclarationContainer? { + val element = if (strict) + PsiTreeUtil.getParentOfType(this, javaClass(), javaClass()) + else + PsiTreeUtil.getNonStrictParentOfType(this, javaClass(), javaClass()) + return element as JetDeclarationContainer? + } + + } } diff --git a/idea/testData/run/UpdateOnClassRename/module/src/Foo.kt b/idea/testData/run/UpdateOnClassRename/module/src/Foo.kt new file mode 100644 index 00000000000..80d6fcfffb5 --- /dev/null +++ b/idea/testData/run/UpdateOnClassRename/module/src/Foo.kt @@ -0,0 +1,8 @@ +package renameTest + +import kotlin.platform.platformStatic + +object Foo { + platformStatic fun main(args: Array) { + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/run/RunConfigurationTest.kt b/idea/tests/org/jetbrains/kotlin/idea/run/RunConfigurationTest.kt index a56fa702f2c..4cf597846c3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/run/RunConfigurationTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/run/RunConfigurationTest.kt @@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightTestCase import com.intellij.execution.Executor import com.intellij.execution.Location import com.intellij.execution.PsiLocation +import com.intellij.execution.RunManagerEx import com.intellij.execution.actions.ConfigurationContext import com.intellij.execution.configurations.JavaCommandLine import com.intellij.execution.configurations.JavaParameters @@ -34,17 +35,21 @@ import com.intellij.openapi.roots.ModuleRootModificationUtil import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiComment import com.intellij.psi.PsiDocumentManager +import com.intellij.psi.PsiElement import com.intellij.psi.PsiManager +import com.intellij.refactoring.RefactoringFactory import com.intellij.testFramework.MapDataContext import com.intellij.testFramework.PlatformTestCase import com.intellij.testFramework.PsiTestUtil import org.jetbrains.kotlin.idea.search.allScope +import org.jetbrains.kotlin.idea.stubindex.JetFullClassNameIndex import org.jetbrains.kotlin.idea.stubindex.JetTopLevelFunctionFqnNameIndex import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil.configureKotlinJsRuntimeAndSdk import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil.configureKotlinRuntimeAndSdk import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.idea.util.application.runWriteAction +import org.jetbrains.kotlin.psi.JetFunction import org.jetbrains.kotlin.psi.JetNamedDeclaration import org.jetbrains.kotlin.psi.JetTreeVisitorVoid import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType @@ -98,6 +103,19 @@ class RunConfigurationTest: CodeInsightTestCase() { doTest(ConfigLibraryUtil::configureKotlinJsRuntimeAndSdk) } + fun testUpdateOnClassRename() { + val createModuleResult = configureModule(moduleDirPath("module"), getTestProject().getBaseDir()!!) + ConfigLibraryUtil.configureKotlinRuntimeAndSdk(createModuleResult.module, PluginTestCaseBase.mockJdk()) + + val runConfiguration = createConfigurationFromObject("renameTest.Foo", save = true) + + val obj = JetFullClassNameIndex.getInstance().get("renameTest.Foo", getTestProject(), getTestProject().allScope()).single() + val rename = RefactoringFactory.getInstance(getTestProject()).createRename(obj, "Bar") + rename.run() + + Assert.assertEquals("renameTest.Bar", runConfiguration.MAIN_CLASS_NAME) + } + private fun doTest(configureRuntime: (Module, Sdk) -> Unit) { val baseDir = getTestProject().getBaseDir()!! val createModuleResult = configureModule(moduleDirPath("module"), baseDir) @@ -140,10 +158,24 @@ class RunConfigurationTest: CodeInsightTestCase() { private fun createConfigurationFromMain(mainFqn: String): JetRunConfiguration { val mainFunction = JetTopLevelFunctionFqnNameIndex.getInstance().get(mainFqn, getTestProject(), getTestProject().allScope()).first() - val dataContext = MapDataContext() - dataContext.put(Location.DATA_KEY, PsiLocation(getTestProject(), mainFunction)) + return createConfigurationFromElement(mainFunction) + } - return ConfigurationContext.getFromContext(dataContext)!!.getConfiguration()!!.getConfiguration() as JetRunConfiguration + private fun createConfigurationFromObject(objectFqn: String, save: Boolean = false): JetRunConfiguration { + val obj = JetFullClassNameIndex.getInstance().get(objectFqn, getTestProject(), getTestProject().allScope()).single() + val mainFunction = obj.getDeclarations().single { it is JetFunction && it.getName() == "main" } + return createConfigurationFromElement(mainFunction, save) + } + + private fun createConfigurationFromElement(element: PsiElement?, save: Boolean = false): JetRunConfiguration { + val dataContext = MapDataContext() + dataContext.put(Location.DATA_KEY, PsiLocation(getTestProject(), element)) + + val runnerAndConfigurationSettings = ConfigurationContext.getFromContext(dataContext)!!.getConfiguration() + if (save) { + RunManagerEx.getInstanceEx(myProject).setTemporaryConfiguration(runnerAndConfigurationSettings) + } + return runnerAndConfigurationSettings!!.getConfiguration() as JetRunConfiguration } private fun configureModule(moduleDir: String, outputParentDir: VirtualFile, configModule: Module = getModule()): CreateModuleResult {