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 fun isAccepted(arguments: CommonCompilerArguments): Boolean
// TODO: it would be nice to split KotlinCoreEnvironment to actual environment and compilation/project configuration
fun eval( fun eval(
arguments: CommonCompilerArguments, arguments: CommonCompilerArguments,
configuration: CompilerConfiguration, 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.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension 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.*
import org.jetbrains.kotlin.cli.common.messages.FilteringMessageCollector import org.jetbrains.kotlin.cli.common.messages.FilteringMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollector 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.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser 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.codegen.CompilationException
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
@@ -98,13 +98,17 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
if (arguments.script) { if (arguments.script) {
val scriptingEvaluator = ScriptEvaluationExtension.getInstances(projectEnvironment.project).find { it.isAccepted(arguments) } val scriptingEvaluator = ScriptEvaluationExtension.getInstances(projectEnvironment.project).find { it.isAccepted(arguments) }
if (scriptingEvaluator == null) { 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 COMPILATION_ERROR
} }
return scriptingEvaluator.eval(arguments, configuration, projectEnvironment) return scriptingEvaluator.eval(arguments, configuration, projectEnvironment)
} else { } else {
ReplFromTerminal.run(rootDisposable, configuration) val shell = ShellExtension.getInstances(projectEnvironment.project).find { it.isAccepted(arguments) }
return ExitCode.OK 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.KotlinSourceRoot
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension 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
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING 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 // used in the daemon for jar cache cleanup
val applicationEnvironment: JavaCoreApplicationEnvironment? get() = ourApplicationEnvironment val applicationEnvironment: JavaCoreApplicationEnvironment? get() = ourApplicationEnvironment
internal fun getOrCreateApplicationEnvironmentForProduction( fun getOrCreateApplicationEnvironmentForProduction(
parentDisposable: Disposable, configuration: CompilerConfiguration parentDisposable: Disposable, configuration: CompilerConfiguration
): JavaCoreApplicationEnvironment { ): JavaCoreApplicationEnvironment {
synchronized(APPLICATION_LOCK) { synchronized(APPLICATION_LOCK) {
@@ -614,6 +615,7 @@ class KotlinCoreEnvironment private constructor(
ExtraImportsProviderExtension.registerExtensionPoint(project) ExtraImportsProviderExtension.registerExtensionPoint(project)
IrGenerationExtension.registerExtensionPoint(project) IrGenerationExtension.registerExtensionPoint(project)
ScriptEvaluationExtension.registerExtensionPoint(project) ScriptEvaluationExtension.registerExtensionPoint(project)
ShellExtension.registerExtensionPoint(project)
} }
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) { internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
@@ -9,9 +9,6 @@ import java.io.File
import java.io.IOError import java.io.IOError
import java.lang.Character.isJavaIdentifierPart import java.lang.Character.isJavaIdentifierPart
import java.lang.Character.isJavaIdentifierStart import java.lang.Character.isJavaIdentifierStart
import java.lang.IllegalArgumentException
import java.lang.RuntimeException
import java.lang.UnsupportedOperationException
import java.net.URLClassLoader import java.net.URLClassLoader
import java.nio.file.FileSystemNotFoundException import java.nio.file.FileSystemNotFoundException
import java.nio.file.Paths 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>() val implementations = mutableListOf<Service>()
for (className in findImplementations(service, files)) { 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(project(":kotlin-build-common"))
compile(commonDep("org.fusesource.jansi", "jansi")) compile(commonDep("org.fusesource.jansi", "jansi"))
compile(commonDep("org.jline", "jline")) compile(commonDep("org.jline", "jline"))
compileOnly(project(":kotlin-scripting-compiler"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") } compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) } compileOnly(intellijDep()) { includeIntellijCoreJarDependencies(project) }
} }
@@ -608,7 +608,7 @@ class CompileServiceImpl(
) )
val messageCollector = KeepFirstErrorMessageCollector(compilerMessagesStream) val messageCollector = KeepFirstErrorMessageCollector(compilerMessagesStream)
val repl = KotlinJvmReplService( val repl = KotlinJvmReplService(
disposable, port, templateClasspath, templateClassName, disposable, port, compilerId, templateClasspath, templateClassName,
messageCollector, operationsTracer messageCollector, operationsTracer
) )
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable)) val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
@@ -661,7 +661,7 @@ class CompileServiceImpl(
val disposable = Disposer.newDisposable() val disposable = Disposer.newDisposable()
val messageCollector = CompileServicesFacadeMessageCollector(servicesFacade, compilationOptions) val messageCollector = CompileServicesFacadeMessageCollector(servicesFacade, compilationOptions)
val repl = KotlinJvmReplService( val repl = KotlinJvmReplService(
disposable, port, templateClasspath, templateClassName, disposable, port, compilerId, templateClasspath, templateClassName,
messageCollector, null messageCollector, null
) )
val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable)) val sessionId = state.sessions.leaseSession(ClientOrSessionProxy(aliveFlagPath, repl, disposable))
@@ -17,20 +17,18 @@
package org.jetbrains.kotlin.daemon package org.jetbrains.kotlin.daemon
import com.intellij.openapi.Disposable 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.*
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.common.repl.*
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompiler import org.jetbrains.kotlin.cli.jvm.plugins.ServiceLoaderLite
import org.jetbrains.kotlin.cli.jvm.repl.GenericReplCompilerState
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.daemon.common.CompileService 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.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 org.jetbrains.kotlin.utils.PathUtil
import java.io.File import java.io.File
import java.io.PrintStream import java.io.PrintStream
@@ -38,12 +36,14 @@ import java.net.URLClassLoader
import java.util.* import java.util.*
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.locks.ReentrantReadWriteLock
import java.util.logging.Logger
import kotlin.concurrent.read import kotlin.concurrent.read
import kotlin.concurrent.write import kotlin.concurrent.write
open class KotlinJvmReplService( open class KotlinJvmReplService(
disposable: Disposable, disposable: Disposable,
val portForServers: Int, val portForServers: Int,
val compilerId: CompilerId,
templateClasspath: List<File>, templateClasspath: List<File>,
templateClassName: String, templateClassName: String,
protected val messageCollector: MessageCollector, protected val messageCollector: MessageCollector,
@@ -51,40 +51,46 @@ open class KotlinJvmReplService(
protected val operationsTracer: RemoteOperationsTracer? protected val operationsTracer: RemoteOperationsTracer?
) : ReplCompileAction, ReplCheckAction, CreateReplStageStateAction { ) : ReplCompileAction, ReplCheckAction, CreateReplStageStateAction {
private val log by lazy { Logger.getLogger("replService") }
protected val configuration = CompilerConfiguration().apply { protected val configuration = CompilerConfiguration().apply {
put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
addJvmClasspathRoots(PathUtil.kotlinPathsForCompiler.let { listOf(it.stdlibPath, it.reflectPath, it.scriptRuntimePath) }) addJvmClasspathRoots(PathUtil.kotlinPathsForCompiler.let { listOf(it.stdlibPath, it.reflectPath, it.scriptRuntimePath) })
addJvmClasspathRoots(templateClasspath) addJvmClasspathRoots(templateClasspath)
put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script") put(CommonConfigurationKeys.MODULE_NAME, "kotlin-script")
languageVersionSettings = LanguageVersionSettingsImpl( languageVersionSettings = LanguageVersionSettingsImpl(
LanguageVersion.LATEST_STABLE, ApiVersion.LATEST_STABLE, mapOf(AnalysisFlags.skipMetadataVersionCheck to true) 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 { private val replCompiler: ReplCompiler? by lazy {
if (scriptDef == null) null try {
else GenericReplCompiler(disposable, scriptDef, configuration, messageCollector) 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() protected val statesLock = ReentrantReadWriteLock()
@@ -125,7 +131,7 @@ open class KotlinJvmReplService(
fun createRemoteState(port: Int = portForServers): RemoteReplStateFacadeServer = statesLock.write { fun createRemoteState(port: Int = portForServers): RemoteReplStateFacadeServer = statesLock.write {
val id = getValidId(stateIdCounter) { id -> states.none { it.key.getId() == id} } 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) states.put(stateFacade, true)
stateFacade stateFacade
} }
@@ -175,9 +181,15 @@ inline internal fun getValidId(counter: AtomicInteger, check: (Int) -> Boolean):
return newId return newId
} }
private fun CompilerConfiguration.configureScripting() { private fun CompilerConfiguration.configureScripting(compilerId: CompilerId) {
val error = try { 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 null
} catch (e: NoClassDefFoundError) { } catch (e: NoClassDefFoundError) {
e e
@@ -17,15 +17,16 @@
package org.jetbrains.kotlin.daemon package org.jetbrains.kotlin.daemon
import org.jetbrains.kotlin.cli.common.repl.ILineId 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.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.ReplStateFacade import org.jetbrains.kotlin.daemon.common.ReplStateFacade
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
import java.rmi.server.UnicastRemoteObject import java.rmi.server.UnicastRemoteObject
class RemoteReplStateFacadeServer(val _id: Int, class RemoteReplStateFacadeServer(
val state: GenericReplCompilerState, val _id: Int,
port: Int = SOCKET_ANY_FREE_PORT val state: IReplStageState<*>,
port: Int = SOCKET_ANY_FREE_PORT
) : ReplStateFacade, ) : ReplStateFacade,
UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) UnicastRemoteObject(port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory)
{ {
+1
View File
@@ -6,6 +6,7 @@ plugins {
} }
dependencies { dependencies {
testCompile(project(":kotlin-scripting-compiler-impl"))
testCompile(projectTests(":compiler:tests-common")) testCompile(projectTests(":compiler:tests-common"))
testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") } testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") }
testCompile(projectTests(":generators:test-generator")) 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.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler 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.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase import org.jetbrains.kotlin.integration.KotlinIntegrationTestBase
import org.jetbrains.kotlin.script.StandardScriptDefinition import org.jetbrains.kotlin.script.StandardScriptDefinition
import org.jetbrains.kotlin.script.loadScriptingPlugin 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.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind 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.KotlinScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.script.loadScriptingPlugin import org.jetbrains.kotlin.script.loadScriptingPlugin
import org.jetbrains.kotlin.scripting.repl.GenericReplCompiler
import org.jetbrains.kotlin.test.ConfigurationKind import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.TestJdkKind
@@ -39,9 +39,12 @@ import java.rmi.server.UnicastRemoteObject
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.concurrent.thread import kotlin.concurrent.thread
import kotlin.script.dependencies.* import kotlin.script.dependencies.Environment
import kotlin.script.experimental.dependencies.* import kotlin.script.dependencies.ScriptContents
import kotlin.script.experimental.dependencies.DependenciesResolver
import kotlin.script.experimental.dependencies.DependenciesResolver.ResolveResult 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.script.templates.ScriptTemplateDefinition
import kotlin.test.fail import kotlin.test.fail
@@ -727,16 +730,17 @@ class CompilerDaemonTest : KotlinIntegrationTestBase() {
daemon, null, CompileService.TargetPlatform.JVM, emptyArray(), TestMessageCollector(), daemon, null, CompileService.TargetPlatform.JVM, emptyArray(), TestMessageCollector(),
classpathFromClassloader(), ScriptWithNoParam::class.qualifiedName!! classpathFromClassloader(), ScriptWithNoParam::class.qualifiedName!!
) )
repl.createState()
} catch (e: Exception) { } catch (e: Exception) {
TestCase.assertEquals( 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 e.message
) )
isErrorThrown = true isErrorThrown = true
} finally { } finally {
repl?.dispose() 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 com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult 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.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.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.TestJdkKind
@@ -86,7 +86,10 @@ abstract class AbstractReplInterpreterTest : KtUsefulTestCase() {
protected fun doTest(path: String) { protected fun doTest(path: String) {
val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK) val configuration = KotlinTestUtils.newConfiguration(ConfigurationKind.ALL, TestJdkKind.MOCK_JDK)
loadScriptingPlugin(configuration) loadScriptingPlugin(configuration)
val repl = ReplInterpreter(testRootDisposable, configuration, ConsoleReplConfiguration()) val repl = ReplInterpreter(
testRootDisposable, configuration,
ConsoleReplConfiguration()
)
for ((code, expected) in loadLines(File(path))) { for ((code, expected) in loadLines(File(path))) {
val lineResult = repl.eval(code) 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.common.repl.*
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.cli.jvm.config.addJvmSdkRoots 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.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
import org.jetbrains.kotlin.scripting.repl.GenericReplCompiler
import org.jetbrains.kotlin.utils.PathUtil import org.jetbrains.kotlin.utils.PathUtil
import java.io.File import java.io.File
import java.net.URLClassLoader import java.net.URLClassLoader
@@ -14,7 +14,7 @@
* limitations under the License. * 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.name.Name
import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry
@@ -1,30 +1,19 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl
import org.jetbrains.kotlin.cli.common.repl.* import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment 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.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.scripting.repl.messages.DiagnosticMessageHolder
import java.util.concurrent.locks.ReentrantReadWriteLock import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.script.experimental.dependencies.ScriptDependencies 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> { override fun reset(): Iterable<ILineId> {
val removedCompiledLines = super.reset() val removedCompiledLines = super.reset()
@@ -60,17 +49,17 @@ abstract class GenericReplCheckerState : IReplStageState<ScriptDescriptor> {
val errorHolder: DiagnosticMessageHolder 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()) : 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() 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 var lastDependencies: ScriptDependencies? = null
} }
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import com.intellij.openapi.util.text.StringUtil 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.common.repl.*
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment 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.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget 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.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.scripting.repl.messages.ConsoleDiagnosticMessageHolder
import kotlin.concurrent.write import kotlin.concurrent.write
const val KOTLIN_REPL_JVM_TARGET_PROPERTY = "kotlin.repl.jvm.target" 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 { override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult {
state.lock.write { 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 scriptFileName = makeScriptBaseName(codeLine)
val virtualFile = val virtualFile =
LightVirtualFile( LightVirtualFile(
@@ -87,7 +76,8 @@ open class GenericReplChecker(
val syntaxErrorReport = AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorHolder) val syntaxErrorReport = AnalyzerWithCompilerReport.reportSyntaxErrors(psiFile, errorHolder)
if (!syntaxErrorReport.isHasErrors) { if (!syntaxErrorReport.isHasErrors) {
checkerState.lastLineState = GenericReplCheckerState.LineState(codeLine, psiFile, errorHolder) checkerState.lastLineState =
org.jetbrains.kotlin.scripting.repl.GenericReplCheckerState.LineState(codeLine, psiFile, errorHolder)
} }
return when { return when {
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
@@ -50,15 +39,17 @@ open class GenericReplCompiler(
messageCollector: MessageCollector messageCollector: MessageCollector
) : this(Disposer.newDisposable(), scriptDefinition, compilerConfiguration, 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 check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = checker.check(state, codeLine)
override fun compile(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCompileResult { override fun compile(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCompileResult {
state.lock.write { 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 { val (psiFile, errorHolder) = run {
if (compilerState.lastLineState == null || compilerState.lastLineState!!.codeLine != codeLine) { if (compilerState.lastLineState == null || compilerState.lastLineState!!.codeLine != codeLine) {
@@ -1,22 +1,11 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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.
*/ */
@file:Suppress("UNUSED_PARAMETER") @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.CompiledReplCodeLine
import org.jetbrains.kotlin.cli.common.repl.ILineId 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) : data class Successful(override val scriptDescriptor: ClassDescriptorWithResolutionScopes, override val diagnostics: Diagnostics) :
ReplLineAnalysisResult ReplLineAnalysisResult
data class WithErrors(override val diagnostics: Diagnostics) : ReplLineAnalysisResult { data class WithErrors(override val diagnostics: Diagnostics) :
ReplLineAnalysisResult {
override val scriptDescriptor: ClassDescriptorWithResolutionScopes? get() = null override val scriptDescriptor: ClassDescriptorWithResolutionScopes? get() = null
} }
} }
@@ -133,7 +123,10 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
try { try {
rootPackageProvider.addDelegateProvider(provider) rootPackageProvider.addDelegateProvider(provider)
} catch (e: UninitializedPropertyAccessException) { } catch (e: UninitializedPropertyAccessException) {
rootPackageProvider = AdaptablePackageMemberDeclarationProvider(provider) rootPackageProvider =
AdaptablePackageMemberDeclarationProvider(
provider
)
} }
} }
@@ -155,7 +148,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
class AdaptablePackageMemberDeclarationProvider( class AdaptablePackageMemberDeclarationProvider(
private var delegateProvider: PackageMemberDeclarationProvider private var delegateProvider: PackageMemberDeclarationProvider
) : DelegatePackageMemberDeclarationProvider(delegateProvider) { ) : org.jetbrains.kotlin.scripting.repl.DelegatePackageMemberDeclarationProvider(delegateProvider) {
fun addDelegateProvider(provider: PackageMemberDeclarationProvider) { fun addDelegateProvider(provider: PackageMemberDeclarationProvider) {
delegateProvider = CombinedPackageMemberDeclarationProvider(listOf(provider, delegateProvider)) delegateProvider = CombinedPackageMemberDeclarationProvider(listOf(provider, delegateProvider))
@@ -182,7 +175,10 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
} }
fun submitLine(ktFile: KtFile, codeLine: ReplCodeLine) { fun submitLine(ktFile: KtFile, codeLine: ReplCodeLine) {
val line = LineInfo.SubmittedLine(ktFile, successfulLines.lastValue()) val line = LineInfo.SubmittedLine(
ktFile,
successfulLines.lastValue()
)
submittedLines[ktFile] = line submittedLines[ktFile] = line
ktFile.fileScopesCustomizer = object : FileScopesCustomizer { ktFile.fileScopesCustomizer = object : FileScopesCustomizer {
override fun createFileScopes(fileScopeFactory: FileScopeFactory): FileScopes { override fun createFileScopes(fileScopeFactory: FileScopeFactory): FileScopes {
@@ -192,13 +188,20 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
} }
fun lineSuccess(ktFile: KtFile, codeLine: ReplCodeLine, scriptDescriptor: ClassDescriptorWithResolutionScopes) { 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 submittedLines[ktFile] = successfulLine
successfulLines.add(CompiledReplCodeLine(ktFile.name, codeLine), successfulLine) successfulLines.add(CompiledReplCodeLine(ktFile.name, codeLine), successfulLine)
} }
fun lineFailure(ktFile: KtFile, codeLine: ReplCodeLine) { 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] private fun lineInfo(ktFile: KtFile) = submittedLines[ktFile]
@@ -1,22 +1,11 @@
/* /*
* Copyright 2010-2017 JetBrains s.r.o. * 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.
* 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 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.PrintWriter
import java.io.StringWriter import java.io.StringWriter
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import com.intellij.openapi.util.io.FileUtil 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.messages.GroupingMessageCollector
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
import org.jetbrains.kotlin.cli.common.repl.replUnescapeLineBreaks 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.CompilerConfiguration
import org.jetbrains.kotlin.config.KotlinCompilerVersion 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.File
import java.io.IOException import java.io.IOException
import java.io.PrintWriter import java.io.PrintWriter
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl
import com.intellij.openapi.Disposable import com.intellij.openapi.Disposable
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys 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.common.repl.*
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot 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.config.CompilerConfiguration
import org.jetbrains.kotlin.script.KotlinScriptDefinition import org.jetbrains.kotlin.script.KotlinScriptDefinition
import org.jetbrains.kotlin.scripting.repl.configuration.ReplConfiguration
import java.io.PrintWriter import java.io.PrintWriter
import java.net.URLClassLoader import java.net.URLClassLoader
import java.util.concurrent.atomic.AtomicInteger import java.util.concurrent.atomic.AtomicInteger
@@ -81,7 +70,12 @@ class ReplInterpreter(
// TODO: add script definition with project-based resolving for IDEA repl // TODO: add script definition with project-based resolving for IDEA repl
private val scriptCompiler: ReplCompiler by lazy { 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 { private val scriptEvaluator: ReplFullEvaluator by lazy {
GenericReplCompilingEvaluator(scriptCompiler, classpathRoots, classLoader, null, ReplRepeatingMode.REPEAT_ANY_PREVIOUS) 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. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl.configuration
import org.jetbrains.kotlin.cli.jvm.repl.IdeReplExceptionReporter import org.jetbrains.kotlin.scripting.repl.IdeReplExceptionReporter
import org.jetbrains.kotlin.cli.jvm.repl.ReplExceptionReporter import org.jetbrains.kotlin.scripting.repl.ReplExceptionReporter
import org.jetbrains.kotlin.cli.jvm.repl.messages.IdeDiagnosticMessageHolder import org.jetbrains.kotlin.scripting.repl.messages.IdeDiagnosticMessageHolder
import org.jetbrains.kotlin.cli.jvm.repl.reader.IdeReplCommandReader import org.jetbrains.kotlin.scripting.repl.reader.IdeReplCommandReader
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplCommandReader import org.jetbrains.kotlin.scripting.repl.reader.ReplCommandReader
import org.jetbrains.kotlin.cli.jvm.repl.reader.ReplSystemInWrapper import org.jetbrains.kotlin.scripting.repl.reader.ReplSystemInWrapper
import org.jetbrains.kotlin.cli.jvm.repl.writer.IdeSystemOutWrapperReplWriter import org.jetbrains.kotlin.scripting.repl.writer.IdeSystemOutWrapperReplWriter
import org.jetbrains.kotlin.cli.jvm.repl.writer.ReplWriter import org.jetbrains.kotlin.scripting.repl.writer.ReplWriter
class IdeReplConfiguration : ReplConfiguration { class IdeReplConfiguration : ReplConfiguration {
override val allowIncompleteLines: Boolean override val allowIncompleteLines: Boolean
get() = false get() = false
override val executionInterceptor: SnippetExecutionInterceptor = object : SnippetExecutionInterceptor { override val executionInterceptor: SnippetExecutionInterceptor = object :
SnippetExecutionInterceptor {
override fun <T> execute(block: () -> T): T { override fun <T> execute(block: () -> T): T {
try { try {
sinWrapper.isReplScriptExecuting = true 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. * 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.
* 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.messages package org.jetbrains.kotlin.scripting.repl.messages
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorBasedReporter import org.jetbrains.kotlin.cli.common.messages.MessageCollectorBasedReporter
@@ -14,7 +14,7 @@
* limitations under the License. * 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 import org.jetbrains.kotlin.cli.common.messages.DiagnosticMessageReporter
@@ -1,20 +1,9 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * 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.
* 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.messages package org.jetbrains.kotlin.scripting.repl.messages
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
@@ -1,22 +1,11 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * 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.
* 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 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.EndOfFileException
import org.jline.reader.LineReader import org.jline.reader.LineReader
import org.jline.reader.LineReaderBuilder 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. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl.reader
import org.jetbrains.kotlin.cli.common.repl.replUnescapeLineBreaks 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.w3c.dom.Element
import org.xml.sax.InputSource import org.xml.sax.InputSource
import java.io.ByteArrayInputStream 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. * 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.
* 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 package org.jetbrains.kotlin.scripting.repl.writer
import org.jetbrains.kotlin.cli.common.repl.replAddLineBreak import org.jetbrains.kotlin.cli.common.repl.replAddLineBreak
import org.jetbrains.kotlin.cli.common.repl.replOutputAsXml 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 org.jetbrains.kotlin.utils.repl.ReplEscapeType.*
import java.io.PrintStream 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: Boolean) = printWithEscaping(x.toString())
override fun print(x: Char) = printWithEscaping(x.toString()) override fun print(x: Char) = printWithEscaping(x.toString())
override fun print(x: Int) = 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 com.intellij.mock.MockProject
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys 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.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.extensions.CollectAdditionalSourcesExtension import org.jetbrains.kotlin.extensions.CollectAdditionalSourcesExtension
import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension 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.ExtraImportsProviderExtension
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
import org.jetbrains.kotlin.script.ScriptDefinitionProvider 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.ScriptExtraImportsProviderExtension
import org.jetbrains.kotlin.scripting.shared.extensions.ScriptingResolveExtension 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 { class ScriptingCompilerConfigurationComponentRegistrar : ComponentRegistrar {
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
CompilerConfigurationExtension.registerExtension(project, ScriptingCompilerConfigurationExtension(project)) CompilerConfigurationExtension.registerExtension(project, ScriptingCompilerConfigurationExtension(project))
CollectAdditionalSourcesExtension.registerExtension(project, ScriptingCollectAdditionalSourcesExtension(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() val scriptDefinitionProvider = CliScriptDefinitionProvider()
project.registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider) project.registerService(ScriptDefinitionProvider::class.java, scriptDefinitionProvider)