From f3faa10fcc7cd126a39bf9318164145e08338fc0 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 13 Jan 2016 19:04:16 +0100 Subject: [PATCH] forbid compiling code in packages with names starting with 'kotlin' unless the -Xallow-kotlin-package command line option is specified --- build.xml | 1 + .../arguments/K2JVMCompilerArguments.java | 3 +++ .../cli/common/CLIConfigurationKeys.java | 2 ++ .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 1 + .../compiler/KotlinToJVMBytecodeCompiler.kt | 27 +++++++++++++++++-- compiler/testData/cli/jvm/extraHelp.out | 1 + compiler/testData/cli/jvm/kotlinPackage.args | 3 +++ compiler/testData/cli/jvm/kotlinPackage.kt | 4 +++ compiler/testData/cli/jvm/kotlinPackage.out | 4 +++ .../cli/KotlincExecutableTestGenerated.java | 6 +++++ libraries/stdlib/pom.xml | 1 + 11 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/cli/jvm/kotlinPackage.args create mode 100644 compiler/testData/cli/jvm/kotlinPackage.kt create mode 100644 compiler/testData/cli/jvm/kotlinPackage.out 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