From a8c4ea04c8e882801e844b20dbc83db9b8c1fbeb Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Tue, 31 May 2022 15:55:47 +0200 Subject: [PATCH] Scripting: add check for 'kotlin' package similar to the regular sources #KT-52598 fixed --- .../org/jetbrains/kotlin/cli/common/utils.kt | 6 +++-- .../experimental/jvmhost/test/ReplTest.kt | 23 +++++++++++++++++++ .../jvmhost/test/ScriptingHostTest.kt | 19 +++++++++++++++ .../plugin/impl/KJvmReplCompilerBase.kt | 3 +++ .../plugin/impl/ScriptJvmCompilerImpls.kt | 3 +++ .../testData/compiler/fib.pkg.kts | 2 +- 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/utils.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/utils.kt index 2c1038ace2c..2368e597496 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/utils.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/utils.kt @@ -42,11 +42,10 @@ fun incrementalCompilationIsEnabledForJs(arguments: CommonCompilerArguments): Bo return arguments.incrementalCompilation ?: IncrementalCompilation.isEnabledForJs() } -fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection): Boolean { +fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection, messageCollector: MessageCollector): Boolean { if (configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE)) { return true } - val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE) val kotlinPackage = FqName("kotlin") for (file in files) { if (file.packageFqName.isSubpackageOf(kotlinPackage)) { @@ -61,6 +60,9 @@ fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collect return true } +fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection): Boolean = + checkKotlinPackageUsage(configuration, files, configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)) + fun getLibraryFromHome( paths: KotlinPaths?, getLibrary: (KotlinPaths) -> File, diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt index c1083b3613c..bf70004908b 100644 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt @@ -382,6 +382,29 @@ class ReplTest : TestCase() { } } + @Test + fun testKotlinPackage() { + val greeting = "Hello from script!" + val error = "Only the Kotlin standard library is allowed to use the 'kotlin' package" + val script = "package kotlin\n\"$greeting\"" + checkEvaluateInReplDiags( + sequenceOf(script), + sequenceOf( + makeFailureResult( + error, path = "Line_0.simplescript.kts", + location = SourceCode.Location(SourceCode.Position(1, 1), SourceCode.Position(1, 15)) + ) + ) + ) + checkEvaluateInRepl( + sequenceOf(script), + sequenceOf(greeting), + simpleScriptCompilationConfiguration.with { + compilerOptions("-Xallow-kotlin-package") + } + ) + } + companion object { private fun positionsEqual(a: SourceCode.Position?, b: SourceCode.Position?): Boolean { if (a == null || b == null) { diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt index ba7cc26a11a..52b87407204 100644 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt @@ -315,6 +315,25 @@ class ScriptingHostTest : TestCase() { Assert.assertEquals(greeting, output) } + @Test + fun testKotlinPackage() { + val greeting = "Hello from script!" + val error = "Only the Kotlin standard library is allowed to use the 'kotlin' package" + val script = "package kotlin\nprintln(\"$greeting\")" + val res0 = evalScript(script) + Assert.assertTrue(res0.reports.any { it.message == error }) + Assert.assertTrue(res0 is ResultWithDiagnostics.Failure) + + val output = captureOut { + val res1 = evalScriptWithConfiguration(script) { + compilerOptions("-Xallow-kotlin-package") + } + Assert.assertTrue(res1.reports.none { it.message == error }) + Assert.assertTrue(res1 is ResultWithDiagnostics.Success) + } + Assert.assertEquals(greeting, output) + } + private fun doDiamondImportTest(evaluationConfiguration: ScriptEvaluationConfiguration? = null): List { val mainScript = "sharedVar += 1\nprintln(\"sharedVar == \$sharedVar\")".toScriptSource("main.kts") val middleScript = File(TEST_DATA_DIR, "importTest/diamondImportMiddle.kts").toScriptSource() diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt index 1e78bc11f00..6cd5288b39d 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -94,6 +95,8 @@ open class KJvmReplCompilerBase( if (firstFailure != null) return firstFailure + checkKotlinPackageUsage(context.environment.configuration, sourceFiles, messageCollector) + if (messageCollector.hasErrors()) return failure(messageCollector) // TODO: support case then JvmDependencyFromClassLoader is registered in non-first line diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt index c5a38b70595..50612206a14 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.impl import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys +import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -126,6 +127,8 @@ private fun compileImpl( messageCollector ) + checkKotlinPackageUsage(context.environment.configuration, sourceFiles, messageCollector) + if (messageCollector.hasErrors() || sourceDependencies.any { it.sourceDependencies is ResultWithDiagnostics.Failure }) { return failure(messageCollector) } diff --git a/plugins/scripting/scripting-compiler/testData/compiler/fib.pkg.kts b/plugins/scripting/scripting-compiler/testData/compiler/fib.pkg.kts index 1e2e80cb593..c226d9add30 100644 --- a/plugins/scripting/scripting-compiler/testData/compiler/fib.pkg.kts +++ b/plugins/scripting/scripting-compiler/testData/compiler/fib.pkg.kts @@ -1,4 +1,4 @@ -package kotlin.scripting.fibonacci +package org.jetbrains.kotlin.scripting.fibonacci // this script expected parameter num : Int fun fib(n: Int): Int {