[FIR] KT-57803: Report the error message for light tree

The renaming prevents the JVM clash.

^KT-57803 Fixed
This commit is contained in:
Nikolay Lunyak
2023-05-26 13:12:44 +03:00
committed by Space Team
parent 7f74950993
commit 23f87eda1f
16 changed files with 114 additions and 19 deletions
@@ -0,0 +1,12 @@
/*
* Copyright 2010-2023 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.cli.js
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.psi.KtFile
fun checkKotlinPackageUsageForPsi(configuration: CompilerConfiguration, files: Collection<KtFile>) =
org.jetbrains.kotlin.cli.common.checkKotlinPackageUsageForPsi(configuration, files)
@@ -220,7 +220,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
environmentForJS.getConfiguration().put(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME, arguments.getRenderInternalDiagnosticNames());
if (!UtilsKt.checkKotlinPackageUsage(environmentForJS.getConfiguration(), sourcesFiles)) return ExitCode.COMPILATION_ERROR;
if (!HelpersKt.checkKotlinPackageUsageForPsi(environmentForJS.getConfiguration(), sourcesFiles)) return ExitCode.COMPILATION_ERROR;
if (arguments.getOutputFile() == null) {
messageCollector.report(ERROR, "Specify output file via -output", null);
@@ -208,7 +208,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
Disposer.register(rootDisposable, zipAccessor)
configurationJs.put(JSConfigurationKeys.ZIP_FILE_SYSTEM_ACCESSOR, zipAccessor)
if (!checkKotlinPackageUsage(environmentForJS.configuration, sourcesFiles)) return COMPILATION_ERROR
if (!checkKotlinPackageUsageForPsi(environmentForJS.configuration, sourcesFiles)) return COMPILATION_ERROR
val outputDirPath = arguments.outputDir
val outputName = arguments.moduleName
@@ -16,15 +16,18 @@
package org.jetbrains.kotlin.cli.common
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.KtSourceFileLinesMapping
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
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.messages.*
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.packageFqName
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.isSubpackageOf
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.text
import org.jetbrains.kotlin.util.Logger
import java.io.File
import kotlin.system.exitProcess
@@ -37,17 +40,23 @@ fun incrementalCompilationIsEnabledForJs(arguments: CommonCompilerArguments): Bo
return arguments.incrementalCompilation ?: IncrementalCompilation.isEnabledForJs()
}
fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection<KtFile>, messageCollector: MessageCollector): Boolean {
fun <F> checkKotlinPackageUsage(
configuration: CompilerConfiguration,
files: Collection<F>,
messageCollector: MessageCollector,
getPackage: (F) -> FqName,
getMessageLocation: (F) -> CompilerMessageSourceLocation?,
): Boolean {
if (configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE)) {
return true
}
val kotlinPackage = FqName("kotlin")
for (file in files) {
if (file.packageFqName.isSubpackageOf(kotlinPackage)) {
if (getPackage(file).isSubpackageOf(kotlinPackage)) {
messageCollector.report(
CompilerMessageSeverity.ERROR,
"Only the Kotlin standard library is allowed to use the 'kotlin' package",
MessageUtil.psiElementToMessageLocation(file.packageDirective!!)
getMessageLocation(file),
)
return false
}
@@ -55,8 +64,46 @@ fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collect
return true
}
fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection<KtFile>): Boolean =
checkKotlinPackageUsage(configuration, files, configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE))
private val CompilerConfiguration.messageCollector: MessageCollector
get() = get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
fun checkKotlinPackageUsageForPsi(
configuration: CompilerConfiguration,
files: Collection<KtFile>,
messageCollector: MessageCollector = configuration.messageCollector,
) =
checkKotlinPackageUsage(
configuration, files, messageCollector,
getPackage = { it.packageFqName },
getMessageLocation = { MessageUtil.psiElementToMessageLocation(it.packageDirective!!) },
)
fun checkKotlinPackageUsageForLightTree(
configuration: CompilerConfiguration,
files: Collection<FirFile>,
messageCollector: MessageCollector = configuration.messageCollector,
) =
checkKotlinPackageUsage(
configuration, files, messageCollector,
getPackage = { it.packageFqName },
getMessageLocation = { it.packageDirective.source?.getLocationWithin(it) },
)
private fun KtSourceElement.getLocationWithin(file: FirFile): CompilerMessageLocationWithRange? {
val sourceFile = file.sourceFile ?: return null
val (startLine, startColumn) = file.getLineAndColumnStartingWithOnesAt(startOffset) ?: return null
val (endLine, endColumn) = file.getLineAndColumnStartingWithOnesAt(endOffset) ?: return null
return CompilerMessageLocationWithRange.create(sourceFile.path, startLine, startColumn, endLine, endColumn, text?.toString())
}
private fun FirFile.getLineAndColumnStartingWithOnesAt(offset: Int?): Pair<Int, Int>? {
return offset?.let { sourceFileLinesMapping?.getLineAndColumnByOffsetStartingWithOnes(it) }
}
private fun KtSourceFileLinesMapping.getLineAndColumnByOffsetStartingWithOnes(startOffset: Int): Pair<Int, Int> {
val (line, column) = getLineAndColumnByOffset(startOffset)
return line + 1 to column + 1
}
fun <PathProvider : Any> getLibraryFromHome(
paths: PathProvider?,
@@ -137,7 +137,7 @@ object FirKotlinToJvmBytecodeCompiler {
performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
if (!checkKotlinPackageUsage(moduleConfiguration, allSources)) return null
if (!checkKotlinPackageUsageForPsi(moduleConfiguration, allSources)) return null
val renderDiagnosticNames = moduleConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME)
@@ -15,7 +15,7 @@ import com.intellij.psi.search.GlobalSearchScope
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.checkKotlinPackageUsageForPsi
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
@@ -107,7 +107,7 @@ object KotlinToJVMBytecodeCompiler {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = module.getSourceFiles(environment.getSourceFiles(), localFileSystem, chunk.size > 1, buildFile)
if (!checkKotlinPackageUsage(environment.configuration, ktFiles)) return false
if (!checkKotlinPackageUsageForPsi(environment.configuration, ktFiles)) return false
val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
val backendInput = codegenFactory.getModuleChunkBackendInput(wholeBackendInput, ktFiles)
@@ -133,7 +133,7 @@ object KotlinToJVMBytecodeCompiler {
moduleVisibilityManager.addFriendPath(path)
}
if (!checkKotlinPackageUsage(environment.configuration, environment.getSourceFiles())) return false
if (!checkKotlinPackageUsageForPsi(environment.configuration, environment.getSourceFiles())) return false
val generationState = analyzeAndGenerate(environment) ?: return false
@@ -117,6 +117,10 @@ fun compileModulesUsingFrontendIrAndLightTree(
performanceManager
)
if (!checkKotlinPackageUsageForLightTree(moduleConfiguration, analysisResults.outputs.flatMap { it.fir })) {
return false
}
performanceManager?.notifyAnalysisFinished()
// TODO: consider what to do if many modules has main classes
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.codegen.CompilationException
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.config.getModuleNameForSource
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
@@ -115,7 +114,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
return ExitCode.COMPILATION_ERROR
}
checkKotlinPackageUsage(environment.configuration, environment.getSourceFiles())
checkKotlinPackageUsageForPsi(environment.configuration, environment.getSourceFiles())
try {
val useFir = configuration.getBoolean(CommonConfigurationKeys.USE_FIR)
+6
View File
@@ -0,0 +1,6 @@
// FIR_IDENTICAL
// ISSUE: KT-57803
package kotlin.internal
fun main(args: Array<String>) {}
+3
View File
@@ -0,0 +1,3 @@
$TESTDATA_DIR$/forbidKotlinPackage.kt
-d
$TEMP_DIR$
+4
View File
@@ -0,0 +1,4 @@
compiler/testData/cli/jvm/forbidKotlinPackage.kt:4:1: error: only the Kotlin standard library is allowed to use the 'kotlin' package
package kotlin.internal
^
COMPILATION_ERROR
+5
View File
@@ -0,0 +1,5 @@
$TESTDATA_DIR$/forbidKotlinPackage.kt
-language-version
2.0
-d
$TEMP_DIR$
+5
View File
@@ -0,0 +1,5 @@
warning: language version 2.0 is experimental, there are no backwards compatibility guarantees for new language and library features
compiler/testData/cli/jvm/forbidKotlinPackage.kt:4:1: error: only the Kotlin standard library is allowed to use the 'kotlin' package
package kotlin.internal
^
COMPILATION_ERROR
@@ -595,6 +595,16 @@ public class CliTestGenerated extends AbstractCliTest {
runTest("compiler/testData/cli/jvm/flagAllowingResultAsReturnType.args");
}
@TestMetadata("forbidKotlinPackageK1.args")
public void testForbidKotlinPackageK1() throws Exception {
runTest("compiler/testData/cli/jvm/forbidKotlinPackageK1.args");
}
@TestMetadata("forbidKotlinPackageK2.args")
public void testForbidKotlinPackageK2() throws Exception {
runTest("compiler/testData/cli/jvm/forbidKotlinPackageK2.args");
}
@TestMetadata("functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.args")
public void testFunctionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference() throws Exception {
runTest("compiler/testData/cli/jvm/functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.args");
@@ -11,7 +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.checkKotlinPackageUsageForPsi
import org.jetbrains.kotlin.cli.common.environment.setIdeaIoUseFallback
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -95,7 +95,7 @@ open class KJvmReplCompilerBase<AnalyzerT : ReplCodeAnalyzerBase>(
if (firstFailure != null)
return firstFailure
checkKotlinPackageUsage(context.environment.configuration, sourceFiles, messageCollector)
checkKotlinPackageUsageForPsi(context.environment.configuration, sourceFiles, messageCollector)
if (messageCollector.hasErrors()) return failure(messageCollector)
@@ -139,7 +139,7 @@ private fun compileImpl(
messageCollector
)
checkKotlinPackageUsage(context.environment.configuration, sourceFiles, messageCollector)
checkKotlinPackageUsageForPsi(context.environment.configuration, sourceFiles, messageCollector)
if (messageCollector.hasErrors() || sourceDependencies.any { it.sourceDependencies is ResultWithDiagnostics.Failure }) {
return failure(messageCollector)