Refactoring: extract common parts for create command line for repl and scratch

This commit is contained in:
Natalia Selezneva
2019-04-12 11:33:32 +03:00
parent 0dd09ea7de
commit dfa5f1f090
4 changed files with 86 additions and 69 deletions
@@ -19,12 +19,10 @@ package org.jetbrains.kotlin.idea.scratch.compile
import com.intellij.execution.configurations.GeneralCommandLine import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.process.CapturingProcessHandler import com.intellij.execution.process.CapturingProcessHandler
import com.intellij.execution.process.ProcessOutput import com.intellij.execution.process.ProcessOutput
import com.intellij.openapi.compiler.ex.CompilerPathsEx
import com.intellij.openapi.module.Module import com.intellij.openapi.module.Module
import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task import com.intellij.openapi.progress.Task
import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.DumbService
import com.intellij.openapi.roots.OrderEnumerator
import com.intellij.openapi.util.Computable import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
@@ -34,7 +32,6 @@ import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
import org.jetbrains.kotlin.codegen.filterClassFiles import org.jetbrains.kotlin.codegen.filterClassFiles
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.console.KotlinConsoleKeeper
import org.jetbrains.kotlin.diagnostics.Severity 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
@@ -45,6 +42,7 @@ import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.idea.scratch.* import org.jetbrains.kotlin.idea.scratch.*
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutput import org.jetbrains.kotlin.idea.scratch.output.ScratchOutput
import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputType import org.jetbrains.kotlin.idea.scratch.output.ScratchOutputType
import org.jetbrains.kotlin.idea.util.JavaParametersBuilder
import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
@@ -177,17 +175,15 @@ class KtCompilingExecutor(file: ScratchFile) : ScratchExecutor(file) {
} }
private fun createCommandLine(originalFile: KtFile, 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 = JavaParametersBuilder(originalFile.project)
javaParameters.mainClass = mainClassName .withSdkFrom(module, true)
.withMainClassName(mainClassName)
.build()
javaParameters.classPath.add(tempOutDir) javaParameters.classPath.add(tempOutDir)
if (module != null) { if (module != null) {
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).toList() javaParameters.classPath.addAll(JavaParametersBuilder.getModuleDependencies(module))
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) val scriptDependencies = ScriptDependenciesManager.getInstance(originalFile.project).getScriptDependencies(originalFile.virtualFile)
@@ -44,7 +44,7 @@ class KtScratchReplExecutor(file: ScratchFile) : ScratchExecutor(file) {
handler.onStart(file) handler.onStart(file)
val module = file.getModule() val module = file.getModule()
val cmdLine = KotlinConsoleKeeper.createCommandLine(module) val cmdLine = KotlinConsoleKeeper.createReplCommandLine(file.project, module)
LOG.printDebugMessage("Execute REPL: ${cmdLine.commandLineString}") LOG.printDebugMessage("Execute REPL: ${cmdLine.commandLineString}")
@@ -17,18 +17,11 @@
package org.jetbrains.kotlin.console package org.jetbrains.kotlin.console
import com.intellij.execution.configurations.GeneralCommandLine import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.configurations.JavaParameters
import com.intellij.execution.configurations.ParametersList
import com.intellij.openapi.compiler.ex.CompilerPathsEx
import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.module.Module import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType
import com.intellij.openapi.projectRoots.SimpleJavaSdkType
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderEnumerator
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.SystemProperties import org.jetbrains.kotlin.idea.util.JavaParametersBuilder
import org.jetbrains.kotlin.utils.PathUtil import org.jetbrains.kotlin.utils.PathUtil
import java.io.File import java.io.File
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -44,7 +37,7 @@ class KotlinConsoleKeeper(val project: Project) {
fun run(module: Module, previousCompilationFailed: Boolean = false): KotlinConsoleRunner? { fun run(module: Module, previousCompilationFailed: Boolean = false): KotlinConsoleRunner? {
val path = module.moduleFilePath val path = module.moduleFilePath
val cmdLine = createCommandLine(module) val cmdLine = createReplCommandLine(project, module)
val consoleRunner = KotlinConsoleRunner(module, cmdLine, previousCompilationFailed, project, REPL_TITLE, path) val consoleRunner = KotlinConsoleRunner(module, cmdLine, previousCompilationFailed, project, REPL_TITLE, path)
consoleRunner.initAndRun() consoleRunner.initAndRun()
@@ -54,61 +47,32 @@ 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 createReplCommandLine(project: Project, module: Module?): GeneralCommandLine {
val javaParameters = createJavaParametersWithSdk(module) val javaParameters = JavaParametersBuilder(project)
.withSdkFrom(module, true)
.withMainClassName("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
.build()
javaParameters.mainClass = "dummy" javaParameters.charset = null
javaParameters.vmParametersList.add("-Dkotlin.repl.ideMode=true")
val commandLine = javaParameters.toCommandLine() javaParameters.classPath.apply {
val kotlinPaths = PathUtil.kotlinPathsForIdeaPlugin
val paramList = commandLine.parametersList addAll(kotlinPaths.compilerClasspath.map { it.absolutePath })
paramList.clearAll() add(kotlinPaths.compilerPath.absolutePath)
}
// use to debug repl process
//paramList.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005")
val kotlinPaths = PathUtil.kotlinPathsForIdeaPlugin
val replClassPath =
(kotlinPaths.compilerClasspath + kotlinPaths.compilerPath)
.joinToString(File.pathSeparator) { it.absolutePath }
paramList.add("-cp")
paramList.add(replClassPath)
paramList.add("-Dkotlin.repl.ideMode=true")
paramList.add("org.jetbrains.kotlin.cli.jvm.K2JVMCompiler")
if (module != null) { if (module != null) {
addPathToCompiledOutput(paramList, module) val classPath = JavaParametersBuilder.getModuleDependencies(module)
if (classPath.isNotEmpty()) {
javaParameters.programParametersList.add("-cp")
javaParameters.programParametersList.add(
classPath.joinToString(File.pathSeparator)
)
}
} }
return commandLine return javaParameters.toCommandLine()
}
fun createJavaParametersWithSdk(module: Module?): JavaParameters {
val params = JavaParameters()
params.charset = null
val sdk = module?.let { ModuleRootManager.getInstance(module).sdk }
if (sdk != null && sdk.sdkType is JavaSdkType && File(sdk.homePath).exists()) {
params.jdk = sdk
}
if (params.jdk == null) {
params.jdk = SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome())
}
return params
}
private fun addPathToCompiledOutput(paramList: ParametersList, module: Module) {
val compiledModulePath = CompilerPathsEx.getOutputPaths(arrayOf(module)).joinToString(File.pathSeparator)
val moduleDependencies = OrderEnumerator.orderEntries(module).recursively().pathsList.pathsString
val compiledOutputClasspath = "$compiledModulePath${File.pathSeparator}$moduleDependencies"
paramList.add("-cp")
paramList.add(compiledOutputClasspath)
} }
} }
} }
@@ -0,0 +1,57 @@
/*
* Copyright 2010-2019 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.util
import com.intellij.execution.configurations.JavaParameters
import com.intellij.openapi.compiler.ex.CompilerPathsEx
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.JavaSdkType
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.projectRoots.SimpleJavaSdkType
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.OrderEnumerator
import com.intellij.util.SystemProperties
import java.io.File
class JavaParametersBuilder(private val project: Project) {
private var setDefaultSdk = false
private var mainClassName: String? = null
private var sdk: Sdk? = null
fun build(): JavaParameters {
return JavaParameters().apply {
this.mainClass = mainClassName
this.jdk = sdk
if (jdk == null && setDefaultSdk) {
this.jdk = SimpleJavaSdkType().createJdk("tmp", SystemProperties.getJavaHome())
}
}
}
fun withMainClassName(name: String?): JavaParametersBuilder {
mainClassName = name
return this
}
fun withSdkFrom(module: Module?, setDefault: Boolean = false): JavaParametersBuilder {
if (module != null) {
val sdk = module.let { ModuleRootManager.getInstance(module).sdk }
if (sdk != null && sdk.sdkType is JavaSdkType && File(sdk.homePath).exists()) {
this.sdk = sdk
}
}
setDefaultSdk = setDefault
return this
}
companion object {
fun getModuleDependencies(module: Module): List<String> {
return CompilerPathsEx.getOutputPaths(arrayOf(module)).toList() +
OrderEnumerator.orderEntries(module).recursively().pathsList.pathList
}
}
}