Move scripting configuration into compiler plugin
This commit is contained in:
@@ -165,7 +165,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
return COMPILATION_ERROR;
|
||||
}
|
||||
|
||||
ExitCode pluginLoadResult = PluginCliParser.loadPluginsSafe(arguments, configuration);
|
||||
ExitCode pluginLoadResult = PluginCliParser.loadPluginsSafe(arguments.getPluginClasspaths(), arguments.getPluginOptions(), configuration);
|
||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult;
|
||||
|
||||
configuration.put(JSConfigurationKeys.LIBRARIES, configureLibraries(arguments, paths, messageCollector));
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
||||
import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal
|
||||
@@ -45,22 +44,14 @@ import org.jetbrains.kotlin.javac.JavacWrapper
|
||||
import org.jetbrains.kotlin.load.java.JavaClassesTracker
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.script.StandardScriptDefinition
|
||||
import org.jetbrains.kotlin.script.experimental.KotlinScriptDefinitionAdapterFromNewAPI
|
||||
import org.jetbrains.kotlin.util.PerformanceCounter
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.lang.management.ManagementFactory
|
||||
import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.jar.JarFile
|
||||
import kotlin.script.experimental.definitions.ScriptDefinitionFromAnnotatedBaseClass
|
||||
|
||||
class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
override fun doExecute(
|
||||
@@ -77,7 +68,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
if (it != OK) return it
|
||||
}
|
||||
|
||||
val pluginLoadResult = PluginCliParser.loadPluginsSafe(arguments, configuration)
|
||||
val pluginLoadResult = loadPlugins(paths, arguments, configuration)
|
||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
||||
|
||||
if (!arguments.script && arguments.buildFile == null) {
|
||||
@@ -153,7 +144,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
KotlinToJVMBytecodeCompiler.configureSourceRoots(configuration, moduleChunk.modules, buildFile)
|
||||
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration, arguments, messageCollector)
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
||||
?: return COMPILATION_ERROR
|
||||
|
||||
registerJavacIfNeeded(environment, arguments).let {
|
||||
@@ -167,7 +158,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
configuration.put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
|
||||
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration, arguments, messageCollector)
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
||||
?: return COMPILATION_ERROR
|
||||
|
||||
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(environment.project)
|
||||
@@ -191,7 +182,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration, arguments, messageCollector)
|
||||
val environment = createCoreEnvironment(rootDisposable, configuration, messageCollector)
|
||||
?: return COMPILATION_ERROR
|
||||
|
||||
registerJavacIfNeeded(environment, arguments).let {
|
||||
@@ -229,6 +220,39 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadPlugins(paths: KotlinPaths?, arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration): ExitCode {
|
||||
val pluginClasspaths = arguments.pluginClasspaths?.toMutableList() ?: ArrayList()
|
||||
val pluginOptions = arguments.pluginOptions?.toMutableList() ?: ArrayList()
|
||||
val isEmbeddable =
|
||||
try {
|
||||
this::class.java.classLoader.loadClass("com.intellij.mock.MockProject") == null
|
||||
} catch (_: ClassNotFoundException) {
|
||||
true
|
||||
} catch (_: NoClassDefFoundError) {
|
||||
true
|
||||
}
|
||||
|
||||
if (!isEmbeddable && pluginClasspaths.none { File(it).name == PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR }) {
|
||||
// if scripting plugin is not enabled explicitly (probably from another path) try to enable it implicitly
|
||||
val libPath = paths?.libPath ?: File(".")
|
||||
val pluginJar = File(libPath, PathUtil.KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR)
|
||||
val scriptingJar = File(libPath, PathUtil.KOTLIN_SCRIPTING_COMMON_JAR)
|
||||
val scriptingJvmJar = File(libPath, PathUtil.KOTLIN_SCRIPTING_JVM_JAR)
|
||||
if (pluginJar.exists() && scriptingJar.exists() && scriptingJvmJar.exists()) {
|
||||
pluginClasspaths.addAll(listOf(pluginJar.canonicalPath, scriptingJar.canonicalPath, scriptingJvmJar.canonicalPath))
|
||||
if (arguments.scriptTemplates?.isNotEmpty() == true) {
|
||||
pluginOptions.add("-P")
|
||||
pluginOptions.add("plugin:kotlin.scripting:script-templates=${arguments.scriptTemplates!!.joinToString(",")}")
|
||||
}
|
||||
if (arguments.scriptResolverEnvironment?.isNotEmpty() == true) {
|
||||
pluginOptions.add("-P")
|
||||
pluginOptions.add("plugin:kotlin.scripting:script-resolver-environment=${arguments.scriptResolverEnvironment!!.joinToString(",")}")
|
||||
}
|
||||
}
|
||||
}
|
||||
return PluginCliParser.loadPluginsSafe(pluginClasspaths, pluginOptions, configuration)
|
||||
}
|
||||
|
||||
private fun registerJavacIfNeeded(
|
||||
environment: KotlinCoreEnvironment,
|
||||
arguments: K2JVMCompilerArguments
|
||||
@@ -257,17 +281,8 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
private fun createCoreEnvironment(
|
||||
rootDisposable: Disposable,
|
||||
configuration: CompilerConfiguration,
|
||||
arguments: K2JVMCompilerArguments,
|
||||
messageCollector: MessageCollector
|
||||
): KotlinCoreEnvironment? {
|
||||
val scriptResolverEnv = createScriptResolverEnvironment(arguments, messageCollector) ?: return null
|
||||
val templatesFromClasspath = discoverScriptTemplatesInClasspath(configuration, messageCollector)
|
||||
configureScriptDefinitions(
|
||||
arguments.scriptTemplates.orEmpty().asIterable() + templatesFromClasspath,
|
||||
configuration,
|
||||
messageCollector,
|
||||
scriptResolverEnv
|
||||
)
|
||||
if (messageCollector.hasErrors()) return null
|
||||
|
||||
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
@@ -278,55 +293,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
initStartNanos = 0L
|
||||
}
|
||||
|
||||
if (!messageCollector.hasErrors()) {
|
||||
scriptResolverEnv.put("projectRoot", environment.project.run { basePath ?: baseDir?.canonicalPath }?.let(::File))
|
||||
return environment
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun discoverScriptTemplatesInClasspath(configuration: CompilerConfiguration, messageCollector: MessageCollector): Iterable<String> {
|
||||
val templates = arrayListOf<String>()
|
||||
val templatesPath = "META-INF/kotlin/script/templates/"
|
||||
for (dep in configuration.jvmClasspathRoots) {
|
||||
when {
|
||||
dep.isFile ->
|
||||
try {
|
||||
with(JarFile(dep)) {
|
||||
for (template in entries()) {
|
||||
if (!template.isDirectory && template.name.startsWith(templatesPath)) {
|
||||
val templateClassName = template.name.removePrefix(templatesPath)
|
||||
templates.add(templateClassName)
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.LOGGING,
|
||||
"Configure scripting: Added template $templateClassName from $dep"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.WARNING,
|
||||
"Configure scripting: unable to process classpath entry $dep: $e"
|
||||
)
|
||||
}
|
||||
dep.isDirectory -> {
|
||||
val dir = File(dep, templatesPath)
|
||||
if (dir.isDirectory) {
|
||||
dir.listFiles().forEach {
|
||||
templates.add(it.name)
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.LOGGING,
|
||||
"Configure scripting: Added template ${it.name} from $dep"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> messageCollector.report(CompilerMessageSeverity.WARNING, "Configure scripting: Unknown classpath entry $dep")
|
||||
}
|
||||
}
|
||||
return templates
|
||||
return if (messageCollector.hasErrors()) null else environment
|
||||
}
|
||||
|
||||
override fun setupPlatformSpecificArgumentsAndServices(
|
||||
@@ -506,73 +473,6 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
return OK
|
||||
}
|
||||
|
||||
fun configureScriptDefinitions(
|
||||
scriptTemplates: List<String>,
|
||||
configuration: CompilerConfiguration,
|
||||
messageCollector: MessageCollector,
|
||||
scriptResolverEnv: HashMap<String, Any?>
|
||||
) {
|
||||
val classpath = configuration.jvmClasspathRoots
|
||||
// TODO: consider using escaping to allow kotlin escaped names in class names
|
||||
if (scriptTemplates.isNotEmpty()) {
|
||||
val classloader =
|
||||
URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), Thread.currentThread().contextClassLoader)
|
||||
var hasErrors = false
|
||||
for (template in scriptTemplates) {
|
||||
try {
|
||||
val cls = classloader.loadClass(template)
|
||||
val def =
|
||||
if (cls.annotations.firstIsInstanceOrNull<kotlin.script.experimental.annotations.KotlinScript>() != null) {
|
||||
KotlinScriptDefinitionAdapterFromNewAPI(ScriptDefinitionFromAnnotatedBaseClass(cls.kotlin))
|
||||
} else {
|
||||
KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, scriptResolverEnv)
|
||||
}
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, def)
|
||||
messageCollector.report(
|
||||
INFO,
|
||||
"Added script definition $template to configuration: name = ${def.name}, " +
|
||||
"resolver = ${def.dependencyResolver.javaClass.name}"
|
||||
)
|
||||
} catch (ex: ClassNotFoundException) {
|
||||
messageCollector.report(ERROR, "Cannot find script definition template class $template")
|
||||
hasErrors = true
|
||||
} catch (ex: Exception) {
|
||||
messageCollector.report(ERROR, "Error processing script definition template $template: ${ex.message}")
|
||||
hasErrors = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (hasErrors) {
|
||||
messageCollector.report(LOGGING, "(Classpath used for templates loading: $classpath)")
|
||||
return
|
||||
}
|
||||
}
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
|
||||
}
|
||||
|
||||
fun createScriptResolverEnvironment(arguments: K2JVMCompilerArguments, messageCollector: MessageCollector): HashMap<String, Any?>? {
|
||||
val scriptResolverEnv = hashMapOf<String, Any?>()
|
||||
// parses key/value pairs in the form <key>=<value>, where
|
||||
// <key> - is a single word (\w+ pattern)
|
||||
// <value> - optionally quoted string with allowed escaped chars (only double-quote and backslash chars are supported)
|
||||
// TODO: implement generic unescaping
|
||||
val envParseRe = """(\w+)=(?:"([^"\\]*(\\.[^"\\]*)*)"|([^\s]*))""".toRegex()
|
||||
val unescapeRe = """\\(["\\])""".toRegex()
|
||||
if (arguments.scriptResolverEnvironment != null) {
|
||||
for (envParam in arguments.scriptResolverEnvironment!!) {
|
||||
val match = envParseRe.matchEntire(envParam)
|
||||
if (match == null || match.groupValues.size < 4 || match.groupValues[1].isBlank()) {
|
||||
messageCollector.report(ERROR, "Unable to parse script-resolver-environment argument $envParam")
|
||||
return null
|
||||
}
|
||||
scriptResolverEnv.put(
|
||||
match.groupValues[1],
|
||||
match.groupValues.drop(2).firstOrNull { it.isNotEmpty() }?.let { unescapeRe.replace(it, "\$1") })
|
||||
}
|
||||
}
|
||||
return scriptResolverEnv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,6 +88,7 @@ import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension
|
||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension
|
||||
import org.jetbrains.kotlin.extensions.PreprocessedVirtualFileFactoryExtension
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
@@ -178,6 +179,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
DeclarationAttributeAltererExtension.registerExtensionPoint(project)
|
||||
PreprocessedVirtualFileFactoryExtension.registerExtensionPoint(project)
|
||||
JsSyntheticTranslateExtension.registerExtensionPoint(project)
|
||||
CompilerConfigurationExtension.registerExtensionPoint(project)
|
||||
|
||||
for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
|
||||
try {
|
||||
@@ -195,12 +197,19 @@ class KotlinCoreEnvironment private constructor(
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
registerProjectServices(projectEnvironment, messageCollector)
|
||||
|
||||
CompilerConfigurationExtension.getInstances(project).forEach {
|
||||
it.updateConfiguration(configuration)
|
||||
}
|
||||
|
||||
sourceFiles += CompileEnvironmentUtil.getKtFiles(project, getSourceRootsCheckingForDuplicates(), this.configuration, {
|
||||
message ->
|
||||
report(ERROR, message)
|
||||
})
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
// We should always support at least the standard script definition
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
|
||||
|
||||
val scriptDefinitionProvider = ScriptDefinitionProvider.getInstance(project) as? CliScriptDefinitionProvider
|
||||
if (scriptDefinitionProvider != null) {
|
||||
scriptDefinitionProvider.setScriptDefinitions(
|
||||
|
||||
@@ -32,11 +32,15 @@ import java.util.*
|
||||
object PluginCliParser {
|
||||
|
||||
@JvmStatic
|
||||
fun loadPluginsSafe(arguments: CommonCompilerArguments, configuration: CompilerConfiguration): ExitCode {
|
||||
fun loadPluginsSafe(pluginClasspaths: Array<String>?, pluginOptions: Array<String>?, configuration: CompilerConfiguration): ExitCode =
|
||||
loadPluginsSafe(pluginClasspaths?.asIterable(), pluginOptions?.asIterable(), configuration)
|
||||
|
||||
@JvmStatic
|
||||
fun loadPluginsSafe(pluginClasspaths: Iterable<String>?, pluginOptions: Iterable<String>?, configuration: CompilerConfiguration): ExitCode {
|
||||
val messageCollector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
try {
|
||||
PluginCliParser.loadPlugins(arguments, configuration)
|
||||
PluginCliParser.loadPlugins(pluginClasspaths, pluginOptions, configuration)
|
||||
}
|
||||
catch (e: PluginCliOptionProcessingException) {
|
||||
val message = e.message + "\n\n" + cliPluginUsageString(e.pluginId, e.options)
|
||||
@@ -55,9 +59,9 @@ object PluginCliParser {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun loadPlugins(arguments: CommonCompilerArguments, configuration: CompilerConfiguration) {
|
||||
fun loadPlugins(pluginClasspaths: Iterable<String>?, pluginOptions: Iterable<String>?, configuration: CompilerConfiguration) {
|
||||
val classLoader = PluginURLClassLoader(
|
||||
arguments.pluginClasspaths
|
||||
pluginClasspaths
|
||||
?.map { File(it).toURI().toURL() }
|
||||
?.toTypedArray()
|
||||
?: arrayOf<URL>(),
|
||||
@@ -68,15 +72,15 @@ object PluginCliParser {
|
||||
componentRegistrars.addAll(BundledCompilerPlugins.componentRegistrars)
|
||||
configuration.addAll(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS, componentRegistrars)
|
||||
|
||||
processPluginOptions(arguments, configuration, classLoader)
|
||||
processPluginOptions(pluginOptions, configuration, classLoader)
|
||||
}
|
||||
|
||||
private fun processPluginOptions(
|
||||
arguments: CommonCompilerArguments,
|
||||
pluginOptions: Iterable<String>?,
|
||||
configuration: CompilerConfiguration,
|
||||
classLoader: ClassLoader
|
||||
) {
|
||||
val optionValuesByPlugin = arguments.pluginOptions?.map(::parsePluginOption)?.groupBy {
|
||||
val optionValuesByPlugin = pluginOptions?.map(::parsePluginOption)?.groupBy {
|
||||
if (it == null) throw CliOptionProcessingException("Wrong plugin option format: $it, should be ${CommonCompilerArguments.PLUGIN_OPTION_FORMAT}")
|
||||
it.pluginId
|
||||
} ?: mapOf()
|
||||
|
||||
@@ -54,7 +54,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
|
||||
): ExitCode {
|
||||
val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
val pluginLoadResult = PluginCliParser.loadPluginsSafe(arguments, configuration)
|
||||
val pluginLoadResult = PluginCliParser.loadPluginsSafe(arguments.pluginClasspaths, arguments.pluginOptions, configuration)
|
||||
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
|
||||
|
||||
for (arg in arguments.freeArgs) {
|
||||
|
||||
@@ -10,8 +10,6 @@ jvmTarget = "1.6"
|
||||
dependencies {
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compile(project(":kotlin-scripting-common"))
|
||||
compile(project(":kotlin-scripting-jvm"))
|
||||
compile(projectDist(":kotlin-stdlib"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.extensions
|
||||
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
|
||||
interface CompilerConfigurationExtension {
|
||||
|
||||
companion object : ProjectExtensionDescriptor<CompilerConfigurationExtension>(
|
||||
"org.jetbrains.kotlin.compilerConfigurationExtension",
|
||||
CompilerConfigurationExtension::class.java
|
||||
)
|
||||
|
||||
fun updateConfiguration(configuration: CompilerConfiguration)
|
||||
}
|
||||
@@ -100,20 +100,6 @@ class CompilerApiTest : KotlinIntegrationTestBase() {
|
||||
}
|
||||
}
|
||||
|
||||
fun testScriptResolverEnvironmentArgsParsing() {
|
||||
|
||||
fun args(body: K2JVMCompilerArguments.() -> Unit): K2JVMCompilerArguments =
|
||||
K2JVMCompilerArguments().apply(body)
|
||||
|
||||
val longStr = (1..100).joinToString { """\" $it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\""" }
|
||||
val unescapeRe = """\\(["\\])""".toRegex()
|
||||
val messageCollector = TestMessageCollector()
|
||||
Assert.assertEquals(hashMapOf("abc" to "def", "11" to "ab cd \\ \"", "long" to unescapeRe.replace(longStr, "\$1")),
|
||||
K2JVMCompiler.createScriptResolverEnvironment(
|
||||
args { scriptResolverEnvironment = arrayOf("abc=def", """11="ab cd \\ \""""", "long=\"$longStr\"") },
|
||||
messageCollector))
|
||||
}
|
||||
|
||||
fun testHelloAppLocal() {
|
||||
val messageCollector = TestMessageCollector()
|
||||
val jar = tmpdir.absolutePath + File.separator + "hello.jar"
|
||||
|
||||
@@ -57,6 +57,9 @@ object PathUtil {
|
||||
const val KOTLIN_REFLECT_SRC_JAR = "$KOTLIN_JAVA_REFLECT_NAME-sources.jar"
|
||||
|
||||
const val KOTLIN_JAVA_SCRIPT_RUNTIME_JAR = "kotlin-script-runtime.jar"
|
||||
const val KOTLIN_SCRIPTING_COMMON_JAR = "kotlin-scripting-common.jar"
|
||||
const val KOTLIN_SCRIPTING_JVM_JAR = "kotlin-scripting-jvm.jar"
|
||||
const val KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR = "kotlin-scripting-compiler.jar"
|
||||
|
||||
const val KOTLIN_TEST_NAME = "kotlin-test"
|
||||
const val KOTLIN_TEST_JAR = "$KOTLIN_TEST_NAME.jar"
|
||||
|
||||
@@ -18,6 +18,7 @@ dependencies {
|
||||
compile(project(":idea:ide-common"))
|
||||
compile(project(":idea:idea-jps-common"))
|
||||
compile(project(":plugins:android-extensions-compiler"))
|
||||
compile(project(":kotlin-scripting-idea-plugin"))
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) { isTransitive = false }
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.script.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||
import org.jetbrains.kotlin.script.ScriptDefinitionProvider
|
||||
import org.jetbrains.kotlin.script.ScriptTemplatesProvider
|
||||
import org.jetbrains.kotlin.script.experimental.KotlinScriptDefinitionAdapterFromNewAPI
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.KotlinScriptDefinitionAdapterFromNewAPI
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
|
||||
@@ -58,6 +58,7 @@ dependencies {
|
||||
runtime project(path: ':kotlin-compiler-runner', configuration: 'runtimeJar')
|
||||
runtime project(':kotlin-reflect')
|
||||
runtime project(':kotlin-scripting-common')
|
||||
runtime project(':kotlin-scripting-compiler-plugin')
|
||||
runtime project(':kotlin-scripting-jvm')
|
||||
|
||||
// com.android.tools.build:gradle has ~50 unneeded transitive dependencies
|
||||
|
||||
@@ -40,6 +40,11 @@
|
||||
<artifactId>kotlin-compiler</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-scripting-compiler-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
|
||||
+3
-3
@@ -49,6 +49,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.KtScript;
|
||||
import org.jetbrains.kotlin.script.ReflectionUtilKt;
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationExtensionKt;
|
||||
import org.jetbrains.kotlin.utils.PathUtil;
|
||||
|
||||
import java.io.File;
|
||||
@@ -183,9 +184,8 @@ public class ExecuteKotlinScriptMojo extends AbstractMojo {
|
||||
configuration.add(JVMConfigurationKeys.CONTENT_ROOTS, new KotlinSourceRoot(scriptFile.getAbsolutePath()));
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME);
|
||||
|
||||
K2JVMCompiler.Companion.configureScriptDefinitions(
|
||||
scriptTemplates.toArray(new String[scriptTemplates.size()]),
|
||||
configuration, messageCollector, new HashMap<>()
|
||||
ScriptingCompilerConfigurationExtensionKt.configureScriptDefinitions(
|
||||
scriptTemplates, configuration, messageCollector, new HashMap<>()
|
||||
);
|
||||
|
||||
KotlinCoreEnvironment environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
description = "Kotlin Scripting Compiler Plugin"
|
||||
|
||||
apply { plugin("kotlin") }
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":compiler:frontend"))
|
||||
compileOnly(project(":compiler:frontend.java"))
|
||||
compileOnly(project(":compiler:plugin-api"))
|
||||
compileOnly(project(":compiler:cli"))
|
||||
compile(project(":kotlin-scripting-common"))
|
||||
compile(project(":kotlin-scripting-jvm"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
testCompile(project(":compiler:frontend"))
|
||||
testCompile(project(":compiler:frontend.script"))
|
||||
testCompile(project(":compiler:plugin-api"))
|
||||
testCompile(project(":compiler:util"))
|
||||
testCompile(project(":compiler:cli"))
|
||||
testCompile(project(":compiler:cli-common"))
|
||||
testCompile(project(":compiler:frontend.java"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" { projectDefault() }
|
||||
}
|
||||
|
||||
val jar = runtimeJar {
|
||||
from(fileTree("$projectDir/src")) { include("META-INF/**") }
|
||||
}
|
||||
sourcesJar()
|
||||
javadocJar()
|
||||
|
||||
publish()
|
||||
|
||||
dist()
|
||||
|
||||
ideaPlugin()
|
||||
|
||||
projectTest {
|
||||
workingDir = rootDir
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCommandLineProcessor
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.script.experimental
|
||||
package org.jetbrains.kotlin.scripting.compiler.plugin
|
||||
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType
|
||||
import kotlinx.coroutines.experimental.runBlocking
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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 java.io.File
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
||||
import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
|
||||
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||
|
||||
object ScriptingConfigurationKeys {
|
||||
val SCRIPT_DEFINITIONS: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create("Script definition classes")
|
||||
|
||||
val SCRIPT_DEFINITIONS_CLASSPATH: CompilerConfigurationKey<List<File>> =
|
||||
CompilerConfigurationKey.create("Additional classpath for the script definitions")
|
||||
|
||||
val DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION: CompilerConfigurationKey<Boolean> =
|
||||
CompilerConfigurationKey.create("Do not extract script definitions from the compilation classpath")
|
||||
|
||||
val LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION: CompilerConfigurationKey<MutableMap<String, Any?>> =
|
||||
CompilerConfigurationKey.create("Script resolver environment")
|
||||
}
|
||||
|
||||
class ScriptingCommandLineProcessor : CommandLineProcessor {
|
||||
companion object {
|
||||
val SCRIPT_DEFINITIONS_OPTION = CliOption(
|
||||
"script-definitions", "<fully qualified class name[,]>", "Script definition classes",
|
||||
required = false, allowMultipleOccurrences = true
|
||||
)
|
||||
val SCRIPT_DEFINITIONS_CLASSPATH_OPTION = CliOption(
|
||||
"script-definitions-classpath", "<classpath entry[:]>", "Additional classpath for the script definitions",
|
||||
required = false, allowMultipleOccurrences = true
|
||||
)
|
||||
val DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION = CliOption(
|
||||
"disable-script-definitions-from-classpath", "true/false", "Do not extract script definitions from the compilation classpath",
|
||||
required = false, allowMultipleOccurrences = false
|
||||
)
|
||||
val LEGACY_SCRIPT_TEMPLATES_OPTION = CliOption(
|
||||
"script-templates", "<fully qualified class name[,]>", "Script definition template classes",
|
||||
required = false, allowMultipleOccurrences = true
|
||||
)
|
||||
val LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION = CliOption(
|
||||
"script-resolver-environment", "<key=value[,]>",
|
||||
"Script resolver environment in key-value pairs (the value could be quoted and escaped)",
|
||||
required = false, allowMultipleOccurrences = true
|
||||
)
|
||||
|
||||
val PLUGIN_ID = "kotlin.scripting"
|
||||
}
|
||||
|
||||
override val pluginId = PLUGIN_ID
|
||||
override val pluginOptions =
|
||||
listOf(
|
||||
SCRIPT_DEFINITIONS_OPTION,
|
||||
SCRIPT_DEFINITIONS_CLASSPATH_OPTION,
|
||||
DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION,
|
||||
LEGACY_SCRIPT_TEMPLATES_OPTION,
|
||||
LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION
|
||||
)
|
||||
|
||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) = when (option) {
|
||||
SCRIPT_DEFINITIONS_OPTION, LEGACY_SCRIPT_TEMPLATES_OPTION -> {
|
||||
val currentDefs = configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS).toMutableList()
|
||||
currentDefs.addAll(value.split(','))
|
||||
configuration.put(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS, currentDefs)
|
||||
}
|
||||
SCRIPT_DEFINITIONS_CLASSPATH_OPTION -> {
|
||||
val currentCP = configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS_CLASSPATH).toMutableList()
|
||||
currentCP.addAll(value.split(File.pathSeparatorChar).map(::File))
|
||||
configuration.put(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS_CLASSPATH, currentCP)
|
||||
}
|
||||
DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION -> {
|
||||
configuration.put(
|
||||
ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION,
|
||||
value.takeUnless { it.isBlank() }?.toBoolean() ?: true
|
||||
)
|
||||
}
|
||||
LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION -> {
|
||||
val currentEnv = configuration.getMap(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION).toMutableMap()
|
||||
// parses key/value pairs in the form <key>=<value>, where
|
||||
// <key> - is a single word (\w+ pattern)
|
||||
// <value> - optionally quoted string with allowed escaped chars (only double-quote and backslash chars are supported)
|
||||
// TODO: implement generic unescaping
|
||||
val envParseRe = """(\w+)=(?:"([^"\\]*(\\.[^"\\]*)*)"|([^\s]*))""".toRegex()
|
||||
val unescapeRe = """\\(["\\])""".toRegex()
|
||||
for (envParam in value.split(',')) {
|
||||
val match = envParseRe.matchEntire(envParam)
|
||||
if (match == null || match.groupValues.size < 4 || match.groupValues[1].isBlank()) {
|
||||
throw CliOptionProcessingException("Unable to parse script-resolver-environment argument $envParam")
|
||||
}
|
||||
currentEnv[match.groupValues[1]] =
|
||||
match.groupValues.drop(2).firstOrNull { it.isNotEmpty() }?.let { unescapeRe.replace(it, "\$1") }
|
||||
}
|
||||
configuration.put(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION, currentEnv)
|
||||
}
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.mock.MockProject
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension
|
||||
import org.jetbrains.kotlin.script.KotlinScriptDefinitionFromAnnotatedTemplate
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.URLClassLoader
|
||||
import java.util.jar.JarFile
|
||||
import kotlin.script.experimental.definitions.ScriptDefinitionFromAnnotatedBaseClass
|
||||
|
||||
class ScriptingCompilerConfigurationExtension(val project: MockProject) : CompilerConfigurationExtension {
|
||||
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) {
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) ?: MessageCollector.NONE
|
||||
val explicitScriptDefinitions = configuration.getList(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS)
|
||||
|
||||
val scriptDefinitions =
|
||||
if (configuration.getBoolean(ScriptingConfigurationKeys.DISABLE_SCRIPT_DEFINITIONS_FROM_CLSSPATH_OPTION))
|
||||
explicitScriptDefinitions
|
||||
else
|
||||
explicitScriptDefinitions + discoverScriptTemplatesInClasspath(configuration, messageCollector)
|
||||
|
||||
if (scriptDefinitions.isNotEmpty()) {
|
||||
val projectRoot = project.run { basePath ?: baseDir?.canonicalPath }?.let(::File)
|
||||
if (projectRoot != null) {
|
||||
configuration.put(
|
||||
ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION,
|
||||
"projectRoot",
|
||||
projectRoot
|
||||
)
|
||||
}
|
||||
configureScriptDefinitions(
|
||||
scriptDefinitions,
|
||||
configuration,
|
||||
messageCollector,
|
||||
configuration.getMap(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ScriptingCompilerConfigurationComponentRegistrar : ComponentRegistrar {
|
||||
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||
CompilerConfigurationExtension.registerExtension(project, ScriptingCompilerConfigurationExtension(project))
|
||||
}
|
||||
}
|
||||
|
||||
private fun discoverScriptTemplatesInClasspath(configuration: CompilerConfiguration, messageCollector: MessageCollector): Iterable<String> {
|
||||
val templates = arrayListOf<String>()
|
||||
val templatesPath = "META-INF/kotlin/script/templates/"
|
||||
for (dep in configuration.jvmClasspathRoots) {
|
||||
when {
|
||||
dep.isFile -> {
|
||||
// this is the compiler behaviour, so the same logic implemented here
|
||||
if (dep.extension == "jar") {
|
||||
try {
|
||||
with(JarFile(dep)) {
|
||||
for (template in entries()) {
|
||||
if (!template.isDirectory && template.name.startsWith(templatesPath)) {
|
||||
val templateClassName = template.name.removePrefix(templatesPath)
|
||||
templates.add(templateClassName)
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.LOGGING,
|
||||
"Configure scripting: Added template $templateClassName from $dep"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.WARNING,
|
||||
"Configure scripting: unable to process classpath entry $dep: $e"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
dep.isDirectory -> {
|
||||
val dir = File(dep, templatesPath)
|
||||
if (dir.isDirectory) {
|
||||
dir.listFiles().forEach {
|
||||
templates.add(it.name)
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.LOGGING,
|
||||
"Configure scripting: Added template ${it.name} from $dep"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> messageCollector.report(CompilerMessageSeverity.WARNING, "Configure scripting: Unknown classpath entry $dep")
|
||||
}
|
||||
}
|
||||
return templates
|
||||
}
|
||||
|
||||
fun configureScriptDefinitions(
|
||||
scriptTemplates: List<String>,
|
||||
configuration: CompilerConfiguration,
|
||||
messageCollector: MessageCollector,
|
||||
scriptResolverEnv: Map<String, Any?>
|
||||
) {
|
||||
val classpath = configuration.jvmClasspathRoots
|
||||
// TODO: consider using escaping to allow kotlin escaped names in class names
|
||||
if (scriptTemplates.isNotEmpty()) {
|
||||
val classloader =
|
||||
URLClassLoader(classpath.map { it.toURI().toURL() }.toTypedArray(), Thread.currentThread().contextClassLoader)
|
||||
var hasErrors = false
|
||||
for (template in scriptTemplates) {
|
||||
try {
|
||||
val cls = classloader.loadClass(template)
|
||||
val def =
|
||||
if (cls.annotations.firstIsInstanceOrNull<kotlin.script.experimental.annotations.KotlinScript>() != null) {
|
||||
KotlinScriptDefinitionAdapterFromNewAPI(ScriptDefinitionFromAnnotatedBaseClass(cls.kotlin))
|
||||
} else {
|
||||
KotlinScriptDefinitionFromAnnotatedTemplate(cls.kotlin, scriptResolverEnv)
|
||||
}
|
||||
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, def)
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.INFO,
|
||||
"Added script definition $template to configuration: name = ${def.name}, " +
|
||||
"resolver = ${def.dependencyResolver.javaClass.name}"
|
||||
)
|
||||
} catch (ex: ClassNotFoundException) {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Cannot find script definition template class $template")
|
||||
hasErrors = true
|
||||
} catch (ex: Exception) {
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"Error processing script definition template $template: ${ex.message}"
|
||||
)
|
||||
hasErrors = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (hasErrors) {
|
||||
messageCollector.report(CompilerMessageSeverity.LOGGING, "(Classpath used for templates loading: $classpath)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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 org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
||||
import org.junit.Assert
|
||||
|
||||
class ScriptingCompilerPluginTest : TestCaseWithTmpdir() {
|
||||
fun testScriptResolverEnvironmentArgsParsing() {
|
||||
|
||||
val longStr = (1..100).joinToString { """\" $it aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\""" }
|
||||
val unescapeRe = """\\(["\\])""".toRegex()
|
||||
val cmdlineProcessor = ScriptingCommandLineProcessor()
|
||||
val configuration = CompilerConfiguration()
|
||||
|
||||
cmdlineProcessor.processOption(
|
||||
ScriptingCommandLineProcessor.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION,
|
||||
"""abc=def,11="ab cd \\ \"",long="$longStr"""",
|
||||
configuration
|
||||
)
|
||||
|
||||
val res = configuration.getMap(ScriptingConfigurationKeys.LEGACY_SCRIPT_RESOLVER_ENVIRONMENT_OPTION)
|
||||
|
||||
Assert.assertEquals(
|
||||
hashMapOf("abc" to "def", "11" to "ab cd \\ \"", "long" to unescapeRe.replace(longStr, "\$1")),
|
||||
res
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
description = "Kotlin Scripting IDEA Plugin"
|
||||
|
||||
apply { plugin("kotlin") }
|
||||
|
||||
dependencies {
|
||||
compile(project(":kotlin-scripting-compiler-plugin"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
|
||||
runtimeJar()
|
||||
|
||||
ideaPlugin()
|
||||
|
||||
@@ -153,6 +153,8 @@ include ":kotlin-build-common",
|
||||
":kotlin-scripting-common",
|
||||
":kotlin-scripting-jvm",
|
||||
":kotlin-scripting-jvm-host",
|
||||
":kotlin-scripting-compiler-plugin",
|
||||
":kotlin-scripting-idea-plugin",
|
||||
":examples:scripting-jvm-simple-script",
|
||||
":examples:scripting-jvm-maven-deps",
|
||||
":pill:generate-all-tests",
|
||||
@@ -251,6 +253,8 @@ project(':kotlin-annotations-android').projectDir = "$rootDir/libraries/tools/ko
|
||||
project(':kotlin-scripting-common').projectDir = "$rootDir/libraries/scripting/common" as File
|
||||
project(':kotlin-scripting-jvm').projectDir = "$rootDir/libraries/scripting/jvm" as File
|
||||
project(':kotlin-scripting-jvm-host').projectDir = "$rootDir/libraries/scripting/jvm-host" as File
|
||||
project(':kotlin-scripting-compiler-plugin').projectDir = "$rootDir/plugins/scripting/scripting-cli" as File
|
||||
project(':kotlin-scripting-idea-plugin').projectDir = "$rootDir/plugins/scripting/scripting-idea" as File
|
||||
project(':examples:scripting-jvm-simple-script').projectDir = "$rootDir/libraries/examples/scripting/jvm-simple-script" as File
|
||||
project(':examples:scripting-jvm-maven-deps').projectDir = "$rootDir/libraries/examples/scripting/jvm-maven-deps" as File
|
||||
project(':pill:generate-all-tests').projectDir = "$rootDir/plugins/pill/generate-all-tests" as File
|
||||
|
||||
Reference in New Issue
Block a user