[JPS] Fix incremental build after changing Java enum used in Kotlin when

EnumWhenTracker implemented for tracking changed java enum class items, that used in kotlin when expression.

#KT-47824 Fixed
This commit is contained in:
Aleksei.Cherepanov
2021-11-04 17:13:56 +03:00
committed by Space
parent ee8de63497
commit 3d8f140d6b
38 changed files with 319 additions and 57 deletions
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.fir.scopes.impl.FirSubstitutionOverrideStorage
import org.jetbrains.kotlin.fir.symbols.FirPhaseManager
import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache
import org.jetbrains.kotlin.fir.types.TypeComponents
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
@@ -94,7 +95,7 @@ fun FirSession.registerCommonJavaComponents(javaModuleResolver: JavaModuleResolv
* Resolve components which are same on all platforms
*/
@OptIn(SessionConfiguration::class)
fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null) {
fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null, enumWhenTracker: EnumWhenTracker? = null) {
register(FirQualifierResolver::class, FirQualifierResolverImpl(this))
register(FirTypeResolver::class, FirTypeResolverImpl(this))
register(CheckersComponent::class, CheckersComponent())
@@ -110,6 +111,12 @@ fun FirSession.registerResolveComponents(lookupTracker: LookupTracker? = null) {
IncrementalPassThroughLookupTrackerComponent(lookupTracker, firFileToPath)
)
}
if (enumWhenTracker != null) {
register(
FirEnumWhenTrackerComponent::class,
IncrementalPassThroughEnumWhenTrackerComponent(enumWhenTracker)
)
}
}
/*
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.name.Name
@@ -88,6 +89,7 @@ object FirSessionFactory {
javaSourcesScope: AbstractProjectFileSearchScope,
librariesScope: AbstractProjectFileSearchScope,
lookupTracker: LookupTracker?,
enumWhenTracker: EnumWhenTracker?,
incrementalCompilationContext: IncrementalCompilationContext?,
extensionRegistrars: List<FirExtensionRegistrar>,
needRegisterJavaElementFinder: Boolean,
@@ -123,6 +125,7 @@ object FirSessionFactory {
extensionRegistrars,
languageVersionSettings = languageVersionSettings,
lookupTracker = lookupTracker,
enumWhenTracker = enumWhenTracker,
needRegisterJavaElementFinder,
init = sessionConfigurator
)
@@ -137,6 +140,7 @@ object FirSessionFactory {
extensionRegistrars: List<FirExtensionRegistrar>,
languageVersionSettings: LanguageVersionSettings = LanguageVersionSettingsImpl.DEFAULT,
lookupTracker: LookupTracker? = null,
enumWhenTracker: EnumWhenTracker? = null,
needRegisterJavaElementFinder: Boolean,
init: FirSessionConfigurator.() -> Unit = {}
): FirSession {
@@ -147,7 +151,7 @@ object FirSessionFactory {
registerCliCompilerOnlyComponents()
registerCommonComponents(languageVersionSettings)
registerCommonJavaComponents(projectEnvironment.getJavaModuleResolver())
registerResolveComponents(lookupTracker)
registerResolveComponents(lookupTracker, enumWhenTracker)
registerJavaSpecificResolveComponents()
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2021 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.session
import org.jetbrains.kotlin.fir.FirEnumWhenTrackerComponent
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
class IncrementalPassThroughEnumWhenTrackerComponent(private val enumWhenTracker: EnumWhenTracker) : FirEnumWhenTrackerComponent() {
override fun report(whenExpressionFilePath: String, enumClassFqName: String) {
enumWhenTracker.report(whenExpressionFilePath, enumClassFqName)
}
}
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.expressions.*
@@ -96,6 +95,10 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Any?): FirStatement {
processExhaustivenessCheck(whenExpression)
bodyResolveComponents.session.enumWhenTracker?.reportEnumUsageInWhen(
bodyResolveComponents.file.sourceFile?.path,
getSubjectType(bodyResolveComponents.session, whenExpression)
)
return whenExpression
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2021 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
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.classId
abstract class FirEnumWhenTrackerComponent : FirSessionComponent {
abstract fun report(whenExpressionFilePath: String, enumClassFqName: String)
}
val FirSession.enumWhenTracker: FirEnumWhenTrackerComponent? by FirSession.nullableSessionComponentAccessor()
fun FirEnumWhenTrackerComponent.reportEnumUsageInWhen(path: String?, subjectType: ConeKotlinType?) {
if (path == null || subjectType == null) return
val fqName = subjectType.classId?.asString()?.replace(".", "$")?.replace("/", ".") ?: return
this.report(path, fqName)
}