[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()); 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) { if (arguments.getOutputFile() == null) {
messageCollector.report(ERROR, "Specify output file via -output", null); messageCollector.report(ERROR, "Specify output file via -output", null);
@@ -208,7 +208,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
Disposer.register(rootDisposable, zipAccessor) Disposer.register(rootDisposable, zipAccessor)
configurationJs.put(JSConfigurationKeys.ZIP_FILE_SYSTEM_ACCESSOR, 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 outputDirPath = arguments.outputDir
val outputName = arguments.moduleName val outputName = arguments.moduleName
@@ -16,15 +16,18 @@
package org.jetbrains.kotlin.cli.common 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.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.IncrementalCompilation 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.FqName
import org.jetbrains.kotlin.name.isSubpackageOf import org.jetbrains.kotlin.name.isSubpackageOf
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.text
import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.util.Logger
import java.io.File import java.io.File
import kotlin.system.exitProcess import kotlin.system.exitProcess
@@ -37,17 +40,23 @@ fun incrementalCompilationIsEnabledForJs(arguments: CommonCompilerArguments): Bo
return arguments.incrementalCompilation ?: IncrementalCompilation.isEnabledForJs() 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)) { if (configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE)) {
return true return true
} }
val kotlinPackage = FqName("kotlin") val kotlinPackage = FqName("kotlin")
for (file in files) { for (file in files) {
if (file.packageFqName.isSubpackageOf(kotlinPackage)) { if (getPackage(file).isSubpackageOf(kotlinPackage)) {
messageCollector.report( messageCollector.report(
CompilerMessageSeverity.ERROR, CompilerMessageSeverity.ERROR,
"Only the Kotlin standard library is allowed to use the 'kotlin' package", "Only the Kotlin standard library is allowed to use the 'kotlin' package",
MessageUtil.psiElementToMessageLocation(file.packageDirective!!) getMessageLocation(file),
) )
return false return false
} }
@@ -55,8 +64,46 @@ fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collect
return true return true
} }
fun checkKotlinPackageUsage(configuration: CompilerConfiguration, files: Collection<KtFile>): Boolean = private val CompilerConfiguration.messageCollector: MessageCollector
checkKotlinPackageUsage(configuration, files, configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)) 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( fun <PathProvider : Any> getLibraryFromHome(
paths: PathProvider?, paths: PathProvider?,
@@ -137,7 +137,7 @@ object FirKotlinToJvmBytecodeCompiler {
performanceManager?.notifyAnalysisStarted() performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
if (!checkKotlinPackageUsage(moduleConfiguration, allSources)) return null if (!checkKotlinPackageUsageForPsi(moduleConfiguration, allSources)) return null
val renderDiagnosticNames = moduleConfiguration.getBoolean(CLIConfigurationKeys.RENDER_DIAGNOSTIC_INTERNAL_NAME) 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.analyzer.AnalysisResult
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys 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.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
@@ -107,7 +107,7 @@ object KotlinToJVMBytecodeCompiler {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = module.getSourceFiles(environment.getSourceFiles(), localFileSystem, chunk.size > 1, buildFile) 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 moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
val backendInput = codegenFactory.getModuleChunkBackendInput(wholeBackendInput, ktFiles) val backendInput = codegenFactory.getModuleChunkBackendInput(wholeBackendInput, ktFiles)
@@ -133,7 +133,7 @@ object KotlinToJVMBytecodeCompiler {
moduleVisibilityManager.addFriendPath(path) 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 val generationState = analyzeAndGenerate(environment) ?: return false
@@ -117,6 +117,10 @@ fun compileModulesUsingFrontendIrAndLightTree(
performanceManager performanceManager
) )
if (!checkKotlinPackageUsageForLightTree(moduleConfiguration, analysisResults.outputs.flatMap { it.fir })) {
return false
}
performanceManager?.notifyAnalysisFinished() performanceManager?.notifyAnalysisFinished()
// TODO: consider what to do if many modules has main classes // 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.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.config.getModuleNameForSource
import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
@@ -115,7 +114,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
return ExitCode.COMPILATION_ERROR return ExitCode.COMPILATION_ERROR
} }
checkKotlinPackageUsage(environment.configuration, environment.getSourceFiles()) checkKotlinPackageUsageForPsi(environment.configuration, environment.getSourceFiles())
try { try {
val useFir = configuration.getBoolean(CommonConfigurationKeys.USE_FIR) 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"); 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") @TestMetadata("functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.args")
public void testFunctionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference() throws Exception { public void testFunctionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference() throws Exception {
runTest("compiler/testData/cli/jvm/functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.args"); 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.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor import org.jetbrains.kotlin.backend.jvm.serialization.JvmIdSignatureDescriptor
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys 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.environment.setIdeaIoUseFallback
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -95,7 +95,7 @@ open class KJvmReplCompilerBase<AnalyzerT : ReplCodeAnalyzerBase>(
if (firstFailure != null) if (firstFailure != null)
return firstFailure return firstFailure
checkKotlinPackageUsage(context.environment.configuration, sourceFiles, messageCollector) checkKotlinPackageUsageForPsi(context.environment.configuration, sourceFiles, messageCollector)
if (messageCollector.hasErrors()) return failure(messageCollector) if (messageCollector.hasErrors()) return failure(messageCollector)
@@ -139,7 +139,7 @@ private fun compileImpl(
messageCollector messageCollector
) )
checkKotlinPackageUsage(context.environment.configuration, sourceFiles, messageCollector) checkKotlinPackageUsageForPsi(context.environment.configuration, sourceFiles, messageCollector)
if (messageCollector.hasErrors() || sourceDependencies.any { it.sourceDependencies is ResultWithDiagnostics.Failure }) { if (messageCollector.hasErrors() || sourceDependencies.any { it.sourceDependencies is ResultWithDiagnostics.Failure }) {
return failure(messageCollector) return failure(messageCollector)