diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index 5e52b1c9b19..f6205c92de5 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -415,6 +415,9 @@ abstract class CommonCompilerArguments : CommonToolArguments() { @Argument(value = "-Xrender-internal-diagnostic-names", description = "Render internal names of warnings and errors") var renderInternalDiagnosticNames: Boolean by FreezableVar(false) + @Argument(value = "-Xallow-any-scripts-in-source-roots", description = "Allow to compile any scripts along with regular Kotlin sources") + var allowAnyScriptsInSourceRoots: Boolean by FreezableVar(false) + @OptIn(IDEAPluginsCompatibilityAPI::class) open fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap, Any> { return HashMap, Any>().apply { @@ -508,6 +511,10 @@ abstract class CommonCompilerArguments : CommonToolArguments() { } } + if (allowAnyScriptsInSourceRoots) { + put(LanguageFeature.SkipStandaloneScriptsInSourceRoots, LanguageFeature.State.DISABLED) + } + // Internal arguments should go last, because it may be useful to override // some feature state via -XX (even if some -X flags were passed) if (internalArguments.isNotEmpty()) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt index 80a54a8a1a5..df173dbf0af 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt @@ -28,6 +28,7 @@ fun CompilerConfiguration.setupCommonArguments( putIfNotNull(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, arguments.intellijPluginRoot) put(CommonConfigurationKeys.REPORT_OUTPUT_FILES, arguments.reportOutputFiles) put(CommonConfigurationKeys.INCREMENTAL_COMPILATION, incrementalCompilationIsEnabled(arguments)) + put(CommonConfigurationKeys.ALLOW_ANY_SCRIPTS_IN_SOURCE_ROOTS, arguments.allowAnyScriptsInSourceRoots) val metadataVersionString = arguments.metadataVersion if (metadataVersionString != null) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index faa363c4b33..3d0b14b11b1 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -637,6 +637,7 @@ class KotlinCoreEnvironment private constructor( JsSyntheticTranslateExtension.registerExtensionPoint(project) CompilerConfigurationExtension.registerExtensionPoint(project) CollectAdditionalSourcesExtension.registerExtensionPoint(project) + ProcessSourcesBeforeCompilingExtension.registerExtensionPoint(project) ExtraImportsProviderExtension.registerExtensionPoint(project) IrGenerationExtension.registerExtensionPoint(project) ScriptEvaluationExtension.registerExtensionPoint(project) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 0037ec5d52e..11ed7612baa 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -37,12 +37,10 @@ import org.jetbrains.kotlin.codegen.ClassBuilderFactories import org.jetbrains.kotlin.codegen.CodegenFactory import org.jetbrains.kotlin.codegen.DefaultCodegenFactory import org.jetbrains.kotlin.codegen.state.GenerationState -import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.diagnostics.DiagnosticReporterFactory import org.jetbrains.kotlin.diagnostics.impl.BaseDiagnosticsCollector +import org.jetbrains.kotlin.extensions.ProcessSourcesBeforeCompilingExtension import org.jetbrains.kotlin.ir.backend.jvm.jvmResolveLibraries import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager import org.jetbrains.kotlin.modules.Module @@ -236,8 +234,11 @@ object KotlinToJVMBytecodeCompiler { } fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? { - val sourceFiles = environment.getSourceFiles() val collector = environment.messageCollector + val sourceFiles = ProcessSourcesBeforeCompilingExtension.getInstances(environment.project) + .fold(environment.getSourceFiles() as Collection) { files, extension -> + extension.processSources(files, environment.configuration) + } // Can be null for Scripts/REPL val performanceManager = environment.configuration.get(CLIConfigurationKeys.PERF_MANAGER) diff --git a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index 7caa6cf2483..962197aa203 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -74,6 +74,10 @@ object CommonConfigurationKeys { @JvmField val INCREMENTAL_COMPILATION = CompilerConfigurationKey.create("Enable incremental compilation") + + @JvmField + val ALLOW_ANY_SCRIPTS_IN_SOURCE_ROOTS = + CompilerConfigurationKey.create("Allow to compile any scripts along with regular Kotlin sources") } var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings diff --git a/compiler/frontend/src/org/jetbrains/kotlin/extensions/ProcessSourcesBeforeCompilingExtension.kt b/compiler/frontend/src/org/jetbrains/kotlin/extensions/ProcessSourcesBeforeCompilingExtension.kt new file mode 100644 index 00000000000..ef698b23751 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/kotlin/extensions/ProcessSourcesBeforeCompilingExtension.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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 +import org.jetbrains.kotlin.psi.KtFile + +interface ProcessSourcesBeforeCompilingExtension { + + companion object : ProjectExtensionDescriptor( + "org.jetbrains.kotlin.processSourcesBeforeCompilingExtension", + ProcessSourcesBeforeCompilingExtension::class.java + ) + + fun processSources( + sources: Collection, + configuration: CompilerConfiguration + ): Collection +} \ No newline at end of file diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 8ce6a898960..7815c84b82f 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -45,6 +45,8 @@ where advanced options include: Turn on range checks for the array access functions -Xwasm-enable-asserts Turn on asserts -Xwasm-kclass-fqn Enable support for FQ names in KClass + -Xallow-any-scripts-in-source-roots + Allow to compile any scripts along with regular Kotlin sources -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info -Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type -Xbuiltins-from-sources Compile builtIns from sources diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index cb3c9750afe..e3eaaff842c 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -150,6 +150,8 @@ where advanced options include: -Xuse-type-table Use type table in metadata serialization -Xvalidate-bytecode Validate generated JVM bytecode before and after optimizations -Xvalidate-ir Validate IR before and after lowering + -Xallow-any-scripts-in-source-roots + Allow to compile any scripts along with regular Kotlin sources -Xallow-kotlin-package Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info -Xallow-result-return-type Allow compiling code when `kotlin.Result` is used as a return type -Xbuiltins-from-sources Compile builtIns from sources diff --git a/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt index dec6c98dd78..34154dbac76 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/cli/LauncherScriptTest.kt @@ -299,7 +299,7 @@ println(42) expectedStderr = "error: unrecognized script type: noInline.myscript; Specify path to the script file as the first argument\n" ) runProcess( - "kotlin", "-howtorun", ".kts", "$testDataDirectory/noInline.myscript", + "kotlin", "-Xallow-any-scripts-in-source-roots", "-howtorun", ".kts", "$testDataDirectory/noInline.myscript", expectedExitCode = 1, expectedStderr = """error: unresolved reference: CompilerOptions (noInline.myscript:1:7) compiler/testData/launcher/noInline.myscript:1:7: error: unresolved reference: CompilerOptions @file:CompilerOptions("-Xno-inline") diff --git a/compiler/tests/org/jetbrains/kotlin/integration/CompilerSmokeTest.java b/compiler/tests/org/jetbrains/kotlin/integration/CompilerSmokeTest.java index 5cc15b62606..64e79733ff7 100644 --- a/compiler/tests/org/jetbrains/kotlin/integration/CompilerSmokeTest.java +++ b/compiler/tests/org/jetbrains/kotlin/integration/CompilerSmokeTest.java @@ -172,7 +172,7 @@ public class CompilerSmokeTest extends CompilerSmokeTestBase { public void testCompileScript() throws Exception { String jar = tmpdir.getAbsolutePath() + File.separator + "script.jar"; - runCompiler("script", "script.kts", "-d", jar); + runCompiler("script", "-Xallow-any-scripts-in-source-roots", "script.kts", "-d", jar); } public void testInlineOnly() throws Exception { diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index eaa28a1a4b2..8a4eb892339 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -278,6 +278,7 @@ enum class LanguageFeature( ForbidInferringTypeVariablesIntoEmptyIntersection(KOTLIN_1_9, kind = BUG_FIX), // KT-51221 ForbidExtensionCallsOnInlineFunctionalParameters(KOTLIN_1_9, kind = BUG_FIX), // KT-52502 ForbidInferringPostponedTypeVariableIntoDeclaredUpperBound(KOTLIN_1_9, kind = BUG_FIX), // KT-47986 + SkipStandaloneScriptsInSourceRoots(KOTLIN_1_9, kind = OTHER), // KT-52525 // Disabled for indefinite time. See KT-48535 and related discussion ApproximateIntegerLiteralTypesInReceiverPosition(sinceVersion = null), diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt index a62b9b53cd5..bfbed715196 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptCompilation.kt @@ -170,6 +170,13 @@ val ScriptCompilationConfigurationKeys.sourceFragments by PropertiesCollection.k */ val ScriptCompilationConfigurationKeys.hostConfiguration by PropertiesCollection.key(isTransient = true) +/** + * Should the script be always considered standalone + * If true, it is ignored when compiled along with other sources (starting from 1.9, according to SkipStandaloneScriptsInSourceRoots language feature) + * true by default + */ +val ScriptCompilationConfigurationKeys.isStandalone by PropertiesCollection.key(true) + /** * The sub-builder DSL for configuring refinement callbacks */ diff --git a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptIdeConfiguration.kt b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptIdeConfiguration.kt index f1757a7bbe0..baa950d508c 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/api/scriptIdeConfiguration.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/api/scriptIdeConfiguration.kt @@ -20,8 +20,8 @@ enum class ScriptAcceptedLocation { Sources, // Under sources roots Tests, // Under test sources roots Libraries, // Under libraries classes or sources - Project, // Under project folder, including sources and test sources roots - Everywhere; + Project, // Project infrastructure: project files excluding source roots + Everywhere; // All places in the project } val ScriptCompilationConfigurationKeys.ide @@ -30,9 +30,4 @@ val ScriptCompilationConfigurationKeys.ide val IdeScriptCompilationConfigurationKeys.dependenciesSources by PropertiesCollection.key>() val IdeScriptCompilationConfigurationKeys.acceptedLocations - by PropertiesCollection.key( - listOf( - ScriptAcceptedLocation.Sources, - ScriptAcceptedLocation.Tests - ) - ) + by PropertiesCollection.key(listOf(ScriptAcceptedLocation.Everywhere)) diff --git a/libraries/scripting/common/src/kotlin/script/experimental/host/configurationFromTemplate.kt b/libraries/scripting/common/src/kotlin/script/experimental/host/configurationFromTemplate.kt index a5e9e4be9e4..84dc8516b27 100644 --- a/libraries/scripting/common/src/kotlin/script/experimental/host/configurationFromTemplate.kt +++ b/libraries/scripting/common/src/kotlin/script/experimental/host/configurationFromTemplate.kt @@ -156,6 +156,10 @@ private fun ScriptCompilationConfiguration.Builder.propertiesFromTemplate( ) { baseClass.replaceOnlyDefault(if (templateClass == baseClassType.fromClass) baseClassType else KotlinType(templateClass)) fileExtension.replaceOnlyDefault(mainAnnotation.fileExtension) + // TODO: remove this exception when gradle switches to the new definitions and sets the property accordingly + if (get(fileExtension) == "gradle.kts") { + isStandalone(false) + } filePathPattern.replaceOnlyDefault(mainAnnotation.filePathPattern) displayName.replaceOnlyDefault(mainAnnotation.displayName) } diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt index 2f0c73cf7dc..c4668bad307 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptCompilationConfigurationFromDefinition.kt @@ -36,6 +36,10 @@ class ScriptCompilationConfigurationFromDefinition( platform(scriptDefinition.platform) @Suppress("DEPRECATION") compilerOptions.putIfAny(scriptDefinition.additionalCompilerArguments) + // TODO: remove this exception when gradle switches to the new definitions and sets the property accordingly + if (scriptDefinition.fileExtension == "gradle.kts") { + isStandalone(false) + } ide { acceptedLocations.put(scriptDefinition.scriptExpectedLocations.mapLegacyExpectedLocations()) } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/extensions/ScriptingProcessSourcesBeforeCompilingExtension.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/extensions/ScriptingProcessSourcesBeforeCompilingExtension.kt new file mode 100644 index 00000000000..28b0bed2a83 --- /dev/null +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/extensions/ScriptingProcessSourcesBeforeCompilingExtension.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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.extensions + +import com.intellij.openapi.project.Project +import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY +import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity +import org.jetbrains.kotlin.config.CommonConfigurationKeys +import org.jetbrains.kotlin.config.CompilerConfiguration +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.languageVersionSettings +import org.jetbrains.kotlin.extensions.ProcessSourcesBeforeCompilingExtension +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider +import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource +import kotlin.script.experimental.api.* + +class ScriptingProcessSourcesBeforeCompilingExtension(val project: Project) : ProcessSourcesBeforeCompilingExtension { + + override fun processSources(sources: Collection, configuration: CompilerConfiguration): Collection { + val versionSettings = configuration.languageVersionSettings + val shouldSkipStandaloneScripts = versionSettings.supportsFeature(LanguageFeature.SkipStandaloneScriptsInSourceRoots) + val definitionProvider by lazy(LazyThreadSafetyMode.NONE) { ScriptDefinitionProvider.getInstance(project) } + val messageCollector = configuration.getNotNull(MESSAGE_COLLECTOR_KEY) + + fun KtFile.isStandaloneScript(): Boolean { + val scriptDefinition = definitionProvider?.findDefinition(KtFileScriptSource(this)) + return scriptDefinition?.compilationConfiguration?.get(ScriptCompilationConfiguration.isStandalone) ?: true + } + + // filter out scripts that are not suitable for source roots, according to the compiler configuration and script definitions + return sources.filter { ktFile -> + when { + !ktFile.isScript() -> true + configuration.getBoolean(CommonConfigurationKeys.ALLOW_ANY_SCRIPTS_IN_SOURCE_ROOTS) -> true + !ktFile.isStandaloneScript() -> true + else -> { + if (!shouldSkipStandaloneScripts) { + messageCollector.report( + CompilerMessageSeverity.WARNING, + "Script '${ktFile.name}' is not supposed to be used along with regular Kotlin sources, and will be ignored in the future versions by default. (Use -Xallow-any-scripts-in-source-roots command line option to opt-in for the old behavior.)" + ) + } + !shouldSkipStandaloneScripts + } + } + } + } +} \ No newline at end of file diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt index 288960a72ac..6c96f383812 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/pluginRegisrar.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.extensions.CollectAdditionalSourcesExtension import org.jetbrains.kotlin.extensions.CompilerConfigurationExtension +import org.jetbrains.kotlin.extensions.ProcessSourcesBeforeCompilingExtension import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension @@ -24,6 +25,7 @@ import org.jetbrains.kotlin.scripting.compiler.plugin.definitions.CliScriptDepen import org.jetbrains.kotlin.scripting.compiler.plugin.definitions.CliScriptReportSink import org.jetbrains.kotlin.scripting.compiler.plugin.extensions.JvmStandardReplFactoryExtension import org.jetbrains.kotlin.scripting.compiler.plugin.extensions.ScriptingCollectAdditionalSourcesExtension +import org.jetbrains.kotlin.scripting.compiler.plugin.extensions.ScriptingProcessSourcesBeforeCompilingExtension import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider import org.jetbrains.kotlin.scripting.extensions.ScriptExtraImportsProviderExtension @@ -56,6 +58,7 @@ class ScriptingCompilerConfigurationComponentRegistrar : ComponentRegistrar { withClassloadingProblemsReporting(messageCollector) { CompilerConfigurationExtension.registerExtension(project, ScriptingCompilerConfigurationExtension(project, hostConfiguration)) CollectAdditionalSourcesExtension.registerExtension(project, ScriptingCollectAdditionalSourcesExtension(project)) + ProcessSourcesBeforeCompilingExtension.registerExtension(project, ScriptingProcessSourcesBeforeCompilingExtension(project)) ScriptEvaluationExtension.registerExtensionIfRequired(project, JvmCliScriptEvaluationExtension()) ShellExtension.registerExtensionIfRequired(project, JvmCliReplShellExtension()) ReplFactoryExtension.registerExtensionIfRequired(project, JvmStandardReplFactoryExtension()) diff --git a/plugins/scripting/scripting-compiler/testData/compiler/mixedCompilation/simpleScript.main.kts b/plugins/scripting/scripting-compiler/testData/compiler/mixedCompilation/simpleScript.main.kts new file mode 100644 index 00000000000..474e6885896 --- /dev/null +++ b/plugins/scripting/scripting-compiler/testData/compiler/mixedCompilation/simpleScript.main.kts @@ -0,0 +1,2 @@ + +val ok = "OK" diff --git a/plugins/scripting/scripting-compiler/testData/compiler/mixedCompilation/simpleScriptInstance.kt b/plugins/scripting/scripting-compiler/testData/compiler/mixedCompilation/simpleScriptInstance.kt new file mode 100644 index 00000000000..339be9f66d5 --- /dev/null +++ b/plugins/scripting/scripting-compiler/testData/compiler/mixedCompilation/simpleScriptInstance.kt @@ -0,0 +1,4 @@ + +fun main() { + println(SimpleScript_main(emptyArray(), java.io.File("")).ok) +} diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt index f6d79647d74..3b7e086a365 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/ScriptingWithCliCompilerTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.scripting.compiler.plugin import org.jetbrains.kotlin.cli.common.CLITool +import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.scripting.compiler.test.linesSplitTrim @@ -187,6 +188,58 @@ class ScriptingWithCliCompilerTest { ) } + @Test + fun testCompileScriptWithRegularKotlin() { + + fun compileVariant(vararg flags: String): Pair, ExitCode> { + return withTempDir { tmpdir -> + val (_, err, exitCode) = captureOutErrRet { + CLITool.doMainNoExit( + K2JVMCompiler(), + arrayOf( + "-d", tmpdir.path, + "-cp", getMainKtsClassPath().joinToString(File.pathSeparator), + *flags, + "$TEST_DATA_DIR/compiler/mixedCompilation/simpleScriptInstance.kt", + "$TEST_DATA_DIR/compiler/mixedCompilation/simpleScript.main.kts" + ) + ) + } + err.linesSplitTrim() to exitCode + } + } + + val scriptInSourceRootWarning = + "warning: script 'simpleScript.main.kts' is not supposed to be used along with regular Kotlin sources, and will be ignored in the future versions" + + val unresolvedScriptError = + "simpleScriptInstance.kt:3:13: error: unresolved reference: SimpleScript_main" + + compileVariant("-language-version", "1.7").let { (errLines, exitCode) -> + Assert.assertTrue(errLines.any { it.startsWith(scriptInSourceRootWarning) }) + Assert.assertEquals(ExitCode.OK, exitCode) + } + + compileVariant("-language-version", "1.7", "-Xallow-any-scripts-in-source-roots").let { (errLines, exitCode) -> + Assert.assertTrue(errLines.none { it.startsWith(scriptInSourceRootWarning) }) + Assert.assertEquals(ExitCode.OK, exitCode) + } + + compileVariant("-language-version", "1.9").let { (errLines, exitCode) -> + if (errLines.none { it.endsWith(unresolvedScriptError) }) { + Assert.fail("Expecting unresolved reference: SimpleScript_main error, got:\n${errLines.joinToString("\n")}") + } + Assert.assertEquals(ExitCode.COMPILATION_ERROR, exitCode) + } + + compileVariant("-language-version", "1.9", "-Xallow-any-scripts-in-source-roots").let { (errLines, exitCode) -> + Assert.assertTrue(errLines.none { + it.endsWith(unresolvedScriptError) || it.startsWith(scriptInSourceRootWarning) + }) + Assert.assertEquals(ExitCode.OK, exitCode) + } + } + private fun getMainKtsClassPath(): List { return listOf( File("dist/kotlinc/lib/kotlin-main-kts.jar").also { diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt index c44f77ae3b9..2921360b257 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/plugin/testUtil.kt @@ -224,10 +224,10 @@ internal fun captureOutErrRet(body: () -> T): Triple { return Triple(outStream.toString().trim(), errStream.toString().trim(), ret) } -internal fun withTempDir(keyName: String = "tmp", body: (File) -> R) { +internal fun withTempDir(keyName: String = "tmp", body: (File) -> R): R { val tempDir = Files.createTempDirectory(keyName).toFile() try { - body(tempDir) + return body(tempDir) } finally { tempDir.deleteRecursively() }