Allow to run scratch without module selected
^KT-23985 Fixed
This commit is contained in:
+1
-6
@@ -68,7 +68,7 @@ class ScratchFileModuleInfoProvider(val project: Project) : ProjectComponent {
|
|||||||
|
|
||||||
val scratchPanel = getEditorWithScratchPanel(source, file)?.second
|
val scratchPanel = getEditorWithScratchPanel(source, file)?.second
|
||||||
scratchPanel?.addModuleListener { psiFile, module ->
|
scratchPanel?.addModuleListener { psiFile, module ->
|
||||||
psiFile.virtualFile.scriptRelatedModuleName = module.name
|
psiFile.virtualFile.scriptRelatedModuleName = module?.name
|
||||||
|
|
||||||
// Drop caches for old module
|
// Drop caches for old module
|
||||||
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
|
ScriptDependenciesModificationTracker.getInstance(project).incModificationCount()
|
||||||
@@ -79,11 +79,6 @@ class ScratchFileModuleInfoProvider(val project: Project) : ProjectComponent {
|
|||||||
val module = ktFile.virtualFile.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) }
|
val module = ktFile.virtualFile.scriptRelatedModuleName?.let { ModuleManager.getInstance(project).findModuleByName(it) }
|
||||||
if (module != null) {
|
if (module != null) {
|
||||||
scratchPanel?.setModule(module)
|
scratchPanel?.setModule(module)
|
||||||
} else {
|
|
||||||
val firstModule = ModuleManager.getInstance(project).modules.firstOrNull()
|
|
||||||
if (firstModule != null) {
|
|
||||||
scratchPanel?.setModule(firstModule)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,11 +62,6 @@ class RunScratchAction : ScratchAction(
|
|||||||
|
|
||||||
val module = scratchPanel.getModule()
|
val module = scratchPanel.getModule()
|
||||||
|
|
||||||
@Suppress("FoldInitializerAndIfToElvis")
|
|
||||||
if (module == null) {
|
|
||||||
return defaultOutputHandler.error(scratchFile, "Module should be selected")
|
|
||||||
}
|
|
||||||
|
|
||||||
val executor = if (isRepl) provider.createReplExecutor(scratchFile) else provider.createCompilingExecutor(scratchFile)
|
val executor = if (isRepl) provider.createReplExecutor(scratchFile) else provider.createCompilingExecutor(scratchFile)
|
||||||
|
|
||||||
@Suppress("FoldInitializerAndIfToElvis")
|
@Suppress("FoldInitializerAndIfToElvis")
|
||||||
@@ -96,7 +91,7 @@ class RunScratchAction : ScratchAction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isAutoRun && isMakeBeforeRun) {
|
if (!isAutoRun && module != null && isMakeBeforeRun) {
|
||||||
val project = scratchPanel.scratchFile.project
|
val project = scratchPanel.scratchFile.project
|
||||||
ProjectTaskManager.getInstance(project).build(arrayOf(module)) { result ->
|
ProjectTaskManager.getInstance(project).build(arrayOf(module)) { result ->
|
||||||
if (result.isAborted || result.errors > 0) {
|
if (result.isAborted || result.errors > 0) {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.diagnostics.Severity
|
|||||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
|
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithAllCompilerChecks
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||||
|
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
|
||||||
import org.jetbrains.kotlin.idea.debugger.DebuggerUtils
|
import org.jetbrains.kotlin.idea.debugger.DebuggerUtils
|
||||||
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
|
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
|
||||||
import org.jetbrains.kotlin.idea.scratch.*
|
import org.jetbrains.kotlin.idea.scratch.*
|
||||||
@@ -63,7 +64,7 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
|||||||
override fun execute() {
|
override fun execute() {
|
||||||
handler.onStart(file)
|
handler.onStart(file)
|
||||||
|
|
||||||
val module = file.getModule() ?: return errorOccurs("Module should be selected", isFatal = true)
|
val module = file.getModule()
|
||||||
val psiFile = file.getPsiFile() as? KtFile ?: return errorOccurs("Couldn't find KtFile for current editor", isFatal = true)
|
val psiFile = file.getPsiFile() as? KtFile ?: return errorOccurs("Couldn't find KtFile for current editor", isFatal = true)
|
||||||
|
|
||||||
if (!checkForErrors(psiFile)) return
|
if (!checkForErrors(psiFile)) return
|
||||||
@@ -90,7 +91,7 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
|||||||
) ?: return
|
) ?: return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val commandLine = createCommandLine(module, result.mainClassName, tempDir.path)
|
val commandLine = createCommandLine(psiFile, module, result.mainClassName, tempDir.path)
|
||||||
|
|
||||||
LOG.printDebugMessage(commandLine.commandLineString)
|
LOG.printDebugMessage(commandLine.commandLineString)
|
||||||
|
|
||||||
@@ -176,16 +177,22 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
|||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createCommandLine(module: Module, mainClassName: String, tempOutDir: String): GeneralCommandLine {
|
private fun createCommandLine(originalFile: KtFile, module: Module?, mainClassName: String, tempOutDir: String): GeneralCommandLine {
|
||||||
val javaParameters = KotlinConsoleKeeper.createJavaParametersWithSdk(module)
|
val javaParameters = KotlinConsoleKeeper.createJavaParametersWithSdk(module)
|
||||||
javaParameters.mainClass = mainClassName
|
javaParameters.mainClass = mainClassName
|
||||||
|
|
||||||
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).toList()
|
|
||||||
val moduleDependencies = OrderEnumerator.orderEntries(module).recursively().pathsList.pathList
|
|
||||||
|
|
||||||
javaParameters.classPath.add(tempOutDir)
|
javaParameters.classPath.add(tempOutDir)
|
||||||
javaParameters.classPath.addAll(compiledModulePath)
|
|
||||||
javaParameters.classPath.addAll(moduleDependencies)
|
if (module != null) {
|
||||||
|
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).toList()
|
||||||
|
javaParameters.classPath.addAll(compiledModulePath)
|
||||||
|
|
||||||
|
val moduleDependencies = OrderEnumerator.orderEntries(module).recursively().pathsList.pathList
|
||||||
|
javaParameters.classPath.addAll(moduleDependencies)
|
||||||
|
}
|
||||||
|
|
||||||
|
val scriptDependencies = ScriptDependenciesManager.getInstance(originalFile.project).getScriptDependencies(originalFile.virtualFile)
|
||||||
|
javaParameters.classPath.addAll(scriptDependencies.classpath.map { it.absolutePath })
|
||||||
|
|
||||||
return javaParameters.toCommandLine()
|
return javaParameters.toCommandLine()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ class KtScratchReplExecutor(file: ScratchFile) : ScratchExecutor(file) {
|
|||||||
override fun execute() {
|
override fun execute() {
|
||||||
handler.onStart(file)
|
handler.onStart(file)
|
||||||
|
|
||||||
val module = file.getModule() ?: return errorOccurs("Module should be selected", isFatal = true)
|
val module = file.getModule()
|
||||||
val cmdLine = KotlinConsoleKeeper.createCommandLine(module)
|
val cmdLine = KotlinConsoleKeeper.createCommandLine(module)
|
||||||
|
|
||||||
LOG.printDebugMessage("Execute REPL: ${cmdLine.commandLineString}")
|
LOG.printDebugMessage("Execute REPL: ${cmdLine.commandLineString}")
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.scratch.ui
|
|||||||
|
|
||||||
|
|
||||||
import com.intellij.application.options.ModulesComboBox
|
import com.intellij.application.options.ModulesComboBox
|
||||||
|
import com.intellij.execution.ui.ConfigurationModuleSelector
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.actionSystem.ActionManager
|
import com.intellij.openapi.actionSystem.ActionManager
|
||||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||||
@@ -115,11 +116,11 @@ class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : JPanel
|
|||||||
moduleChooser.selectedModule = module
|
moduleChooser.selectedModule = module
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addModuleListener(f: (PsiFile, Module) -> Unit) {
|
fun addModuleListener(f: (PsiFile, Module?) -> Unit) {
|
||||||
moduleChooser.addActionListener {
|
moduleChooser.addActionListener {
|
||||||
val selectedModule = moduleChooser.selectedModule
|
val selectedModule = moduleChooser.selectedModule
|
||||||
val psiFile = scratchFile.getPsiFile()
|
val psiFile = scratchFile.getPsiFile()
|
||||||
if (selectedModule != null && psiFile != null) {
|
if (psiFile != null) {
|
||||||
f(psiFile, selectedModule)
|
f(psiFile, selectedModule)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,6 +163,7 @@ class ScratchTopPanel private constructor(val scratchFile: ScratchFile) : JPanel
|
|||||||
setModules(ModuleManager.getInstance(project).modules.filter {
|
setModules(ModuleManager.getInstance(project).modules.filter {
|
||||||
it.productionSourceInfo() != null || it.testSourceInfo() != null
|
it.productionSourceInfo() != null || it.testSourceInfo() != null
|
||||||
})
|
})
|
||||||
|
allowEmptySelection(ConfigurationModuleSelector.NO_MODULE_TEXT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +54,7 @@ class KotlinConsoleKeeper(val project: Project) {
|
|||||||
companion object {
|
companion object {
|
||||||
@JvmStatic fun getInstance(project: Project) = ServiceManager.getService(project, KotlinConsoleKeeper::class.java)
|
@JvmStatic fun getInstance(project: Project) = ServiceManager.getService(project, KotlinConsoleKeeper::class.java)
|
||||||
|
|
||||||
fun createCommandLine(module: Module): GeneralCommandLine {
|
fun createCommandLine(module: Module?): GeneralCommandLine {
|
||||||
val javaParameters = createJavaParametersWithSdk(module)
|
val javaParameters = createJavaParametersWithSdk(module)
|
||||||
|
|
||||||
javaParameters.mainClass = "dummy"
|
javaParameters.mainClass = "dummy"
|
||||||
@@ -79,16 +79,18 @@ class KotlinConsoleKeeper(val project: Project) {
|
|||||||
|
|
||||||
paramList.add("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
|
paramList.add("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
|
||||||
|
|
||||||
addPathToCompiledOutput(paramList, module)
|
if (module != null) {
|
||||||
|
addPathToCompiledOutput(paramList, module)
|
||||||
|
}
|
||||||
|
|
||||||
return commandLine
|
return commandLine
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createJavaParametersWithSdk(module: Module): JavaParameters {
|
fun createJavaParametersWithSdk(module: Module?): JavaParameters {
|
||||||
val params = JavaParameters()
|
val params = JavaParameters()
|
||||||
params.charset = null
|
params.charset = null
|
||||||
|
|
||||||
val sdk = ModuleRootManager.getInstance(module).sdk
|
val sdk = module?.let { ModuleRootManager.getInstance(module).sdk }
|
||||||
if (sdk != null && sdk.sdkType is JavaSdkType && File(sdk.homePath).exists()) {
|
if (sdk != null && sdk.sdkType is JavaSdkType && File(sdk.homePath).exists()) {
|
||||||
params.jdk = sdk
|
params.jdk = sdk
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
arrayListOf(1, 2).size // RESULT: 2
|
||||||
|
|
||||||
|
//NO_MODULE
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
arrayListOf(1, 2).size
|
||||||
|
|
||||||
|
//NO_MODULE
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
arrayListOf(1, 2).size // RESULT: res0: kotlin.Int = 2
|
||||||
|
|
||||||
|
//NO_MODULE
|
||||||
@@ -12,6 +12,7 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
|
|||||||
import com.intellij.openapi.roots.CompilerModuleExtension
|
import com.intellij.openapi.roots.CompilerModuleExtension
|
||||||
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
import com.intellij.openapi.roots.ModuleRootModificationUtil
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
@@ -27,9 +28,11 @@ import org.jetbrains.kotlin.idea.highlighter.KotlinHighlightingUtil
|
|||||||
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
|
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
|
||||||
import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport
|
import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport
|
||||||
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer
|
import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer
|
||||||
|
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
@@ -100,11 +103,15 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
|
|||||||
|
|
||||||
if (!KotlinHighlightingUtil.shouldHighlight(psiFile)) error("Highlighting for scratch file is switched off")
|
if (!KotlinHighlightingUtil.shouldHighlight(psiFile)) error("Highlighting for scratch file is switched off")
|
||||||
|
|
||||||
val (editor, scratchPanel) = getEditorWithScratchPanel(myManager, scratchFile)?: error("Couldn't find scratch panel")
|
val (editor, scratchPanel) = getEditorWithScratchPanel(myManager, scratchFile) ?: error("Couldn't find scratch panel")
|
||||||
scratchPanel.scratchFile.saveOptions {
|
scratchPanel.scratchFile.saveOptions {
|
||||||
copy(isRepl = isRepl, isInteractiveMode = false)
|
copy(isRepl = isRepl, isInteractiveMode = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!InTextDirectivesUtils.isDirectiveDefined(fileText, "// NO_MODULE")) {
|
||||||
|
scratchPanel.setModule(myFixture.module)
|
||||||
|
}
|
||||||
|
|
||||||
launchScratch(scratchFile)
|
launchScratch(scratchFile)
|
||||||
|
|
||||||
UIUtil.dispatchAllInvocationEvents()
|
UIUtil.dispatchAllInvocationEvents()
|
||||||
@@ -128,7 +135,10 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
|
|||||||
.filterIsInstance<InlayScratchFileRenderer>()
|
.filterIsInstance<InlayScratchFileRenderer>()
|
||||||
.forEach {
|
.forEach {
|
||||||
val str = it.toString()
|
val str = it.toString()
|
||||||
val offset = doc.getLineEndOffset(line); actualOutput.insert(offset, "${str.takeWhile { it.isWhitespace() }}// ${str.trim()}")
|
val offset = doc.getLineEndOffset(line); actualOutput.insert(
|
||||||
|
offset,
|
||||||
|
"${str.takeWhile { it.isWhitespace() }}// ${str.trim()}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +170,15 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
|
|||||||
|
|
||||||
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory()
|
override fun getTestDataPath() = KotlinTestUtils.getHomeDirectory()
|
||||||
|
|
||||||
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
|
|
||||||
|
override fun getProjectDescriptor(): com.intellij.testFramework.LightProjectDescriptor {
|
||||||
|
val testName = StringUtil.toLowerCase(getTestName(false))
|
||||||
|
|
||||||
|
return when {
|
||||||
|
testName.endsWith("NoRuntime") -> KotlinLightProjectDescriptor.INSTANCE
|
||||||
|
else -> KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun setUp() {
|
override fun setUp() {
|
||||||
super.setUp()
|
super.setUp()
|
||||||
|
|||||||
+10
@@ -56,6 +56,11 @@ public class ScratchRunActionTestGenerated extends AbstractScratchRunActionTest
|
|||||||
runTest("idea/testData/scratch/simpleFun.kts");
|
runTest("idea/testData/scratch/simpleFun.kts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleNoRuntime.kts")
|
||||||
|
public void testSimpleNoRuntime() throws Exception {
|
||||||
|
runTest("idea/testData/scratch/simpleNoRuntime.kts");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("spacesAtLineStart.kts")
|
@TestMetadata("spacesAtLineStart.kts")
|
||||||
public void testSpacesAtLineStart() throws Exception {
|
public void testSpacesAtLineStart() throws Exception {
|
||||||
runTest("idea/testData/scratch/spacesAtLineStart.kts");
|
runTest("idea/testData/scratch/spacesAtLineStart.kts");
|
||||||
@@ -134,6 +139,11 @@ public class ScratchRunActionTestGenerated extends AbstractScratchRunActionTest
|
|||||||
runTest("idea/testData/scratch/simpleFun.kts");
|
runTest("idea/testData/scratch/simpleFun.kts");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleNoRuntime.kts")
|
||||||
|
public void testSimpleNoRuntime() throws Exception {
|
||||||
|
runTest("idea/testData/scratch/simpleNoRuntime.kts");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("spacesAtLineStart.kts")
|
@TestMetadata("spacesAtLineStart.kts")
|
||||||
public void testSpacesAtLineStart() throws Exception {
|
public void testSpacesAtLineStart() throws Exception {
|
||||||
runTest("idea/testData/scratch/spacesAtLineStart.kts");
|
runTest("idea/testData/scratch/spacesAtLineStart.kts");
|
||||||
|
|||||||
Reference in New Issue
Block a user