Move REPL implementations to the scripting compiler impl module

This commit is contained in:
Ilya Chernikov
2019-02-26 12:12:24 +01:00
parent 199b32cad7
commit 4f135a5fe5
48 changed files with 456 additions and 486 deletions
@@ -0,0 +1,27 @@
/*
* 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.cli.common.extensions
import com.intellij.core.JavaCoreProjectEnvironment
import org.jetbrains.kotlin.cli.common.repl.ReplCompiler
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import java.io.File
interface ReplFactoryExtension {
companion object : ProjectExtensionDescriptor<ReplFactoryExtension>(
"org.jetbrains.kotlin.replFactoryExtension",
ReplFactoryExtension::class.java
)
fun makeReplCompiler(
templateClassName: String,
templateClasspath: List<File>,
baseClassLoader: ClassLoader?,
configuration: CompilerConfiguration,
projectEnvironment: JavaCoreProjectEnvironment
): ReplCompiler
}
@@ -19,7 +19,6 @@ interface ScriptEvaluationExtension {
fun isAccepted(arguments: CommonCompilerArguments): Boolean
// TODO: it would be nice to split KotlinCoreEnvironment to actual environment and compilation/project configuration
fun eval(
arguments: CommonCompilerArguments,
configuration: CompilerConfiguration,
@@ -0,0 +1,27 @@
/*
* 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.cli.common.extensions
import com.intellij.core.JavaCoreProjectEnvironment
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
interface ShellExtension {
companion object : ProjectExtensionDescriptor<ShellExtension>(
"org.jetbrains.kotlin.shellExtension",
ShellExtension::class.java
)
fun isAccepted(arguments: CommonCompilerArguments): Boolean
fun run(
arguments: CommonCompilerArguments,
configuration: CompilerConfiguration,
projectEnvironment: JavaCoreProjectEnvironment
): ExitCode
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.cli.common.ExitCode.*
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.messages.FilteringMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -36,7 +37,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
import org.jetbrains.kotlin.codegen.CompilationException
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
@@ -98,13 +98,17 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
if (arguments.script) {
val scriptingEvaluator = ScriptEvaluationExtension.getInstances(projectEnvironment.project).find { it.isAccepted(arguments) }
if (scriptingEvaluator == null) {
messageCollector.report(ERROR, "Unable to evaluate script, no scripting plugin found")
messageCollector.report(ERROR, "Unable to evaluate script, no scripting plugin loaded")
return COMPILATION_ERROR
}
return scriptingEvaluator.eval(arguments, configuration, projectEnvironment)
} else {
ReplFromTerminal.run(rootDisposable, configuration)
return ExitCode.OK
val shell = ShellExtension.getInstances(projectEnvironment.project).find { it.isAccepted(arguments) }
if (shell == null) {
messageCollector.report(ERROR, "Unable to run REPL, no scripting plugin loaded")
return COMPILATION_ERROR
}
return shell.run(arguments, configuration, projectEnvironment)
}
}
@@ -75,6 +75,7 @@ import org.jetbrains.kotlin.cli.common.config.ContentRoot
import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
@@ -460,7 +461,7 @@ class KotlinCoreEnvironment private constructor(
// used in the daemon for jar cache cleanup
val applicationEnvironment: JavaCoreApplicationEnvironment? get() = ourApplicationEnvironment
internal fun getOrCreateApplicationEnvironmentForProduction(
fun getOrCreateApplicationEnvironmentForProduction(
parentDisposable: Disposable, configuration: CompilerConfiguration
): JavaCoreApplicationEnvironment {
synchronized(APPLICATION_LOCK) {
@@ -614,6 +615,7 @@ class KotlinCoreEnvironment private constructor(
ExtraImportsProviderExtension.registerExtensionPoint(project)
IrGenerationExtension.registerExtensionPoint(project)
ScriptEvaluationExtension.registerExtensionPoint(project)
ShellExtension.registerExtensionPoint(project)
}
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
@@ -9,9 +9,6 @@ import java.io.File
import java.io.IOError
import java.lang.Character.isJavaIdentifierPart
import java.lang.Character.isJavaIdentifierStart
import java.lang.IllegalArgumentException
import java.lang.RuntimeException
import java.lang.UnsupportedOperationException
import java.net.URLClassLoader
import java.nio.file.FileSystemNotFoundException
import java.nio.file.Paths
@@ -44,6 +41,10 @@ object ServiceLoaderLite {
}
}
return loadImplementations(service, files, classLoader)
}
fun <Service> loadImplementations(service: Class<out Service>, files: List<File>, classLoader: ClassLoader): MutableList<Service> {
val implementations = mutableListOf<Service>()
for (className in findImplementations(service, files)) {
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2017 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.cli.jvm.repl.configuration
import org.jetbrains.kotlin.cli.jvm.repl.ReplExceptionReporter
import org.jetbrains.kotlin.cli.jvm.repl.messages.ConsoleDiagnosticMessageHolder
import org.jetbrains.kotlin.cli.jvm.repl.reader.ConsoleReplCommandReader
import org.jetbrains.kotlin.cli.jvm.repl.writer.ConsoleReplWriter
class ConsoleReplConfiguration : ReplConfiguration {
override val writer = ConsoleReplWriter()
override val exceptionReporter
get() = ReplExceptionReporter
override val commandReader = ConsoleReplCommandReader()
override val allowIncompleteLines: Boolean
get() = true
override val executionInterceptor
get() = SnippetExecutionInterceptor
override fun createDiagnosticHolder() = ConsoleDiagnosticMessageHolder()
}
@@ -1,32 +0,0 @@
/*
* Copyright 2010-2017 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.cli.jvm.repl.configuration
import org.jetbrains.kotlin.cli.jvm.repl.ReplExceptionReporter
import org.jetbrains.kotlin.cli.jvm.repl.messages.*
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader
import org.jetbrains.kotlin.cli.jvm.repl.writer.ReplWriter
interface ReplConfiguration {
val writer: ReplWriter
val exceptionReporter: ReplExceptionReporter
val commandReader: ReplCommandReader
val allowIncompleteLines: Boolean
val executionInterceptor: SnippetExecutionInterceptor
fun createDiagnosticHolder(): DiagnosticMessageHolder
}
@@ -1,25 +0,0 @@
/*
* Copyright 2010-2017 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.cli.jvm.repl.configuration
interface SnippetExecutionInterceptor {
fun <T> execute(block: () -> T): T
companion object Plain : SnippetExecutionInterceptor {
override fun <T> execute(block: () -> T) = block()
}
}
@@ -1,24 +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.cli.jvm.repl.reader
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
class IdeReplCommandReader : ReplCommandReader {
override fun readLine(next: ReplFromTerminal.WhatNextAfterOneLine) = readLine()
override fun flushHistory() = Unit
}
@@ -1,24 +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.cli.jvm.repl.reader
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
interface ReplCommandReader {
fun readLine(next: ReplFromTerminal.WhatNextAfterOneLine): String?
fun flushHistory()
}
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2017 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.cli.jvm.repl.writer
class ConsoleReplWriter : ReplWriter {
override fun printlnWelcomeMessage(x: String) = println(x)
override fun printlnHelpMessage(x: String) = println(x)
override fun outputCompileError(x: String) = println(x)
override fun outputCommandResult(x: String) = println(x)
override fun outputRuntimeError(x: String) = println(x)
override fun notifyReadLineStart() {}
override fun notifyReadLineEnd() {}
override fun notifyIncomplete() {}
override fun notifyCommandSuccess() {}
override fun sendInternalErrorReport(x: String) {}
}
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2016 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.cli.jvm.repl.writer
interface ReplWriter {
fun printlnWelcomeMessage(x: String)
fun printlnHelpMessage(x: String)
fun outputCommandResult(x: String)
fun notifyReadLineStart()
fun notifyReadLineEnd()
fun notifyIncomplete()
fun notifyCommandSuccess()
fun outputCompileError(x: String)
fun outputRuntimeError(x: String)
fun sendInternalErrorReport(x: String)
}
-1
View File
@@ -11,7 +11,6 @@ dependencies {
compile(project(":kotlin-build-common"))
compile(commonDep("org.fusesource.jansi", "jansi"))
compile(commonDep("org.jline", "jline"))
compileOnly(project(":kotlin-scripting-compiler"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
}
@@ -608,7 +608,7 @@ class CompileServiceImpl(
)
val messageCollector = KeepFirstErrorMessageCollector(compilerMessagesStream)
val repl = KotlinJvmReplService(
disposable, port, templateClasspath, templateClassName,
disposable, port, compilerId, templateClasspath, templateClassName,
messageCollector, operationsTracer
)
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
@@ -661,7 +661,7 @@ class CompileServiceImpl(
val disposable = Disposer.newDisposable()
val messageCollector = CompileServicesFacadeMessageCollector(servicesFacade, compilationOptions)
val repl = KotlinJvmReplService(
disposable, port, templateClasspath, templateClassName,
disposable, port, compilerId, templateClasspath, templateClassName,
messageCollector, null
)
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
@@ -17,20 +17,18 @@
package org.jetbrains.kotlin.daemon
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.extensions.ReplFactoryExtension
import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompiler
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompilerState
import org.jetbrains.kotlin.cli.jvm.plugins.ServiceLoaderLite
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.daemon.common.CompileService
import org.jetbrains.kotlin.daemon.common.CompilerId
import org.jetbrains.kotlin.daemon.common.RemoteOperationsTracer
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.io.PrintStream
@@ -38,12 +36,14 @@ import java.net.URLClassLoader
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.locks.ReentrantReadWriteLock
import java.util.logging.Logger
import kotlin.concurrent.read
import kotlin.concurrent.write
open class KotlinJvmReplService(
disposable: Disposable,
val portForServers: Int,
val compilerId: CompilerId,
templateClasspath: List<File>,
templateClassName: String,
protected val messageCollector: MessageCollector,
@@ -51,40 +51,46 @@ open class KotlinJvmReplService(
protected val operationsTracer: RemoteOperationsTracer?
) : ReplCompileAction, ReplCheckAction, CreateReplStageStateAction {
private val log by lazy { Logger.getLogger("replService") }
protected val configuration = CompilerConfiguration().apply {
put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
addJvmClasspathRoots(PathUtil.kotlinPathsForCompiler.let { listOf(it.stdlibPath, it.reflectPath, it.scriptRuntimePath) })
addJvmClasspathRoots(templateClasspath)
put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script")
languageVersionSettings = LanguageVersionSettingsImpl(
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlags.skipMetadataVersionCheck to true)
)
configureScripting()
configureScripting(compilerId)
}
protected fun makeScriptDefinition(templateClasspath: List<File>, templateClassName: String): KotlinScriptDefinition? {
val classloader = URLClassLoader(templateClasspath.map { it.toURI().toURL() }.toTypedArray(), this::class.java.classLoader)
try {
val cls = classloader.loadClass(templateClassName)
val def = KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, emptyMap())
messageCollector.report(INFO, "New script definition $templateClassName: files pattern = \"${def.scriptFilePattern}\", " +
"resolver = ${def.dependencyResolver.javaClass.name}")
return def
}
catch (ex: ClassNotFoundException) {
messageCollector.report(ERROR, "Cannot find script definition template class $templateClassName")
}
catch (ex: Exception) {
messageCollector.report(ERROR, "Error processing script definition template $templateClassName: ${ex.message}")
}
return null
}
private val scriptDef = makeScriptDefinition(templateClasspath, templateClassName)
private val replCompiler: ReplCompiler? by lazy {
if (scriptDef == null) null
else GenericReplCompiler(disposable, scriptDef, configuration, messageCollector)
try {
val projectEnvironment =
KotlinCoreEnvironment.ProjectEnvironment(
disposable,
KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(disposable, configuration)
)
ReplFactoryExtension.registerExtensionPoint(projectEnvironment.project)
projectEnvironment.registerExtensionsFromPlugins(configuration)
val replFactories = ReplFactoryExtension.getInstances(projectEnvironment.project)
if (replFactories.isEmpty()) {
throw java.lang.IllegalStateException("no scripting plugin loaded")
} else if (replFactories.size > 1) {
throw java.lang.IllegalStateException("several scripting plugins loaded")
}
replFactories.first().makeReplCompiler(
templateClassName,
templateClasspath,
this::class.java.classLoader,
configuration,
projectEnvironment
)
} catch (ex: Throwable) {
messageCollector.report(CompilerMessageSeverity.ERROR, "Unable to construct repl compiler: ${ex.message}")
throw IllegalStateException("Unable to use scripting/REPL in the daemon: ${ex.message}", ex)
}
}
protected val statesLock = ReentrantReadWriteLock()
@@ -125,7 +131,7 @@ open class KotlinJvmReplService(
fun createRemoteState(port: Int = portForServers): RemoteReplStateFacadeServer = statesLock.write {
val id = getValidId(stateIdCounter) { id -> states.none { it.key.getId() == id} }
val stateFacade = RemoteReplStateFacadeServer(id, createState().asState(GenericReplCompilerState::class.java), port)
val stateFacade = RemoteReplStateFacadeServer(id, createState(), port)
states.put(stateFacade, true)
stateFacade
}
@@ -175,9 +181,15 @@ inline internal fun getValidId(counter: AtomicInteger, check: (Int) -> Boolean):
return newId
}
private fun CompilerConfiguration.configureScripting() {
private fun CompilerConfiguration.configureScripting(compilerId: CompilerId) {
val error = try {
add(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, ScriptingCompilerConfigurationComponentRegistrar())
val componentRegistrars =
(this::class.java.classLoader as? URLClassLoader)?.let {
ServiceLoaderLite.loadImplementations(ComponentRegistrar::class.java, it)
} ?: ServiceLoaderLite.loadImplementations(
ComponentRegistrar::class.java, compilerId.compilerClasspath.map(::File), this::class.java.classLoader
)
addAll(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, componentRegistrars)
null
} catch (e: NoClassDefFoundError) {
e
@@ -17,15 +17,16 @@
package org.jetbrains.kotlin.daemon
import org.jetbrains.kotlin.cli.common.repl.ILineId
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompilerState
import org.jetbrains.kotlin.cli.common.repl.IReplStageState
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.ReplStateFacade
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
import java.rmi.server.UnicastRemoteObject
class RemoteReplStateFacadeServer(val _id: Int,
val state: GenericReplCompilerState,
port: Int = SOCKET_ANY_FREE_PORT
class RemoteReplStateFacadeServer(
val _id: Int,
val state: IReplStageState<*>,
port: Int = SOCKET_ANY_FREE_PORT
) : ReplStateFacade,
UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory)
{
+1
View File
@@ -6,6 +6,7 @@ plugins {
}
dependencies {
testCompile(project(":kotlin-scripting-compiler-impl"))
testCompile(projectTests(":compiler:tests-common"))
testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") }
testCompile(projectTests(":generators:test-generator"))
@@ -25,14 +25,14 @@ import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompiler
import org.jetbrains.kotlin.cli.jvm.repl.KOTLIN_REPL_JVM_TARGET_PROPERTY
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
import org.jetbrains.kotlin.script.StandardScriptDefinition
import org.jetbrains.kotlin.script.loadScriptingPlugin
import org.jetbrains.kotlin.scripting.repl.GenericReplCompiler
import org.jetbrains.kotlin.scripting.repl.KOTLIN_REPL_JVM_TARGET_PROPERTY
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.script.loadScriptingPlugin
import org.jetbrains.kotlin.scripting.repl.GenericReplCompiler
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
@@ -39,9 +39,12 @@ import java.rmi.server.UnicastRemoteObject
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.concurrent.thread
import kotlin.script.dependencies.*
import kotlin.script.experimental.dependencies.*
import kotlin.script.dependencies.Environment
import kotlin.script.dependencies.ScriptContents
import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.experimental.dependencies.DependenciesResolver.ResolveResult
import kotlin.script.experimental.dependencies.ScriptDependencies
import kotlin.script.experimental.dependencies.asSuccess
import kotlin.script.templates.ScriptTemplateDefinition
import kotlin.test.fail
@@ -727,16 +730,17 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
daemon, null, CompileService.TargetPlatform.JVM, emptyArray(), TestMessageCollector(),
classpathFromClassloader(), ScriptWithNoParam::class.qualifiedName!!
)
repl.createState()
} catch (e: Exception) {
TestCase.assertEquals(
"Unable to use scripting/REPL in the daemon, no kotlin-scripting-compiler.jar or its dependencies are found in the compiler classpath",
"Unable to use scripting/REPL in the daemon: no scripting plugin loaded",
e.message
)
isErrorThrown = true
} finally {
repl?.dispose()
}
TestCase.assertTrue("Expecting exception that kotlin-scripting-plugin is not found in the classpath", isErrorThrown)
TestCase.assertTrue("Expecting exception that scripting plugin is not loaded", isErrorThrown)
}
}
@@ -18,9 +18,9 @@ package org.jetbrains.kotlin.repl
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ConsoleReplConfiguration
import org.jetbrains.kotlin.cli.jvm.repl.ReplInterpreter
import org.jetbrains.kotlin.script.loadScriptingPlugin
import org.jetbrains.kotlin.scripting.repl.ReplInterpreter
import org.jetbrains.kotlin.scripting.repl.configuration.ConsoleReplConfiguration
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
@@ -86,7 +86,10 @@ abstract class AbstractReplInterpreterTest : KtUsefulTestCase() {
protected fun doTest(path: String) {
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK)
loadScriptingPlugin(configuration)
val repl = ReplInterpreter(testRootDisposable, configuration, ConsoleReplConfiguration())
val repl = ReplInterpreter(
testRootDisposable, configuration,
ConsoleReplConfiguration()
)
for ((code, expected) in loadLines(File(path))) {
val lineResult = repl.eval(code)
@@ -21,12 +21,12 @@ import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.addJvmSdkRoots
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompiler
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
import org.jetbrains.kotlin.scripting.repl.GenericReplCompiler
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.net.URLClassLoader
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
@@ -1,30 +1,19 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.repl.messages.DiagnosticMessageHolder
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.script.experimental.dependencies.ScriptDependencies
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
class ReplCompilerStageHistory(private val state: org.jetbrains.kotlin.scripting.repl.GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {
override fun reset(): Iterable<ILineId> {
val removedCompiledLines = super.reset()
@@ -60,17 +49,17 @@ abstract class GenericReplCheckerState : IReplStageState<ScriptDescriptor> {
val errorHolder: DiagnosticMessageHolder
)
var lastLineState: LineState? = null // for transferring state to the compiler in most typical case
var lastLineState: org.jetbrains.kotlin.scripting.repl.GenericReplCheckerState.LineState? = null // for transferring state to the compiler in most typical case
}
class GenericReplCompilerState(environment: KotlinCoreEnvironment, override val lock: ReentrantReadWriteLock = ReentrantReadWriteLock()) :
IReplStageState<ScriptDescriptor>, GenericReplCheckerState() {
IReplStageState<ScriptDescriptor>, org.jetbrains.kotlin.scripting.repl.GenericReplCheckerState() {
override val history = ReplCompilerStageHistory(this)
override val history = org.jetbrains.kotlin.scripting.repl.ReplCompilerStageHistory(this)
override val currentGeneration: Int get() = (history as BasicReplStageHistory<*>).currentGeneration.get()
val analyzerEngine = ReplCodeAnalyzer(environment)
val analyzerEngine = org.jetbrains.kotlin.scripting.repl.ReplCodeAnalyzer(environment)
var lastDependencies: ScriptDependencies? = null
}
@@ -1,20 +1,9 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.text.StringUtil
@@ -28,7 +17,6 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.repl.messages.ConsoleDiagnosticMessageHolder
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
@@ -36,6 +24,7 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.scripting.repl.messages.ConsoleDiagnosticMessageHolder
import kotlin.concurrent.write
const val KOTLIN_REPL_JVM_TARGET_PROPERTY = "kotlin.repl.jvm.target"
@@ -69,7 +58,7 @@ open class GenericReplChecker(
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult {
state.lock.write {
val checkerState = state.asState(GenericReplCheckerState::class.java)
val checkerState = state.asState(org.jetbrains.kotlin.scripting.repl.GenericReplCheckerState::class.java)
val scriptFileName = makeScriptBaseName(codeLine)
val virtualFile =
LightVirtualFile(
@@ -87,7 +76,8 @@ open class GenericReplChecker(
val syntaxErrorReport = AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorHolder)
if (!syntaxErrorReport.isHasErrors) {
checkerState.lastLineState = GenericReplCheckerState.LineState(codeLine, psiFile, errorHolder)
checkerState.lastLineState =
org.jetbrains.kotlin.scripting.repl.GenericReplCheckerState.LineState(codeLine, psiFile, errorHolder)
}
return when {
@@ -1,20 +1,9 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.Disposer
@@ -50,15 +39,17 @@ open class GenericReplCompiler(
messageCollector: MessageCollector
) : this(Disposer.newDisposable(), scriptDefinition, compilerConfiguration, messageCollector)
private val checker = GenericReplChecker(disposable, scriptDefinition, compilerConfiguration, messageCollector)
private val checker =
GenericReplChecker(disposable, scriptDefinition, compilerConfiguration, messageCollector)
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = GenericReplCompilerState(checker.environment, lock)
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> =
org.jetbrains.kotlin.scripting.repl.GenericReplCompilerState(checker.environment, lock)
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = checker.check(state, codeLine)
override fun compile(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCompileResult {
state.lock.write {
val compilerState = state.asState(GenericReplCompilerState::class.java)
val compilerState = state.asState(org.jetbrains.kotlin.scripting.repl.GenericReplCompilerState::class.java)
val (psiFile, errorHolder) = run {
if (compilerState.lastLineState == null || compilerState.lastLineState!!.codeLine != codeLine) {
@@ -1,22 +1,11 @@
/*
* Copyright 2010-2016 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.
* 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.
*/
@file:Suppress("UNUSED_PARAMETER")
package org.jetbrains.kotlin.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import org.jetbrains.kotlin.cli.common.repl.CompiledReplCodeLine
import org.jetbrains.kotlin.cli.common.repl.ILineId
@@ -85,7 +74,8 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
data class Successful(override val scriptDescriptor: ClassDescriptorWithResolutionScopes, override val diagnostics: Diagnostics) :
ReplLineAnalysisResult
data class WithErrors(override val diagnostics: Diagnostics) : ReplLineAnalysisResult {
data class WithErrors(override val diagnostics: Diagnostics) :
ReplLineAnalysisResult {
override val scriptDescriptor: ClassDescriptorWithResolutionScopes? get() = null
}
}
@@ -133,7 +123,10 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
try {
rootPackageProvider.addDelegateProvider(provider)
} catch (e: UninitializedPropertyAccessException) {
rootPackageProvider = AdaptablePackageMemberDeclarationProvider(provider)
rootPackageProvider =
AdaptablePackageMemberDeclarationProvider(
provider
)
}
}
@@ -155,7 +148,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
class AdaptablePackageMemberDeclarationProvider(
private var delegateProvider: PackageMemberDeclarationProvider
) : DelegatePackageMemberDeclarationProvider(delegateProvider) {
) : org.jetbrains.kotlin.scripting.repl.DelegatePackageMemberDeclarationProvider(delegateProvider) {
fun addDelegateProvider(provider: PackageMemberDeclarationProvider) {
delegateProvider = CombinedPackageMemberDeclarationProvider(listOf(provider, delegateProvider))
@@ -182,7 +175,10 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
}
fun submitLine(ktFile: KtFile, codeLine: ReplCodeLine) {
val line = LineInfo.SubmittedLine(ktFile, successfulLines.lastValue())
val line = LineInfo.SubmittedLine(
ktFile,
successfulLines.lastValue()
)
submittedLines[ktFile] = line
ktFile.fileScopesCustomizer = object : FileScopesCustomizer {
override fun createFileScopes(fileScopeFactory: FileScopeFactory): FileScopes {
@@ -192,13 +188,20 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
}
fun lineSuccess(ktFile: KtFile, codeLine: ReplCodeLine, scriptDescriptor: ClassDescriptorWithResolutionScopes) {
val successfulLine = LineInfo.SuccessfulLine(ktFile, successfulLines.lastValue(), scriptDescriptor)
val successfulLine = LineInfo.SuccessfulLine(
ktFile,
successfulLines.lastValue(),
scriptDescriptor
)
submittedLines[ktFile] = successfulLine
successfulLines.add(CompiledReplCodeLine(ktFile.name, codeLine), successfulLine)
}
fun lineFailure(ktFile: KtFile, codeLine: ReplCodeLine) {
submittedLines[ktFile] = LineInfo.FailedLine(ktFile, successfulLines.lastValue())
submittedLines[ktFile] = LineInfo.FailedLine(
ktFile,
successfulLines.lastValue()
)
}
private fun lineInfo(ktFile: KtFile) = submittedLines[ktFile]
@@ -1,22 +1,11 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import org.jetbrains.kotlin.cli.jvm.repl.writer.ReplWriter
import org.jetbrains.kotlin.scripting.repl.writer.ReplWriter
import java.io.PrintWriter
import java.io.StringWriter
@@ -1,20 +1,9 @@
/*
* Copyright 2010-2016 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.
* 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.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.io.FileUtil
@@ -22,11 +11,11 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
import org.jetbrains.kotlin.cli.common.repl.replUnescapeLineBreaks
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ConsoleReplConfiguration
import org.jetbrains.kotlin.cli.jvm.repl.configuration.IdeReplConfiguration
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ReplConfiguration
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.scripting.repl.configuration.ConsoleReplConfiguration
import org.jetbrains.kotlin.scripting.repl.configuration.IdeReplConfiguration
import org.jetbrains.kotlin.scripting.repl.configuration.ReplConfiguration
import java.io.File
import java.io.IOException
import java.io.PrintWriter
@@ -1,20 +1,9 @@
/*
* Copyright 2010-2016 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.
* 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.cli.jvm.repl
package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
@@ -25,9 +14,9 @@ import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
import org.jetbrains.kotlin.cli.jvm.repl.configuration.ReplConfiguration
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.scripting.repl.configuration.ReplConfiguration
import java.io.PrintWriter
import java.net.URLClassLoader
import java.util.concurrent.atomic.AtomicInteger
@@ -81,7 +70,12 @@ class ReplInterpreter(
// TODO: add script definition with project-based resolving for IDEA repl
private val scriptCompiler: ReplCompiler by lazy {
GenericReplCompiler(disposable, REPL_LINE_AS_SCRIPT_DEFINITION, configuration, messageCollector)
GenericReplCompiler(
disposable,
REPL_LINE_AS_SCRIPT_DEFINITION,
configuration,
messageCollector
)
}
private val scriptEvaluator: ReplFullEvaluator by lazy {
GenericReplCompilingEvaluator(scriptCompiler, classpathRoots, classLoader, null, ReplRepeatingMode.REPEAT_ANY_PREVIOUS)
@@ -0,0 +1,28 @@
/*
* 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.scripting.repl.configuration
import org.jetbrains.kotlin.scripting.repl.ReplExceptionReporter
import org.jetbrains.kotlin.scripting.repl.messages.ConsoleDiagnosticMessageHolder
import org.jetbrains.kotlin.scripting.repl.reader.ConsoleReplCommandReader
import org.jetbrains.kotlin.scripting.repl.writer.ConsoleReplWriter
class ConsoleReplConfiguration : ReplConfiguration {
override val writer = ConsoleReplWriter()
override val exceptionReporter
get() = ReplExceptionReporter
override val commandReader = ConsoleReplCommandReader()
override val allowIncompleteLines: Boolean
get() = true
override val executionInterceptor
get() = SnippetExecutionInterceptor
override fun createDiagnosticHolder() = ConsoleDiagnosticMessageHolder()
}
@@ -1,35 +1,25 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl.configuration
package org.jetbrains.kotlin.scripting.repl.configuration
import org.jetbrains.kotlin.cli.jvm.repl.IdeReplExceptionReporter
import org.jetbrains.kotlin.cli.jvm.repl.ReplExceptionReporter
import org.jetbrains.kotlin.cli.jvm.repl.messages.IdeDiagnosticMessageHolder
import org.jetbrains.kotlin.cli.jvm.repl.reader.IdeReplCommandReader
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplSystemInWrapper
import org.jetbrains.kotlin.cli.jvm.repl.writer.IdeSystemOutWrapperReplWriter
import org.jetbrains.kotlin.cli.jvm.repl.writer.ReplWriter
import org.jetbrains.kotlin.scripting.repl.IdeReplExceptionReporter
import org.jetbrains.kotlin.scripting.repl.ReplExceptionReporter
import org.jetbrains.kotlin.scripting.repl.messages.IdeDiagnosticMessageHolder
import org.jetbrains.kotlin.scripting.repl.reader.IdeReplCommandReader
import org.jetbrains.kotlin.scripting.repl.reader.ReplCommandReader
import org.jetbrains.kotlin.scripting.repl.reader.ReplSystemInWrapper
import org.jetbrains.kotlin.scripting.repl.writer.IdeSystemOutWrapperReplWriter
import org.jetbrains.kotlin.scripting.repl.writer.ReplWriter
class IdeReplConfiguration : ReplConfiguration {
override val allowIncompleteLines: Boolean
get() = false
override val executionInterceptor: SnippetExecutionInterceptor = object : SnippetExecutionInterceptor {
override val executionInterceptor: SnippetExecutionInterceptor = object :
SnippetExecutionInterceptor {
override fun <T> execute(block: () -> T): T {
try {
sinWrapper.isReplScriptExecuting = true
@@ -0,0 +1,21 @@
/*
* 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.scripting.repl.configuration
import org.jetbrains.kotlin.scripting.repl.ReplExceptionReporter
import org.jetbrains.kotlin.scripting.repl.messages.DiagnosticMessageHolder
import org.jetbrains.kotlin.scripting.repl.reader.ReplCommandReader
import org.jetbrains.kotlin.scripting.repl.writer.ReplWriter
interface ReplConfiguration {
val writer: ReplWriter
val exceptionReporter: ReplExceptionReporter
val commandReader: ReplCommandReader
val allowIncompleteLines: Boolean
val executionInterceptor: SnippetExecutionInterceptor
fun createDiagnosticHolder(): DiagnosticMessageHolder
}
@@ -0,0 +1,14 @@
/*
* 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.scripting.repl.configuration
interface SnippetExecutionInterceptor {
fun <T> execute(block: () -> T): T
companion object Plain : SnippetExecutionInterceptor {
override fun <T> execute(block: () -> T) = block()
}
}
@@ -1,20 +1,9 @@
/*
* 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.
* 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.cli.jvm.repl.messages
package org.jetbrains.kotlin.scripting.repl.messages
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorBasedReporter
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.cli.jvm.repl.messages
package org.jetbrains.kotlin.scripting.repl.messages
import org.jetbrains.kotlin.cli.common.messages.DiagnosticMessageReporter
@@ -1,20 +1,9 @@
/*
* 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.
* 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.cli.jvm.repl.messages
package org.jetbrains.kotlin.scripting.repl.messages
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiFile
@@ -1,22 +1,11 @@
/*
* 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.
* 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.cli.jvm.repl.reader
package org.jetbrains.kotlin.scripting.repl.reader
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
import org.jetbrains.kotlin.scripting.repl.ReplFromTerminal
import org.jline.reader.EndOfFileException
import org.jline.reader.LineReader
import org.jline.reader.LineReaderBuilder
@@ -0,0 +1,13 @@
/*
* 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.scripting.repl.reader
import org.jetbrains.kotlin.scripting.repl.ReplFromTerminal
class IdeReplCommandReader : ReplCommandReader {
override fun readLine(next: ReplFromTerminal.WhatNextAfterOneLine) = readLine()
override fun flushHistory() = Unit
}
@@ -0,0 +1,13 @@
/*
* 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.scripting.repl.reader
import org.jetbrains.kotlin.scripting.repl.ReplFromTerminal
interface ReplCommandReader {
fun readLine(next: ReplFromTerminal.WhatNextAfterOneLine): String?
fun flushHistory()
}
@@ -1,23 +1,12 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl.reader
package org.jetbrains.kotlin.scripting.repl.reader
import org.jetbrains.kotlin.cli.common.repl.replUnescapeLineBreaks
import org.jetbrains.kotlin.cli.jvm.repl.writer.ReplWriter
import org.jetbrains.kotlin.scripting.repl.writer.ReplWriter
import org.w3c.dom.Element
import org.xml.sax.InputSource
import java.io.ByteArrayInputStream
@@ -0,0 +1,20 @@
/*
* 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.scripting.repl.writer
class ConsoleReplWriter : ReplWriter {
override fun printlnWelcomeMessage(x: String) = println(x)
override fun printlnHelpMessage(x: String) = println(x)
override fun outputCompileError(x: String) = println(x)
override fun outputCommandResult(x: String) = println(x)
override fun outputRuntimeError(x: String) = println(x)
override fun notifyReadLineStart() {}
override fun notifyReadLineEnd() {}
override fun notifyIncomplete() {}
override fun notifyCommandSuccess() {}
override fun sendInternalErrorReport(x: String) {}
}
@@ -1,20 +1,9 @@
/*
* Copyright 2010-2017 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.
* 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.cli.jvm.repl.writer
package org.jetbrains.kotlin.scripting.repl.writer
import org.jetbrains.kotlin.cli.common.repl.replAddLineBreak
import org.jetbrains.kotlin.cli.common.repl.replOutputAsXml
@@ -22,7 +11,8 @@ import org.jetbrains.kotlin.utils.repl.ReplEscapeType
import org.jetbrains.kotlin.utils.repl.ReplEscapeType.*
import java.io.PrintStream
class IdeSystemOutWrapperReplWriter(standardOut: PrintStream) : PrintStream(standardOut, true), ReplWriter {
class IdeSystemOutWrapperReplWriter(standardOut: PrintStream) : PrintStream(standardOut, true),
ReplWriter {
override fun print(x: Boolean) = printWithEscaping(x.toString())
override fun print(x: Char) = printWithEscaping(x.toString())
override fun print(x: Int) = printWithEscaping(x.toString())
@@ -0,0 +1,19 @@
/*
* 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.scripting.repl.writer
interface ReplWriter {
fun printlnWelcomeMessage(x: String)
fun printlnHelpMessage(x: String)
fun outputCommandResult(x: String)
fun notifyReadLineStart()
fun notifyReadLineEnd()
fun notifyIncomplete()
fun notifyCommandSuccess()
fun outputCompileError(x: String)
fun outputRuntimeError(x: String)
fun sendInternalErrorReport(x: String)
}
@@ -0,0 +1,27 @@
/*
* 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.scripting.compiler.plugin
import com.intellij.core.JavaCoreProjectEnvironment
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.scripting.repl.ReplFromTerminal
class JvmCliReplShellExtension : ShellExtension {
override fun isAccepted(arguments: CommonCompilerArguments): Boolean = true
override fun run(
arguments: CommonCompilerArguments,
configuration: CompilerConfiguration,
projectEnvironment: JavaCoreProjectEnvironment
): ExitCode {
ReplFromTerminal.run(projectEnvironment.parentDisposable, configuration)
return ExitCode.OK
}
}
@@ -0,0 +1,45 @@
/*
* 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.scripting.compiler.plugin
import com.intellij.core.JavaCoreProjectEnvironment
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.extensions.ReplFactoryExtension
import org.jetbrains.kotlin.cli.common.repl.ReplCompiler
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.scripting.repl.GenericReplCompiler
import java.io.File
import java.net.URLClassLoader
class JvmStandardReplFactoryExtension : ReplFactoryExtension {
override fun makeReplCompiler(
templateClassName: String,
templateClasspath: List<File>,
baseClassLoader: ClassLoader?,
configuration: CompilerConfiguration,
projectEnvironment: JavaCoreProjectEnvironment
): ReplCompiler = GenericReplCompiler(
projectEnvironment.parentDisposable,
makeScriptDefinition(templateClasspath, templateClassName, baseClassLoader),
configuration,
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
)
private fun makeScriptDefinition(
templateClasspath: List<File>, templateClassName: String, baseClassLoader: ClassLoader?
): KotlinScriptDefinition = try {
val classloader = URLClassLoader(templateClasspath.map { it.toURI().toURL() }.toTypedArray(), baseClassLoader)
val cls = classloader.loadClass(templateClassName)
KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, emptyMap())
} catch (ex: ClassNotFoundException) {
throw IllegalStateException("Cannot find script definition template class $templateClassName", ex)
} catch (ex: Exception) {
throw IllegalStateException("Error loading script definition template $templateClassName", ex)
}
}
@@ -7,11 +7,14 @@ package org.jetbrains.kotlin.scripting.compiler.plugin
import com.intellij.mock.MockProject
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.extensions.ReplFactoryExtension
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.extensions.CollectAdditionalSourcesExtension
import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
@@ -23,11 +26,21 @@ import org.jetbrains.kotlin.scripting.legacy.CliScriptReportSink
import org.jetbrains.kotlin.scripting.shared.extensions.ScriptExtraImportsProviderExtension
import org.jetbrains.kotlin.scripting.shared.extensions.ScriptingResolveExtension
private fun <T> ProjectExtensionDescriptor<T>.registerExtensionIfRequired(project: MockProject, extension: T) {
try {
registerExtension(project, extension)
} catch (ex: IllegalArgumentException) {
// ignore
}
}
class ScriptingCompilerConfigurationComponentRegistrar : ComponentRegistrar {
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
CompilerConfigurationExtension.registerExtension(project, ScriptingCompilerConfigurationExtension(project))
CollectAdditionalSourcesExtension.registerExtension(project, ScriptingCollectAdditionalSourcesExtension(project))
ScriptEvaluationExtension.registerExtension(project, JvmCliScriptEvaluationExtension())
ScriptEvaluationExtension.registerExtensionIfRequired(project, JvmCliScriptEvaluationExtension())
ShellExtension.registerExtensionIfRequired(project, JvmCliReplShellExtension())
ReplFactoryExtension.registerExtensionIfRequired(project, JvmStandardReplFactoryExtension())
val scriptDefinitionProvider = CliScriptDefinitionProvider()
project.registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider)