[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:
committed by
Space Team
parent
2719dd188f
commit
8ae751926c
@@ -8,11 +8,14 @@ package org.jetbrains.kotlin.cli.common
|
|||||||
import org.jetbrains.kotlin.KtSourceFile
|
import org.jetbrains.kotlin.KtSourceFile
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
|
||||||
import org.jetbrains.kotlin.config.*
|
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.checkers.registerExtendedCommonCheckers
|
||||||
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
|
||||||
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
|
||||||
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
|
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.name.Name
|
||||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||||
import org.jetbrains.kotlin.platform.WasmPlatform
|
|
||||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||||
@@ -359,7 +361,10 @@ private inline fun <F> createSingleSession(
|
|||||||
analyzerServices
|
analyzerServices
|
||||||
)
|
)
|
||||||
|
|
||||||
val session = createFirSession(files, platformModuleData, sessionProvider, sessionConfigurator)
|
val session = createFirSession(files, platformModuleData, sessionProvider) {
|
||||||
|
sessionConfigurator()
|
||||||
|
useCheckers(OptInLanguageVersionSettingsCheckers)
|
||||||
|
}
|
||||||
return SessionWithSources(session, files)
|
return SessionWithSources(session, files)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +404,12 @@ private inline fun <F> createSessionsForLegacyMppProject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val commonSession = createFirSession(commonFiles, commonModuleData, sessionProvider, sessionConfigurator)
|
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(
|
return listOf(
|
||||||
SessionWithSources(commonSession, commonFiles),
|
SessionWithSources(commonSession, commonFiles),
|
||||||
@@ -436,10 +446,17 @@ private inline fun <F> createSessionsForHmppProject(
|
|||||||
moduleDataForHmppModule[module] = moduleData
|
moduleDataForHmppModule[module] = moduleData
|
||||||
}
|
}
|
||||||
|
|
||||||
return hmppModuleStructure.modules.map { module ->
|
return hmppModuleStructure.modules.mapIndexed { i, module ->
|
||||||
val moduleData = moduleDataForHmppModule.getValue(module)
|
val moduleData = moduleDataForHmppModule.getValue(module)
|
||||||
val sources = files.filter { fileBelongsToModule(it, module.name) }
|
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)
|
SessionWithSources(session, sources)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -6,10 +6,9 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.checkers
|
package org.jetbrains.kotlin.fir.analysis.checkers
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirLanguageVersionSettingsChecker
|
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirLanguageVersionSettingsChecker
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.config.FirOptInLanguageVersionSettingsChecker
|
|
||||||
|
|
||||||
object CommonLanguageVersionSettingsCheckers : LanguageVersionSettingsCheckers() {
|
object CommonLanguageVersionSettingsCheckers : LanguageVersionSettingsCheckers() {
|
||||||
|
|
||||||
override val languageVersionSettingsCheckers: Set<FirLanguageVersionSettingsChecker>
|
override val languageVersionSettingsCheckers: Set<FirLanguageVersionSettingsChecker>
|
||||||
get() = setOf(FirOptInLanguageVersionSettingsChecker)
|
get() = setOf()
|
||||||
}
|
}
|
||||||
+15
@@ -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)
|
||||||
|
}
|
||||||
+18
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
kotlin.stdlib.default.dependency=false
|
||||||
+9
@@ -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
|
||||||
Reference in New Issue
Block a user