[FIR] Let OptIn LV checker only run on last module in HMPP compilation

This fixes an issue where the opt-in annotation is defined in one of the
source sets of the compilation but opt-ins are defined for the whole
compilation which leads to false-positive "Opt-in requirement marker is
unresolved" in (e.g. common) source sets that don't have a dependency on
the module that contains the annotation.

#KT-60755 Fixed
This commit is contained in:
Kirill Rakhman
2023-08-04 10:08:08 +02:00
committed by Space Team
parent 2719dd188f
commit 8ae751926c
7 changed files with 91 additions and 10 deletions
@@ -8,11 +8,14 @@ package org.jetbrains.kotlin.cli.common
import org.jetbrains.kotlin.KtSourceFile
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirModuleDataImpl
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.OptInLanguageVersionSettingsCheckers
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionInterfaceProvider
import org.jetbrains.kotlin.fir.session.*
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
@@ -24,7 +27,6 @@ import org.jetbrains.kotlin.load.kotlin.PackageAndMetadataPartProvider
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.WasmPlatform
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.platform.konan.NativePlatforms
@@ -359,7 +361,10 @@ private inline fun <F> createSingleSession(
analyzerServices
)
val session = createFirSession(files, platformModuleData, sessionProvider, sessionConfigurator)
val session = createFirSession(files, platformModuleData, sessionProvider) {
sessionConfigurator()
useCheckers(OptInLanguageVersionSettingsCheckers)
}
return SessionWithSources(session, files)
}
@@ -399,7 +404,12 @@ private inline fun <F> createSessionsForLegacyMppProject(
}
val commonSession = createFirSession(commonFiles, commonModuleData, sessionProvider, sessionConfigurator)
val platformSession = createFirSession(platformFiles, platformModuleData, sessionProvider, sessionConfigurator)
val platformSession = createFirSession(platformFiles, platformModuleData, sessionProvider) {
sessionConfigurator()
// The CLI session might contain an opt-in for an annotation that's defined in the platform module.
// Therefore, only run the opt-in LV checker on the platform module.
useCheckers(OptInLanguageVersionSettingsCheckers)
}
return listOf(
SessionWithSources(commonSession, commonFiles),
@@ -436,10 +446,17 @@ private inline fun <F> createSessionsForHmppProject(
moduleDataForHmppModule[module] = moduleData
}
return hmppModuleStructure.modules.map { module ->
return hmppModuleStructure.modules.mapIndexed { i, module ->
val moduleData = moduleDataForHmppModule.getValue(module)
val sources = files.filter { fileBelongsToModule(it, module.name) }
val session = createFirSession(sources, moduleData, sessionProvider, sessionConfigurator)
val session = createFirSession(sources, moduleData, sessionProvider) {
sessionConfigurator()
// The CLI session might contain an opt-in for an annotation that's defined in one of the modules.
// The only module that's guaranteed to have a dependency on this module is the last one.
if (i == hmppModuleStructure.modules.lastIndex) {
useCheckers(OptInLanguageVersionSettingsCheckers)
}
}
SessionWithSources(session, sources)
}
}
@@ -6,10 +6,9 @@
package org.jetbrains.kotlin.fir.analysis.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirLanguageVersionSettingsChecker
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirOptInLanguageVersionSettingsChecker
object CommonLanguageVersionSettingsCheckers : LanguageVersionSettingsCheckers() {
override val languageVersionSettingsCheckers: Set<FirLanguageVersionSettingsChecker>
get() = setOf(FirOptInLanguageVersionSettingsChecker)
}
get() = setOf()
}
@@ -0,0 +1,15 @@
/*
* 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.fir.analysis.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirLanguageVersionSettingsChecker
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirOptInLanguageVersionSettingsChecker
object OptInLanguageVersionSettingsCheckers : LanguageVersionSettingsCheckers() {
override val languageVersionSettingsCheckers: Set<FirLanguageVersionSettingsChecker>
get() = setOf(FirOptInLanguageVersionSettingsChecker)
}
@@ -137,4 +137,22 @@ class CustomK2Tests : KGPBaseTest() {
}
}
}
@GradleTest
@DisplayName("All source sets have opt-in for annotation defined in platform source set. KT-60755")
fun kt60755OptInDefinedInPlatform(gradleVersion: GradleVersion) {
with(
project(
"k2-mpp-opt-in-in-platform",
gradleVersion,
buildOptions = defaultBuildOptions.copy(languageVersion = "2.0"),
)
) {
val taskToExecute = ":compileKotlinJvm"
build(taskToExecute) {
assertTasksExecuted(taskToExecute)
assertOutputDoesNotContain("Opt-in requirement marker foo.bar.MyOptIn is unresolved")
}
}
}
}
@@ -0,0 +1,22 @@
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
plugins {
kotlin("multiplatform")
}
repositories {
mavenLocal()
mavenCentral()
}
kotlin {
jvm()
sourceSets {
all {
languageSettings.optIn("foo.bar.MyOptIn")
}
}
}
@@ -0,0 +1,9 @@
/*
* 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 foo.bar
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
annotation class MyOptIn