diff --git a/build.xml b/build.xml
index 38f751c6dd1..daf8f2c64a7 100644
--- a/build.xml
+++ b/build.xml
@@ -750,6 +750,7 @@
+
> COMPILER_PLUGINS =
CompilerConfigurationKey.create("compiler plugins");
+ public static final CompilerConfigurationKey ALLOW_KOTLIN_PACKAGE =
+ CompilerConfigurationKey.create("allow kotlin package");
private CLIConfigurationKeys() {
}
diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt
index 077bf531dbb..97d94d6eeb5 100644
--- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt
+++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt
@@ -275,6 +275,7 @@ open class K2JVMCompiler : CLICompiler() {
configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline)
configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize)
configuration.put(JVMConfigurationKeys.MULTIFILE_FACADES_OPEN, arguments.multifileFacadesOpen);
+ configuration.put(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE, arguments.allowKotlinPackage);
}
private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List {
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 cd01ce56d07..aa5ae072306 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
@@ -21,7 +21,9 @@ import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CompilerPluginContext
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAll
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.jvm.config.*
@@ -35,6 +37,8 @@ import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.name.isSubpackageOf
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
@@ -106,10 +110,11 @@ object KotlinToJVMBytecodeCompiler {
for (module in chunk) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
- val jetFiles = CompileEnvironmentUtil.getKtFiles(
+ val ktFiles = CompileEnvironmentUtil.getKtFiles(
environment.project, getAbsolutePaths(directory, module)) { s -> throw IllegalStateException("Should have been checked before: " + s) }
+ if (!checkKotlinPackageUsage(environment, ktFiles)) return false
val moduleOutputDirectory = File(module.getOutputDirectory())
- val generationState = generate(environment, result, jetFiles, module, moduleOutputDirectory,
+ val generationState = generate(environment, result, ktFiles, module, moduleOutputDirectory,
module.getModuleName())
outputFiles.put(module, generationState.factory)
}
@@ -173,6 +178,7 @@ object KotlinToJVMBytecodeCompiler {
moduleVisibilityManager.addFriendPath(path)
}
+ if (!checkKotlinPackageUsage(environment, environment.getSourceFiles())) return false
val generationState = analyzeAndGenerate(environment) ?: return false
val mainClass = findMainClass(generationState, environment.getSourceFiles())
@@ -360,6 +366,23 @@ object KotlinToJVMBytecodeCompiler {
return generationState
}
+ private fun checkKotlinPackageUsage(environment: KotlinCoreEnvironment, files: Collection): Boolean {
+ if (environment.configuration.get(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE) == true) {
+ return true
+ }
+ val messageCollector = environment.configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
+ val kotlinPackage = FqName.topLevel(Name.identifier("kotlin"))
+ files.forEach {
+ if (it.packageFqName.isSubpackageOf(kotlinPackage)) {
+ messageCollector.report(CompilerMessageSeverity.ERROR,
+ "Only the Kotlin standard library is allowed to use the 'kotlin' package",
+ MessageUtil.psiElementToMessageLocation(it.packageDirective!!))
+ return false
+ }
+ }
+ return true
+ }
+
fun KotlinCoreEnvironment.messageCollector(): MessageCollector {
val result = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
assert(result != null) { "Message collector not specified in compiler configuration" }
diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out
index a39536a38ac..0e871954e54 100644
--- a/compiler/testData/cli/jvm/extraHelp.out
+++ b/compiler/testData/cli/jvm/extraHelp.out
@@ -5,6 +5,7 @@ where advanced options include:
-Xno-optimize Disable optimizations
-Xreport-perf Report detailed performance statistics
-Xmultifile-facades-open Compile multifile facade classes as open
+ -Xallow-kotlin-package Allow compiling code in package 'kotlin'
-Xno-inline Disable method inlining
-Xrepeat Repeat compilation (for performance analysis)
-Xplugin Load plugins from the given classpath
diff --git a/compiler/testData/cli/jvm/kotlinPackage.args b/compiler/testData/cli/jvm/kotlinPackage.args
new file mode 100644
index 00000000000..61d00a6b529
--- /dev/null
+++ b/compiler/testData/cli/jvm/kotlinPackage.args
@@ -0,0 +1,3 @@
+$TESTDATA_DIR$/kotlinPackage.kt
+-d
+$TEMP_DIR$
diff --git a/compiler/testData/cli/jvm/kotlinPackage.kt b/compiler/testData/cli/jvm/kotlinPackage.kt
new file mode 100644
index 00000000000..afc3dc9a780
--- /dev/null
+++ b/compiler/testData/cli/jvm/kotlinPackage.kt
@@ -0,0 +1,4 @@
+package kotlin.mylibrary
+
+class MyLibraryManager {
+}
diff --git a/compiler/testData/cli/jvm/kotlinPackage.out b/compiler/testData/cli/jvm/kotlinPackage.out
new file mode 100644
index 00000000000..b2770332251
--- /dev/null
+++ b/compiler/testData/cli/jvm/kotlinPackage.out
@@ -0,0 +1,4 @@
+compiler/testData/cli/jvm/kotlinPackage.kt:1:1: error: only the Kotlin standard library is allowed to use the 'kotlin' package
+package kotlin.mylibrary
+^
+COMPILATION_ERROR
\ No newline at end of file
diff --git a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java
index cfff9476d52..1e23f2a3c72 100644
--- a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java
+++ b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java
@@ -133,6 +133,12 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes
doJvmTest(fileName);
}
+ @TestMetadata("kotlinPackage.args")
+ public void testKotlinPackage() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/kotlinPackage.args");
+ doJvmTest(fileName);
+ }
+
@TestMetadata("multipleTextRangesInDiagnosticsOrder.args")
public void testMultipleTextRangesInDiagnosticsOrder() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/multipleTextRangesInDiagnosticsOrder.args");
diff --git a/libraries/stdlib/pom.xml b/libraries/stdlib/pom.xml
index 31a7f63f5db..c872823f663 100644
--- a/libraries/stdlib/pom.xml
+++ b/libraries/stdlib/pom.xml
@@ -40,6 +40,7 @@
-Xmultifile-facades-open
+ -Xallow-kotlin-package